int CShop::GetQuantityForItem(const CInventoryItemPtr& item) { int quantity = item->GetPersistentCount(); // Check if this is a weapon CInventoryWeaponItemPtr weaponItem = boost::dynamic_pointer_cast<CInventoryWeaponItem>(item); bool isWeapon = (weaponItem != NULL); if (isWeapon) { // Use the ammonition for weapon items if (weaponItem->NeedsAmmo()) { quantity = weaponItem->GetAmmo(); } else { // Non-ammo weapons need to be enabled to be added quantity = weaponItem->IsEnabled() ? 1 : 0; } } return quantity; }
CInventoryItemPtr CInventory::ValidateAmmo(idEntity* ent, const bool gotFromShop) // grayman (#2376) { // Sanity check if (ent == NULL) return CInventoryItemPtr(); // Check for ammonition int amount = ent->spawnArgs.GetInt("inv_ammo_amount", "0"); if (amount <= 0) { return CInventoryItemPtr(); // not ammo } CInventoryItemPtr returnValue; idStr weaponName = ent->spawnArgs.GetString("inv_weapon_name", ""); if (weaponName.IsEmpty()) { DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("Could not find 'inv_weapon_name' on item %s.\r", ent->name.c_str()); gameLocal.Warning("Could not find 'inv_weapon_name' on item %s.", ent->name.c_str()); return returnValue; } // grayman (#2376) // If we already got this from the shop, zero the ammo count. if (gotFromShop) { amount = 0; // Ammo already given, so clear it. We could leave at // this point, but the calling method expects a CInventoryItemPtr, // so we have to execute the following code to obtain it. } // Find the weapon category CInventoryCategoryPtr weaponCategory = GetCategory(TDM_PLAYER_WEAPON_CATEGORY); if (weaponCategory == NULL) { DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("Could not find weapon category in inventory.\r"); return returnValue; } // Look for the weapon with the given name for (int i = 0; i < weaponCategory->GetNumItems(); i++) { CInventoryWeaponItemPtr weaponItem = boost::dynamic_pointer_cast<CInventoryWeaponItem>(weaponCategory->GetItem(i)); // Is this the right weapon? if (weaponItem != NULL && weaponItem->GetWeaponName() == weaponName) { DM_LOG(LC_INVENTORY, LT_DEBUG)LOGSTRING("Adding %d ammo to weapon %s.\r", amount, weaponName.c_str()); // Add the ammo to this weapon weaponItem->SetAmmo(weaponItem->GetAmmo() + amount); if (!ent->spawnArgs.GetBool("inv_map_start", "0") && !ent->spawnArgs.GetBool("inv_no_pickup_message", "0")) { // Tels: For some reason "inv_name" here is "Fire Arrow", even tho this string never appears anywhere // when running f.i. in "German". So use weaponItem->GetName(), which is correctly "#str_02435": idStr msg = common->Translate( weaponItem->GetName() ); if (amount > 1) { msg += " x" + idStr(amount); } NotifyOwnerAboutPickup(msg, weaponItem); } // We're done return weaponItem; } } return returnValue; }
void CInventory::CopyPersistentItemsFrom(const CInventory& sourceInventory, idEntity* newOwner) { // Obtain the weapon category for this inventory CInventoryCategoryPtr weaponCategory = GetCategory(TDM_PLAYER_WEAPON_CATEGORY); // Cycle through all categories to add them for ( int c = 0 ; c < sourceInventory.GetNumCategories() ; ++c ) { const CInventoryCategoryPtr& category = sourceInventory.GetCategory(c); for ( int itemIdx = 0 ; itemIdx < category->GetNumItems() ; ++itemIdx ) { const CInventoryItemPtr& item = category->GetItem(itemIdx); if (item->GetPersistentCount() <= 0) { DM_LOG(LC_INVENTORY, LT_DEBUG)LOGSTRING( "Item %s is not marked as persistent, won't add to player inventory.\r", common->Translate(item->GetName().c_str())); continue; // not marked as persistent } // Check if the shop handled that item already const idDict* itemDict = item->GetSavedItemEntityDict(); if (itemDict != NULL) { CShopItemPtr shopItem = gameLocal.m_Shop->FindShopItemDefByClassName(itemDict->GetString("classname")); if ( (shopItem != NULL) && (CShop::GetQuantityForItem(item) > 0) ) { // grayman #3723 - if there's no shop in this mission, // then we can't rely on it to process this inventory item. if ( gameLocal.m_Shop->ShopExists() ) { DM_LOG(LC_INVENTORY, LT_DEBUG)LOGSTRING( "Item %s would be handled by the shop, won't add that to player inventory.\r", common->Translate(item->GetName().c_str())); continue; } } } // Is set to true if we should add this item. // For weapon items with ammo this will be set to false to prevent double-additions bool addItem = true; // Handle weapons separately, otherwise we might end up with duplicate weapon items CInventoryWeaponItemPtr weaponItem = boost::dynamic_pointer_cast<CInventoryWeaponItem>(item); if (weaponItem && weaponCategory) { // Weapon items need special consideration. For arrow-based weapons try to merge the ammo. for ( int w = 0 ; w < weaponCategory->GetNumItems() ; ++w ) { CInventoryWeaponItemPtr thisWeapon = boost::dynamic_pointer_cast<CInventoryWeaponItem>(weaponCategory->GetItem(w)); if (!thisWeapon) { continue; } if (thisWeapon->GetWeaponName() == weaponItem->GetWeaponName()) { // Prevent adding this item, we already have one addItem = false; // Found a matching weapon, does it use ammo? if (thisWeapon->NeedsAmmo()) { DM_LOG(LC_INVENTORY, LT_DEBUG)LOGSTRING( "Adding persistent ammo %d to player weapon %s.\r", weaponItem->GetAmmo(), thisWeapon->GetWeaponName().c_str()); // Add the persistent ammo count to this item thisWeapon->SetAmmo(thisWeapon->GetAmmo() + weaponItem->GetAmmo()); } else { // Doesn't need ammo, check enabled state if (weaponItem->IsEnabled() && !thisWeapon->IsEnabled()) { DM_LOG(LC_INVENTORY, LT_DEBUG)LOGSTRING( "Enabling weapon item %s as the persistent inventory contains an enabled one.\r", thisWeapon->GetWeaponName().c_str()); thisWeapon->SetEnabled(true); } } break; } } } if (addItem) { DM_LOG(LC_INVENTORY, LT_DEBUG)LOGSTRING( "Adding persistent item %s to player inventory, quantity: %d.\r", common->Translate(item->GetName().c_str()), item->GetPersistentCount()); item->SetOwner(newOwner); // Add this item to our inventory PutItem(item, item->Category()->GetName()); // If we didn't have a weapon category at this point, we should be able to get one now if (weaponItem && !weaponCategory) { weaponCategory = GetCategory(TDM_PLAYER_WEAPON_CATEGORY); } } } } }