Skip to content

Commit

Permalink
Move loot entry check to more correct place
Browse files Browse the repository at this point in the history
Check for loot entry fit more to LootStore class.
  • Loading branch information
cyberium committed Jan 31, 2024
1 parent 6718ea9 commit 5373579
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 46 deletions.
85 changes: 41 additions & 44 deletions src/game/Loot/LootMgr.cpp
Expand Up @@ -174,15 +174,12 @@ void LootStore::LoadLootTable()
}
}

LootStoreItem storeitem = LootStoreItem(item, chanceOrQuestChance, group, conditionId, mincountOrRef, maxcount);

if (!storeitem.IsValid(*this, entry)) // Validity checks
// Validity checks
if (!IsValidItemTemplate(entry, item, group, mincountOrRef, chanceOrQuestChance, maxcount))
continue;

LootTemplate* currenTpl = &m_LootTemplates[entry];

// Adds current row to the template
currenTpl->AddEntry(storeitem);
// Add the item to the loot store
m_LootTemplates[entry].AddEntry(LootStoreItem(item, chanceOrQuestChance, group, conditionId, mincountOrRef, maxcount));
++count;
}
while (queryResult->NextRow());
Expand Down Expand Up @@ -310,88 +307,88 @@ bool LootStore::HaveLootFor(uint32 loot_id) const
return m_LootTemplates.find(loot_id) != m_LootTemplates.end();
}

//
// --------- LootStoreItem ---------
//

// Checks if the entry (quest, non-quest, reference) takes it's chance (at loot generation)
// RATE_DROP_ITEMS is no longer used for all types of entries
bool LootStoreItem::Roll(bool rate) const
{
if (chance >= 100.0f)
return true;

if (mincountOrRef < 0) // reference case
return roll_chance_f(chance * (rate ? sWorld.getConfig(CONFIG_FLOAT_RATE_DROP_ITEM_REFERENCED) : 1.0f));

if (needs_quest)
return roll_chance_f(chance * (rate ? sWorld.getConfig(CONFIG_FLOAT_RATE_DROP_ITEM_QUEST) : 1.0f));

ItemPrototype const* pProto = ObjectMgr::GetItemPrototype(itemid);

float qualityModifier = pProto && rate ? sWorld.getConfig(qualityToRate[pProto->Quality]) : 1.0f;

return roll_chance_f(chance * qualityModifier);
}

// Checks correctness of values
bool LootStoreItem::IsValid(LootStore const& store, uint32 entry) const
bool LootStore::IsValidItemTemplate(uint32 entry, uint32 itemId, uint32 group, int32 mincountOrRef, float chanceOrQuestChance, uint32 maxCount) const
{
float chance = fabs(chanceOrQuestChance);
if (group >= 1 << 7) // it stored in 7 bit field
{
sLog.outErrorDb("Table '%s' entry %d item %d: group (%u) must be less %u - skipped", store.GetName(), entry, itemid, group, 1 << 7);
sLog.outErrorDb("Table '%s' entry %d item %d: group (%u) must be less %u - skipped", GetName(), entry, itemId, group, 1 << 7);
return false;
}

if (mincountOrRef == 0)
{
sLog.outErrorDb("Table '%s' entry %d item %d: wrong mincountOrRef (%d) - skipped", store.GetName(), entry, itemid, mincountOrRef);
sLog.outErrorDb("Table '%s' entry %d item %d: wrong mincountOrRef (%d) - skipped", GetName(), entry, itemId, mincountOrRef);
return false;
}

if (mincountOrRef > 0) // item (quest or non-quest) entry, maybe grouped
{
ItemPrototype const* proto = ObjectMgr::GetItemPrototype(itemid);
ItemPrototype const* proto = ObjectMgr::GetItemPrototype(itemId);
if (!proto)
{
sLog.outErrorDb("Table '%s' entry %d item %d: item entry not listed in `item_template` - skipped", store.GetName(), entry, itemid);
sLog.outErrorDb("Table '%s' entry %d item %d: item entry not listed in `item_template` - skipped", GetName(), entry, itemId);
return false;
}

if (chance == 0 && group == 0) // Zero chance is allowed for grouped entries only
{
sLog.outErrorDb("Table '%s' entry %d item %d: equal-chanced grouped entry, but group not defined - skipped", store.GetName(), entry, itemid);
sLog.outErrorDb("Table '%s' entry %d item %d: equal-chanced grouped entry, but group not defined - skipped", GetName(), entry, itemId);
return false;
}

if (chance != 0 && chance < 0.000001f) // loot with low chance
{
sLog.outErrorDb("Table '%s' entry %d item %d: low chance (%f) - skipped", store.GetName(), entry, itemid, chance);
sLog.outErrorDb("Table '%s' entry %d item %d: low chance (%f) - skipped", GetName(), entry, itemId, chance);
return false;
}

if (maxcount < mincountOrRef) // wrong max count
if (maxCount < mincountOrRef) // wrong max count
{
sLog.outErrorDb("Table '%s' entry %d item %d: max count (%u) less that min count (%i) - skipped", store.GetName(), entry, itemid, uint32(maxcount), mincountOrRef);
sLog.outErrorDb("Table '%s' entry %d item %d: max count (%u) less that min count (%i) - skipped", GetName(), entry, itemId, uint32(maxCount), mincountOrRef);
return false;
}
}
else // mincountOrRef < 0
{
if (needs_quest)
if (chanceOrQuestChance < 0)
{
sLog.outErrorDb("Table '%s' entry %d item %d: negative chance is given for a reference, skipped", store.GetName(), entry, itemid);
sLog.outErrorDb("Table '%s' entry %d item %d: negative chance is given for a reference, skipped", GetName(), entry, itemId);
return false;
}
if (chance == 0 && group == 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);
sLog.outErrorDb("Table '%s' entry %d item %d: zero chance is given for a reference, reference will never be used, skipped", GetName(), entry, itemId);
return false;
}
}
return true; // Referenced template existence is checked at whole store level
}

//
// --------- LootStoreItem ---------
//

// Checks if the entry (quest, non-quest, reference) takes it's chance (at loot generation)
// RATE_DROP_ITEMS is no longer used for all types of entries
bool LootStoreItem::Roll(bool rate) const
{
if (chance >= 100.0f)
return true;

if (mincountOrRef < 0) // reference case
return roll_chance_f(chance * (rate ? sWorld.getConfig(CONFIG_FLOAT_RATE_DROP_ITEM_REFERENCED) : 1.0f));

if (needs_quest)
return roll_chance_f(chance * (rate ? sWorld.getConfig(CONFIG_FLOAT_RATE_DROP_ITEM_QUEST) : 1.0f));

ItemPrototype const* pProto = ObjectMgr::GetItemPrototype(itemid);

float qualityModifier = pProto && rate ? sWorld.getConfig(qualityToRate[pProto->Quality]) : 1.0f;

return roll_chance_f(chance * qualityModifier);
}

//
// --------- LootItem ---------
//
Expand Down
5 changes: 3 additions & 2 deletions src/game/Loot/LootMgr.h
Expand Up @@ -217,8 +217,6 @@ struct LootStoreItem
{}

bool Roll(bool rate) const; // Checks if the entry takes it's chance (at loot generation)
bool IsValid(LootStore const& store, uint32 entry) const;
// Checks correctness of values
};

struct LootItem
Expand Down Expand Up @@ -283,6 +281,9 @@ class LootStore
char const* GetEntryName() const { return m_entryName; }
bool IsRatesAllowed() const { return m_ratesAllowed; }

// Checks if drop rules are valid for the item
bool IsValidItemTemplate(uint32 entry, uint32 itemId, uint32 group, int32 mincountOrRef, float chance, uint32 maxCount) const;

protected:
void LoadLootTable();
void Clear();
Expand Down

0 comments on commit 5373579

Please sign in to comment.