diff options
| author | ForesterDev <forester.manv@gmail.com> | 2017-10-29 13:15:22 +0400 |
|---|---|---|
| committer | Aokromes <Aokromes@users.noreply.github.com> | 2017-10-29 10:15:22 +0100 |
| commit | a64d1ec51eb11fd01a26d08a09de3d8d7dd89675 (patch) | |
| tree | d596fc0956ea1ff59493d5f41d9a789a73be733f /src | |
| parent | bbd339370ed2eea5f12e79a977fd9e0e93543101 (diff) | |
Core/Quests: implement Quest Greeting (DB table quest_greeting)
* Core/Quests: implement Quest Greetings. Partial port https://github.com/TrinityCore/TrinityCore/commit/22e230ecec1c7ce4eb4daeb60adfa03098271f34
Diffstat (limited to 'src')
| -rw-r--r-- | src/server/game/Accounts/RBAC.h | 3 | ||||
| -rw-r--r-- | src/server/game/Entities/Creature/GossipDef.cpp | 42 | ||||
| -rw-r--r-- | src/server/game/Globals/ObjectMgr.cpp | 128 | ||||
| -rw-r--r-- | src/server/game/Globals/ObjectMgr.h | 30 | ||||
| -rw-r--r-- | src/server/game/World/World.cpp | 4 | ||||
| -rw-r--r-- | src/server/scripts/Commands/cs_reload.cpp | 20 |
6 files changed, 214 insertions, 13 deletions
diff --git a/src/server/game/Accounts/RBAC.h b/src/server/game/Accounts/RBAC.h index 05747f96739..0f8e031ba20 100644 --- a/src/server/game/Accounts/RBAC.h +++ b/src/server/game/Accounts/RBAC.h @@ -748,7 +748,7 @@ enum RBACPermissions RBAC_PERM_COMMAND_SERVER_RESTART_FORCE = 840, RBAC_PERM_COMMAND_NEARGRAVEYARD = 841, RBAC_PERM_COMMAND_RELOAD_CHARACTER_TEMPLATE = 842, // not on 3.3.5a - RBAC_PERM_COMMAND_RELOAD_QUEST_GREETING = 843, // not on 3.3.5a + RBAC_PERM_COMMAND_RELOAD_QUEST_GREETING = 843, RBAC_PERM_COMMAND_SCENE = 844, // not on 3.3.5a RBAC_PERM_COMMAND_SCENE_DEBUG = 845, // not on 3.3.5a RBAC_PERM_COMMAND_SCENE_PLAY = 846, // not on 3.3.5a @@ -772,6 +772,7 @@ enum RBACPermissions RBAC_PERM_COMMAND_GROUP_MAINASSIST = 864, RBAC_PERM_COMMAND_NPC_SHOWLOOT = 865, RBAC_PERM_COMMAND_LIST_SPAWNPOINTS = 866, + RBAC_PERM_COMMAND_RELOAD_QUEST_GREETING_LOCALE = 867, // custom permissions 1000+ RBAC_PERM_MAX diff --git a/src/server/game/Entities/Creature/GossipDef.cpp b/src/server/game/Entities/Creature/GossipDef.cpp index caa700f6672..4a39c233fc2 100644 --- a/src/server/game/Entities/Creature/GossipDef.cpp +++ b/src/server/game/Entities/Creature/GossipDef.cpp @@ -323,16 +323,33 @@ void QuestMenu::ClearMenu() _questMenuItems.clear(); } -void PlayerMenu::SendQuestGiverQuestList(QEmote const& eEmote, const std::string& Title, ObjectGuid npcGUID) +void PlayerMenu::SendQuestGiverQuestList(QEmote const& eEmote, const std::string& Title, ObjectGuid guid) { WorldPacket data(SMSG_QUESTGIVER_QUEST_LIST, 100); // guess size - data << uint64(npcGUID); - data << Title; - data << uint32(eEmote._Delay); // player emote - data << uint32(eEmote._Emote); // NPC emote + data << uint64(guid); + + if (QuestGreeting const* questGreeting = sObjectMgr->GetQuestGreeting(guid)) + { + std::string strGreeting = questGreeting->greeting; + + LocaleConstant localeConstant = _session->GetSessionDbLocaleIndex(); + if (localeConstant != LOCALE_enUS) + if (QuestGreetingLocale const* questGreetingLocale = sObjectMgr->GetQuestGreetingLocale(MAKE_PAIR32(guid.GetEntry(), guid.GetTypeId()))) + ObjectMgr::GetLocaleString(questGreetingLocale->greeting, localeConstant, strGreeting); + + data << strGreeting; + data << uint32(questGreeting->greetEmoteDelay); + data << uint32(questGreeting->greetEmoteType); + } + else + { + data << Title; + data << uint32(eEmote._Delay); // player emote + data << uint32(eEmote._Emote); // NPC emote + } size_t count_pos = data.wpos(); - data << uint8 (0); + data << uint8(0); uint32 count = 0; // Store this instead of checking the Singleton every loop iteration @@ -340,9 +357,9 @@ void PlayerMenu::SendQuestGiverQuestList(QEmote const& eEmote, const std::string for (uint32 i = 0; i < _questMenu.GetMenuItemCount(); ++i) { - QuestMenuItem const& qmi = _questMenu.GetItem(i); + QuestMenuItem const& questMenuItem = _questMenu.GetItem(i); - uint32 questID = qmi.QuestId; + uint32 questID = questMenuItem.QuestId; if (Quest const* quest = sObjectMgr->GetQuestTemplate(questID)) { @@ -351,14 +368,14 @@ void PlayerMenu::SendQuestGiverQuestList(QEmote const& eEmote, const std::string LocaleConstant localeConstant = _session->GetSessionDbLocaleIndex(); if (localeConstant != LOCALE_enUS) - if (QuestLocale const* localeData = sObjectMgr->GetQuestLocale(questID)) - ObjectMgr::GetLocaleString(localeData->Title, localeConstant, title); + if (QuestLocale const* questTemplateLocaleData = sObjectMgr->GetQuestLocale(questID)) + ObjectMgr::GetLocaleString(questTemplateLocaleData->Title, localeConstant, title); if (questLevelInTitle) Quest::AddQuestLevelToTitle(title, quest->GetQuestLevel()); data << uint32(questID); - data << uint32(qmi.QuestIcon); + data << uint32(questMenuItem.QuestIcon); data << int32(quest->GetQuestLevel()); data << uint32(quest->GetFlags()); // 3.3.3 quest flags data << uint8(0); // 3.3.3 changes icon: blue question or yellow exclamation @@ -368,7 +385,8 @@ void PlayerMenu::SendQuestGiverQuestList(QEmote const& eEmote, const std::string data.put<uint8>(count_pos, count); _session->SendPacket(&data); - TC_LOG_DEBUG("network", "WORLD: Sent SMSG_QUESTGIVER_QUEST_LIST NPC=%s", npcGUID.ToString().c_str()); + + TC_LOG_DEBUG("network", "WORLD: Sent SMSG_QUESTGIVER_QUEST_LIST (QuestGiver: %s)", guid.ToString().c_str()); } void PlayerMenu::SendQuestGiverStatus(uint8 questStatus, ObjectGuid npcGUID) const diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 974916a66fe..c7e083a66ee 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -5982,6 +5982,134 @@ 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 +{ + auto itr = _questGreetingStore.find(guid.GetTypeId()); + if (itr == _questGreetingStore.end()) + return nullptr; + + auto questItr = itr->second.find(guid.GetEntry()); + if (questItr == itr->second.end()) + return nullptr; + + return questItr->second; +} + +void ObjectMgr::LoadQuestGreetings() +{ + uint32 oldMSTime = getMSTime(); + + _questGreetingStore.clear(); // need for reload case + + // 0 1 2 3 4 + QueryResult result = WorldDatabase.Query("SELECT ID, Type, GreetEmoteType, GreetEmoteDelay, Greeting FROM quest_greeting"); + if (!result) + { + TC_LOG_INFO("server.loading", ">> Loaded 0 quest greetings. DB table `quest_greeting` is empty."); + 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); + continue; + } + 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); + continue; + } + break; + default: + TC_LOG_ERROR("sql.sql", "Table `quest_greeting`: unknown type = %u for entry = %u. Skipped.", type, id); + continue; + } + + uint16 greetEmoteType = fields[2].GetUInt16(); + + if (greetEmoteType > 0 && !sEmotesStore.LookupEntry(greetEmoteType)) + { + TC_LOG_DEBUG("sql.sql", "Table `quest_greeting`: entry %u has greetEmoteType = %u but emote does not exist. Set to 0.", id, greetEmoteType); + greetEmoteType = 0; + } + + uint32 greetEmoteDelay = fields[3].GetUInt32(); + std::string greeting = fields[4].GetString(); + + _questGreetingStore[type][id] = new QuestGreeting(greetEmoteType, greetEmoteDelay, greeting); + + ++count; + } + while (result->NextRow()); + + TC_LOG_INFO("server.loading", ">> Loaded %u quest_greeting in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); +} + +void ObjectMgr::LoadQuestGreetingsLocales() +{ + uint32 oldMSTime = getMSTime(); + + _questGreetingLocaleStore.clear(); // need for reload case + + // 0 1 2 3 + QueryResult result = WorldDatabase.Query("SELECT ID, Type, Locale, Greeting FROM quest_greeting_locale"); + if (!result) + { + TC_LOG_INFO("server.loading", ">> Loaded 0 quest_greeting locales. DB table `quest_greeting_locale` is empty."); + return; + } + + do + { + Field* fields = result->Fetch(); + + uint32 id = fields[0].GetUInt32(); + uint8 type = fields[1].GetUInt8(); + // overwrite + switch (type) + { + case 0: // Creature + type = TYPEID_UNIT; + break; + case 1: // GameObject + type = TYPEID_GAMEOBJECT; + break; + default: + break; + } + + std::string localeName = fields[2].GetString(); + std::string greeting = fields[3].GetString(); + + QuestGreetingLocale& data = _questGreetingLocaleStore[MAKE_PAIR32(id, type)]; + LocaleConstant locale = GetLocaleByName(localeName); + if (locale == LOCALE_enUS) + continue; + + AddLocaleString(greeting, locale, data.greeting); + } while (result->NextRow()); + + TC_LOG_INFO("server.loading", ">> Loaded %u quest greeting locale strings in %u ms", uint32(_questGreetingLocaleStore.size()), GetMSTimeDiffToNow(oldMSTime)); +} + void ObjectMgr::LoadTavernAreaTriggers() { uint32 oldMSTime = getMSTime(); diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h index 3f52a2f77a6..8a07723a34e 100644 --- a/src/server/game/Globals/ObjectMgr.h +++ b/src/server/game/Globals/ObjectMgr.h @@ -532,6 +532,11 @@ struct TrinityString std::vector<std::string> Content; }; +struct QuestGreetingLocale +{ + std::vector<std::string> greeting; +}; + typedef std::map<ObjectGuid, ObjectGuid> LinkedRespawnContainer; typedef std::unordered_map<uint32, CreatureTemplate> CreatureTemplateContainer; typedef std::unordered_map<uint32, CreatureAddon> CreatureTemplateAddonContainer; @@ -574,6 +579,7 @@ struct PointOfInterestLocale }; typedef std::unordered_map<uint32, PointOfInterestLocale> PointOfInterestLocaleContainer; +typedef std::unordered_map<uint32, QuestGreetingLocale> QuestGreetingLocaleContainer; typedef std::unordered_map<uint32, TrinityString> TrinityStringContainer; @@ -794,6 +800,19 @@ struct QuestPOIWrapper typedef std::unordered_map<uint32, QuestPOIWrapper> 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; + struct GraveyardData { uint32 safeLocId; @@ -998,6 +1017,7 @@ class TC_GAME_API ObjectMgr } GossipText const* GetGossipText(uint32 Text_ID) const; + QuestGreeting const* GetQuestGreeting(ObjectGuid guid) const; WorldSafeLocsEntry const* GetDefaultGraveyard(uint32 team) const; WorldSafeLocsEntry const* GetClosestGraveyard(float x, float y, float z, uint32 MapId, uint32 team) const; @@ -1155,6 +1175,7 @@ class TC_GAME_API ObjectMgr void LoadPageTextLocales(); void LoadGossipMenuItemsLocales(); void LoadPointOfInterestLocales(); + void LoadQuestGreetingsLocales(); void LoadInstanceTemplate(); void LoadInstanceEncounters(); void LoadMailLevelRewards(); @@ -1166,6 +1187,7 @@ class TC_GAME_API ObjectMgr void LoadAreaTriggerTeleports(); void LoadAccessRequirements(); void LoadQuestAreaTriggers(); + void LoadQuestGreetings(); void LoadAreaTriggerScripts(); void LoadTavernAreaTriggers(); void LoadGameObjectForQuests(); @@ -1374,6 +1396,12 @@ class TC_GAME_API ObjectMgr if (itr == _pointOfInterestLocaleStore.end()) return nullptr; return &itr->second; } + QuestGreetingLocale const* GetQuestGreetingLocale(uint32 id) const + { + QuestGreetingLocaleContainer::const_iterator itr = _questGreetingLocaleStore.find(id); + if (itr == _questGreetingLocaleStore.end()) return nullptr; + return &itr->second; + } TrinityString const* GetTrinityString(uint32 entry) const { @@ -1527,6 +1555,7 @@ class TC_GAME_API ObjectMgr TavernAreaTriggerContainer _tavernAreaTriggerStore; GameObjectForQuestContainer _gameObjectForQuestStore; GossipTextContainer _gossipTextStore; + QuestGreetingContainer _questGreetingStore; AreaTriggerContainer _areaTriggerStore; AreaTriggerScriptContainer _areaTriggerScriptStore; AccessRequirementContainer _accessRequirementStore; @@ -1637,6 +1666,7 @@ class TC_GAME_API ObjectMgr PageTextLocaleContainer _pageTextLocaleStore; GossipMenuItemsLocaleContainer _gossipMenuItemsLocaleStore; PointOfInterestLocaleContainer _pointOfInterestLocaleStore; + QuestGreetingLocaleContainer _questGreetingLocaleStore; TrinityStringContainer _trinityStringStore; diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index f4e1a7b2d74..7e34a4ae91f 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -1611,6 +1611,7 @@ void World::SetInitialWorldSettings() sObjectMgr->LoadPageTextLocales(); sObjectMgr->LoadGossipMenuItemsLocales(); sObjectMgr->LoadPointOfInterestLocales(); + sObjectMgr->LoadQuestGreetingsLocales(); sObjectMgr->SetDBCLocaleIndex(GetDefaultDbcLocale()); // Get once for all the locale index of DBC language (console/broadcasts) TC_LOG_INFO("server.loading", ">> Localization strings loaded in %u ms", GetMSTimeDiffToNow(oldMSTime)); @@ -1762,6 +1763,9 @@ void World::SetInitialWorldSettings() TC_LOG_INFO("server.loading", "Loading Quests Starters and Enders..."); sObjectMgr->LoadQuestStartersAndEnders(); // must be after quest load + TC_LOG_INFO("server.loading", "Loading Quests Greetings..."); + sObjectMgr->LoadQuestGreetings(); // must be loaded after creature_template, gameobject_template tables + TC_LOG_INFO("server.loading", "Loading Objects Pooling Data..."); sPoolMgr->LoadFromDB(); diff --git a/src/server/scripts/Commands/cs_reload.cpp b/src/server/scripts/Commands/cs_reload.cpp index faeb77cccec..d40d67fc859 100644 --- a/src/server/scripts/Commands/cs_reload.cpp +++ b/src/server/scripts/Commands/cs_reload.cpp @@ -129,6 +129,8 @@ public: { "pickpocketing_loot_template", rbac::RBAC_PERM_COMMAND_RELOAD_PICKPOCKETING_LOOT_TEMPLATE, true, &HandleReloadLootTemplatesPickpocketingCommand, "" }, { "points_of_interest", rbac::RBAC_PERM_COMMAND_RELOAD_POINTS_OF_INTEREST, true, &HandleReloadPointsOfInterestCommand, "" }, { "prospecting_loot_template", rbac::RBAC_PERM_COMMAND_RELOAD_PROSPECTING_LOOT_TEMPLATE, true, &HandleReloadLootTemplatesProspectingCommand, "" }, + { "quest_greeting", rbac::RBAC_PERM_COMMAND_RELOAD_QUEST_GREETING, true, &HandleReloadQuestGreetingCommand, "" }, + { "quest_greeting_locale", rbac::RBAC_PERM_COMMAND_RELOAD_QUEST_GREETING_LOCALE, true, &HandleReloadLocalesQuestGreetingCommand, "" }, { "quest_poi", rbac::RBAC_PERM_COMMAND_RELOAD_QUEST_POI, true, &HandleReloadQuestPOICommand, "" }, { "quest_template", rbac::RBAC_PERM_COMMAND_RELOAD_QUEST_TEMPLATE, true, &HandleReloadQuestTemplateCommand, "" }, { "rbac", rbac::RBAC_PERM_COMMAND_RELOAD_RBAC, true, &HandleReloadRBACCommand, "" }, @@ -243,6 +245,7 @@ public: static bool HandleReloadAllQuestCommand(ChatHandler* handler, char const* /*args*/) { + HandleReloadQuestGreetingCommand(handler, ""); HandleReloadQuestAreaTriggersCommand(handler, "a"); HandleReloadQuestPOICommand(handler, "a"); HandleReloadQuestTemplateCommand(handler, "a"); @@ -317,6 +320,7 @@ public: HandleReloadLocalesPageTextCommand(handler, "a"); HandleReloadLocalesPointsOfInterestCommand(handler, "a"); HandleReloadLocalesQuestCommand(handler, "a"); + HandleReloadLocalesQuestGreetingCommand(handler, ""); return true; } @@ -523,6 +527,22 @@ public: return true; } + static bool HandleReloadQuestGreetingCommand(ChatHandler* handler, char const* /*args*/) + { + TC_LOG_INFO("misc", "Re-Loading Quest Greeting ..."); + sObjectMgr->LoadQuestGreetings(); + handler->SendGlobalGMSysMessage("DB table `quest_greeting` reloaded."); + return true; + } + + static bool HandleReloadLocalesQuestGreetingCommand(ChatHandler* handler, char const* /*args*/) + { + TC_LOG_INFO("misc", "Re-Loading Quest Greeting locales..."); + sObjectMgr->LoadQuestGreetingsLocales(); + handler->SendGlobalGMSysMessage("DB table `quest_greeting_locale` reloaded."); + return true; + } + static bool HandleReloadQuestTemplateCommand(ChatHandler* handler, char const* /*args*/) { TC_LOG_INFO("misc", "Re-Loading Quest Templates..."); |
