// RMI receiver in the server to remove all items from the inventory. changes are automatically propagated to the clients
IMPLEMENT_RMI(CInventory, SvReq_RemoveAllItems)
{
  IItemSystem* pItemSystem = CCryAction::GetCryAction()->GetIItemSystem();
  
  IItem* pItem = pItemSystem->GetItem( GetCurrentItem() );
  if (pItem) 
  {
    pItem->Select(false);
    pItemSystem->SetActorItem( GetActor(), (EntityId)0, false );
  }

	Destroy();

	if (gEnv->bMultiplayer)
	{
		TRMIInventory_Dummy Info;
		GetGameObject()->InvokeRMI( Cl_RemoveAllAmmo(), Info, eRMI_ToAllClients);
	}
	else
	{
		ResetAmmo();
	}

	return true;
}
// RMI receiver in the server to remove an item from the inventory. change is automatically propagated to the clients
IMPLEMENT_RMI(CInventory, SvReq_RemoveItem)
{
	TRMIInventory_Item Info(params);
	
  IItemSystem* pItemSystem = CCryAction::GetCryAction()->GetIItemSystem();
  
	IEntityClass* pClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass( Info.m_ItemClass.c_str());
	if (pClass)
	{
    IItem* pItem = pItemSystem->GetItem( GetItemByClass( pClass ) );
    if (pItem && pItem->GetEntityId()==GetCurrentItem()) 
    {
      pItem->Select(false);
      pItemSystem->SetActorItem( GetActor(), (EntityId)0, false );
    }

    if (pItem)
      gEnv->pEntitySystem->RemoveEntity( pItem->GetEntityId() );
  }
	return true;
}
示例#3
0
// Give an equipment pack (resp. items/ammo) to an actor
bool CEquipmentManager::GiveEquipmentPack(IActor* pActor, const char* packName, bool bAdd, bool selectPrimary)
{
	if (!pActor)
		return false;

	// causes side effects, don't remove
	CGiveEquipmentPackNotifier notifier(this, pActor);

	SEquipmentPack* pPack = GetPack(packName);

	if (pPack == 0)
	{
		const IEntity* pEntity = pActor->GetEntity();
		GameWarning("[EquipmentMgr]: Cannot give pack '%s' to Actor '%s'. Pack not found.", packName, pEntity ? pEntity->GetName() : "<unnamed>"); 
		return false;
	}

	IInventory *pInventory = pActor->GetInventory();
	if (pInventory == 0)
	{
		const IEntity* pEntity = pActor->GetEntity();
		GameWarning("[EquipmentMgr]: Cannot give pack '%s' to Actor '%s'. No inventory.", packName, pEntity ? pEntity->GetName() : "<unnamed>"); 
		return false;
	}

	bool bHasNoWeapon = false;
	bool bHasAnySelected = false;
	const char *strNoWeapon = "NoWeapon";


	if (bAdd == false)
	{
		IItem* pItem = m_pItemSystem->GetItem(pInventory->GetCurrentItem());
		if (pItem)
		{
			pItem->Select(false);
			m_pItemSystem->SetActorItem(pActor, (EntityId)0, false);
		}
		pInventory->RemoveAllItems(true);
		pInventory->ResetAmmo();
	}
	else
	{
		// Since we're adding items, check on the current status of NoWeapon
		bHasNoWeapon = pInventory->GetCountOfClass(strNoWeapon) > 0;
	}

	std::vector<SEquipmentPack::SEquipmentItem>::const_iterator itemIter = pPack->m_items.begin();
	std::vector<SEquipmentPack::SEquipmentItem>::const_iterator itemIterEnd = pPack->m_items.end();

	for ( ; itemIter != itemIterEnd; ++itemIter)
	{
		const SEquipmentPack::SEquipmentItem& item = *itemIter;

		// If the equipmentPack specifies a primary weapon then select this item if it's the specified item, if
		// the equipmentPack doesn't specify a primary weapon then just select the first item of the set (fallback)
		bool bPrimaryItem = (itemIter == pPack->m_items.begin());
		if (!pPack->m_primaryItem.empty())
			bPrimaryItem = (pPack->m_primaryItem.compare(item.m_name) == 0);

		EntityId itemId = m_pItemSystem->GiveItem(pActor, item.m_name, false, bPrimaryItem, true); // don't select

		// Update state of NoWeapon
		bHasNoWeapon |= (item.m_name == strNoWeapon);
		bHasAnySelected |= bPrimaryItem;

		if(!item.m_setup.empty())
		{
			if(IItem* pItem = m_pItemSystem->GetItem(itemId))
			{
				//remove all current accessories (initial setup in xml) and attach the specified list
				pItem->DetachAllAccessories();

				int numAccessories = item.m_setup.size();

				for(int i = 0; i < numAccessories; i++)
				{
					m_pItemSystem->GiveItem(pActor, item.m_setup[i]->GetName(), false, false, false);
					pItem->AttachAccessory(item.m_setup[i], true, true, true, true);
				}
			}
		}
	}

	// Handle the case where NoWeapon is not currently in possession of the actor (CE-1290)
	// In this case, give the NoWeapon item anyway, and then select it if nothing else is selected
	if (bHasNoWeapon == false)
	{
		GameWarning("[EquipmentMgr]: The pack '%s' does not contain '%s', given it anyway because it's required.", packName, strNoWeapon); 
		m_pItemSystem->GiveItem(pActor, strNoWeapon, false, !bHasAnySelected);
	}

	// Handle ammo
	std::map<string, int>::const_iterator iter = pPack->m_ammoCount.begin();
	std::map<string, int>::const_iterator iterEnd = pPack->m_ammoCount.end();

	if (bAdd)
	{
		while (iter != iterEnd)
		{
			if (iter->second>0)
			{
				IEntityClass* pClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass(iter->first);
				if(pClass)
				{
					const int count = pInventory->GetAmmoCount(pClass) + iter->second;
					pInventory->SetAmmoCount(pClass, count);
					if (gEnv->bServer)
					{
						pActor->GetGameObject()->InvokeRMI(CInventory::Cl_SetAmmoCount(), 
																							 TRMIInventory_Ammo(pClass->GetName(), count), 
																							 eRMI_ToRemoteClients);
					}
/*					
					if(IActor* pIventoryActor = pInventory->GetActor())
						if(pIventoryActor->IsClient())
							pIventoryActor->NotifyInventoryAmmoChange(pClass, iter->second);
*/
				}
				else
				{
					GameWarning("[EquipmentMgr]: Invalid AmmoType '%s' in Pack '%s'.", iter->first.c_str(), packName); 
				}
			}
			++iter;
		}
	}
	else
	{
		while (iter != iterEnd)
		{
			if (iter->second>0)
			{
				IEntityClass* pClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass(iter->first);
				if(pClass)
				{
					pInventory->SetAmmoCount(pClass, iter->second);
/*					
					if(IActor* pIventoryActor = pInventory->GetActor())
						if(pIventoryActor->IsClient())
							pIventoryActor->NotifyInventoryAmmoChange(pClass, iter->second);
*/
				}
				else
				{
					GameWarning("[EquipmentMgr]: Invalid AmmoType '%s' in Pack '%s'.", iter->first.c_str(), packName); 
				}
			}
			++iter;
		}
	}

	return true;
}