aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/server/game/Loot/LootMgr.cpp105
-rw-r--r--src/server/game/Loot/LootMgr.h16
2 files changed, 55 insertions, 66 deletions
diff --git a/src/server/game/Loot/LootMgr.cpp b/src/server/game/Loot/LootMgr.cpp
index 949f6ee4deb..833f6a0ad5d 100644
--- a/src/server/game/Loot/LootMgr.cpp
+++ b/src/server/game/Loot/LootMgr.cpp
@@ -85,7 +85,7 @@ class LootTemplate::LootGroup // A set of loot def
LootGroup(LootGroup&&) = delete;
LootGroup& operator=(LootGroup const&) = delete;
LootGroup& operator=(LootGroup&&) = delete;
- ~LootGroup();
+ ~LootGroup() = default;
void AddEntry(LootStoreItem* item); // Adds an entry to the group (at loading stage)
bool HasDropForPlayer(Player const* player, bool strictUsabilityCheck) const;
@@ -318,43 +318,36 @@ bool LootStoreItem::IsValid(LootStore const& store, uint32 entry) const
// --------- LootTemplate::LootGroup ---------
//
-LootTemplate::LootGroup::~LootGroup()
-{
- while (!ExplicitlyChanced.empty())
- {
- delete ExplicitlyChanced.back();
- ExplicitlyChanced.pop_back();
- }
-
- while (!EqualChanced.empty())
- {
- delete EqualChanced.back();
- EqualChanced.pop_back();
- }
-}
-
// Adds an entry to the group (at loading stage)
void LootTemplate::LootGroup::AddEntry(LootStoreItem* item)
{
if (item->chance != 0)
- ExplicitlyChanced.push_back(item);
+ ExplicitlyChanced.emplace_back(item);
else
- EqualChanced.push_back(item);
+ EqualChanced.emplace_back(item);
}
// Rolls an item from the group, returns NULL if all miss their chances
LootStoreItem const* LootTemplate::LootGroup::Roll(uint16 lootMode, Player const* personalLooter /*= nullptr*/) const
{
- LootStoreItemList possibleLoot = ExplicitlyChanced;
- Trinity::Containers::EraseIf(possibleLoot, LootGroupInvalidSelector(lootMode, personalLooter));
+ auto getValidLoot = [](LootStoreItemList const& items, uint16 lootMode, Player const* personalLooter)
+ {
+ std::vector<LootStoreItem const*> possibleLoot;
+ possibleLoot.resize(items.size());
+ std::ranges::transform(items, possibleLoot.begin(), [](std::unique_ptr<LootStoreItem> const& i) { return i.get(); });
+ Trinity::Containers::EraseIf(possibleLoot, LootGroupInvalidSelector(lootMode, personalLooter));
+ return possibleLoot;
+ };
+
+ std::vector<LootStoreItem const*> possibleLoot = getValidLoot(ExplicitlyChanced, lootMode, personalLooter);
if (!possibleLoot.empty()) // First explicitly chanced entries are checked
{
float roll = rand_chance();
- for (LootStoreItemList::const_iterator itr = possibleLoot.begin(); itr != possibleLoot.end(); ++itr) // check each explicitly chanced entry in the template and modify its chance based on quality.
+ for (auto itr = possibleLoot.begin(); itr != possibleLoot.end(); ++itr) // check each explicitly chanced entry in the template and modify its chance based on quality.
{
- LootStoreItem* item = *itr;
+ LootStoreItem const* item = *itr;
if (item->chance >= 100.0f)
return item;
@@ -364,8 +357,7 @@ LootStoreItem const* LootTemplate::LootGroup::Roll(uint16 lootMode, Player const
}
}
- possibleLoot = EqualChanced;
- Trinity::Containers::EraseIf(possibleLoot, LootGroupInvalidSelector(lootMode, personalLooter));
+ possibleLoot = getValidLoot(EqualChanced, lootMode, personalLooter);
if (!possibleLoot.empty()) // If nothing selected yet - an item is taken from equal-chanced part
return Trinity::Containers::SelectRandomContainerElement(possibleLoot);
@@ -374,13 +366,13 @@ LootStoreItem const* LootTemplate::LootGroup::Roll(uint16 lootMode, Player const
bool LootTemplate::LootGroup::HasDropForPlayer(Player const* player, bool strictUsabilityCheck) const
{
- for (LootStoreItem const* lootStoreItem : ExplicitlyChanced)
+ for (std::unique_ptr<LootStoreItem> const& lootStoreItem : ExplicitlyChanced)
if (LootItem::AllowedForPlayer(player, nullptr, lootStoreItem->itemid, lootStoreItem->needs_quest,
!lootStoreItem->needs_quest || ASSERT_NOTNULL(sObjectMgr->GetItemTemplate(lootStoreItem->itemid))->HasFlag(ITEM_FLAGS_CU_FOLLOW_LOOT_RULES),
strictUsabilityCheck, lootStoreItem->conditions))
return true;
- for (LootStoreItem const* lootStoreItem : EqualChanced)
+ for (std::unique_ptr<LootStoreItem> const& lootStoreItem : EqualChanced)
if (LootItem::AllowedForPlayer(player, nullptr, lootStoreItem->itemid, lootStoreItem->needs_quest,
!lootStoreItem->needs_quest || ASSERT_NOTNULL(sObjectMgr->GetItemTemplate(lootStoreItem->itemid))->HasFlag(ITEM_FLAGS_CU_FOLLOW_LOOT_RULES),
strictUsabilityCheck, lootStoreItem->conditions))
@@ -461,7 +453,7 @@ void LootTemplate::LootGroup::CheckLootRefs(LootTemplateMap const& /*store*/, Lo
{
for (LootStoreItemList::const_iterator ieItr = ExplicitlyChanced.begin(); ieItr != ExplicitlyChanced.end(); ++ieItr)
{
- LootStoreItem* item = *ieItr;
+ LootStoreItem* item = ieItr->get();
if (item->reference > 0)
{
if (!LootTemplates_Reference.GetLootFor(item->reference))
@@ -473,7 +465,7 @@ void LootTemplate::LootGroup::CheckLootRefs(LootTemplateMap const& /*store*/, Lo
for (LootStoreItemList::const_iterator ieItr = EqualChanced.begin(); ieItr != EqualChanced.end(); ++ieItr)
{
- LootStoreItem* item = *ieItr;
+ LootStoreItem* item = ieItr->get();
if (item->reference > 0)
{
if (!LootTemplates_Reference.GetLootFor(item->reference))
@@ -488,29 +480,24 @@ void LootTemplate::LootGroup::CheckLootRefs(LootTemplateMap const& /*store*/, Lo
// --------- LootTemplate ---------
//
-LootTemplate::~LootTemplate()
-{
- for (LootStoreItemList::iterator i = Entries.begin(); i != Entries.end(); ++i)
- delete *i;
-
- for (size_t i = 0; i < Groups.size(); ++i)
- delete Groups[i];
-}
+LootTemplate::LootTemplate() = default;
+LootTemplate::LootTemplate(LootTemplate&&) noexcept = default;
+LootTemplate& LootTemplate::operator=(LootTemplate&&) noexcept = default;
+LootTemplate::~LootTemplate() = default;
// Adds an entry to the group (at loading stage)
void LootTemplate::AddEntry(LootStoreItem* item)
{
if (item->groupid > 0 && item->reference == 0) // Group
{
- if (item->groupid >= Groups.size())
- Groups.resize(item->groupid, nullptr); // Adds new group the the loot template if needed
- if (!Groups[item->groupid - 1])
- Groups[item->groupid - 1] = new LootGroup();
+ std::unique_ptr<LootGroup>& group = Trinity::Containers::EnsureWritableVectorIndex(Groups, item->groupid - 1);
+ if (!group)
+ group.reset(new LootGroup()); // Adds new group the the loot template if needed
- Groups[item->groupid - 1]->AddEntry(item); // Adds new entry to the group
+ group->AddEntry(item); // Adds new entry to the group
}
else // Non-grouped entries and references are stored together
- Entries.push_back(item);
+ Entries.emplace_back(item);
}
void LootTemplate::CopyConditions(LootItem* li) const
@@ -518,7 +505,7 @@ void LootTemplate::CopyConditions(LootItem* li) const
// Copies the conditions list from a template item to a LootItemData
for (LootStoreItemList::const_iterator _iter = Entries.begin(); _iter != Entries.end(); ++_iter)
{
- LootStoreItem* item = *_iter;
+ LootStoreItem* item = _iter->get();
if (item->itemid != li->itemid)
continue;
@@ -545,7 +532,7 @@ void LootTemplate::Process(Loot& loot, bool rate, uint16 lootMode, uint8 groupId
// Rolling non-grouped items
for (LootStoreItemList::const_iterator i = Entries.begin(); i != Entries.end(); ++i)
{
- LootStoreItem* item = *i;
+ LootStoreItem* item = i->get();
if (!(item->lootmode & lootMode)) // Do not add if mode mismatch
continue;
@@ -576,7 +563,7 @@ void LootTemplate::Process(Loot& loot, bool rate, uint16 lootMode, uint8 groupId
// Now processing groups
for (LootGroups::const_iterator i = Groups.begin(); i != Groups.end(); ++i)
- if (LootGroup* group = *i)
+ if (LootGroup* group = i->get())
group->Process(loot, lootMode, personalLooter);
}
@@ -594,7 +581,7 @@ void LootTemplate::ProcessPersonalLoot(std::unordered_map<Player*, std::unique_p
};
// Rolling non-grouped items
- for (LootStoreItem const* item : Entries)
+ for (std::unique_ptr<LootStoreItem> const& item : Entries)
{
if (!(item->lootmode & lootMode)) // Do not add if mode mismatch
continue;
@@ -660,7 +647,7 @@ void LootTemplate::ProcessPersonalLoot(std::unordered_map<Player*, std::unique_p
}
// Now processing groups
- for (LootGroup const* group : Groups)
+ for (std::unique_ptr<LootGroup> const& group : Groups)
{
if (group)
{
@@ -693,7 +680,7 @@ bool LootTemplate::HasDropForPlayer(Player const* player, uint8 groupId, bool st
}
// Checking non-grouped entries
- for (LootStoreItem* lootStoreItem : Entries)
+ for (std::unique_ptr<LootStoreItem> const& lootStoreItem : Entries)
{
if (lootStoreItem->reference > 0) // References processing
{
@@ -710,7 +697,7 @@ bool LootTemplate::HasDropForPlayer(Player const* player, uint8 groupId, bool st
}
// Now checking groups
- for (LootGroup* group : Groups)
+ for (std::unique_ptr<LootGroup> const& group : Groups)
if (group)
if (group->HasDropForPlayer(player, strictUsabilityCheck))
return true;
@@ -734,7 +721,7 @@ bool LootTemplate::HasQuestDrop(LootTemplateMap const& store, uint8 groupId) con
for (LootStoreItemList::const_iterator i = Entries.begin(); i != Entries.end(); ++i)
{
- LootStoreItem* item = *i;
+ LootStoreItem* item = i->get();
if (item->reference > 0) // References
{
LootTemplateMap::const_iterator Referenced = store.find(item->reference);
@@ -749,7 +736,7 @@ bool LootTemplate::HasQuestDrop(LootTemplateMap const& store, uint8 groupId) con
// Now processing groups
for (LootGroups::const_iterator i = Groups.begin(); i != Groups.end(); ++i)
- if (LootGroup* group = *i)
+ if (LootGroup* group = i->get())
if (group->HasQuestDrop())
return true;
@@ -773,7 +760,7 @@ bool LootTemplate::HasQuestDropForPlayer(LootTemplateMap const& store, Player co
// Checking non-grouped entries
for (LootStoreItemList::const_iterator i = Entries.begin(); i != Entries.end(); ++i)
{
- LootStoreItem* item = *i;
+ LootStoreItem* item = i->get();
if (item->reference > 0) // References processing
{
LootTemplateMap::const_iterator Referenced = store.find(item->reference);
@@ -788,7 +775,7 @@ bool LootTemplate::HasQuestDropForPlayer(LootTemplateMap const& store, Player co
// Now checking groups
for (LootGroups::const_iterator i = Groups.begin(); i != Groups.end(); ++i)
- if (LootGroup* group = *i)
+ if (LootGroup* group = i->get())
if (group->HasQuestDropForPlayer(player))
return true;
@@ -810,7 +797,7 @@ void LootTemplate::CheckLootRefs(LootTemplateMap const& store, LootIdSet* ref_se
{
for (LootStoreItemList::const_iterator ieItr = Entries.begin(); ieItr != Entries.end(); ++ieItr)
{
- LootStoreItem* item = *ieItr;
+ LootStoreItem* item = ieItr->get();
if (item->reference > 0)
{
if (!LootTemplates_Reference.GetLootFor(item->reference))
@@ -821,7 +808,7 @@ void LootTemplate::CheckLootRefs(LootTemplateMap const& store, LootIdSet* ref_se
}
for (LootGroups::const_iterator grItr = Groups.begin(); grItr != Groups.end(); ++grItr)
- if (LootGroup* group = *grItr)
+ if (LootGroup* group = grItr->get())
group->CheckLootRefs(store, ref_set);
}
@@ -829,7 +816,7 @@ bool LootTemplate::LinkConditions(ConditionId const& id, ConditionsReference ref
{
if (!Entries.empty())
{
- for (LootStoreItem* item : Entries)
+ for (std::unique_ptr<LootStoreItem>& item : Entries)
{
if (item->itemid == uint32(id.SourceEntry))
{
@@ -841,7 +828,7 @@ bool LootTemplate::LinkConditions(ConditionId const& id, ConditionsReference ref
if (!Groups.empty())
{
- for (LootGroup* group : Groups)
+ for (std::unique_ptr<LootGroup>& group : Groups)
{
if (!group)
continue;
@@ -849,7 +836,7 @@ bool LootTemplate::LinkConditions(ConditionId const& id, ConditionsReference ref
LootStoreItemList* itemList = group->GetExplicitlyChancedItemList();
if (!itemList->empty())
{
- for (LootStoreItem* item : *itemList)
+ for (std::unique_ptr<LootStoreItem> const& item : *itemList)
{
if (item->itemid == uint32(id.SourceEntry))
{
@@ -862,7 +849,7 @@ bool LootTemplate::LinkConditions(ConditionId const& id, ConditionsReference ref
itemList = group->GetEqualChancedItemList();
if (!itemList->empty())
{
- for (LootStoreItem* item : *itemList)
+ for (std::unique_ptr<LootStoreItem> const& item : *itemList)
{
if (item->itemid == uint32(id.SourceEntry))
{
diff --git a/src/server/game/Loot/LootMgr.h b/src/server/game/Loot/LootMgr.h
index 53f9a485aaa..c199f263737 100644
--- a/src/server/game/Loot/LootMgr.h
+++ b/src/server/game/Loot/LootMgr.h
@@ -58,7 +58,7 @@ struct TC_GAME_API LootStoreItem
bool IsValid(LootStore const& store, uint32 entry) const; // Checks correctness of values
};
-typedef std::vector<LootStoreItem*> LootStoreItemList;
+typedef std::vector<std::unique_ptr<LootStoreItem>> LootStoreItemList;
typedef std::unordered_map<uint32, std::unique_ptr<LootTemplate>> LootTemplateMap;
typedef std::set<uint32> LootIdSet;
@@ -107,10 +107,16 @@ class TC_GAME_API LootStore
class TC_GAME_API LootTemplate
{
class LootGroup; // A set of loot definitions for items (refs are not allowed inside)
- typedef std::vector<LootGroup*> LootGroups;
+ typedef std::vector<std::unique_ptr<LootGroup>> LootGroups;
public:
- LootTemplate() { }
+ LootTemplate();
+
+ LootTemplate(LootTemplate const&) = delete;
+ LootTemplate(LootTemplate&&) noexcept;
+ LootTemplate& operator=(LootTemplate const&) = delete;
+ LootTemplate& operator=(LootTemplate&&) noexcept;
+
~LootTemplate();
// Adds an entry to the group (at loading stage)
@@ -136,10 +142,6 @@ class TC_GAME_API LootTemplate
private:
LootStoreItemList Entries; // not grouped only
LootGroups Groups; // groups have own (optimised) processing, grouped entries go there
-
- // Objects of this class must never be copied, we are storing pointers in container
- LootTemplate(LootTemplate const&) = delete;
- LootTemplate& operator=(LootTemplate const&) = delete;
};
std::unordered_map<ObjectGuid, std::unique_ptr<Loot>> GenerateDungeonEncounterPersonalLoot(uint32 dungeonEncounterId,