mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-16 07:30:42 +01:00
Core/Quests: Implemented quest greeting locales
This commit is contained in:
12
sql/updates/world/master/2018_04_24_01_world.sql
Normal file
12
sql/updates/world/master/2018_04_24_01_world.sql
Normal file
@@ -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;
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -1633,6 +1633,7 @@ void World::SetInitialWorldSettings()
|
||||
sObjectMgr->LoadCreatureLocales();
|
||||
sObjectMgr->LoadGameObjectLocales();
|
||||
sObjectMgr->LoadQuestTemplateLocale();
|
||||
sObjectMgr->LoadQuestGreetingLocales();
|
||||
sObjectMgr->LoadQuestOfferRewardLocale();
|
||||
sObjectMgr->LoadQuestRequestItemsLocale();
|
||||
sObjectMgr->LoadQuestObjectivesLocale();
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user