View Issue Details

IDProjectCategoryView StatusLast Update
0002234The Dark ModCodingpublic26.12.2010 17:16
ReporterSerpentine Assigned Togreebo  
PriorityhighSeveritynormalReproducibilityalways
Status closedResolutionfixed 
PlatformWin32OSWindowsOS VersionXP
Product VersionTDM 1.02 
Target VersionTDM 1.03Fixed in VersionTDM 1.03 
Summary0002234: Weapon scrolling broken
DescriptionTrying to scroll through weapons using the mouse wheel or a scroll weapon bind does not work if you do not already have a weapon in hand; you can scroll if you already have a weapon out but as soon as you reach the empty weapon slot you will be stuck until you can swap to another weapon directly, using a number key or such.
Steps To ReproducePick up a bunch of weapons
Try scroll through them with your mouse wheel
(if you didn't have any weapon out you shouldn't have a weapon now)
press the number key corresponding to one of the weapons
scroll through them with your mouse wheel
TagsNo tags attached.
Attached Files
2234_weapon_selection.patch (6,713 bytes)   
Index: DarkMod/Inventory/Category.cpp
===================================================================
--- DarkMod/Inventory/Category.cpp	(revision 3910)
+++ DarkMod/Inventory/Category.cpp	(working copy)
@@ -100,16 +100,24 @@
 	}
 }
 
-void CInventoryCategory::PutItem(const CInventoryItemPtr& item)
+void CInventoryCategory::PutItem(const CInventoryItemPtr& item, bool insertAtFront)
 {
 	if (item == NULL) return;
 
 	item->SetOwner(m_Owner.GetEntity());
 	item->SetCategory(this);
 
-	// Insert this item at the front of the list.
-	// This is a tad slower, but has been requested (issue #2144)
-	m_Item.Insert(item, 0);
+	if (insertAtFront)
+	{
+		// Insert this item at the front of the list.
+		// This is a tad slower, but has been requested (issue #2144)
+		m_Item.Insert(item, 0);
+	}
+	else
+	{
+		// Add to end of list
+		m_Item.Append(item);
+	}
 }
 
 bool CInventoryCategory::SwapItemPosition(const CInventoryItemPtr& item1, const CInventoryItemPtr& item2)
Index: DarkMod/Inventory/Category.h
===================================================================
--- DarkMod/Inventory/Category.h	(revision 3910)
+++ DarkMod/Inventory/Category.h	(working copy)
@@ -46,11 +46,22 @@
 	int						GetLoot(int& gold, int& jewelry, int& goods);
 
 	/**
-	 * greebo: Adds the given item to this category
+	 * greebo: Adds the given item to this category, behaves like std::list::push_front()
 	 */
-	void					PutItem(const CInventoryItemPtr& Item);
+	void					PutItemFront(const CInventoryItemPtr& item)
+	{
+		PutItem(item, true);
+	}
 
 	/**
+	 * greebo: Adds the given item to this category, behaves like std::list::push_back()
+	 */
+	void					PutItemBack(const CInventoryItemPtr& item)
+	{
+		PutItem(item, false);
+	}
+
+	/**
 	 * greebo: Removes the specified <item> from this category.
 	 */
 	void					RemoveItem(const CInventoryItemPtr& item);
@@ -73,6 +84,9 @@
 	void					Restore(idRestoreGame *savefile);
 
 private:
+	void					PutItem(const CInventoryItemPtr& item, bool insertAtFront);
+
+private:
 	CInventory*				m_Inventory;			// The inventory this group belongs to.
 	idEntityPtr<idEntity>	m_Owner;
 
Index: DarkMod/Inventory/Inventory.cpp
===================================================================
--- DarkMod/Inventory/Inventory.cpp	(revision 3910)
+++ DarkMod/Inventory/Inventory.cpp	(working copy)
@@ -501,7 +501,7 @@
 	}
 
 	// Pack the item into the category
-	category->PutItem(item);
+	category->PutItemFront(item);
 
 	// Objective callback for non-loot items:
 	// non-loot item passes in inv_name and individual item count, SuperGroupVal of 1
Index: game/player.cpp
===================================================================
--- game/player.cpp	(revision 3910)
+++ game/player.cpp	(working copy)
@@ -1056,6 +1056,9 @@
 
 void idPlayer::AddWeaponsToInventory()
 {
+	// A local storage, to sort weapons by index
+	std::map<int, CInventoryWeaponItemPtr> weapons;
+
 	for (const idKeyValue* kv = spawnArgs.MatchPrefix("def_weapon"); kv != NULL; kv = spawnArgs.MatchPrefix("def_weapon", kv))
 	{
 		if (kv->GetValue().IsEmpty()) continue; // skip empty spawnargs
@@ -1085,11 +1088,20 @@
 			
 		item->SetWeaponIndex(weaponNum);
 
+		// Store into the map, to have it sorted by name
+		weapons[weaponNum] = item;
+	}
+
+	DM_LOG(LC_INVENTORY, LT_DEBUG)LOGSTRING("Number of weapons found: %d\r", static_cast<int>(weapons.size()));
+
+	// Finally, add all found weapons to our inventory category, sorted by their index
+	for (std::map<int, CInventoryWeaponItemPtr>::const_iterator i = weapons.begin(); i != weapons.end(); ++i)
+	{
 		// Add it to the weapon category
-		m_WeaponCursor->GetCurrentCategory()->PutItem(item);
+		m_WeaponCursor->GetCurrentCategory()->PutItemBack(i->second);
 	}
 
-	DM_LOG(LC_INVENTORY, LT_DEBUG)LOGSTRING("Total number of weapons found: %d\r", m_WeaponCursor->GetCurrentCategory()->GetNumItems());
+	DM_LOG(LC_INVENTORY, LT_DEBUG)LOGSTRING("Total number of weapons added: %d\r", m_WeaponCursor->GetCurrentCategory()->GetNumItems());
 }
 
 void idPlayer::NextInventoryMap()
@@ -3220,6 +3232,33 @@
 	NextWeapon();
 }
 
+int idPlayer::GetHightestWeaponIndex()
+{
+	CInventoryCategoryPtr weaponCategory = m_WeaponCursor->GetCurrentCategory();
+
+	assert(weaponCategory != NULL);
+
+	int numWeapons = weaponCategory->GetNumItems();
+
+	int highestIndex = -1;
+
+	for (int i = 0; i < numWeapons; ++i)
+	{
+		CInventoryWeaponItemPtr item = boost::dynamic_pointer_cast<CInventoryWeaponItem>(weaponCategory->GetItem(i));
+
+		assert(item != NULL);
+
+		int candidate = item->GetWeaponIndex();
+
+		if (candidate > highestIndex)
+		{
+			highestIndex = candidate;
+		}
+	}
+
+	return highestIndex;
+}
+
 /*
 ===============
 idPlayer::NextWeapon
@@ -3254,21 +3293,17 @@
 	}
 
 	int curWeaponIndex = curItem->GetWeaponIndex();
+	int highestIndex = GetHightestWeaponIndex();
 
-	CInventoryWeaponItemPtr lastWeapon =
-		boost::dynamic_pointer_cast<CInventoryWeaponItem>(weaponCategory->GetItem(weaponCategory->GetNumItems() - 1));
-
-	if (lastWeapon == NULL) return;
-
-	int highestIndex = lastWeapon->GetWeaponIndex();
-
 	int nextWeaponIndex = curWeaponIndex;
 
-	do {
+	do
+	{
 		// Try to select the next weapon item
 		nextWeaponIndex++;
 
-		if (nextWeaponIndex > highestIndex) {
+		if (nextWeaponIndex > highestIndex)
+		{
 			nextWeaponIndex = 0;
 		}
 	} while (!SelectWeapon(nextWeaponIndex, false) && nextWeaponIndex != curWeaponIndex);
@@ -3308,21 +3343,17 @@
 	}
 
 	int curWeaponIndex = curItem->GetWeaponIndex();
-
-	CInventoryWeaponItemPtr lastWeapon =
-		boost::dynamic_pointer_cast<CInventoryWeaponItem>(weaponCategory->GetItem(weaponCategory->GetNumItems() - 1));
-
-	if (lastWeapon == NULL) return;
-
-	int highestIndex = lastWeapon->GetWeaponIndex();
+	int highestIndex = GetHightestWeaponIndex();
 	
 	int prevWeaponIndex = curWeaponIndex;
 
-	do {
+	do
+	{
 		// Try to select the previous weapon item
 		prevWeaponIndex--;
 
-		if (prevWeaponIndex < 0) {
+		if (prevWeaponIndex < 0)
+		{
 			prevWeaponIndex = highestIndex;
 		}
 	} while (!SelectWeapon(prevWeaponIndex, false) && prevWeaponIndex != curWeaponIndex);
Index: game/player.h
===================================================================
--- game/player.h	(revision 3910)
+++ game/player.h	(working copy)
@@ -622,6 +622,10 @@
 	void					NextBestWeapon( void );
 	void					PrevWeapon( void );
 
+	// greebo: Returns the highest weapon index in the weapon inventory category (-1 if empty/error)
+	// Traverses the entire category, so this is not the fastest code
+	int						GetHightestWeaponIndex();
+
 	// returns FALSE if the weapon with the requested index could not be selected
 	bool					SelectWeapon( int num, bool force );
 
2234_weapon_selection.patch (6,713 bytes)   

Activities

greebo

greebo

05.06.2010 07:19

administrator   ~0003041

Resolved, but not yet in SVN - fix is attached.
greebo

greebo

06.06.2010 14:15

administrator   ~0003044

Fix is in SVN.

Issue History

Date Modified Username Field Change
30.05.2010 14:04 Serpentine New Issue
05.06.2010 06:13 angua Status new => assigned
05.06.2010 06:13 angua Assigned To => angua
05.06.2010 06:13 angua Assigned To angua => greebo
05.06.2010 07:18 greebo File Added: 2234_weapon_selection.patch
05.06.2010 07:19 greebo Note Added: 0003041
05.06.2010 07:19 greebo Status assigned => resolved
05.06.2010 07:19 greebo Resolution open => fixed
05.06.2010 07:19 greebo Target Version => TDM 1.03
05.06.2010 07:29 greebo Fixed in Version => TDM 1.03
06.06.2010 14:15 greebo Note Added: 0003044
26.12.2010 17:16 greebo Status resolved => closed