void CAICorpse::AboutToBeRemoved() { IItemSystem* pItemSystem = g_pGame->GetIGameFramework()->GetIItemSystem(); ICharacterInstance* pCharacter = GetEntity()->GetCharacter(0); IAttachmentManager* pAttachmentManager = (pCharacter != NULL) ? pCharacter->GetIAttachmentManager() : NULL; for (uint32 i = 0; i < (uint32)m_attachedItemsInfo.size(); ++i) { AttachedItem& attachedItem = m_attachedItemsInfo[i]; IItem* pItem = pItemSystem->GetItem( attachedItem.id ); if((pItem != NULL) && ShouldDropOnCorpseRemoval( pItem->GetEntity()->GetClass() )) { IAttachment* pAttachment = (pAttachmentManager != NULL) ? pAttachmentManager->GetInterfaceByName( attachedItem.attachmentName.c_str() ) : NULL; if(pAttachment != NULL) { pAttachment->ClearBinding(); } pItem->Drop( 1.0f, false, true ); pItem->GetEntity()->SetFlags( pItem->GetEntity()->GetFlags() & ~ENTITY_FLAG_NO_SAVE ); attachedItem.id = 0; } } }
//------------------------------------------------------------------------ void CInventory::SerializeInventoryForLevelChange( TSerialize ser ) { IActor *pActor = GetActor(); if(!pActor) return; if(ser.IsReading()) { m_stats.ammoInfo.clear(); } m_bSerializeLTL = true; //Items by class (accessories) ser.BeginGroup("accessorySlots"); int exSize = m_stats.accessorySlots.size(); ser.Value("Size", exSize); if(ser.IsReading()) { m_stats.accessorySlots.resize(0); if(exSize>0) m_stats.accessorySlots.reserve(exSize); } for(int i = 0; i<exSize; ++i) { string accessoryName; if(ser.IsWriting()) accessoryName = m_stats.accessorySlots[i]->GetName(); ser.BeginGroup("Class"); ser.Value("AccessoryName", accessoryName); ser.EndGroup(); if(ser.IsReading()) { IEntityClass* pAccessoryClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass(accessoryName); CRY_ASSERT(pAccessoryClass); if (pAccessoryClass) { m_stats.accessorySlots.push_back(pAccessoryClass); } } } ser.EndGroup();//"accessorySlots" if(ser.IsReading()) { for(int r = 0; r < m_stats.slots.size(); ++r) { IItem *pItem = m_pGameFrameWork->GetIItemSystem()->GetItem(m_stats.slots[r]); if(pItem) { pItem->Drop(); pItem->GetEntity()->SetFlags(pItem->GetEntity()->GetFlags()|ENTITY_FLAG_UPDATE_HIDDEN); pItem->GetEntity()->Hide(true); gEnv->pEntitySystem->RemoveEntity(m_stats.slots[r]); } } } int numItems = 0; string currentItemNameOnReading; if(ser.IsReading()) { m_stats.slots.clear(); m_stats.currentItemId = 0; m_stats.holsteredItemId = 0; m_stats.lastItemId = 0; string itemName; ser.Value("numOfItems", numItems); for(int i = 0; i < numItems; ++i) { ser.BeginGroup("Items"); bool nextItemExists = false; ser.Value("nextItemExists", nextItemExists); if(nextItemExists) { ser.Value("ItemName", itemName); EntityId id = m_pGameFrameWork->GetIItemSystem()->GiveItem(pActor, itemName.c_str(), false, false, false); IItem *pItem = m_pGameFrameWork->GetIItemSystem()->GetItem(id); if(pItem) { //actual serialization pItem->SerializeLTL(ser); } else CryWarning(VALIDATOR_MODULE_GAME, VALIDATOR_ERROR, "Couldn't spawn inventory item %s, got id %i.", itemName.c_str(), id); } ser.EndGroup(); } ser.Value("CurrentItemName", itemName); if(stricmp(itemName.c_str(), "none")) { currentItemNameOnReading = itemName; IEntityClass *pClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass(itemName.c_str()); if(pClass) { if(IItem* pItem = m_pGameFrameWork->GetIItemSystem()->GetItem(GetItemByClass(pClass))) { if (pActor->GetCurrentItem() && pActor->GetCurrentItem() != pItem) pActor->GetCurrentItem()->Select(false); pItem->Select(true); m_stats.currentItemId = pItem->GetEntityId(); } else m_stats.currentItemId = m_pGameFrameWork->GetIItemSystem()->GiveItem(pActor, itemName.c_str(), false, true, false); } } } else { numItems = m_stats.slots.size(); ser.Value("numOfItems", numItems); for(int i = 0; i < numItems; ++i) { ser.BeginGroup("Items"); IItem *pItem = m_pGameFrameWork->GetIItemSystem()->GetItem(m_stats.slots[i]); bool nextItem = true; if(pItem) { ser.Value("nextItemExists", nextItem); ser.Value("ItemName", pItem->GetEntity()->GetClass()->GetName()); pItem->SerializeLTL(ser); } else { nextItem = false; ser.Value("nextItemExists", nextItem); } ser.EndGroup(); } bool currentItemIsInInventory = stl::find(m_stats.slots, m_stats.currentItemId); IItem* pCurrentItem = NULL; if (currentItemIsInInventory) { pCurrentItem = m_pGameFrameWork->GetIItemSystem()->GetItem(m_stats.currentItemId); } else { pCurrentItem = m_pGameFrameWork->GetIItemSystem()->GetItem(GetHolsteredItem()); //Fallback to last selected one... if (!pCurrentItem) { pCurrentItem = m_pGameFrameWork->GetIItemSystem()->GetItem(GetLastItem()); // desperate fallback to any weapon... // this fallback should never be needed. However, right now it happens if the player loads a savegame where a heavyweapon is being used, right before the end of the mission. // that is a bug, but at this point is safer to just do this bruteforce fallback instead of fixing it // TODO: to fix that and remove this fallback... if (!pCurrentItem) { for(int i = 0; i < numItems; ++i) { IItem *pItem = m_pGameFrameWork->GetIItemSystem()->GetItem( m_stats.slots[i] ); if (pItem) { const char* pCategoryName = m_pGameFrameWork->GetIItemSystem()->GetItemCategory( pItem->GetEntity()->GetClass()->GetName() ); if (pCategoryName) { EInventorySlots slotType = GetSlotForItemCategory( pCategoryName ); if (slotType==eInventorySlot_Weapon) { pCurrentItem = pItem; break; } } } } } } } if (pCurrentItem) { ser.Value("CurrentItemName", pCurrentItem->GetEntity()->GetClass()->GetName()); } else { string name("none"); ser.Value("CurrentItemName", name); } } //**************************************AMMO ser.BeginGroup("Ammo"); TAmmoInfoMap::iterator ammoInfoIt = m_stats.ammoInfo.begin(); int ammoAmount = m_stats.ammoInfo.size(); ser.Value("AmmoAmount", ammoAmount); for(int i = 0; i < ammoAmount; ++i) { string name; int amount = 0; int users = 0; int capacity = 0; if(ser.IsWriting()) { IEntityClass* pAmmoClass = ammoInfoIt->first; CRY_ASSERT(pAmmoClass); name = (pAmmoClass) ? pAmmoClass->GetName() : ""; const SAmmoInfo& ammoInfo = ammoInfoIt->second;; amount = ammoInfo.GetCount(); capacity = ammoInfo.GetCapacity(); ++ammoInfoIt; } ser.BeginGroup("Ammo"); ser.Value("AmmoName", name); ser.Value("Bullets", amount); ser.Value("Capacity", capacity); ser.EndGroup(); if(ser.IsReading()) { IEntityClass* pClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass(name); CRY_ASSERT(pClass); TAmmoInfoMap::iterator it = m_stats.ammoInfo.find(pClass); if (it == m_stats.ammoInfo.end()) { m_stats.ammoInfo[pClass] = SAmmoInfo(amount, capacity); } else { it->second.SetCount(amount); it->second.SetCapacity(capacity); } } } ser.EndGroup(); m_bSerializeLTL = false; }