aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Entities/Creature/Creature.cpp4
-rw-r--r--src/server/game/Entities/GameObject/GameObject.cpp4
-rw-r--r--src/server/game/Loot/LootMgr.cpp30
-rw-r--r--src/server/game/Loot/LootMgr.h3
4 files changed, 30 insertions, 11 deletions
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp
index 93d4796f21a..220bc4378ae 100644
--- a/src/server/game/Entities/Creature/Creature.cpp
+++ b/src/server/game/Entities/Creature/Creature.cpp
@@ -289,6 +289,10 @@ bool Creature::InitEntry(uint32 Entry, uint32 /*team*/, const CreatureData* data
--diff;
}
+ // Initialize loot duplicate count depending on raid difficulty
+ if (GetMap()->IsRaid() && GetMap()->GetSpawnMode() & RAID_DIFFICULTY_MASK_25MAN)
+ loot.maxDuplicates = 3;
+
SetEntry(Entry); // normal entry always
m_creatureInfo = cinfo; // map mode related always
diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp
index bf0fbb4199d..61e7943453e 100644
--- a/src/server/game/Entities/GameObject/GameObject.cpp
+++ b/src/server/game/Entities/GameObject/GameObject.cpp
@@ -258,6 +258,10 @@ bool GameObject::Create(uint32 guidlow, uint32 name_id, Map* map, uint32 phaseMa
LastUsedScriptID = GetGOInfo()->ScriptId;
AIM_Initialize();
+ // Initialize loot duplicate count depending on raid difficulty
+ if (map->IsRaid() && map->GetSpawnMode() & RAID_DIFFICULTY_MASK_25MAN)
+ loot.maxDuplicates = 3;
+
return true;
}
diff --git a/src/server/game/Loot/LootMgr.cpp b/src/server/game/Loot/LootMgr.cpp
index 128cf358557..56e72a10930 100644
--- a/src/server/game/Loot/LootMgr.cpp
+++ b/src/server/game/Loot/LootMgr.cpp
@@ -52,16 +52,27 @@ LootStore LootTemplates_Reference("reference_loot_template", "reference
LootStore LootTemplates_Skinning("skinning_loot_template", "creature skinning id", true);
LootStore LootTemplates_Spell("spell_loot_template", "spell id (random item creating)", false);
-struct NotMatchingLootMode : public std::unary_function<LootStoreItem*, bool>
+// Selects invalid loot items to be removed from group possible entries (before rolling)
+struct LootGroupInvalidSelector : public std::unary_function<LootStoreItem*, bool>
{
- explicit NotMatchingLootMode(uint16 lootMode) : _lootMode(lootMode) { }
+ explicit LootGroupInvalidSelector(Loot const& loot, uint16 lootMode) : _loot(loot), _lootMode(lootMode) { }
bool operator()(LootStoreItem* item) const
{
- return !(item->lootmode & _lootMode);
+ if (!(item->lootmode & _lootMode))
+ return true;
+
+ uint8 foundDuplicates = 0;
+ for (std::vector<LootItem>::const_iterator itr = _loot.items.begin(); itr != _loot.items.end(); ++itr)
+ if (itr->itemid == item->itemid)
+ if (++foundDuplicates == _loot.maxDuplicates)
+ return true;
+
+ return false;
}
private:
+ Loot const& _loot;
uint16 _lootMode;
};
@@ -89,7 +100,7 @@ class LootTemplate::LootGroup // A set of loot def
LootStoreItemList ExplicitlyChanced; // Entries with chances defined in DB
LootStoreItemList EqualChanced; // Zero chances - every entry takes the same chance
- LootStoreItem const* Roll(uint16 lootMode) const; // Rolls an item from the group, returns NULL if all miss their chances
+ LootStoreItem const* Roll(Loot& loot, uint16 lootMode) const; // Rolls an item from the group, returns NULL if all miss their chances
// This class must never be copied - storing pointers
LootGroup(LootGroup const&);
@@ -1076,10 +1087,10 @@ void LootTemplate::LootGroup::AddEntry(LootStoreItem* item)
}
// Rolls an item from the group, returns NULL if all miss their chances
-LootStoreItem const* LootTemplate::LootGroup::Roll(uint16 lootMode) const
+LootStoreItem const* LootTemplate::LootGroup::Roll(Loot& loot, uint16 lootMode) const
{
LootStoreItemList possibleLoot = ExplicitlyChanced;
- possibleLoot.remove_if(NotMatchingLootMode(lootMode));
+ possibleLoot.remove_if(LootGroupInvalidSelector(loot, lootMode));
if (!possibleLoot.empty()) // First explicitly chanced entries are checked
{
@@ -1098,7 +1109,7 @@ LootStoreItem const* LootTemplate::LootGroup::Roll(uint16 lootMode) const
}
possibleLoot = EqualChanced;
- possibleLoot.remove_if(NotMatchingLootMode(lootMode));
+ possibleLoot.remove_if(LootGroupInvalidSelector(loot, lootMode));
if (!possibleLoot.empty()) // If nothing selected yet - an item is taken from equal-chanced part
return Trinity::Containers::SelectRandomContainerElement(possibleLoot);
@@ -1145,7 +1156,7 @@ void LootTemplate::LootGroup::CopyConditions(ConditionList /*conditions*/)
// 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
{
- if (LootStoreItem const* item = Roll(lootMode))
+ if (LootStoreItem const* item = Roll(loot, lootMode))
loot.AddItem(*item);
}
@@ -1285,7 +1296,7 @@ void LootTemplate::Process(Loot& loot, bool rate, uint16 lootMode, uint8 groupId
for (LootStoreItemList::const_iterator i = Entries.begin(); i != Entries.end(); ++i)
{
LootStoreItem* item = *i;
- if (item->lootmode &~ lootMode) // Do not add if mode mismatch
+ if (!(item->lootmode & lootMode)) // Do not add if mode mismatch
continue;
if (!item->Roll(rate))
@@ -1294,7 +1305,6 @@ void LootTemplate::Process(Loot& loot, bool rate, uint16 lootMode, uint8 groupId
if (item->mincountOrRef < 0) // References processing
{
LootTemplate const* Referenced = LootTemplates_Reference.GetLootFor(-item->mincountOrRef);
-
if (!Referenced)
continue; // Error message already printed at loading stage
diff --git a/src/server/game/Loot/LootMgr.h b/src/server/game/Loot/LootMgr.h
index df2717ee36e..5c858a35242 100644
--- a/src/server/game/Loot/LootMgr.h
+++ b/src/server/game/Loot/LootMgr.h
@@ -298,12 +298,13 @@ struct Loot
uint8 unlootedCount;
uint64 roundRobinPlayer; // GUID of the player having the Round-Robin ownership for the loot. If 0, round robin owner has released.
LootType loot_type; // required for achievement system
+ uint8 maxDuplicates; // Max amount of items with the same entry that can drop (default is 1; on 25 man raid mode 3)
// GUIDLow of container that holds this loot (item_instance.entry)
// Only set for inventory items that can be right-click looted
uint32 containerID;
- Loot(uint32 _gold = 0) : gold(_gold), unlootedCount(0), loot_type(LOOT_CORPSE), containerID(0) {}
+ Loot(uint32 _gold = 0) : gold(_gold), unlootedCount(0), loot_type(LOOT_CORPSE), maxDuplicates(1), containerID(0) {}
~Loot() { clear(); }
// For deleting items at loot removal since there is no backward interface to the Item()