Exemplo n.º 1
0
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;
}
Exemplo n.º 2
0
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);
				}
			}
		}
	}
}