diff options
Diffstat (limited to 'src/server')
| -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..."); | 
