From 55b43c67519359f0e5a96004c393898b3c62add3 Mon Sep 17 00:00:00 2001 From: Malcrom Date: Sat, 27 Sep 2014 22:40:58 -0230 Subject: Core/LootMgr: Update lootMgr to normalize loot_template tables --- src/server/game/Loot/LootMgr.cpp | 132 ++++++++++++++++++++------------------- src/server/game/Loot/LootMgr.h | 23 +++---- 2 files changed, 79 insertions(+), 76 deletions(-) (limited to 'src') diff --git a/src/server/game/Loot/LootMgr.cpp b/src/server/game/Loot/LootMgr.cpp index f4f0979d091..fe66a4c98ed 100644 --- a/src/server/game/Loot/LootMgr.cpp +++ b/src/server/game/Loot/LootMgr.cpp @@ -133,7 +133,7 @@ uint32 LootStore::LoadLootTable() Clear(); // 0 1 2 3 4 5 6 - QueryResult result = WorldDatabase.PQuery("SELECT entry, item, ChanceOrQuestChance, lootmode, groupid, mincountOrRef, maxcount FROM %s", GetName()); + QueryResult result = WorldDatabase.PQuery("SELECT Entry, Item, Reference, Chance, QuestRequired, LootMode, GroupId, MinCount, MaxCount FROM %s", GetName()); if (!result) return 0; @@ -146,25 +146,27 @@ uint32 LootStore::LoadLootTable() uint32 entry = fields[0].GetUInt32(); uint32 item = fields[1].GetUInt32(); - float chanceOrQuestChance = fields[2].GetFloat(); - uint16 lootmode = fields[3].GetUInt16(); - uint8 group = fields[4].GetUInt8(); - int32 mincountOrRef = fields[5].GetInt32(); - int32 maxcount = fields[6].GetUInt8(); + uint32 reference = fields[2].GetUInt32(); + float chance = fields[3].GetFloat(); + bool needsquest = fields[4].GetBool(); + uint16 lootmode = fields[5].GetUInt16(); + uint8 groupid = fields[6].GetUInt8(); + int32 mincount = fields[7].GetInt32(); + int32 maxcount = fields[8].GetUInt8(); if (maxcount > std::numeric_limits::max()) { - TC_LOG_ERROR("sql.sql", "Table '%s' entry %d item %d: maxcount value (%u) to large. must be less %u - skipped", GetName(), entry, item, maxcount, std::numeric_limits::max()); + TC_LOG_ERROR("sql.sql", "Table '%s' Entry %d Item %d: MaxCount value (%u) to large. must be less %u - skipped", GetName(), entry, item, maxcount, std::numeric_limits::max()); continue; // error already printed to log/console. } - if (group >= 1 << 7) // it stored in 7 bit field + if (groupid >= 1 << 7) // it stored in 7 bit field { - TC_LOG_ERROR("sql.sql", "Table '%s' entry %d item %d: group (%u) must be less %u - skipped", GetName(), entry, item, group, 1 << 7); + TC_LOG_ERROR("sql.sql", "Table '%s' Entry %d Item %d: GroupId (%u) must be less %u - skipped", GetName(), entry, item, groupid, 1 << 7); return 0; } - LootStoreItem* storeitem = new LootStoreItem(item, chanceOrQuestChance, lootmode, group, mincountOrRef, maxcount); + LootStoreItem* storeitem = new LootStoreItem(item, reference, chance, needsquest, lootmode, groupid, mincount, maxcount); if (!storeitem->IsValid(*this, entry)) // Validity checks { @@ -173,7 +175,7 @@ uint32 LootStore::LoadLootTable() } // Looking for the template of the entry - // often entries are put together + // often entries are put together if (m_LootTemplates.empty() || tab->first != entry) { // Searching the template (in case template Id changed) @@ -267,12 +269,12 @@ void LootStore::ReportUnusedIds(LootIdSet const& lootIdSet) const { // all still listed ids isn't referenced for (LootIdSet::const_iterator itr = lootIdSet.begin(); itr != lootIdSet.end(); ++itr) - TC_LOG_ERROR("sql.sql", "Table '%s' entry %d isn't %s and not referenced from loot, and then useless.", GetName(), *itr, GetEntryName()); + TC_LOG_ERROR("sql.sql", "Table '%s' Entry %d isn't %s and not referenced from loot, and thus useless.", GetName(), *itr, GetEntryName()); } -void LootStore::ReportNotExistedId(uint32 id) const +void LootStore::ReportNonExistingId(uint32 id) const { - TC_LOG_ERROR("sql.sql", "Table '%s' entry %d (%s) does not exist but used as loot id in DB.", GetName(), id, GetEntryName()); + TC_LOG_ERROR("sql.sql", "Table '%s' Entry %d (%s) does not exist but is used as loot id in DB.", GetName(), id, GetEntryName()); } // @@ -286,7 +288,7 @@ bool LootStoreItem::Roll(bool rate) const if (chance >= 100.0f) return true; - if (mincountOrRef < 0) // reference case + if (reference > 0) // reference case return roll_chance_f(chance* (rate ? sWorld->getRate(RATE_DROP_ITEM_REFERENCED) : 1.0f)); ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(itemid); @@ -299,47 +301,47 @@ bool LootStoreItem::Roll(bool rate) const // Checks correctness of values bool LootStoreItem::IsValid(LootStore const& store, uint32 entry) const { - if (mincountOrRef == 0) + if (mincount == 0) { - TC_LOG_ERROR("sql.sql", "Table '%s' entry %d item %d: wrong mincountOrRef (%d) - skipped", store.GetName(), entry, itemid, mincountOrRef); + TC_LOG_ERROR("sql.sql", "Table '%s' Entry %d Item %d: wrong MinCount (%d) - skipped", store.GetName(), entry, itemid, mincount); return false; } - if (mincountOrRef > 0) // item (quest or non-quest) entry, maybe grouped + if (reference == 0) // item (quest or non-quest) entry, maybe grouped { ItemTemplate const* proto = sObjectMgr->GetItemTemplate(itemid); if (!proto) { - TC_LOG_ERROR("sql.sql", "Table '%s' entry %d item %d: item entry not listed in `item_template` - skipped", store.GetName(), entry, itemid); + TC_LOG_ERROR("sql.sql", "Table '%s' Entry %d Item %d: item entry not listed in `item_template` - skipped", store.GetName(), entry, itemid); return false; } - if (chance == 0 && group == 0) // Zero chance is allowed for grouped entries only + if (chance == 0 && groupid == 0) // Zero chance is allowed for grouped entries only { - TC_LOG_ERROR("sql.sql", "Table '%s' entry %d item %d: equal-chanced grouped entry, but group not defined - skipped", store.GetName(), entry, itemid); + TC_LOG_ERROR("sql.sql", "Table '%s' Entry %d Item %d: equal-chanced grouped entry, but group not defined - skipped", store.GetName(), entry, itemid); return false; } if (chance != 0 && chance < 0.000001f) // loot with low chance { - TC_LOG_ERROR("sql.sql", "Table '%s' entry %d item %d: low chance (%f) - skipped", + TC_LOG_ERROR("sql.sql", "Table '%s' Entry %d Item %d: low chance (%f) - skipped", store.GetName(), entry, itemid, chance); return false; } - if (maxcount < mincountOrRef) // wrong max count + if (maxcount < mincount) // wrong max count { - TC_LOG_ERROR("sql.sql", "Table '%s' entry %d item %d: max count (%u) less that min count (%i) - skipped", store.GetName(), entry, itemid, int32(maxcount), mincountOrRef); + TC_LOG_ERROR("sql.sql", "Table '%s' Entry %d Item %d: MaxCount (%u) less that MinCount (%i) - skipped", store.GetName(), entry, itemid, int32(maxcount), mincount); return false; } } - else // mincountOrRef < 0 + else // if reference loot { if (needs_quest) - TC_LOG_ERROR("sql.sql", "Table '%s' entry %d item %d: quest chance will be treated as non-quest chance", store.GetName(), entry, itemid); + TC_LOG_ERROR("sql.sql", "Table '%s' Entry %d Item %d: quest required will be ignored", store.GetName(), entry, itemid); else if (chance == 0) // no chance for the reference { - TC_LOG_ERROR("sql.sql", "Table '%s' entry %d item %d: zero chance is specified for a reference, skipped", store.GetName(), entry, itemid); + TC_LOG_ERROR("sql.sql", "Table '%s' Entry %d Item %d: zero chance is specified for a reference, skipped", store.GetName(), entry, itemid); return false; } } @@ -417,7 +419,7 @@ void Loot::AddItem(LootStoreItem const& item) if (!proto) return; - uint32 count = urand(item.mincountOrRef, item.maxcount); + uint32 count = urand(item.mincount, item.maxcount); uint32 stacks = count / proto->GetMaxStackSize() + ((count % proto->GetMaxStackSize()) ? 1 : 0); std::vector& lootItems = item.needs_quest ? quest_items : items; @@ -1213,24 +1215,24 @@ void LootTemplate::LootGroup::CheckLootRefs(LootTemplateMap const& /*store*/, Lo for (LootStoreItemList::const_iterator ieItr = ExplicitlyChanced.begin(); ieItr != ExplicitlyChanced.end(); ++ieItr) { LootStoreItem* item = *ieItr; - if (item->mincountOrRef < 0) + if (item->reference > 0) { - if (!LootTemplates_Reference.GetLootFor(-item->mincountOrRef)) - LootTemplates_Reference.ReportNotExistedId(-item->mincountOrRef); + if (!LootTemplates_Reference.GetLootFor(item->reference)) + LootTemplates_Reference.ReportNonExistingId(item->reference); else if (ref_set) - ref_set->erase(-item->mincountOrRef); + ref_set->erase(item->reference); } } for (LootStoreItemList::const_iterator ieItr = EqualChanced.begin(); ieItr != EqualChanced.end(); ++ieItr) { LootStoreItem* item = *ieItr; - if (item->mincountOrRef < 0) + if (item->reference > 0) { - if (!LootTemplates_Reference.GetLootFor(-item->mincountOrRef)) - LootTemplates_Reference.ReportNotExistedId(-item->mincountOrRef); + if (!LootTemplates_Reference.GetLootFor(item->reference)) + LootTemplates_Reference.ReportNonExistingId(item->reference); else if (ref_set) - ref_set->erase(-item->mincountOrRef); + ref_set->erase(item->reference); } } } @@ -1251,16 +1253,16 @@ LootTemplate::~LootTemplate() // Adds an entry to the group (at loading stage) void LootTemplate::AddEntry(LootStoreItem* item) { - if (item->group > 0 && item->mincountOrRef > 0) // Group + if (item->groupid > 0 && item->reference == 0) // Group { - if (item->group >= Groups.size()) - Groups.resize(item->group, NULL); // Adds new group the the loot template if needed - if (!Groups[item->group - 1]) - Groups[item->group - 1] = new LootGroup(); + if (item->groupid >= Groups.size()) + Groups.resize(item->groupid, NULL); // Adds new group the the loot template if needed + if (!Groups[item->groupid - 1]) + Groups[item->groupid - 1] = new LootGroup(); - Groups[item->group-1]->AddEntry(item); // Adds new entry to the group + Groups[item->groupid - 1]->AddEntry(item); // Adds new entry to the group } - else // Non-grouped entries and references are stored together + else // Non-grouped entries and references are stored together Entries.push_back(item); } @@ -1299,7 +1301,7 @@ void LootTemplate::Process(Loot& loot, bool rate, uint16 lootMode, uint8 groupId if (!Groups[groupId - 1]) return; - Groups[groupId-1]->Process(loot, lootMode); + Groups[groupId - 1]->Process(loot, lootMode); return; } @@ -1313,15 +1315,15 @@ void LootTemplate::Process(Loot& loot, bool rate, uint16 lootMode, uint8 groupId if (!item->Roll(rate)) continue; // Bad luck for the entry - if (item->mincountOrRef < 0) // References processing + if (item->reference > 0) // References processing { - LootTemplate const* Referenced = LootTemplates_Reference.GetLootFor(-item->mincountOrRef); + LootTemplate const* Referenced = LootTemplates_Reference.GetLootFor(item->reference); if (!Referenced) continue; // Error message already printed at loading stage uint32 maxcount = uint32(float(item->maxcount) * sWorld->getRate(RATE_DROP_ITEM_REFERENCED_AMOUNT)); for (uint32 loop = 0; loop < maxcount; ++loop) // Ref multiplicator - Referenced->Process(loot, rate, lootMode, item->group); + Referenced->Process(loot, rate, lootMode, item->groupid); } else // Plain entries (not a reference, not grouped) loot.AddItem(*item); // Chance is already checked, just add @@ -1350,12 +1352,12 @@ bool LootTemplate::HasQuestDrop(LootTemplateMap const& store, uint8 groupId) con for (LootStoreItemList::const_iterator i = Entries.begin(); i != Entries.end(); ++i) { LootStoreItem* item = *i; - if (item->mincountOrRef < 0) // References + if (item->reference > 0) // References { - LootTemplateMap::const_iterator Referenced = store.find(-item->mincountOrRef); + LootTemplateMap::const_iterator Referenced = store.find(item->reference); if (Referenced == store.end()) continue; // Error message [should be] already printed at loading stage - if (Referenced->second->HasQuestDrop(store, item->group)) + if (Referenced->second->HasQuestDrop(store, item->groupid)) return true; } else if (item->needs_quest) @@ -1382,19 +1384,19 @@ bool LootTemplate::HasQuestDropForPlayer(LootTemplateMap const& store, Player co if (!Groups[groupId - 1]) return false; - return Groups[groupId-1]->HasQuestDropForPlayer(player); + return Groups[groupId - 1]->HasQuestDropForPlayer(player); } // Checking non-grouped entries for (LootStoreItemList::const_iterator i = Entries.begin(); i != Entries.end(); ++i) { LootStoreItem* item = *i; - if (item->mincountOrRef < 0) // References processing + if (item->reference > 0) // References processing { - LootTemplateMap::const_iterator Referenced = store.find(-item->mincountOrRef); + LootTemplateMap::const_iterator Referenced = store.find(item->reference); if (Referenced == store.end()) continue; // Error message already printed at loading stage - if (Referenced->second->HasQuestDropForPlayer(store, player, item->group)) + if (Referenced->second->HasQuestDropForPlayer(store, player, item->groupid)) return true; } else if (player->HasQuestForItem(item->itemid)) @@ -1426,12 +1428,12 @@ void LootTemplate::CheckLootRefs(LootTemplateMap const& store, LootIdSet* ref_se for (LootStoreItemList::const_iterator ieItr = Entries.begin(); ieItr != Entries.end(); ++ieItr) { LootStoreItem* item = *ieItr; - if (item->mincountOrRef < 0) + if (item->reference > 0) { - if (!LootTemplates_Reference.GetLootFor(-item->mincountOrRef)) - LootTemplates_Reference.ReportNotExistedId(-item->mincountOrRef); + if (!LootTemplates_Reference.GetLootFor(item->reference)) + LootTemplates_Reference.ReportNonExistingId(item->reference); else if (ref_set) - ref_set->erase(-item->mincountOrRef); + ref_set->erase(item->reference); } } @@ -1501,7 +1503,7 @@ bool LootTemplate::addConditionItem(Condition* cond) bool LootTemplate::isReference(uint32 id) { for (LootStoreItemList::const_iterator ieItr = Entries.begin(); ieItr != Entries.end(); ++ieItr) - if ((*ieItr)->itemid == id && (*ieItr)->mincountOrRef < 0) + if ((*ieItr)->itemid == id && (*ieItr)->reference > 0) return true; return false;//not found or not reference @@ -1523,7 +1525,7 @@ void LoadLootTemplates_Creature() if (uint32 lootid = itr->second.lootid) { if (lootIdSet.find(lootid) == lootIdSet.end()) - LootTemplates_Creature.ReportNotExistedId(lootid); + LootTemplates_Creature.ReportNonExistingId(lootid); else lootIdSetUsed.insert(lootid); } @@ -1556,7 +1558,7 @@ void LoadLootTemplates_Disenchant() if (uint32 lootid = itr->second.DisenchantID) { if (lootIdSet.find(lootid) == lootIdSet.end()) - LootTemplates_Disenchant.ReportNotExistedId(lootid); + LootTemplates_Disenchant.ReportNonExistingId(lootid); else lootIdSetUsed.insert(lootid); } @@ -1614,7 +1616,7 @@ void LoadLootTemplates_Gameobject() if (uint32 lootid = itr->second.GetLootId()) { if (lootIdSet.find(lootid) == lootIdSet.end()) - LootTemplates_Gameobject.ReportNotExistedId(lootid); + LootTemplates_Gameobject.ReportNonExistingId(lootid); else lootIdSetUsed.insert(lootid); } @@ -1701,7 +1703,7 @@ void LoadLootTemplates_Pickpocketing() if (uint32 lootid = itr->second.pickpocketLootId) { if (lootIdSet.find(lootid) == lootIdSet.end()) - LootTemplates_Pickpocketing.ReportNotExistedId(lootid); + LootTemplates_Pickpocketing.ReportNonExistingId(lootid); else lootIdSetUsed.insert(lootid); } @@ -1788,7 +1790,7 @@ void LoadLootTemplates_Skinning() if (uint32 lootid = itr->second.SkinLootId) { if (lootIdSet.find(lootid) == lootIdSet.end()) - LootTemplates_Skinning.ReportNotExistedId(lootid); + LootTemplates_Skinning.ReportNonExistingId(lootid); else lootIdSetUsed.insert(lootid); } @@ -1832,7 +1834,7 @@ void LoadLootTemplates_Spell() // ignore 61756 (Northrend Inscription Research (FAST QA VERSION) for example if (!(spellInfo->Attributes & SPELL_ATTR0_NOT_SHAPESHIFT) || (spellInfo->Attributes & SPELL_ATTR0_TRADESPELL)) { - LootTemplates_Spell.ReportNotExistedId(spell_id); + LootTemplates_Spell.ReportNonExistingId(spell_id); } } else diff --git a/src/server/game/Loot/LootMgr.h b/src/server/game/Loot/LootMgr.h index 673e5b6841e..1f5c0251eec 100644 --- a/src/server/game/Loot/LootMgr.h +++ b/src/server/game/Loot/LootMgr.h @@ -125,19 +125,20 @@ class LootStore; struct LootStoreItem { uint32 itemid; // id of the item - float chance; // always positive, chance to drop for both quest and non-quest items, chance to be used for refs - int32 mincountOrRef; // mincount for drop items (positive) or minus referenced TemplateleId (negative) + uint32 reference; // referenced TemplateleId + float chance; // chance to drop for both quest and non-quest items, chance to be used for refs + bool needs_quest : 1; // quest drop (quest is required for item to drop) uint16 lootmode; - uint8 group :7; - bool needs_quest :1; // quest drop (negative ChanceOrQuestChance in DB) - uint8 maxcount :8; // max drop count for the item (mincountOrRef positive) or Ref multiplicator (mincountOrRef negative) + uint8 groupid : 7; + uint8 mincount; // mincount for drop items + uint8 maxcount : 8; // max drop count for the item mincount or Ref multiplicator ConditionList conditions; // additional loot condition - // Constructor, converting ChanceOrQuestChance -> (chance, needs_quest) + // Constructor // displayid is filled in IsValid() which must be called after - LootStoreItem(uint32 _itemid, float _chanceOrQuestChance, uint16 _lootmode, uint8 _group, int32 _mincountOrRef, uint8 _maxcount) - : itemid(_itemid), chance(std::fabs(_chanceOrQuestChance)), mincountOrRef(_mincountOrRef), lootmode(_lootmode), - group(_group), needs_quest(_chanceOrQuestChance < 0), maxcount(_maxcount) + LootStoreItem(uint32 _itemid, uint32 _reference, float _chance, bool _needs_quest, uint16 _lootmode, uint8 _groupid, int32 _mincount, uint8 _maxcount) + : itemid(_itemid), reference(_reference), chance(_chance), needs_quest(_needs_quest), + lootmode(_lootmode), groupid(_groupid), mincount(_mincount), maxcount(_maxcount) { } bool Roll(bool rate) const; // Checks if the entry takes it's chance (at loot generation) @@ -165,7 +166,7 @@ struct LootItem bool canSave; // Constructor, copies most fields from LootStoreItem, generates random count and random suffixes/properties - // Should be called for non-reference LootStoreItem entries only (mincountOrRef > 0) + // Should be called for non-reference LootStoreItem entries only (reference = 0) explicit LootItem(LootStoreItem const& li); // Empty constructor for creating an empty LootItem to be filled in with DB data @@ -215,7 +216,7 @@ class LootStore uint32 LoadAndCollectLootIds(LootIdSet& ids_set); void CheckLootRefs(LootIdSet* ref_set = NULL) const; // check existence reference and remove it from ref_set void ReportUnusedIds(LootIdSet const& ids_set) const; - void ReportNotExistedId(uint32 id) const; + void ReportNonExistingId(uint32 id) const; bool HaveLootFor(uint32 loot_id) const { return m_LootTemplates.find(loot_id) != m_LootTemplates.end(); } bool HaveQuestLootFor(uint32 loot_id) const; -- cgit v1.2.3 From ad336996eef7a30a82c9bcb3da2997fd9bd04e67 Mon Sep 17 00:00:00 2001 From: Malcrom Date: Sat, 27 Sep 2014 23:17:29 -0230 Subject: Core/LootMgr: Forgot to change this. Found by Vincent Micheal --- src/server/game/Loot/LootMgr.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/server/game/Loot/LootMgr.cpp b/src/server/game/Loot/LootMgr.cpp index fe66a4c98ed..fd9a91ebb6a 100644 --- a/src/server/game/Loot/LootMgr.cpp +++ b/src/server/game/Loot/LootMgr.cpp @@ -151,7 +151,7 @@ uint32 LootStore::LoadLootTable() bool needsquest = fields[4].GetBool(); uint16 lootmode = fields[5].GetUInt16(); uint8 groupid = fields[6].GetUInt8(); - int32 mincount = fields[7].GetInt32(); + int32 mincount = fields[7].GetUInt8(); int32 maxcount = fields[8].GetUInt8(); if (maxcount > std::numeric_limits::max()) -- cgit v1.2.3