diff options
author | Shauren <shauren.trinity@gmail.com> | 2018-04-24 23:59:37 +0200 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2018-04-24 23:59:37 +0200 |
commit | b172ba7b8a440faf068a6ea8c60fc2a1640689a6 (patch) | |
tree | a838680c6d7f3f7595a1352c35bdfdbfbd9d410a /src | |
parent | c05d887e8d554d51b7c0066e3acd8214eb3c3d4e (diff) |
Core/Quests: Implemented quest greeting locales
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/Entities/Creature/GossipDef.cpp | 20 | ||||
-rw-r--r-- | src/server/game/Entities/Creature/GossipDef.h | 3 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 21 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.h | 2 | ||||
-rw-r--r-- | src/server/game/Globals/ObjectMgr.cpp | 97 | ||||
-rw-r--r-- | src/server/game/Globals/ObjectMgr.h | 19 | ||||
-rw-r--r-- | src/server/game/Quests/QuestDef.h | 16 | ||||
-rw-r--r-- | src/server/game/World/World.cpp | 1 | ||||
-rw-r--r-- | src/server/scripts/Commands/cs_reload.cpp | 2 |
9 files changed, 129 insertions, 52 deletions
diff --git a/src/server/game/Entities/Creature/GossipDef.cpp b/src/server/game/Entities/Creature/GossipDef.cpp index e30e5d28e95..58c77eb63b6 100644 --- a/src/server/game/Entities/Creature/GossipDef.cpp +++ b/src/server/game/Entities/Creature/GossipDef.cpp @@ -344,19 +344,24 @@ void QuestMenu::ClearMenu() _questMenuItems.clear(); } -void PlayerMenu::SendQuestGiverQuestListMessage(ObjectGuid guid) +void PlayerMenu::SendQuestGiverQuestListMessage(Object* questgiver) { + ObjectGuid guid = questgiver->GetGUID(); + LocaleConstant localeConstant = _session->GetSessionDbLocaleIndex(); + WorldPackets::Quest::QuestGiverQuestListMessage questList; questList.QuestGiverGUID = guid; - if (QuestGreeting const* questGreeting = sObjectMgr->GetQuestGreeting(guid)) + if (QuestGreeting const* questGreeting = sObjectMgr->GetQuestGreeting(questgiver->GetTypeId(), questgiver->GetEntry())) { - questList.GreetEmoteDelay = questGreeting->greetEmoteDelay; - questList.GreetEmoteType = questGreeting->greetEmoteType; - questList.Greeting = questGreeting->greeting; + questList.GreetEmoteDelay = questGreeting->EmoteDelay; + questList.GreetEmoteType = questGreeting->EmoteType; + questList.Greeting = questGreeting->Text; + + if (localeConstant != LOCALE_enUS) + if (QuestGreetingLocale const* questGreetingLocale = sObjectMgr->GetQuestGreetingLocale(questgiver->GetTypeId(), questgiver->GetEntry())) + ObjectMgr::GetLocaleString(questGreetingLocale->Greeting, localeConstant, questList.Greeting); } - else - TC_LOG_ERROR("misc", "Guid: %s - No quest greeting found.", guid.ToString().c_str()); // Store this instead of checking the Singleton every loop iteration bool questLevelInTitle = sWorld->getBoolConfig(CONFIG_UI_QUESTLEVELS_IN_DIALOGS); @@ -371,7 +376,6 @@ void PlayerMenu::SendQuestGiverQuestListMessage(ObjectGuid guid) { std::string title = quest->GetLogTitle(); - LocaleConstant localeConstant = _session->GetSessionDbLocaleIndex(); if (localeConstant != LOCALE_enUS) if (QuestTemplateLocale const* questTemplateLocale = sObjectMgr->GetQuestLocale(questID)) ObjectMgr::GetLocaleString(questTemplateLocale->LogTitle, localeConstant, title); diff --git a/src/server/game/Entities/Creature/GossipDef.h b/src/server/game/Entities/Creature/GossipDef.h index ea718b21863..bc79a9ab847 100644 --- a/src/server/game/Entities/Creature/GossipDef.h +++ b/src/server/game/Entities/Creature/GossipDef.h @@ -24,6 +24,7 @@ #include "NPCHandler.h" #include <map> +class Object; class Quest; class WorldSession; @@ -278,7 +279,7 @@ class TC_GAME_API PlayerMenu /*********************************************************/ void SendQuestGiverStatus(uint32 questStatus, ObjectGuid npcGUID) const; - void SendQuestGiverQuestListMessage(ObjectGuid npcGUID); + void SendQuestGiverQuestListMessage(Object* questgiver); void SendQuestQueryResponse(Quest const* quest) const; void SendQuestGiverQuestDetails(Quest const* quest, ObjectGuid npcGUID, bool autoLaunched, bool displayPopup) const; diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 27db6496e84..531b3bb16a0 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -14398,7 +14398,7 @@ void Player::SendPreparedGossip(WorldObject* source) { if (PlayerTalkClass->GetGossipMenu().Empty() && !PlayerTalkClass->GetQuestMenu().Empty()) { - SendPreparedQuest(source->GetGUID()); + SendPreparedQuest(source); return; } } @@ -14475,7 +14475,7 @@ void Player::OnGossipSelect(WorldObject* source, uint32 optionIndex, uint32 menu break; case GOSSIP_OPTION_QUESTGIVER: PrepareQuestMenu(guid); - SendPreparedQuest(guid); + SendPreparedQuest(source); break; case GOSSIP_OPTION_VENDOR: case GOSSIP_OPTION_ARMORER: @@ -14645,7 +14645,7 @@ void Player::PrepareQuestMenu(ObjectGuid guid) } } -void Player::SendPreparedQuest(ObjectGuid guid) +void Player::SendPreparedQuest(WorldObject* source) { QuestMenu& questMenu = PlayerTalkClass->GetQuestMenu(); if (questMenu.Empty()) @@ -14662,36 +14662,35 @@ void Player::SendPreparedQuest(ObjectGuid guid) { if (qmi0.QuestIcon == 4) { - PlayerTalkClass->SendQuestGiverRequestItems(quest, guid, CanRewardQuest(quest, false), true); + PlayerTalkClass->SendQuestGiverRequestItems(quest, source->GetGUID(), CanRewardQuest(quest, false), true); return; } // Send completable on repeatable and autoCompletable quest if player don't have quest /// @todo verify if check for !quest->IsDaily() is really correct (possibly not) else { - Object* object = ObjectAccessor::GetObjectByTypeMask(*this, guid, TYPEMASK_UNIT | TYPEMASK_GAMEOBJECT | TYPEMASK_ITEM); - if (!object || (!object->hasQuest(questId) && !object->hasInvolvedQuest(questId))) + if (!source->hasQuest(questId) && !source->hasInvolvedQuest(questId)) { PlayerTalkClass->SendCloseGossip(); return; } - if (object->GetTypeId() != TYPEID_UNIT || object->GetUInt64Value(UNIT_NPC_FLAGS) & UNIT_NPC_FLAG_GOSSIP) + if (source->GetTypeId() != TYPEID_UNIT || source->GetUInt64Value(UNIT_NPC_FLAGS) & UNIT_NPC_FLAG_GOSSIP) { if (quest->IsAutoAccept() && CanAddQuest(quest, true) && CanTakeQuest(quest, true)) - AddQuestAndCheckCompletion(quest, object); + AddQuestAndCheckCompletion(quest, source); if (quest->IsAutoComplete() && quest->IsRepeatable() && !quest->IsDailyOrWeekly()) - PlayerTalkClass->SendQuestGiverRequestItems(quest, guid, CanCompleteRepeatableQuest(quest), true); + PlayerTalkClass->SendQuestGiverRequestItems(quest, source->GetGUID(), CanCompleteRepeatableQuest(quest), true); else - PlayerTalkClass->SendQuestGiverQuestDetails(quest, guid, true, false); + PlayerTalkClass->SendQuestGiverQuestDetails(quest, source->GetGUID(), true, false); return; } } } } - PlayerTalkClass->SendQuestGiverQuestListMessage(guid); + PlayerTalkClass->SendQuestGiverQuestListMessage(source); } bool Player::IsActiveQuest(uint32 quest_id) const diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index a514a35d096..b167ad36423 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -1357,7 +1357,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> } void PrepareQuestMenu(ObjectGuid guid); - void SendPreparedQuest(ObjectGuid guid); + void SendPreparedQuest(WorldObject* source); bool IsActiveQuest(uint32 quest_id) const; Quest const* GetNextQuest(ObjectGuid guid, Quest const* quest) const; bool CanSeeStartQuest(Quest const* quest); diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 713a7a04343..1811ac2a4f9 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -293,10 +293,6 @@ ObjectMgr::~ObjectMgr() for (AccessRequirementContainer::iterator itr = _accessRequirementStore.begin(); itr != _accessRequirementStore.end(); ++itr) delete itr->second; - - for (QuestGreetingContainer::iterator itr = _questGreetingStore.begin(); itr != _questGreetingStore.end(); ++itr) - for (std::unordered_map<uint32, QuestGreeting const*>::iterator itr2 = itr->second.begin(); itr2 != itr->second.end(); ++itr2) - delete itr2->second; } void ObjectMgr::AddLocaleString(std::string&& value, LocaleConstant localeConstant, std::vector<std::string>& data) @@ -4831,6 +4827,60 @@ void ObjectMgr::LoadQuestObjectivesLocale() TC_LOG_INFO("server.loading", ">> Loaded " SZFMTD " Quest Objectives locale strings in %u ms", _questObjectivesLocaleStore.size(), GetMSTimeDiffToNow(oldMSTime)); } +void ObjectMgr::LoadQuestGreetingLocales() +{ + uint32 oldMSTime = getMSTime(); + + for (std::size_t i = 0; i < _questGreetingLocaleStore.size(); ++i) + _questGreetingLocaleStore[i].clear(); + + // 0 1 2 3 + QueryResult result = WorldDatabase.Query("SELECT Id, type, locale, Greeting FROM quest_greeting_locale"); + if (!result) + return; + + uint32 count = 0; + do + { + Field* fields = result->Fetch(); + + uint32 id = fields[0].GetUInt32(); + uint8 type = fields[1].GetUInt8(); + switch (type) + { + case 0: // Creature + if (!sObjectMgr->GetCreatureTemplate(id)) + { + TC_LOG_ERROR("sql.sql", "Table `quest_greeting_locale`: creature template entry %u does not exist.", id); + continue; + } + break; + case 1: // GameObject + if (!sObjectMgr->GetGameObjectTemplate(id)) + { + TC_LOG_ERROR("sql.sql", "Table `quest_greeting_locale`: gameobject template entry %u does not exist.", id); + continue; + } + break; + default: + continue; + } + + std::string localeName = fields[2].GetString(); + + LocaleConstant locale = GetLocaleByName(localeName); + if (locale == LOCALE_enUS) + continue; + + QuestGreetingLocale& data = _questGreetingLocaleStore[type][id]; + AddLocaleString(fields[3].GetString(), locale, data.Greeting); + ++count; + } + while (result->NextRow()); + + TC_LOG_INFO("server.loading", ">> Loaded %u Quest Greeting locale strings in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); +} + void ObjectMgr::LoadQuestOfferRewardLocale() { uint32 oldMSTime = getMSTime(); @@ -5935,24 +5985,38 @@ void ObjectMgr::LoadQuestAreaTriggers() TC_LOG_INFO("server.loading", ">> Loaded %u quest trigger points in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); } -QuestGreeting const* ObjectMgr::GetQuestGreeting(ObjectGuid guid) const +QuestGreeting const* ObjectMgr::GetQuestGreeting(TypeID type, uint32 id) const { - auto itr = _questGreetingStore.find(guid.GetTypeId()); - if (itr == _questGreetingStore.end()) + uint32 typeIndex; + if (type == TYPEID_UNIT) + typeIndex = 0; + else if (type == TYPEID_GAMEOBJECT) + typeIndex = 1; + else return nullptr; - auto questItr = itr->second.find(guid.GetEntry()); - if (questItr == itr->second.end()) + return Trinity::Containers::MapGetValuePtr(_questGreetingStore[typeIndex], id); +} + +QuestGreetingLocale const* ObjectMgr::GetQuestGreetingLocale(TypeID type, uint32 id) const +{ + uint32 typeIndex; + if (type == TYPEID_UNIT) + typeIndex = 0; + else if (type == TYPEID_GAMEOBJECT) + typeIndex = 1; + else return nullptr; - return questItr->second; + return Trinity::Containers::MapGetValuePtr(_questGreetingLocaleStore[typeIndex], id); } void ObjectMgr::LoadQuestGreetings() { uint32 oldMSTime = getMSTime(); - _questGreetingStore.clear(); // need for reload case + for (std::size_t i = 0; i < _questGreetingStore.size(); ++i) + _questGreetingStore[i].clear(); // 0 1 2 3 QueryResult result = WorldDatabase.Query("SELECT ID, type, GreetEmoteType, GreetEmoteDelay, Greeting FROM quest_greeting"); @@ -5962,19 +6026,16 @@ void ObjectMgr::LoadQuestGreetings() return; } - _questGreetingStore.rehash(result->GetRowCount()); - + uint32 count = 0; do { Field* fields = result->Fetch(); uint32 id = fields[0].GetUInt32(); uint8 type = fields[1].GetUInt8(); - // overwrite switch (type) { case 0: // Creature - type = TYPEID_UNIT; if (!sObjectMgr->GetCreatureTemplate(id)) { TC_LOG_ERROR("sql.sql", "Table `quest_greeting`: creature template entry %u does not exist.", id); @@ -5982,7 +6043,6 @@ void ObjectMgr::LoadQuestGreetings() } break; case 1: // GameObject - type = TYPEID_GAMEOBJECT; if (!sObjectMgr->GetGameObjectTemplate(id)) { TC_LOG_ERROR("sql.sql", "Table `quest_greeting`: gameobject template entry %u does not exist.", id); @@ -5997,11 +6057,12 @@ void ObjectMgr::LoadQuestGreetings() uint32 greetEmoteDelay = fields[3].GetUInt32(); std::string greeting = fields[4].GetString(); - _questGreetingStore[type][id] = new QuestGreeting(greetEmoteType, greetEmoteDelay, greeting); + _questGreetingStore[type].emplace(std::piecewise_construct, std::forward_as_tuple(id), std::forward_as_tuple(greetEmoteType, greetEmoteDelay, std::move(greeting))); + ++count; } while (result->NextRow()); - TC_LOG_INFO("server.loading", ">> Loaded %u quest_greeting in %u ms", uint32(_questGreetingStore.size()), GetMSTimeDiffToNow(oldMSTime)); + TC_LOG_INFO("server.loading", ">> Loaded %u quest_greeting in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); } void ObjectMgr::LoadTavernAreaTriggers() diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h index 6812f3ece18..d8a667210c1 100644 --- a/src/server/game/Globals/ObjectMgr.h +++ b/src/server/game/Globals/ObjectMgr.h @@ -729,18 +729,8 @@ struct QuestPOI typedef std::vector<QuestPOI> QuestPOIVector; typedef std::unordered_map<uint32, QuestPOIVector> QuestPOIContainer; -struct QuestGreeting -{ - uint16 greetEmoteType; - uint32 greetEmoteDelay; - std::string greeting; - - QuestGreeting() : greetEmoteType(0), greetEmoteDelay(0) { } - QuestGreeting(uint16 _greetEmoteType, uint32 _greetEmoteDelay, std::string _greeting) - : greetEmoteType(_greetEmoteType), greetEmoteDelay(_greetEmoteDelay), greeting(_greeting) { } -}; - -typedef std::unordered_map<uint8, std::unordered_map<uint32, QuestGreeting const*>> QuestGreetingContainer; +typedef std::array<std::unordered_map<uint32, QuestGreeting>, 2> QuestGreetingContainer; +typedef std::array<std::unordered_map<uint32, QuestGreetingLocale>, 2> QuestGreetingLocaleContainer; struct GraveYardData { @@ -1067,7 +1057,8 @@ class TC_GAME_API ObjectMgr } NpcText const* GetNpcText(uint32 textID) const; - QuestGreeting const* GetQuestGreeting(ObjectGuid guid) const; + QuestGreeting const* GetQuestGreeting(TypeID type, uint32 id) const; + QuestGreetingLocale const* GetQuestGreetingLocale(TypeID type, uint32 id) const; WorldSafeLocsEntry const* GetDefaultGraveYard(uint32 team) const; WorldSafeLocsEntry const* GetClosestGraveYard(WorldLocation const& location, uint32 team, WorldObject* conditionObject) const; @@ -1212,6 +1203,7 @@ class TC_GAME_API ObjectMgr void LoadItemScriptNames(); void LoadQuestTemplateLocale(); void LoadQuestObjectivesLocale(); + void LoadQuestGreetingLocales(); void LoadQuestOfferRewardLocale(); void LoadQuestRequestItemsLocale(); void LoadPageTextLocales(); @@ -1627,6 +1619,7 @@ class TC_GAME_API ObjectMgr GameObjectForQuestContainer _gameObjectForQuestStore; NpcTextContainer _npcTextStore; QuestGreetingContainer _questGreetingStore; + QuestGreetingLocaleContainer _questGreetingLocaleStore; AreaTriggerContainer _areaTriggerStore; AreaTriggerScriptContainer _areaTriggerScriptStore; AccessRequirementContainer _accessRequirementStore; diff --git a/src/server/game/Quests/QuestDef.h b/src/server/game/Quests/QuestDef.h index 88132ce0285..adbec0efd6c 100644 --- a/src/server/game/Quests/QuestDef.h +++ b/src/server/game/Quests/QuestDef.h @@ -254,6 +254,22 @@ enum QuestObjectiveFlags QUEST_OBJECTIVE_FLAG_PART_OF_PROGRESS_BAR = 0x40, // hidden objective used to calculate progress bar percent (quests are limited to a single progress bar objective) }; +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<std::string> Greeting; +}; + struct QuestTemplateLocale { std::vector<std::string> LogTitle; diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index e4e04040bfe..f90fc39c36d 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -1633,6 +1633,7 @@ void World::SetInitialWorldSettings() sObjectMgr->LoadCreatureLocales(); sObjectMgr->LoadGameObjectLocales(); sObjectMgr->LoadQuestTemplateLocale(); + sObjectMgr->LoadQuestGreetingLocales(); sObjectMgr->LoadQuestOfferRewardLocale(); sObjectMgr->LoadQuestRequestItemsLocale(); sObjectMgr->LoadQuestObjectivesLocale(); diff --git a/src/server/scripts/Commands/cs_reload.cpp b/src/server/scripts/Commands/cs_reload.cpp index df24f26bd5d..2fdf3dde956 100644 --- a/src/server/scripts/Commands/cs_reload.cpp +++ b/src/server/scripts/Commands/cs_reload.cpp @@ -1060,10 +1060,12 @@ public: TC_LOG_INFO("misc", "Re-Loading Quest Locale ... "); sObjectMgr->LoadQuestTemplateLocale(); sObjectMgr->LoadQuestObjectivesLocale(); + sObjectMgr->LoadQuestGreetingLocales(); sObjectMgr->LoadQuestOfferRewardLocale(); sObjectMgr->LoadQuestRequestItemsLocale(); handler->SendGlobalGMSysMessage("DB table `quest_template_locale` reloaded."); handler->SendGlobalGMSysMessage("DB table `quest_objectives_locale` reloaded."); + handler->SendGlobalGMSysMessage("DB table `quest_greeting_locale` reloaded."); handler->SendGlobalGMSysMessage("DB table `quest_offer_reward_locale` reloaded."); handler->SendGlobalGMSysMessage("DB table `quest_request_items_locale` reloaded."); return true; |