aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/updates/world/master/2018_04_24_01_world.sql12
-rw-r--r--src/server/game/Entities/Creature/GossipDef.cpp20
-rw-r--r--src/server/game/Entities/Creature/GossipDef.h3
-rw-r--r--src/server/game/Entities/Player/Player.cpp21
-rw-r--r--src/server/game/Entities/Player/Player.h2
-rw-r--r--src/server/game/Globals/ObjectMgr.cpp97
-rw-r--r--src/server/game/Globals/ObjectMgr.h19
-rw-r--r--src/server/game/Quests/QuestDef.h16
-rw-r--r--src/server/game/World/World.cpp1
-rw-r--r--src/server/scripts/Commands/cs_reload.cpp2
10 files changed, 141 insertions, 52 deletions
diff --git a/sql/updates/world/master/2018_04_24_01_world.sql b/sql/updates/world/master/2018_04_24_01_world.sql
new file mode 100644
index 00000000000..ef3f38041d5
--- /dev/null
+++ b/sql/updates/world/master/2018_04_24_01_world.sql
@@ -0,0 +1,12 @@
+--
+-- Table structure for table `quest_greeting_locale`
+--
+DROP TABLE IF EXISTS `quest_greeting_locale`;
+CREATE TABLE `quest_greeting_locale` (
+ `ID` int(10) unsigned NOT NULL DEFAULT '0',
+ `type` tinyint(3) unsigned NOT NULL DEFAULT '0',
+ `locale` varchar(4) NOT NULL,
+ `Greeting` text,
+ `VerifiedBuild` smallint(6) NOT NULL DEFAULT '0',
+ PRIMARY KEY (`ID`,`type`,`locale`)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8;
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;