diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/Entities/Creature/GossipDef.cpp | 5 | ||||
-rw-r--r-- | src/server/game/Entities/Creature/GossipDef.h | 4 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 4 | ||||
-rw-r--r-- | src/server/game/Globals/ObjectMgr.cpp | 44 | ||||
-rw-r--r-- | src/server/game/Globals/ObjectMgr.h | 11 | ||||
-rw-r--r-- | src/server/game/World/World.cpp | 8 | ||||
-rw-r--r-- | src/server/scripts/Commands/cs_reload.cpp | 2 |
7 files changed, 43 insertions, 35 deletions
diff --git a/src/server/game/Entities/Creature/GossipDef.cpp b/src/server/game/Entities/Creature/GossipDef.cpp index 1a7fa91e4f5..aad55cd5c30 100644 --- a/src/server/game/Entities/Creature/GossipDef.cpp +++ b/src/server/game/Entities/Creature/GossipDef.cpp @@ -133,17 +133,16 @@ void GossipMenu::AddMenuItem(uint32 menuId, uint32 optionIndex, uint32 sender, u /// Add menu item with existing method. Menu item id -1 is also used in ADD_GOSSIP_ITEM macro. uint32 newOptionIndex = AddMenuItem(-1, itr->second.OptionIcon, strOptionText, sender, action, strBoxText, itr->second.BoxMoney, itr->second.BoxCoded); - AddGossipMenuItemData(newOptionIndex, itr->second.ActionMenuId, itr->second.ActionPoiId, itr->second.TrainerId); + AddGossipMenuItemData(newOptionIndex, itr->second.ActionMenuId, itr->second.ActionPoiId); } } -void GossipMenu::AddGossipMenuItemData(uint32 optionIndex, uint32 gossipActionMenuId, uint32 gossipActionPoi, uint32 trainerId) +void GossipMenu::AddGossipMenuItemData(uint32 optionIndex, uint32 gossipActionMenuId, uint32 gossipActionPoi) { GossipMenuItemData& itemData = _menuItemData[optionIndex]; itemData.GossipActionMenuId = gossipActionMenuId; itemData.GossipActionPoi = gossipActionPoi; - itemData.TrainerId = trainerId; } uint32 GossipMenu::GetMenuItemSender(uint32 menuItemId) const diff --git a/src/server/game/Entities/Creature/GossipDef.h b/src/server/game/Entities/Creature/GossipDef.h index aacdf164caa..69f5e118277 100644 --- a/src/server/game/Entities/Creature/GossipDef.h +++ b/src/server/game/Entities/Creature/GossipDef.h @@ -147,8 +147,6 @@ struct GossipMenuItemData { uint32 GossipActionMenuId; // MenuId of the gossip triggered by this action uint32 GossipActionPoi; - - uint32 TrainerId; }; // need an ordered container @@ -176,7 +174,7 @@ class TC_GAME_API GossipMenu void SetLocale(LocaleConstant locale) { _locale = locale; } LocaleConstant GetLocale() const { return _locale; } - void AddGossipMenuItemData(uint32 optionIndex, uint32 gossipActionMenuId, uint32 gossipActionPoi, uint32 trainerId); + void AddGossipMenuItemData(uint32 optionIndex, uint32 gossipActionMenuId, uint32 gossipActionPoi); uint32 GetMenuItemCount() const { return uint32(_menuItems.size()); } bool Empty() const { return _menuItems.empty(); } diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 4568dcecece..4d47e9d9ccc 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -14712,7 +14712,7 @@ void Player::PrepareGossipMenu(WorldObject* source, uint32 menuId /*= 0*/, bool } menu->GetGossipMenu().AddMenuItem(itr->second.OptionIndex, itr->second.OptionIcon, strOptionText, 0, itr->second.OptionType, strBoxText, itr->second.BoxMoney, itr->second.BoxCoded); - menu->GetGossipMenu().AddGossipMenuItemData(itr->second.OptionIndex, itr->second.ActionMenuId, itr->second.ActionPoiId, itr->second.TrainerId); + menu->GetGossipMenu().AddGossipMenuItemData(itr->second.OptionIndex, itr->second.ActionMenuId, itr->second.ActionPoiId); } } } @@ -14813,7 +14813,7 @@ void Player::OnGossipSelect(WorldObject* source, uint32 optionIndex, uint32 menu GetSession()->SendStablePet(guid); break; case GOSSIP_OPTION_TRAINER: - GetSession()->SendTrainerList(source->ToCreature(), menuItemData->TrainerId); + GetSession()->SendTrainerList(source->ToCreature(), sObjectMgr->GetCreatureTrainerForGossipOption(source->GetEntry(), menuId, optionIndex)); break; case GOSSIP_OPTION_LEARNDUALSPEC: break; 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; diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h index 85974e3b9da..e5b3ba78226 100644 --- a/src/server/game/Globals/ObjectMgr.h +++ b/src/server/game/Globals/ObjectMgr.h @@ -682,7 +682,6 @@ struct GossipMenuItems uint32 BoxMoney; std::string BoxText; uint32 BoxBroadcastTextId; - uint32 TrainerId; ConditionContainer Conditions; }; @@ -1297,7 +1296,7 @@ class TC_GAME_API ObjectMgr void LoadVendors(); void LoadTrainers(); - void LoadCreatureDefaultTrainers(); + void LoadCreatureTrainers(); void LoadPhases(); void UnloadPhaseConditions(); @@ -1519,7 +1518,11 @@ class TC_GAME_API ObjectMgr bool DeleteGameTele(std::string const& name); Trainer::Trainer const* GetTrainer(uint32 trainerId) const; - uint32 GetCreatureDefaultTrainer(uint32 creatureId) const; + uint32 GetCreatureDefaultTrainer(uint32 creatureId) const + { + return GetCreatureTrainerForGossipOption(creatureId, 0, 0); + } + uint32 GetCreatureTrainerForGossipOption(uint32 creatureId, uint32 gossipMenuId, uint32 gossipOptionIndex) const; VendorItemData const* GetNpcVendorItemList(uint32 entry) const { @@ -1779,7 +1782,7 @@ class TC_GAME_API ObjectMgr CacheVendorItemContainer _cacheVendorItemStore; std::unordered_map<uint32, Trainer::Trainer> _trainers; - std::unordered_map<uint32, uint32> _creatureDefaultTrainers; + std::map<std::tuple<uint32, uint32, uint32>, uint32> _creatureDefaultTrainers; std::set<uint32> _difficultyEntries[MAX_CREATURE_DIFFICULTIES]; // already loaded difficulty 1 value in creatures, used in CheckCreatureTemplate std::set<uint32> _hasDifficultyEntries[MAX_CREATURE_DIFFICULTIES]; // already loaded creatures with difficulty 1 values, used in CheckCreatureTemplate diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index cce33cd7795..db5c0c45e6e 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -1995,14 +1995,14 @@ void World::SetInitialWorldSettings() TC_LOG_INFO("server.loading", "Loading Trainers..."); sObjectMgr->LoadTrainers(); // must be after load CreatureTemplate - TC_LOG_INFO("server.loading", "Loading Creature default trainers..."); - sObjectMgr->LoadCreatureDefaultTrainers(); - TC_LOG_INFO("server.loading", "Loading Gossip menu..."); sObjectMgr->LoadGossipMenu(); TC_LOG_INFO("server.loading", "Loading Gossip menu options..."); - sObjectMgr->LoadGossipMenuItems(); // must be after LoadTrainers + sObjectMgr->LoadGossipMenuItems(); + + TC_LOG_INFO("server.loading", "Loading Creature trainers..."); + sObjectMgr->LoadCreatureTrainers(); // must be after LoadGossipMenuItems TC_LOG_INFO("server.loading", "Loading Vendors..."); sObjectMgr->LoadVendors(); // must be after load CreatureTemplate and ItemTemplate diff --git a/src/server/scripts/Commands/cs_reload.cpp b/src/server/scripts/Commands/cs_reload.cpp index ccb032f6c02..a75bb33fdd7 100644 --- a/src/server/scripts/Commands/cs_reload.cpp +++ b/src/server/scripts/Commands/cs_reload.cpp @@ -696,7 +696,7 @@ public: { TC_LOG_INFO("misc", "Re-Loading `trainer` Table!"); sObjectMgr->LoadTrainers(); - sObjectMgr->LoadCreatureDefaultTrainers(); + sObjectMgr->LoadCreatureTrainers(); handler->SendGlobalGMSysMessage("DB table `trainer` reloaded."); handler->SendGlobalGMSysMessage("DB table `trainer_locale` reloaded."); handler->SendGlobalGMSysMessage("DB table `trainer_spell` reloaded."); |