From 2e02c76399f34a210141474fc80106b54b4b4ebe Mon Sep 17 00:00:00 2001 From: Kitzunu <24550914+Kitzunu@users.noreply.github.com> Date: Tue, 13 Aug 2024 21:09:36 +0200 Subject: [PATCH] fix(Core/Creature): quest_greeting_locale (#19615) * fix(Core/Creature): quest_greeting_locale * closes https://github.com/azerothcore/azerothcore-wotlk/issues/14845 --- .../rev_1723569725185190500.sql | 2 + .../game/Entities/Creature/GossipDef.cpp | 10 +-- src/server/game/Globals/ObjectMgr.cpp | 77 +++++++++++-------- src/server/game/Globals/ObjectMgr.h | 36 +-------- src/server/game/World/World.cpp | 2 +- src/server/scripts/Commands/cs_reload.cpp | 9 +-- 6 files changed, 53 insertions(+), 83 deletions(-) create mode 100644 data/sql/updates/pending_db_world/rev_1723569725185190500.sql diff --git a/data/sql/updates/pending_db_world/rev_1723569725185190500.sql b/data/sql/updates/pending_db_world/rev_1723569725185190500.sql new file mode 100644 index 000000000..a441925ef --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1723569725185190500.sql @@ -0,0 +1,2 @@ +-- +DELETE FROM `command` WHERE `name` = 'reload quest_greeting_locale'; diff --git a/src/server/game/Entities/Creature/GossipDef.cpp b/src/server/game/Entities/Creature/GossipDef.cpp index f0b1f75f7..d85dbdfdb 100644 --- a/src/server/game/Entities/Creature/GossipDef.cpp +++ b/src/server/game/Entities/Creature/GossipDef.cpp @@ -319,12 +319,10 @@ void PlayerMenu::SendQuestGiverQuestList(QEmote const& eEmote, std::string const if (QuestGreeting const* questGreeting = sObjectMgr->GetQuestGreeting(guid.GetTypeId(), guid.GetEntry())) { - std::string strGreeting = questGreeting->Text; - - LocaleConstant localeConstant = _session->GetSessionDbLocaleIndex(); - if (localeConstant != LOCALE_enUS) - if (QuestGreetingLocale const* questGreetingLocale = sObjectMgr->GetQuestGreetingLocale(guid.GetTypeId(), guid.GetEntry())) - ObjectMgr::GetLocaleString(questGreetingLocale->Greeting, localeConstant, strGreeting); + LocaleConstant locale = _session->GetSessionDbLocaleIndex(); + std::string strGreeting = questGreeting->Greeting[DEFAULT_LOCALE]; + if (questGreeting->Greeting.size() > size_t(locale) && !questGreeting->Greeting.empty()) + strGreeting = questGreeting->Greeting[locale]; data << strGreeting; data << uint32(questGreeting->EmoteDelay); diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index a21794a09..aff933782 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -6213,7 +6213,7 @@ void ObjectMgr::LoadQuestAreaTriggers() QuestGreeting const* ObjectMgr::GetQuestGreeting(TypeID type, uint32 id) const { - uint32 typeIndex; + uint8 typeIndex; if (type == TYPEID_UNIT) typeIndex = 0; else if (type == TYPEID_GAMEOBJECT) @@ -6221,15 +6221,19 @@ QuestGreeting const* ObjectMgr::GetQuestGreeting(TypeID type, uint32 id) const else return nullptr; - return Acore::Containers::MapGetValuePtr(_questGreetingStore[typeIndex], id); + std::pair pairKey = std::make_pair(id, typeIndex); + QuestGreetingContainer::const_iterator itr = _questGreetingStore.find(pairKey); + if (itr == _questGreetingStore.end()) + return nullptr; + + return &itr->second; } void ObjectMgr::LoadQuestGreetings() { uint32 oldMSTime = getMSTime(); - for (std::size_t i = 0; i < _questGreetingStore.size(); ++i) - _questGreetingStore[i].clear(); + _questGreetingStore.clear(); // For reload case // 0 1 2 3 4 QueryResult result = WorldDatabase.Query("SELECT ID, Type, GreetEmoteType, GreetEmoteDelay, Greeting FROM quest_greeting"); @@ -6239,8 +6243,6 @@ void ObjectMgr::LoadQuestGreetings() return; } - uint32 count = 0; - do { Field* fields = result->Fetch(); @@ -6249,35 +6251,35 @@ void ObjectMgr::LoadQuestGreetings() uint8 type = fields[1].Get(); switch (type) { - case 0: // Creature - if (!sObjectMgr->GetCreatureTemplate(id)) - { - LOG_ERROR("sql.sql", "Table `quest_greeting`: creature template entry {} does not exist.", id); + case 0: // Creature + if (!sObjectMgr->GetCreatureTemplate(id)) + { + LOG_ERROR("sql.sql", "Table `quest_greeting`: creature template entry {} does not exist.", id); + continue; + } + break; + case 1: // GameObject + if (!sObjectMgr->GetGameObjectTemplate(id)) + { + LOG_ERROR("sql.sql", "Table `quest_greeting`: gameobject template entry {} does not exist.", id); + continue; + } + break; + default: + LOG_ERROR("sql.sql", "Table `quest_greeting` has unknown type {} for id {}, skipped.", type, id); continue; - } - break; - case 1: // GameObject - if (!sObjectMgr->GetGameObjectTemplate(id)) - { - LOG_ERROR("sql.sql", "Table `quest_greeting`: gameobject template entry {} does not exist.", id); - continue; - } - break; - default: - continue; } - uint16 greetEmoteType = fields[2].Get(); - uint32 greetEmoteDelay = fields[3].Get(); - std::string greeting = fields[4].Get(); + std::pair pairKey = std::make_pair(id, type); + QuestGreeting& data = _questGreetingStore[pairKey]; - _questGreetingStore[type].emplace(std::piecewise_construct, std::forward_as_tuple(id), std::forward_as_tuple(greetEmoteType, greetEmoteDelay, std::move(greeting))); - - ++count; + data.EmoteType = fields[2].Get(); + data.EmoteDelay = fields[3].Get(); + AddLocaleString(fields[4].Get(), LOCALE_enUS, data.Greeting); } while (result->NextRow()); - LOG_INFO("server.loading", ">> Loaded {} quest_greeting in {} ms", count, GetMSTimeDiffToNow(oldMSTime)); + LOG_INFO("server.loading", ">> Loaded {} quest_greeting in {} ms", _questGreetingStore.size(), GetMSTimeDiffToNow(oldMSTime)); LOG_INFO("server.loading", " "); } @@ -6285,8 +6287,6 @@ void ObjectMgr::LoadQuestGreetingsLocales() { uint32 oldMSTime = getMSTime(); - _questGreetingLocaleStore.clear(); - // 0 1 2 3 QueryResult result = WorldDatabase.Query("SELECT ID, Type, Locale, Greeting FROM quest_greeting_locale"); if (!result) @@ -6295,6 +6295,7 @@ void ObjectMgr::LoadQuestGreetingsLocales() return; } + uint32 localeCount = 0; do { Field* fields = result->Fetch(); @@ -6321,17 +6322,25 @@ void ObjectMgr::LoadQuestGreetingsLocales() continue; } - std::string localeName = fields[2].Get(); + std::pair pairKey = std::make_pair(id, type); + QuestGreeting& data = _questGreetingStore[pairKey]; - LocaleConstant locale = GetLocaleByName(localeName); + QuestGreetingContainer::iterator qgc = _questGreetingStore.find(pairKey); + if (qgc == _questGreetingStore.end()) + { + LOG_ERROR("sql.sql", "QuestGreeting (Id: {} Type: {}) found in table `quest_greeting_locale` but does not exist in `quest_greeting`. Skipped!", id, type); + continue; + } + + LocaleConstant locale = GetLocaleByName(fields[2].Get()); if (locale == LOCALE_enUS) continue; - QuestGreetingLocale& data = _questGreetingLocaleStore[MAKE_PAIR32(type, id)]; AddLocaleString(fields[3].Get(), locale, data.Greeting); + localeCount++; } while (result->NextRow()); - LOG_INFO("server.loading", ">> Loaded {} quest greeting Locale Strings in {} ms", (uint32)_questGreetingLocaleStore.size(), GetMSTimeDiffToNow(oldMSTime)); + LOG_INFO("server.loading", ">> Loaded {} quest greeting Locale Strings in {} ms", localeCount, GetMSTimeDiffToNow(oldMSTime)); LOG_INFO("server.loading", " "); } diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h index 399711e88..e09935f35 100644 --- a/src/server/game/Globals/ObjectMgr.h +++ b/src/server/game/Globals/ObjectMgr.h @@ -599,20 +599,9 @@ struct QuestGreeting { uint16 EmoteType; uint32 EmoteDelay; - std::string Text; - - QuestGreeting() : EmoteType(0), EmoteDelay(0) { } - QuestGreeting(uint16 emoteType, uint32 emoteDelay, std::string text) - : EmoteType(emoteType), EmoteDelay(emoteDelay), Text(std::move(text)) { } -}; - -struct QuestGreetingLocale -{ std::vector Greeting; }; -typedef std::unordered_map QuestGreetingLocaleContainer; - struct GossipMenuItems { uint32 MenuID; @@ -672,7 +661,7 @@ struct QuestPOI typedef std::vector QuestPOIVector; typedef std::unordered_map QuestPOIContainer; -typedef std::array, 2> QuestGreetingContainer; +typedef std::map, QuestGreeting> QuestGreetingContainer; typedef std::unordered_map CacheVendorItemContainer; typedef std::unordered_map CacheTrainerSpellContainer; @@ -1275,26 +1264,6 @@ public: if (itr == _pointOfInterestLocaleStore.end()) return nullptr; return &itr->second; } - [[nodiscard]] QuestGreetingLocale const* GetQuestGreetingLocale(TypeID type, uint32 id) const - { - uint32 typeIndex; - if (type == TYPEID_UNIT) - { - typeIndex = 0; - } - else if (type == TYPEID_GAMEOBJECT) - { - typeIndex = 1; - } - else - { - return nullptr; - } - - QuestGreetingLocaleContainer::const_iterator itr = _questGreetingLocaleStore.find(MAKE_PAIR32(typeIndex, id)); - if (itr == _questGreetingLocaleStore.end()) return nullptr; - return &itr->second; - } [[nodiscard]] QuestOfferRewardLocale const* GetQuestOfferRewardLocale(uint32 entry) const { auto itr = _questOfferRewardLocaleStore.find(entry); @@ -1313,7 +1282,7 @@ public: if (itr == _npcTextLocaleStore.end()) return nullptr; return &itr->second; } - QuestGreeting const* GetQuestGreeting(TypeID type, uint32 id) const; + [[nodiscard]] QuestGreeting const* GetQuestGreeting(TypeID type, uint32 id) const; GameObjectData& NewGOData(ObjectGuid::LowType guid) { return _gameObjectDataStore[guid]; } void DeleteGOData(ObjectGuid::LowType guid); @@ -1621,7 +1590,6 @@ private: AcoreStringContainer _acoreStringStore; GossipMenuItemsLocaleContainer _gossipMenuItemsLocaleStore; PointOfInterestLocaleContainer _pointOfInterestLocaleStore; - QuestGreetingLocaleContainer _questGreetingLocaleStore; CacheVendorItemContainer _cacheVendorItemStore; CacheTrainerSpellContainer _cacheTrainerSpellStore; diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index e35a5a3ab..f780a3ff7 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -1793,7 +1793,7 @@ void World::SetInitialWorldSettings() LOG_INFO("server.loading", "Loading Quest Greetings..."); sObjectMgr->LoadQuestGreetings(); // must be loaded after creature_template, gameobject_template tables LOG_INFO("server.loading", "Loading Quest Greeting Locales..."); - sObjectMgr->LoadQuestGreetingsLocales(); // must be loaded after creature_template, gameobject_template tables + sObjectMgr->LoadQuestGreetingsLocales(); // must be loaded after creature_template, gameobject_template tables, quest_greeting LOG_INFO("server.loading", "Loading Quest Money Rewards..."); sObjectMgr->LoadQuestMoneyRewards(); diff --git a/src/server/scripts/Commands/cs_reload.cpp b/src/server/scripts/Commands/cs_reload.cpp index c179db040..87737ac4e 100644 --- a/src/server/scripts/Commands/cs_reload.cpp +++ b/src/server/scripts/Commands/cs_reload.cpp @@ -139,7 +139,6 @@ public: { "points_of_interest", HandleReloadPointsOfInterestCommand, SEC_ADMINISTRATOR, Console::Yes }, { "prospecting_loot_template", HandleReloadLootTemplatesProspectingCommand, SEC_ADMINISTRATOR, Console::Yes }, { "quest_greeting", HandleReloadQuestGreetingCommand, SEC_ADMINISTRATOR, Console::Yes }, - { "quest_greeting_locale", HandleReloadLocalesQuestGreetingCommand, SEC_ADMINISTRATOR, Console::Yes }, { "quest_poi", HandleReloadQuestPOICommand, SEC_ADMINISTRATOR, Console::Yes }, { "quest_template", HandleReloadQuestTemplateCommand, SEC_ADMINISTRATOR, Console::Yes }, { "reference_loot_template", HandleReloadLootTemplatesReferenceCommand, SEC_ADMINISTRATOR, Console::Yes }, @@ -270,7 +269,6 @@ public: HandleReloadQuestAreaTriggersCommand(handler); HandleReloadQuestPOICommand(handler); HandleReloadQuestTemplateCommand(handler); - HandleReloadLocalesQuestGreetingCommand(handler); LOG_INFO("server.loading", "Reloading Quests Relations..."); sObjectMgr->LoadQuestStartersAndEnders(); @@ -556,13 +554,8 @@ public: LOG_INFO("server.loading", "Reloading Quest Greeting ..."); sObjectMgr->LoadQuestGreetings(); handler->SendGlobalGMSysMessage("DB table `quest_greeting` reloaded."); - return true; - } - - static bool HandleReloadLocalesQuestGreetingCommand(ChatHandler* handler) - { LOG_INFO("server.loading", "Reloading Quest Greeting locales..."); - sObjectMgr->LoadQuestGreetingsLocales(); + sObjectMgr->LoadQuestGreetingsLocales(); // Must be after LoadQuestGreetings() handler->SendGlobalGMSysMessage("DB table `quest_greeting_locale` reloaded."); return true; }