diff options
author | Shauren <shauren.trinity@gmail.com> | 2020-07-31 11:21:24 +0200 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2020-07-31 11:21:24 +0200 |
commit | 1340f2cdb33a4feac01e68d2f65ae1ae486e135f (patch) | |
tree | bc47f6026c5f493ace39e6c0d9fd128ea8507a14 /src/server/game/Globals/ObjectMgr.cpp | |
parent | 8116ad58892b2170d4cea32a6ce2c5c265acf4b2 (diff) |
Core/Creatures: Move gossip trainer assignment to creature_trainer table - same gossip can open different trainers depending on which creature it is assigned to
Closes #21723
Diffstat (limited to 'src/server/game/Globals/ObjectMgr.cpp')
-rw-r--r-- | src/server/game/Globals/ObjectMgr.cpp | 44 |
1 files changed, 26 insertions, 18 deletions
diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 73a0b0c0c6d..53681914dfd 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -8738,33 +8738,51 @@ void ObjectMgr::LoadTrainers() TC_LOG_INFO("server.loading", ">> Loaded " SZFMTD " Trainers in %u ms", _trainers.size(), GetMSTimeDiffToNow(oldMSTime)); } -void ObjectMgr::LoadCreatureDefaultTrainers() +void ObjectMgr::LoadCreatureTrainers() { uint32 oldMSTime = getMSTime(); _creatureDefaultTrainers.clear(); - if (QueryResult result = WorldDatabase.Query("SELECT CreatureId, TrainerId FROM creature_default_trainer")) + if (QueryResult result = WorldDatabase.Query("SELECT CreatureId, TrainerId, MenuId, OptionIndex FROM creature_trainer")) { do { Field* fields = result->Fetch(); uint32 creatureId = fields[0].GetUInt32(); uint32 trainerId = fields[1].GetUInt32(); + uint32 gossipMenuId = fields[2].GetUInt32(); + uint32 gossipOptionIndex = fields[3].GetUInt32(); if (!GetCreatureTemplate(creatureId)) { - TC_LOG_ERROR("sql.sql", "Table `creature_default_trainer` references non-existing creature template (CreatureId: %u), ignoring", creatureId); + TC_LOG_ERROR("sql.sql", "Table `creature_trainer` references non-existing creature template (CreatureId: %u), ignoring", creatureId); continue; } if (!GetTrainer(trainerId)) { - TC_LOG_ERROR("sql.sql", "Table `creature_default_trainer` references non-existing trainer (TrainerId: %u) for CreatureId %u, ignoring", trainerId, creatureId); + TC_LOG_ERROR("sql.sql", "Table `creature_trainer` references non-existing trainer (TrainerId: %u) for CreatureId %u MenuId %u OptionIndex %u, ignoring", + trainerId, creatureId, gossipMenuId, gossipOptionIndex); continue; } - _creatureDefaultTrainers[creatureId] = trainerId; + if (gossipMenuId || gossipOptionIndex) + { + Trinity::IteratorPair<GossipMenuItemsContainer::const_iterator> gossipMenuItems = GetGossipMenuItemsMapBounds(gossipMenuId); + auto gossipOptionItr = std::find_if(gossipMenuItems.begin(), gossipMenuItems.end(), [gossipOptionIndex](std::pair<uint32 const, GossipMenuItems> const& entry) + { + return entry.second.OptionIndex == gossipOptionIndex; + }); + if (gossipOptionItr == gossipMenuItems.end()) + { + TC_LOG_ERROR("sql.sql", "Table `creature_trainer` references non-existing gossip menu option (MenuId %u OptionIndex %u) for CreatureId %u and TrainerId %u, ignoring", + gossipMenuId, gossipOptionIndex, creatureId, trainerId); + continue; + } + } + + _creatureDefaultTrainers[std::make_tuple(creatureId, gossipMenuId, gossipOptionIndex)] = trainerId; } while (result->NextRow()); } @@ -8924,13 +8942,10 @@ void ObjectMgr::LoadGossipMenuItems() // 7 8 "oa.ActionMenuId, oa.ActionPoiId, " // 9 10 11 12 - "ob.BoxCoded, ob.BoxMoney, ob.BoxText, ob.BoxBroadcastTextId, " - // 13 - "ot.TrainerId " + "ob.BoxCoded, ob.BoxMoney, ob.BoxText, ob.BoxBroadcastTextId " "FROM gossip_menu_option o " "LEFT JOIN gossip_menu_option_action oa ON o.MenuId = oa.MenuId AND o.OptionIndex = oa.OptionIndex " "LEFT JOIN gossip_menu_option_box ob ON o.MenuId = ob.MenuId AND o.OptionIndex = ob.OptionIndex " - "LEFT JOIN gossip_menu_option_trainer ot ON o.MenuId = ot.MenuId AND o.OptionIndex = ot.OptionIndex " "ORDER BY o.MenuId, o.OptionIndex"); if (!result) @@ -8958,7 +8973,6 @@ void ObjectMgr::LoadGossipMenuItems() gMenuItem.BoxMoney = fields[10].GetUInt32(); gMenuItem.BoxText = fields[11].GetString(); gMenuItem.BoxBroadcastTextId = fields[12].GetUInt32(); - gMenuItem.TrainerId = fields[13].GetUInt32(); if (gMenuItem.OptionIcon >= GOSSIP_ICON_MAX) { @@ -8993,12 +9007,6 @@ void ObjectMgr::LoadGossipMenuItems() } } - if (gMenuItem.TrainerId && !GetTrainer(gMenuItem.TrainerId)) - { - TC_LOG_ERROR("sql.sql", "Table `gossip_menu_option_trainer` for MenuId %u, OptionIndex %u use non-existing TrainerId %u, ignoring", gMenuItem.MenuId, gMenuItem.OptionIndex, gMenuItem.TrainerId); - gMenuItem.TrainerId = 0; - } - _gossipMenuItemsStore.insert(GossipMenuItemsContainer::value_type(gMenuItem.MenuId, gMenuItem)); } while (result->NextRow()); @@ -9010,9 +9018,9 @@ Trainer::Trainer const* ObjectMgr::GetTrainer(uint32 trainerId) const return Trinity::Containers::MapGetValuePtr(_trainers, trainerId); } -uint32 ObjectMgr::GetCreatureDefaultTrainer(uint32 creatureId) const +uint32 ObjectMgr::GetCreatureTrainerForGossipOption(uint32 creatureId, uint32 gossipMenuId, uint32 gossipOptionIndex) const { - auto itr = _creatureDefaultTrainers.find(creatureId); + auto itr = _creatureDefaultTrainers.find(std::make_tuple(creatureId, gossipMenuId, gossipOptionIndex)); if (itr != _creatureDefaultTrainers.end()) return itr->second; |