예제 #1
0
void CShop::AddPersistentStartingEquipment() {
	const CInventory &sourceInventory = *gameLocal.persistentPlayerInventory;
	// 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_MAINMENU, LT_DEBUG )LOGSTRING(
					"Item %s is not marked as persistent, won't add to shop.\r",
					item->GetName().c_str() );
				continue; // not marked as persistent
			}
			const idDict *itemDict = item->GetSavedItemEntityDict();
			if( itemDict == NULL ) {
				DM_LOG( LC_MAINMENU, LT_WARNING )LOGSTRING(
					"Item %s is marked as persistent, but has no saved item dictionary.\r",
					item->GetName().c_str() );
				continue;
			}
			idStr className = itemDict->GetString( "classname" );
			// Try to look up the corresponding shop item definition for this item's classname
			CShopItemPtr found = FindShopItemDefByClassName( className );
			if( found == NULL ) {
				DM_LOG( LC_MAINMENU, LT_DEBUG )LOGSTRING(
					"Can't find shopitem definition for classname %s, skipping.\r", className.c_str() );
				continue;
			}
			int quantity = GetQuantityForItem( item );
			// Don't attempt to merge if we don't have anything to merge in the first place
			if( quantity == 0 ) {
				DM_LOG( LC_MAINMENU, LT_DEBUG )LOGSTRING(
					"Persistent weapon doesn't have ammo, skipping.\r", className.c_str() );
				continue;
			}
			// Check if this is a weapon
			CInventoryWeaponItemPtr weaponItem = boost::dynamic_pointer_cast<CInventoryWeaponItem>( item );
			bool isWeapon = ( weaponItem != NULL );
			bool weaponIsAllowedEmpty = weaponItem ? weaponItem->IsAllowedEmpty() : false;
			bool itemMerged = MergeIntoStartingEquipment( className, quantity, isWeapon, weaponIsAllowedEmpty );
			// Append the item to the list if it didn't contribute quantity to
			// an existing list item.
			if( !itemMerged ) {
				CShopItemPtr anItem( new CShopItem( *found, quantity, 0, false ) );
				bool canDrop = itemDict->GetBool( "inv_droppable", "1" );
				anItem->SetCanDrop( canDrop );
				_startingItems.Append( anItem );
			}
		}
	}
}
예제 #2
0
파일: Shop.cpp 프로젝트: dolanor/TheDarkMod
void CShop::AddMapItems(idMapFile* mapFile)
{
	// get the difficulty level

	idStr diffString = "diff_" + idStr(gameLocal.m_DifficultyManager.GetDifficultyLevel()) + "_nospawn";

	// Cycle through map entities. Since the number of entities can change in the loop,
	// always refresh the entity count used to terminate the loop.

	// Skip entity 0, which is the world.

	for (int i = 1; i < mapFile->GetNumEntities(); i++)
	{
		idMapEntity* mapEnt = mapFile->GetEntity(i);

		// does this entity have an inv_map_start spawnflag set to 1?

		if (mapEnt->epairs.GetBool("inv_map_start", "0"))
		{
			// does this entity exist in the chosen difficulty level?

			if (idStr::Icmp(mapEnt->epairs.GetString(diffString, "0"), "0") == 0)
			{
				idStr className = mapEnt->epairs.GetString("classname");
				int quantity;
				bool isWeapon = false;	// is this an arrow?
				int max_ammo = 1;	// in case this is a weapon

				// Special handling for arrows. The shop definitions allow for
				// atdm:weapon_*, but not atdm:ammo_*. The latter form is used on
				// map entities. If this is an atdm:ammo_* entity, change its ID (itemName)
				// to the allowable atdm:weapon_* form.

				if (className.Find("atdm:ammo_") >= 0)
				{
					isWeapon = true;
					className.Replace( "atdm:ammo_", "atdm:weapon_" );

					// An arrow's quantity is defined by "inv_ammo_amount" instead
					// of "inv_count". Look for that.

					quantity = mapEnt->epairs.GetInt("inv_ammo_amount", "0");

					// Arrow quantities have limits. See if you can find the limit
					// for this weapon.

					if (quantity > 0)
					{
						max_ammo = GetMaxAmmo(className);
						quantity = (quantity > max_ammo) ? max_ammo : quantity;
					}
				}
				else
				{
					quantity = mapEnt->epairs.GetInt("inv_count", "1");
				}

				if (quantity > 0)
				{
					CShopItemPtr found = FindShopItemDefByClassName(className);

					if (found != NULL)
					{
						// We don't have much info about the weapon item at this point and FindEntityDefDict() is lagging
						// so let's assume there is only a shortsword and blackjack as possible melee items for now
						bool isMeleeWeapon = (className.Cmp("atdm:weapon_shortsword") == 0 || className.Cmp("atdm:weapon_blackjack") == 0);

						// If this item is stackable, and already exists in the _startingItems list,
						// bump up the quantity there instead of appending the item to the list.
						// If the item is not stackable, and we already have it, ignore it.
						bool itemMerged = MergeIntoStartingEquipment(className, quantity, isWeapon, isMeleeWeapon);

						// Append the item to the list if it didn't contribute quantity to
						// an existing list item.

						if (!itemMerged)
						{
							CShopItemPtr anItem(new CShopItem(*found, quantity, 0, false));

							bool canDrop = mapEnt->epairs.GetBool("inv_droppable", "1");
							anItem->SetCanDrop(canDrop);

							_startingItems.Append(anItem);
						}
					}
					else
					{
						gameLocal.Warning("Map entity is not a valid shop item: %s", className.c_str());
					}
				}
			}
		}
	}
}