View Issue Details
| ID | Project | Category | View Status | Date Submitted | Last Update |
|---|---|---|---|---|---|
| 0002234 | The Dark Mod | Coding | public | 30.05.2010 14:04 | 26.12.2010 17:16 |
| Reporter | Serpentine | Assigned To | greebo | ||
| Priority | high | Severity | normal | Reproducibility | always |
| Status | closed | Resolution | fixed | ||
| Platform | Win32 | OS | Windows | OS Version | XP |
| Product Version | TDM 1.02 | ||||
| Target Version | TDM 1.03 | Fixed in Version | TDM 1.03 | ||
| Summary | 0002234: Weapon scrolling broken | ||||
| Description | Trying 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 Reproduce | Pick 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 | ||||
| Tags | No 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 );
| ||||
| 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 |