*Fix the issue where two items are supposed to drop from a group, but only one item drops, as a second roll is never performed. Based on code by elegos.

--HG--
branch : trunk
This commit is contained in:
maximius
2009-11-17 18:55:47 -08:00
parent 5faca1e54d
commit 06ea80ee4b
+38 -8
View File
@@ -860,26 +860,56 @@ bool LootTemplate::LootGroup::HasQuestDropForPlayer(Player const * player) const
// Rolls an item from the group (if any takes its chance) and adds the item to the loot
void LootTemplate::LootGroup::Process(Loot& loot, uint16 lootMode) const
{
// build up list of possible drops
std::list<uint32> *possibleDrops = new std::list<uint32>();
for (LootStoreItemList::const_iterator itr = EqualChanced.begin(); itr != EqualChanced.end(); ++itr)
possibleDrops->push_back(itr->itemid); // add all of the equal chanced items to possibleDrops
for (LootStoreItemList::const_iterator itr = ExplicitlyChanced.begin(); itr != ExplicitlyChanced.end(); ++itr)
possibleDrops->push_back(itr->itemid); // add all of the explicitly chanced items to possibleDrops
possibleDrops->unique(); // remove duplicates
uint8 uiFailSafeLoopBreaker = 0;
while (!possibleDrops->empty()) // continue rolling while possibleDrops contains data
{
++uiFailSafeLoopBreaker;
if (uiFailSafeLoopBreaker == 255)
{
sLog.outError("Tried to roll for loot from the same loot group too many times, aborting to avoid a crash.");
return;
}
LootStoreItem const *item = Roll();
if (item != NULL && item->lootmode & lootMode) // only add this item if roll succeeds and the mode matches
{
if (std::find(possibleDrops->begin(), possibleDrops->end(), item->itemid) == possibleDrops->end())
continue; // if item->itemid can't be found in possibleDrops, roll again
bool duplicate = false;
if (ItemPrototype const *_proto = sItemStorage.LookupEntry<ItemPrototype>(item->itemid))
{
uint8 _item_counter = 0;
LootItemList::const_iterator _item = loot.items.begin();
for (; _item != loot.items.end(); ++_item)
if (_item->itemid == item->itemid)
for (LootItemList::const_iterator _item = loot.items.begin(); _item != loot.items.end(); ++_item)
if (_item->itemid == item->itemid) // search through the items that have already dropped
{
++_item_counter;
if (_proto->InventoryType == 0 && _item_counter == 3) // Non-equippable items are limited to 3 drops
return;
duplicate = true;
else if(_proto->InventoryType != 0 && _item_counter == 1) // Equippable item are limited to 1 drop
duplicate = true;
}
}
if (duplicate) // if item->itemid is a duplicate, remove it from possibleDrops
possibleDrops->remove(item->itemid);
else // otherwise, add the item and exit the function
{
loot.AddItem(*item);
return;
}
//if (_item != loot.items.end())
// return;
}
loot.AddItem(*item);
}
}
@@ -988,7 +1018,7 @@ void LootTemplate::Process(Loot& loot, LootStore const& store, bool rate, uint16
uint8 _item_counter = 0;
LootItemList::const_iterator _item = loot.items.begin();
for (; _item != loot.items.end(); ++_item)
if (_item->itemid == i->itemid)
if (_item->itemid == i->itemid) // search through the items that have already dropped
{
++_item_counter;
if (_proto->InventoryType == 0 && _item_counter == 3) // Non-equippable items are limited to 3 drops