Skip to content

Commit

Permalink
Add reference support for grouped loot tables.
Browse files Browse the repository at this point in the history
Now, grouped reference_loot_template entries can also reference other reference loot lists.
This enhancement may simplifies certain redundant loot tables.

Grouped loot refers to items where the 'groupId' in the '*_loot_template' is greater than 0.

INSERT INTO `reference_loot_template`(`entry`, `item`, `ChanceOrQuestChance`, `groupid`, `mincountOrRef`, `maxcount`, `condition_id`, `comments`) VALUES
(35040, 13955, 0, 1, 1     , 1, 0, 'Stoneform Shoulders'),
(35040, 13983, 0, 1, 1     , 1, 0, 'Gravestone War Axe'),
(35040, 14024, 0, 1, 1     , 1, 0, 'Frightalon'),
(35040, 16734, 0, 1, 1     , 1, 0, 'Boots of Valor'),
(35040, 60294, 0, 1, -60294, 1, 0, 'NPC LOOT (Green World Drop) - (Item Levels: 59-63) - (NPC Levels: 60) - VANILLA NPC ONLY');

For example, the provided SQL INSERT INTO statement demonstrates a reference_loot_template entry (entry: 35040) with several items.
This entry can be referenced in any loot table, and the outcome will be as follows:
 - Only one item from the list will be chosen.
 - The last line, which is a reference, will be treated with the same chance as any other item (considered an equally chanced group).
 - The rules for referenced items with entry 60294 can be customized, resulting in one or multiple items.
  • Loading branch information
cyberium committed Jan 5, 2024
1 parent bd23c93 commit b337f6f
Showing 1 changed file with 21 additions and 11 deletions.
32 changes: 21 additions & 11 deletions src/game/Loot/LootMgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,8 @@ class LootTemplate::LootGroup // A set of loot def
bool HasQuestDrop() const; // True if group includes at least 1 quest drop entry
bool HasQuestDropForPlayer(Player const* player) const;
// The same for active quests of the player
void Process(Loot& loot, Player const* lootOwner) const; // Rolls an item from the group (if any) and adds the item to the loot
// Rolls an item from the group (if any) and adds the item to the loot
void Process(Loot& loot, Player const* lootOwner, LootStore const& store, bool rate) const;
float RawTotalChance() const; // Overall chance for the group (without equal chanced items)
float TotalChance() const; // Overall chance for the group

Expand Down Expand Up @@ -351,11 +352,6 @@ bool LootStoreItem::IsValid(LootStore const& store, uint32 entry) const
sLog.outErrorDb("Table '%s' entry %d item %d: negative chance is given for a reference, skipped", store.GetName(), entry, itemid);
return false;
}
if (chance == 0) // no chance for the reference
{
sLog.outErrorDb("Table '%s' entry %d item %d: zero chance is given for a reference, reference will never be used, skipped", store.GetName(), entry, itemid);
return false;
}
}
return true; // Referenced template existence is checked at whole store level
}
Expand Down Expand Up @@ -2558,11 +2554,25 @@ 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, Player const* lootOwner) const
void LootTemplate::LootGroup::Process(Loot& loot, Player const* lootOwner, LootStore const& store, bool rate) const
{
LootStoreItem const* item = Roll(loot, lootOwner);
if (item != nullptr)
loot.AddItem(*item);
{
if (item->mincountOrRef > 0)
loot.AddItem(*item);
else
{
// we should continue and get next loot reference to process this loot list
LootTemplate const* lRef = LootTemplates_Reference.GetLootFor(-item->mincountOrRef);

if (lRef)
{
for (uint32 loop = 0; loop < item->maxcount; ++loop)
lRef->Process(loot, lootOwner, store, rate);
}
}
}
}

// Overall chance for the group without equal chanced items
Expand Down Expand Up @@ -2634,7 +2644,7 @@ void LootTemplate::LootGroup::CheckLootRefs(LootIdSet* ref_set) const
// Adds an entry to the group (at loading stage)
void LootTemplate::AddEntry(LootStoreItem& item)
{
if (item.group > 0 && item.mincountOrRef > 0) // Group
if (item.group > 0) // Group
{
if (item.group >= Groups.size())
Groups.resize(item.group); // Adds new group the the loot template if needed
Expand All @@ -2652,7 +2662,7 @@ void LootTemplate::Process(Loot& loot, Player const* lootOwner, LootStore const&
if (groupId > Groups.size())
return; // Error message already printed at loading stage

Groups[groupId - 1].Process(loot, lootOwner);
Groups[groupId - 1].Process(loot, lootOwner, store, rate);
return;
}

Expand Down Expand Up @@ -2682,7 +2692,7 @@ void LootTemplate::Process(Loot& loot, Player const* lootOwner, LootStore const&

// Now processing groups
for (const auto& Group : Groups)
Group.Process(loot, lootOwner);
Group.Process(loot, lootOwner, store, rate);
}

// True if template includes at least 1 quest drop entry
Expand Down

0 comments on commit b337f6f

Please sign in to comment.