Core/Misc: converted quest, creature and quest query packets to packet class and ported query data caching from 335 branch

This commit is contained in:
Ovahlord committed 2020-07-28 21:34:12 +02:00
1 parent 8c4491f3a0
commit 64c4b4f529
22 files changed
+924 -387

No files matched your search

@@ -42,6 +42,7 @@
#include "PhasingHandler.h" #include "PhasingHandler.h"
#include "Player.h" #include "Player.h"
#include "PoolMgr.h" #include "PoolMgr.h"
#include "QueryPackets.h"
#include "QuestDef.h" #include "QuestDef.h"
#include "ScriptedGossip.h" #include "ScriptedGossip.h"
#include "SpellAuraEffects.h" #include "SpellAuraEffects.h"
@@ -164,6 +165,69 @@ uint32 CreatureTemplate::GetFirstVisibleModel() const
return 17519; return 17519;
} }
void CreatureTemplate::InitializeQueryData()
{
WorldPacket queryTemp;
for (uint8 loc = LOCALE_enUS; loc < TOTAL_LOCALES; ++loc)
{
queryTemp = BuildQueryData(static_cast<LocaleConstant>(loc));
QueryData[loc] = queryTemp;
}
}
WorldPacket CreatureTemplate::BuildQueryData(LocaleConstant loc) const
{
WorldPackets::Query::QueryCreatureResponse queryTemp;
std::string locName = Name;
std::string locNameAlt = FemaleName;
std::string locTitle = Title;
if (CreatureLocale const* cl = sObjectMgr->GetCreatureLocale(Entry))
{
ObjectMgr::GetLocaleString(cl->Name, loc, locName);
ObjectMgr::GetLocaleString(cl->FemaleName, loc, locNameAlt);
ObjectMgr::GetLocaleString(cl->Title, loc, locTitle);
}
queryTemp.CreatureID = Entry;
queryTemp.Allow = true;
queryTemp.Stats.Name[0] = locName;
queryTemp.Stats.NameAlt[0] = locNameAlt;
queryTemp.Stats.Title = locTitle;
queryTemp.Stats.CursorName = IconName;
queryTemp.Stats.Flags[0] = type_flags;
queryTemp.Stats.Flags[1] = type_flags2;
queryTemp.Stats.CreatureType = type;
queryTemp.Stats.CreatureFamily = family;
queryTemp.Stats.Classification = rank;
for (uint8 i = 0; i < MAX_KILL_CREDIT; ++i)
queryTemp.Stats.ProxyCreatureID[i] = KillCredit[i];
queryTemp.Stats.CreatureDisplayID[0] = Modelid1;
queryTemp.Stats.CreatureDisplayID[1] = Modelid2;
queryTemp.Stats.CreatureDisplayID[2] = Modelid3;
queryTemp.Stats.CreatureDisplayID[3] = Modelid4;
queryTemp.Stats.HpMulti = ModHealth;
queryTemp.Stats.EnergyMulti = ModMana;
queryTemp.Stats.Leader = RacialLeader;
for (uint32 i = 0; i < MAX_CREATURE_QUEST_ITEMS; ++i)
queryTemp.Stats.QuestItems[i] = 0;
if (std::vector<uint32> const* items = sObjectMgr->GetCreatureQuestItemList(Entry))
for (uint32 i = 0; i < MAX_CREATURE_QUEST_ITEMS; ++i)
if (i < items->size())
queryTemp.Stats.QuestItems[i] = (*items)[i];
queryTemp.Stats.CreatureMovementInfoID = movementId;
queryTemp.Stats.RequiredExpansion = expansionUnknown;
queryTemp.Write();
queryTemp.ShrinkToFit();
return queryTemp.Move();
}
bool AssistDelayEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/) bool AssistDelayEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/)
{ {
if (Unit* victim = ObjectAccessor::GetUnit(m_owner, m_victim)) if (Unit* victim = ObjectAccessor::GetUnit(m_owner, m_victim))
@@ -25,6 +25,7 @@
#include "Duration.h" #include "Duration.h"
#include "Loot.h" #include "Loot.h"
#include "MapObject.h" #include "MapObject.h"
#include <list> #include <list>
class CreatureAI; class CreatureAI;
@@ -28,6 +28,7 @@
#include <vector> #include <vector>
#include <cmath> #include <cmath>
class WorldPacket;
struct ItemTemplate; struct ItemTemplate;
enum class VisibilityDistanceType : uint8; enum class VisibilityDistanceType : uint8;
@@ -195,6 +196,7 @@ struct TC_GAME_API CreatureTemplate
uint32 SpellSchoolImmuneMask; uint32 SpellSchoolImmuneMask;
uint32 flags_extra; uint32 flags_extra;
uint32 ScriptID; uint32 ScriptID;
WorldPacket QueryData[TOTAL_LOCALES];
uint32 GetRandomValidModelId() const; uint32 GetRandomValidModelId() const;
uint32 GetFirstValidModelId() const; uint32 GetFirstValidModelId() const;
uint32 GetFirstInvisibleModel() const; uint32 GetFirstInvisibleModel() const;
@@ -226,6 +228,9 @@ struct TC_GAME_API CreatureTemplate
// if can tame exotic then can tame any tameable // if can tame exotic then can tame any tameable
return canTameExotic || !IsExotic(); return canTameExotic || !IsExotic();
} }
void InitializeQueryData();
WorldPacket BuildQueryData(LocaleConstant loc) const;
}; };
#pragma pack(push, 1) #pragma pack(push, 1)
+9 -177
View File
@@ -246,7 +246,7 @@ void PlayerMenu::SendGossipMenu(uint32 titleTextId, ObjectGuid objectGUID)
ObjectMgr::GetLocaleString(localeData->Title, localeConstant, title); ObjectMgr::GetLocaleString(localeData->Title, localeConstant, title);
if (questLevelInTitle) if (questLevelInTitle)
AddQuestLevelToTitle(title, quest->GetQuestLevel()); Quest::AddQuestLevelToTitle(title, quest->GetQuestLevel());
data << title; // max 0x200 data << title; // max 0x200
} }
@@ -377,7 +377,7 @@ void PlayerMenu::SendQuestGiverQuestList(QEmote const& eEmote, const std::string
ObjectMgr::GetLocaleString(questTemplateLocaleData->Title, localeConstant, title); ObjectMgr::GetLocaleString(questTemplateLocaleData->Title, localeConstant, title);
if (questLevelInTitle) if (questLevelInTitle)
AddQuestLevelToTitle(title, quest->GetQuestLevel()); Quest::AddQuestLevelToTitle(title, quest->GetQuestLevel());
bool repeatable = quest->IsAutoComplete() && quest->IsRepeatable() && !quest->IsDailyOrWeekly() && !quest->IsMonthly(); bool repeatable = quest->IsAutoComplete() && quest->IsRepeatable() && !quest->IsDailyOrWeekly() && !quest->IsMonthly();
questList.QuestDataText.emplace_back(questID, questMenuItem.QuestIcon, quest->GetQuestLevel(), quest->GetFlags(), repeatable, title); questList.QuestDataText.emplace_back(questID, questMenuItem.QuestIcon, quest->GetQuestLevel(), quest->GetFlags(), repeatable, title);
@@ -428,7 +428,7 @@ void PlayerMenu::SendQuestGiverQuestDetails(Quest const* quest, ObjectGuid npcGU
} }
if (sWorld->getBoolConfig(CONFIG_UI_QUESTLEVELS_IN_DIALOGS)) if (sWorld->getBoolConfig(CONFIG_UI_QUESTLEVELS_IN_DIALOGS))
AddQuestLevelToTitle(packet.QuestTitle, quest->GetQuestLevel()); Quest::AddQuestLevelToTitle(packet.QuestTitle, quest->GetQuestLevel());
packet.QuestGiverGUID = npcGUID; packet.QuestGiverGUID = npcGUID;
packet.InformUnit = _session->GetPlayer()->GetPlayerSharingQuest(); packet.InformUnit = _session->GetPlayer()->GetPlayerSharingQuest();
@@ -457,172 +457,14 @@ void PlayerMenu::SendQuestGiverQuestDetails(Quest const* quest, ObjectGuid npcGU
void PlayerMenu::SendQuestQueryResponse(Quest const* quest) const void PlayerMenu::SendQuestQueryResponse(Quest const* quest) const
{ {
std::string questTitle = quest->GetTitle(); if (sWorld->getBoolConfig(CONFIG_CACHE_DATA_QUERIES))
std::string questDetails = quest->GetDetails(); _session->SendPacket(&quest->QueryData[static_cast<uint32>(_session->GetSessionDbLocaleIndex())]);
std::string questObjectives = quest->GetObjectives();
std::string questAreaDescription = quest->GetAreaDescription();
std::string questCompletedText = quest->GetCompletedText();
std::string questGiverTextWindow = quest->GetQuestGiverTextWindow();
std::string questGiverTargetName = quest->GetQuestGiverTargetName();
std::string questTurnTextWindow = quest->GetQuestTurnTextWindow();
std::string questTurnTargetName = quest->GetQuestTurnTargetName();
std::string questObjectiveText[QUEST_OBJECTIVES_COUNT];
for (uint8 i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
questObjectiveText[i] = quest->ObjectiveText[i];
LocaleConstant localeConstant = _session->GetSessionDbLocaleIndex();
if (localeConstant != LOCALE_enUS)
{
if (QuestLocale const* localeData = sObjectMgr->GetQuestLocale(quest->GetQuestId()))
{
ObjectMgr::GetLocaleString(localeData->Title, localeConstant, questTitle);
ObjectMgr::GetLocaleString(localeData->Details, localeConstant, questDetails);
ObjectMgr::GetLocaleString(localeData->Objectives, localeConstant, questObjectives);
ObjectMgr::GetLocaleString(localeData->AreaDescription, localeConstant, questAreaDescription);
ObjectMgr::GetLocaleString(localeData->CompletedText, localeConstant, questCompletedText);
ObjectMgr::GetLocaleString(localeData->QuestGiverTextWindow, localeConstant, questGiverTextWindow);
ObjectMgr::GetLocaleString(localeData->QuestGiverTargetName, localeConstant, questGiverTargetName);
ObjectMgr::GetLocaleString(localeData->QuestTurnTextWindow, localeConstant, questTurnTextWindow);
ObjectMgr::GetLocaleString(localeData->QuestTurnTargetName, localeConstant, questTurnTargetName);
for (uint8 i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
ObjectMgr::GetLocaleString(localeData->ObjectiveText[i], localeConstant, questObjectiveText[i]);
}
}
WorldPacket data(SMSG_QUEST_QUERY_RESPONSE, 100); // guess size
data << uint32(quest->GetQuestId()); // quest id
data << uint32(quest->GetQuestMethod()); // Accepted values: 0, 1 or 2. 0 == IsAutoComplete() (skip objectives/details)
data << uint32(quest->GetQuestLevel()); // may be -1, static data, in other cases must be used dynamic level: Player::GetQuestLevel (0 is not known, but assuming this is no longer valid for quest intended for client)
data << uint32(quest->GetMinLevel()); // min level
data << uint32(quest->GetZoneOrSort()); // zone or sort to display in quest log
data << uint32(quest->GetType()); // quest type
data << uint32(quest->GetSuggestedPlayers()); // suggested players count
data << uint32(quest->GetRepObjectiveFaction()); // shown in quest log as part of quest objective
data << uint32(quest->GetRepObjectiveValue()); // shown in quest log as part of quest objective
data << uint32(quest->GetRepObjectiveFaction2()); // shown in quest log as part of quest objective OPPOSITE faction
data << uint32(quest->GetRepObjectiveValue2()); // shown in quest log as part of quest objective OPPOSITE faction
data << uint32(quest->GetNextQuestInChain()); // client will request this quest from NPC, if not 0
data << uint32(quest->GetXPId()); // used for calculating rewarded experience
if (quest->HasFlag(QUEST_FLAGS_HIDDEN_REWARDS))
data << uint32(0); // Hide money rewarded
else
data << uint32(quest->GetRewOrReqMoney(_session->GetPlayer())); // reward money (below max lvl)
data << uint32(quest->GetRewMoneyMaxLevel()); // used in XP calculation at client
data << uint32(quest->GetRewSpell()); // reward spell, this spell will display (icon) (cast if RewSpellCast == 0)
data << int32(quest->GetRewSpellCast()); // cast spell
// rewarded honor points
data << uint32(quest->GetRewHonorAddition());
data << float(quest->GetRewHonorMultiplier());
data << uint32(quest->GetSrcItemId()); // source item id
data << uint32(quest->GetFlags()); // quest flags
data << uint32(quest->GetMinimapTargetMark()); // minimap target mark (skull, etc. missing enum)
data << uint32(quest->GetCharTitleId()); // CharTitleId, new 2.4.0, player gets this title (id from CharTitles)
data << uint32(quest->GetPlayersSlain()); // players slain
data << uint32(quest->GetBonusTalents()); // bonus talents
data << uint32(quest->GetRewArenaPoints()); // bonus arena points FIXME: arena points were removed, right?
data << uint32(quest->GetRewardSkillId()); // reward skill id
data << uint32(quest->GetRewardSkillPoints()); // reward skill points
data << uint32(quest->GetRewardReputationMask()); // rep mask (unsure on what it does)
data << uint32(quest->GetQuestGiverPortrait()); // quest giver entry ?
data << uint32(quest->GetQuestTurnInPortrait()); // quest turnin entry ?
if (quest->HasFlag(QUEST_FLAGS_HIDDEN_REWARDS))
{
for (uint8 i = 0; i < QUEST_REWARDS_COUNT; ++i)
data << uint32(0) << uint32(0);
for (uint8 i = 0; i < QUEST_REWARD_CHOICES_COUNT; ++i)
data << uint32(0) << uint32(0);
}
else else
{ {
for (uint8 i = 0; i < QUEST_REWARDS_COUNT; ++i) WorldPacket queryPacket = quest->BuildQueryData(_session->GetSessionDbLocaleIndex());
{ _session->SendPacket(&queryPacket);
data << uint32(quest->RewardItemId[i]);
data << uint32(quest->RewardItemIdCount[i]);
}
for (uint8 i = 0; i < QUEST_REWARD_CHOICES_COUNT; ++i)
{
data << uint32(quest->RewardChoiceItemId[i]);
data << uint32(quest->RewardChoiceItemCount[i]);
}
} }
for (uint8 i = 0; i < QUEST_REPUTATIONS_COUNT; ++i) // reward factions ids
data << uint32(quest->RewardFactionId[i]);
for (uint8 i = 0; i < QUEST_REPUTATIONS_COUNT; ++i) // columnid+1 QuestFactionReward.dbc?
data << int32(quest->RewardFactionValueId[i]);
for (uint8 i = 0; i < QUEST_REPUTATIONS_COUNT; ++i) // unknown usage
data << int32(quest->RewardFactionValueIdOverride[i]);
data << uint32(quest->GetPOIContinent());
data << float(quest->GetPOIx());
data << float(quest->GetPOIy());
data << uint32(quest->GetPointOpt());
if (sWorld->getBoolConfig(CONFIG_UI_QUESTLEVELS_IN_DIALOGS))
AddQuestLevelToTitle(questTitle, quest->GetQuestLevel());
data << questTitle;
data << questObjectives;
data << questDetails;
data << questAreaDescription;
data << questCompletedText; // display in quest objectives window once all objectives are completed
for (uint8 i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
{
if (quest->RequiredNpcOrGo[i] < 0)
data << uint32((quest->RequiredNpcOrGo[i] * (-1)) | 0x80000000); // client expects gameobject template id in form (id|0x80000000)
else
data << uint32(quest->RequiredNpcOrGo[i]);
data << uint32(quest->RequiredNpcOrGoCount[i]);
data << uint32(quest->ItemDrop[i]);
data << uint32(quest->ItemDropQuantity[i]);
}
for (uint8 i = 0; i < QUEST_ITEM_OBJECTIVES_COUNT; ++i)
{
data << uint32(quest->RequiredItemId[i]);
data << uint32(quest->RequiredItemCount[i]);
}
data << uint32(quest->GetRequiredSpell()); // Is it required to be cast, learned or what?
for (uint8 i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
data << questObjectiveText[i];
for (uint32 i = 0; i < QUEST_REWARD_CURRENCY_COUNT; ++i)
{
data << uint32(quest->RewardCurrencyId[i]);
data << uint32(quest->RewardCurrencyCount[i]);
}
for (uint32 i = 0; i < QUEST_REQUIRED_CURRENCY_COUNT; ++i)
{
data << uint32(quest->RequiredCurrencyId[i]);
data << uint32(quest->RequiredCurrencyCount[i]);
}
data << questGiverTextWindow;
data << questGiverTargetName;
data << questTurnTextWindow;
data << questTurnTargetName;
data << uint32(quest->GetSoundAccept());
data << uint32(quest->GetSoundTurnIn());
_session->SendPacket(&data);
TC_LOG_DEBUG("network", "WORLD: Sent SMSG_QUEST_QUERY_RESPONSE questid=%u", quest->GetQuestId()); TC_LOG_DEBUG("network", "WORLD: Sent SMSG_QUEST_QUERY_RESPONSE questid=%u", quest->GetQuestId());
} }
@@ -652,7 +494,7 @@ void PlayerMenu::SendQuestGiverOfferReward(Quest const* quest, ObjectGuid npcGUI
} }
if (sWorld->getBoolConfig(CONFIG_UI_QUESTLEVELS_IN_DIALOGS)) if (sWorld->getBoolConfig(CONFIG_UI_QUESTLEVELS_IN_DIALOGS))
AddQuestLevelToTitle(packet.QuestTitle, quest->GetQuestLevel()); Quest::AddQuestLevelToTitle(packet.QuestTitle, quest->GetQuestLevel());
WorldPackets::Quest::QuestGiverOfferReward& offer = packet.QuestData; WorldPackets::Quest::QuestGiverOfferReward& offer = packet.QuestData;
@@ -698,7 +540,7 @@ void PlayerMenu::SendQuestGiverRequestItems(Quest const* quest, ObjectGuid npcGU
} }
if (sWorld->getBoolConfig(CONFIG_UI_QUESTLEVELS_IN_DIALOGS)) if (sWorld->getBoolConfig(CONFIG_UI_QUESTLEVELS_IN_DIALOGS))
AddQuestLevelToTitle(questTitle, quest->GetQuestLevel()); Quest::AddQuestLevelToTitle(questTitle, quest->GetQuestLevel());
WorldPackets::Quest::QuestGiverRequestItems packet; WorldPackets::Quest::QuestGiverRequestItems packet;
@@ -765,13 +607,3 @@ void PlayerMenu::SendQuestGiverRequestItems(Quest const* quest, ObjectGuid npcGU
_session->SendPacket(packet.Write()); _session->SendPacket(packet.Write());
TC_LOG_DEBUG("network", "WORLD: Sent SMSG_QUEST_GIVER_REQUEST_ITEMS NPC=%s, questid=%u", npcGUID.ToString().c_str(), quest->GetQuestId()); TC_LOG_DEBUG("network", "WORLD: Sent SMSG_QUEST_GIVER_REQUEST_ITEMS NPC=%s, questid=%u", npcGUID.ToString().c_str(), quest->GetQuestId());
} }
void PlayerMenu::AddQuestLevelToTitle(std::string &title, int32 level)
{
// Adds the quest level to the front of the quest title
// example: [13] Westfall Stew
std::stringstream questTitlePretty;
questTitlePretty << "[" << level << "] " << title;
title = questTitlePretty.str();
}
@@ -303,8 +303,6 @@ class TC_GAME_API PlayerMenu
void SendQuestGiverOfferReward(Quest const* quest, ObjectGuid npcGUID, bool autoLaunched) const; void SendQuestGiverOfferReward(Quest const* quest, ObjectGuid npcGUID, bool autoLaunched) const;
void SendQuestGiverRequestItems(Quest const* quest, ObjectGuid npcGUID, bool canComplete, bool autoLaunched) const; void SendQuestGiverRequestItems(Quest const* quest, ObjectGuid npcGUID, bool canComplete, bool autoLaunched) const;
static void AddQuestLevelToTitle(std::string &title, int32 level);
private: private:
GossipMenu _gossipMenu; GossipMenu _gossipMenu;
QuestMenu _questMenu; QuestMenu _questMenu;
@@ -37,6 +37,7 @@
#include "OutdoorPvPMgr.h" #include "OutdoorPvPMgr.h"
#include "PhasingHandler.h" #include "PhasingHandler.h"
#include "PoolMgr.h" #include "PoolMgr.h"
#include "QueryPackets.h"
#include "ScriptMgr.h" #include "ScriptMgr.h"
#include "SpellMgr.h" #include "SpellMgr.h"
#include "Transport.h" #include "Transport.h"
@@ -57,6 +58,60 @@ QuaternionData QuaternionData::fromEulerAnglesZYX(float Z, float Y, float X)
return QuaternionData(quat.x, quat.y, quat.z, quat.w); return QuaternionData(quat.x, quat.y, quat.z, quat.w);
} }
void GameObjectTemplate::InitializeQueryData()
{
WorldPacket queryTemp;
for (uint8 loc = LOCALE_enUS; loc < TOTAL_LOCALES; ++loc)
{
queryTemp = BuildQueryData(static_cast<LocaleConstant>(loc));
QueryData[loc] = queryTemp;
}
}
WorldPacket GameObjectTemplate::BuildQueryData(LocaleConstant loc) const
{
WorldPackets::Query::QueryGameObjectResponse queryTemp;
std::string locName = name;
std::string locIconName = IconName;
std::string locCastBarCaption = castBarCaption;
if (GameObjectLocale const* gameObjectLocale = sObjectMgr->GetGameObjectLocale(entry))
{
ObjectMgr::GetLocaleString(gameObjectLocale->Name, loc, locName);
ObjectMgr::GetLocaleString(gameObjectLocale->CastBarCaption, loc, locCastBarCaption);
}
queryTemp.GameObjectID = entry;
queryTemp.Allow = true;
queryTemp.Stats.Type = type;
queryTemp.Stats.DisplayID = displayId;
queryTemp.Stats.Name[0] = locName;
queryTemp.Stats.IconName = locIconName;
queryTemp.Stats.CastBarCaption = locCastBarCaption;
queryTemp.Stats.UnkString = unk1;
for (uint8 i = 0; i < MAX_GAMEOBJECT_DATA; ++i)
queryTemp.Stats.Data[i] = raw.data[i];
queryTemp.Stats.Size = size;
for (uint32 i = 0; i < MAX_GAMEOBJECT_QUEST_ITEMS; ++i)
queryTemp.Stats.QuestItems[i] = 0;
if (std::vector<uint32> const* items = sObjectMgr->GetCreatureQuestItemList(entry))
for (uint32 i = 0; i < MAX_GAMEOBJECT_QUEST_ITEMS; ++i)
if (i < items->size())
queryTemp.Stats.QuestItems[i] = (*items)[i];
queryTemp.Stats.RequiredLevel = RequiredLevel;
queryTemp.Write();
queryTemp.ShrinkToFit();
return queryTemp.Move();
}
GameObject::GameObject() : WorldObject(false), MapObject(), GameObject::GameObject() : WorldObject(false), MapObject(),
m_model(nullptr), m_goValue(), m_AI(nullptr), m_respawnCompatibilityMode(false), _triggerJustAppeared(true) m_model(nullptr), m_goValue(), m_AI(nullptr), m_respawnCompatibilityMode(false), _triggerJustAppeared(true)
{ {
@@ -29,6 +29,8 @@
#define MAX_GAMEOBJECT_QUEST_ITEMS 6 #define MAX_GAMEOBJECT_QUEST_ITEMS 6
class WorldPacket;
// from `gameobject_template` // from `gameobject_template`
struct GameObjectTemplate struct GameObjectTemplate
{ {
@@ -426,6 +428,7 @@ struct GameObjectTemplate
std::string AIName; std::string AIName;
uint32 ScriptId; uint32 ScriptId;
WorldPacket QueryData[TOTAL_LOCALES];
// helpers // helpers
bool IsDespawnAtAction() const bool IsDespawnAtAction() const
@@ -594,6 +597,9 @@ struct GameObjectTemplate
default: return false; default: return false;
} }
} }
void InitializeQueryData();
WorldPacket BuildQueryData(LocaleConstant loc) const;
}; };
// From `gameobject_template_addon` // From `gameobject_template_addon`
+88 -6
View File
@@ -46,6 +46,8 @@
#include "PhasingHandler.h" #include "PhasingHandler.h"
#include "Player.h" #include "Player.h"
#include "PoolMgr.h" #include "PoolMgr.h"
#include "QuestDef.h"
#include "QueryPackets.h"
#include "Random.h" #include "Random.h"
#include "ReputationMgr.h" #include "ReputationMgr.h"
#include "ScriptMgr.h" #include "ScriptMgr.h"
@@ -7741,7 +7743,6 @@ void ObjectMgr::LoadQuestPOI()
// 0 1 2 3 4 5 6 7 // 0 1 2 3 4 5 6 7
QueryResult result = WorldDatabase.Query("SELECT QuestID, id, ObjectiveIndex, MapID, WorldMapAreaId, Floor, Priority, Flags FROM quest_poi order by QuestID"); QueryResult result = WorldDatabase.Query("SELECT QuestID, id, ObjectiveIndex, MapID, WorldMapAreaId, Floor, Priority, Flags FROM quest_poi order by QuestID");
if (!result) if (!result)
{ {
TC_LOG_ERROR("server.loading", ">> Loaded 0 quest POI definitions. DB table `quest_poi` is empty."); TC_LOG_ERROR("server.loading", ">> Loaded 0 quest POI definitions. DB table `quest_poi` is empty.");
@@ -7751,7 +7752,7 @@ void ObjectMgr::LoadQuestPOI()
// 0 1 2 3 // 0 1 2 3
QueryResult points = WorldDatabase.Query("SELECT QuestID, Idx1, X, Y FROM quest_poi_points ORDER BY QuestID DESC, Idx2"); QueryResult points = WorldDatabase.Query("SELECT QuestID, Idx1, X, Y FROM quest_poi_points ORDER BY QuestID DESC, Idx2");
std::vector<std::vector<std::vector<QuestPOIPoint> > > POIs; std::vector<std::vector<std::vector<QuestPOIBlobPoint>>> POIs;
if (points) if (points)
{ {
@@ -7772,7 +7773,10 @@ void ObjectMgr::LoadQuestPOI()
if (POIs[questId].size() <= id + 1) if (POIs[questId].size() <= id + 1)
POIs[questId].resize(id + 10); POIs[questId].resize(id + 10);
QuestPOIPoint point(x, y); QuestPOIBlobPoint point;
point.X = x;
point.Y = y;
POIs[questId][id].push_back(point); POIs[questId][id].push_back(point);
} while (points->NextRow()); } while (points->NextRow());
} }
@@ -7790,11 +7794,30 @@ void ObjectMgr::LoadQuestPOI()
uint32 unk3 = fields[6].GetUInt32(); uint32 unk3 = fields[6].GetUInt32();
uint32 unk4 = fields[7].GetUInt32(); uint32 unk4 = fields[7].GetUInt32();
QuestPOI POI(id, objIndex, mapId, WorldMapAreaId, FloorId, unk3, unk4); QuestPOIBlobData POI;
POI.BlobIndex = id;
POI.ObjectiveIndex = objIndex;
POI.MapID = mapId;
POI.WorldMapAreaID = WorldMapAreaId;
POI.Floor = FloorId;
POI.Unk3 = unk3;
POI.Unk4 = unk4;
if (questId < POIs.size() && id < POIs[questId].size()) if (questId < POIs.size() && id < POIs[questId].size())
{ {
POI.points = POIs[questId][id]; POI.QuestPOIBlobPointStats = POIs[questId][id];
_questPOIStore[questId].push_back(POI); auto itr = _questPOIStore.find(questId);
if (itr == _questPOIStore.end())
{
QuestPOIWrapper wrapper;
QuestPOIData data;
data.QuestID = questId;
wrapper.POIData = data;
_questPOIStore.emplace(questId, std::move(wrapper));
}
_questPOIStore.at(questId).POIData.QuestPOIBlobDataStats.push_back(POI);
} }
else else
TC_LOG_ERROR("sql.sql", "Table quest_poi references unknown quest points for quest %u POI id %u", questId, id); TC_LOG_ERROR("sql.sql", "Table quest_poi references unknown quest points for quest %u POI id %u", questId, id);
@@ -10098,3 +10121,62 @@ uint32 ObjectMgr::GetGameObjectTypeByEntry(uint32 entry) const
return MAX_GAMEOBJECT_TYPE; return MAX_GAMEOBJECT_TYPE;
} }
void ObjectMgr::InitializeQueriesData(QueryDataGroup mask)
{
// cache disabled
if (!sWorld->getBoolConfig(CONFIG_CACHE_DATA_QUERIES))
return;
// Initialize Query data for creatures
if (mask & QUERY_DATA_CREATURES)
for (auto& creaturePair : _creatureTemplateStore)
creaturePair.second.InitializeQueryData();
// Initialize Query Data for gameobjects
if (mask & QUERY_DATA_GAMEOBJECTS)
for (auto& gameobjectPair : _gameObjectTemplateStore)
gameobjectPair.second.InitializeQueryData();
// Initialize Query Data for quests
if (mask & QUERY_DATA_QUESTS)
for (auto& questPair : _questTemplates)
questPair.second.InitializeQueryData();
// Initialize Quest POI data
if (mask & QUERY_DATA_POIS)
for (auto& poiPair : _questPOIStore)
poiPair.second.InitializeQueryData();
}
void QuestPOIWrapper::InitializeQueryData()
{
QueryDataBuffer = BuildQueryData();
}
ByteBuffer QuestPOIWrapper::BuildQueryData() const
{
ByteBuffer tempBuffer;
tempBuffer << uint32(POIData.QuestID); // quest ID
tempBuffer << uint32(POIData.QuestPOIBlobDataStats.size()); // POI count
for (QuestPOIBlobData const& questPOIBlobData : POIData.QuestPOIBlobDataStats)
{
tempBuffer << uint32(questPOIBlobData.BlobIndex); // POI index
tempBuffer << int32(questPOIBlobData.ObjectiveIndex); // objective index
tempBuffer << uint32(questPOIBlobData.MapID); // mapid
tempBuffer << uint32(questPOIBlobData.WorldMapAreaID); // areaid
tempBuffer << uint32(questPOIBlobData.Floor); // floorid
tempBuffer << uint32(questPOIBlobData.Unk3); // unknown
tempBuffer << uint32(questPOIBlobData.Unk4); // unknown
tempBuffer << uint32(questPOIBlobData.QuestPOIBlobPointStats.size()); // POI points count
for (QuestPOIBlobPoint const& questPOIBlobPoint : questPOIBlobData.QuestPOIBlobPointStats)
{
tempBuffer << int32(questPOIBlobPoint.X); // POI point x
tempBuffer << int32(questPOIBlobPoint.Y); // POI point y
}
}
return tempBuffer;
}
+43 -21
View File
@@ -809,32 +809,42 @@ typedef std::multimap<uint32, GossipMenuItems> GossipMenuItemsContainer;
typedef std::pair<GossipMenuItemsContainer::const_iterator, GossipMenuItemsContainer::const_iterator> GossipMenuItemsMapBounds; typedef std::pair<GossipMenuItemsContainer::const_iterator, GossipMenuItemsContainer::const_iterator> GossipMenuItemsMapBounds;
typedef std::pair<GossipMenuItemsContainer::iterator, GossipMenuItemsContainer::iterator> GossipMenuItemsMapBoundsNonConst; typedef std::pair<GossipMenuItemsContainer::iterator, GossipMenuItemsContainer::iterator> GossipMenuItemsMapBoundsNonConst;
struct QuestPOIPoint struct QuestPOIBlobPoint
{ {
int32 x; int32 X = 0;
int32 y; int32 Y = 0;
QuestPOIPoint() : x(0), y(0) { }
QuestPOIPoint(int32 _x, int32 _y) : x(_x), y(_y) { }
}; };
struct QuestPOI struct QuestPOIBlobData
{ {
uint32 Id; uint32 BlobIndex = 0;
int32 ObjectiveIndex; int32 ObjectiveIndex = 0;
uint32 MapId; uint32 MapID = 0;
uint32 AreaId; uint32 WorldMapAreaID = 0;
uint32 FloorId; uint32 Floor = 0;
uint32 Unk3; uint32 Unk3 = 0;
uint32 Unk4; uint32 Unk4 = 0;
std::vector<QuestPOIPoint> points; std::vector<QuestPOIBlobPoint> QuestPOIBlobPointStats;
QuestPOI() : Id(0), ObjectiveIndex(0), MapId(0), AreaId(0), FloorId(0), Unk3(0), Unk4(0) { }
QuestPOI(uint32 id, int32 objIndex, uint32 mapId, uint32 areaId, uint32 floorId, uint32 unk3, uint32 unk4) : Id(id), ObjectiveIndex(objIndex), MapId(mapId), AreaId(areaId), FloorId(floorId), Unk3(unk3), Unk4(unk4) { }
}; };
typedef std::vector<QuestPOI> QuestPOIVector; struct QuestPOIData
typedef std::unordered_map<uint32, QuestPOIVector> QuestPOIContainer; {
uint32 QuestID = 0;
std::vector<QuestPOIBlobData> QuestPOIBlobDataStats;
};
struct QuestPOIWrapper
{
QuestPOIData POIData;
ByteBuffer QueryDataBuffer;
void InitializeQueryData();
ByteBuffer BuildQueryData() const;
QuestPOIWrapper() : QueryDataBuffer(0) { }
};
typedef std::unordered_map<uint32, QuestPOIWrapper> QuestPOIContainer;
struct QuestGreeting struct QuestGreeting
{ {
@@ -934,6 +944,16 @@ struct PhaseAreaInfo
ConditionContainer Conditions; ConditionContainer Conditions;
}; };
enum QueryDataGroup
{
QUERY_DATA_CREATURES = 0x01,
QUERY_DATA_GAMEOBJECTS = 0x02,
QUERY_DATA_QUESTS = 0x04,
QUERY_DATA_POIS = 0x08,
QUERY_DATA_ALL = 0xFF
};
class PlayerDumpReader; class PlayerDumpReader;
class TC_GAME_API ObjectMgr class TC_GAME_API ObjectMgr
@@ -1103,7 +1123,7 @@ class TC_GAME_API ObjectMgr
return nullptr; return nullptr;
} }
QuestPOIVector const* GetQuestPOIVector(uint32 questId) QuestPOIWrapper const* GetQuestPOIWrapper(uint32 questId)
{ {
QuestPOIContainer::const_iterator itr = _questPOIStore.find(questId); QuestPOIContainer::const_iterator itr = _questPOIStore.find(questId);
if (itr != _questPOIStore.end()) if (itr != _questPOIStore.end())
@@ -1226,6 +1246,8 @@ class TC_GAME_API ObjectMgr
void LoadTrainers(); void LoadTrainers();
void LoadCreatureDefaultTrainers(); void LoadCreatureDefaultTrainers();
void InitializeQueriesData(QueryDataGroup mask);
void LoadPhases(); void LoadPhases();
void UnloadPhaseConditions(); void UnloadPhaseConditions();
void LoadTerrainSwapDefaults(); void LoadTerrainSwapDefaults();
+40 -168
View File
@@ -90,152 +90,54 @@ void WorldSession::SendQueryTimeResponse()
} }
/// Only _static_ data is sent in this packet !!! /// Only _static_ data is sent in this packet !!!
void WorldSession::HandleCreatureQueryOpcode(WorldPacket& recvData) void WorldSession::HandleCreatureQueryOpcode(WorldPackets::Query::QueryCreature& query)
{ {
uint32 entry; if (CreatureTemplate const* ci = sObjectMgr->GetCreatureTemplate(query.CreatureID))
recvData >> entry;
ObjectGuid guid;
recvData >> guid;
CreatureTemplate const* creatureInfo = sObjectMgr->GetCreatureTemplate(entry);
if (creatureInfo)
{ {
std::string Name, FemaleName, Title; TC_LOG_DEBUG("network", "WORLD: CMSG_CREATURE_QUERY '%s' - Entry: %u.", ci->Name.c_str(), query.CreatureID);
Name = creatureInfo->Name; if (sWorld->getBoolConfig(CONFIG_CACHE_DATA_QUERIES))
FemaleName = creatureInfo->FemaleName; SendPacket(&ci->QueryData[static_cast<uint32>(GetSessionDbLocaleIndex())]);
Title = creatureInfo->Title;
LocaleConstant locale = GetSessionDbLocaleIndex();
if (locale != LOCALE_enUS)
{
if (CreatureLocale const* creatureLocale = sObjectMgr->GetCreatureLocale(entry))
{
ObjectMgr::GetLocaleString(creatureLocale->Name, locale, Name);
ObjectMgr::GetLocaleString(creatureLocale->FemaleName, locale, FemaleName);
ObjectMgr::GetLocaleString(creatureLocale->Title, locale, Title);
}
}
TC_LOG_DEBUG("network", "WORLD: CMSG_CREATURE_QUERY '%s' - Entry: %u.", creatureInfo->Name.c_str(), entry);
WorldPacket data(SMSG_CREATURE_QUERY_RESPONSE, 100); // guess size
data << uint32(entry); // creature entry
data << Name; // Name
for (uint8 i = 0; i < 3; i++)
data << uint8(0); // name2, ..., name3
data << FemaleName; // FemaleName
for (uint8 i = 0; i < 3; i++)
data << uint8(0); // name5, ..., name8
data << Title; // Title
data << creatureInfo->IconName; // "Directions" for guard, string for Icons 2.3.0
data << uint32(creatureInfo->type_flags); // flags
data << uint32(creatureInfo->type_flags2); // unknown meaning
data << uint32(creatureInfo->type); // CreatureType.dbc
data << uint32(creatureInfo->family); // CreatureFamily.dbc
data << uint32(creatureInfo->rank); // Creature Rank (elite, boss, etc)
data << uint32(creatureInfo->KillCredit[0]); // new in 3.1, kill credit
data << uint32(creatureInfo->KillCredit[1]); // new in 3.1, kill credit
data << uint32(creatureInfo->Modelid1); // Modelid1
data << uint32(creatureInfo->Modelid2); // Modelid2
data << uint32(creatureInfo->Modelid3); // Modelid3
data << uint32(creatureInfo->Modelid4); // Modelid4
data << float(creatureInfo->ModHealth); // dmg/hp modifier
data << float(creatureInfo->ModMana); // dmg/mana modifier
data << uint8(creatureInfo->RacialLeader); // RacialLeader
std::vector<uint32> const* items = sObjectMgr->GetCreatureQuestItemList(entry);
if (items)
for (uint32 i = 0; i < MAX_CREATURE_QUEST_ITEMS; ++i)
data << (i < items->size() ? uint32((*items)[i]) : uint32(0));
else else
for (uint32 i = 0; i < MAX_CREATURE_QUEST_ITEMS; ++i) {
data << uint32(0); WorldPacket response = ci->BuildQueryData(GetSessionDbLocaleIndex());
SendPacket(&response);
data << uint32(creatureInfo->movementId); // CreatureMovementInfo.dbc }
data << uint32(creatureInfo->expansionUnknown); // unknown meaning
SendPacket(&data);
TC_LOG_DEBUG("network", "WORLD: Sent SMSG_CREATURE_QUERY_RESPONSE"); TC_LOG_DEBUG("network", "WORLD: Sent SMSG_CREATURE_QUERY_RESPONSE");
} }
else else
{ {
TC_LOG_DEBUG("network", "WORLD: CMSG_CREATURE_QUERY - NO CREATURE INFO! (%s, ENTRY: %u)", TC_LOG_DEBUG("network", "WORLD: CMSG_CREATURE_QUERY - NO CREATURE INFO! (%s, ENTRY: %u)",
guid.ToString().c_str(), entry); query.GUID.ToString().c_str(), query.CreatureID);
WorldPacket data(SMSG_CREATURE_QUERY_RESPONSE, 4);
data << uint32(entry | 0x80000000);
SendPacket(&data);
WorldPackets::Query::QueryCreatureResponse response;
response.CreatureID = query.CreatureID;
SendPacket(response.Write());
TC_LOG_DEBUG("network", "WORLD: Sent SMSG_CREATURE_QUERY_RESPONSE"); TC_LOG_DEBUG("network", "WORLD: Sent SMSG_CREATURE_QUERY_RESPONSE");
} }
} }
/// Only _static_ data is sent in this packet !!! /// Only _static_ data is sent in this packet !!!
void WorldSession::HandleGameObjectQueryOpcode(WorldPacket& recvData) void WorldSession::HandleGameObjectQueryOpcode(WorldPackets::Query::QueryGameObject& query)
{ {
uint32 entry; if (GameObjectTemplate const* info = sObjectMgr->GetGameObjectTemplate(query.GameObjectID))
recvData >> entry;
ObjectGuid guid;
recvData >> guid;
GameObjectTemplate const* info = sObjectMgr->GetGameObjectTemplate(entry);
if (info)
{ {
std::string Name; if (sWorld->getBoolConfig(CONFIG_CACHE_DATA_QUERIES))
std::string IconName; SendPacket(&info->QueryData[static_cast<uint32>(GetSessionDbLocaleIndex())]);
std::string CastBarCaption;
Name = info->name;
IconName = info->IconName;
CastBarCaption = info->castBarCaption;
LocaleConstant localeConstant = GetSessionDbLocaleIndex();
if (localeConstant != LOCALE_enUS)
{
if (GameObjectLocale const* gameObjectLocale = sObjectMgr->GetGameObjectLocale(entry))
{
ObjectMgr::GetLocaleString(gameObjectLocale->Name, localeConstant, Name);
ObjectMgr::GetLocaleString(gameObjectLocale->CastBarCaption, localeConstant, CastBarCaption);
}
}
TC_LOG_DEBUG("network", "WORLD: CMSG_GAMEOBJECT_QUERY '%s' - Entry: %u. ", info->name.c_str(), entry);
WorldPacket data (SMSG_GAMEOBJECT_QUERY_RESPONSE, 150);
data << uint32(entry);
data << uint32(info->type);
data << uint32(info->displayId);
data << Name;
data << uint8(0) << uint8(0) << uint8(0); // name2, name3, name4
data << IconName; // 2.0.3, string. Icon name to use instead of default icon for go's (ex: "Attack" makes sword)
data << CastBarCaption; // 2.0.3, string. Text will appear in Cast Bar when using GO (ex: "Collecting")
data << info->unk1; // 2.0.3, string
data.append(info->raw.data, MAX_GAMEOBJECT_DATA);
data << float(info->size); // go size
data << int32(info->RequiredLevel); // 4.x, Required level
std::vector<uint32> const* items = sObjectMgr->GetGameObjectQuestItemList(entry);
if (items)
for (size_t i = 0; i < MAX_GAMEOBJECT_QUEST_ITEMS; ++i)
data << (i < items->size() ? uint32((*items)[i]) : uint32(0));
else else
for (size_t i = 0; i < MAX_GAMEOBJECT_QUEST_ITEMS; ++i) {
data << uint32(0); WorldPacket response = info->BuildQueryData(GetSessionDbLocaleIndex());
SendPacket(&response);
SendPacket(&data); }
TC_LOG_DEBUG("network", "WORLD: Sent SMSG_GAMEOBJECT_QUERY_RESPONSE"); TC_LOG_DEBUG("network", "WORLD: Sent SMSG_GAMEOBJECT_QUERY_RESPONSE");
} }
else else
{ {
TC_LOG_DEBUG("network", "WORLD: CMSG_GAMEOBJECT_QUERY - Missing gameobject info for (%s, ENTRY: %u)", TC_LOG_DEBUG("network", "WORLD: CMSG_GAMEOBJECT_QUERY - Missing gameobject info for (%s, ENTRY: %u)",
guid.ToString().c_str(), entry); query.GUID.ToString().c_str(), query.GameObjectID);
WorldPacket data (SMSG_GAMEOBJECT_QUERY_RESPONSE, 4);
data << uint32(entry | 0x80000000); WorldPackets::Query::QueryGameObjectResponse response;
SendPacket(&data); response.GameObjectID = query.GameObjectID;
SendPacket(response.Write());
TC_LOG_DEBUG("network", "WORLD: Sent SMSG_GAMEOBJECT_QUERY_RESPONSE"); TC_LOG_DEBUG("network", "WORLD: Sent SMSG_GAMEOBJECT_QUERY_RESPONSE");
} }
} }
@@ -469,61 +371,31 @@ void WorldSession::HandleQuestNPCQuery(WorldPacket& recvData)
SendPacket(&data); SendPacket(&data);
} }
void WorldSession::HandleQuestPOIQuery(WorldPacket& recvData) void WorldSession::HandleQuestPOIQuery(WorldPackets::Query::QuestPOIQuery& query)
{ {
uint32 count; if (query.MissingQuestCount > MAX_QUEST_LOG_SIZE)
recvData >> count; // quest count, max=25
if (count > MAX_QUEST_LOG_SIZE)
{
recvData.rfinish();
return; return;
}
// Read quest ids and add the in a unordered_set so we don't send POIs for the same quest multiple times // Read quest ids and add the in a unordered_set so we don't send POIs for the same quest multiple times
std::unordered_set<uint32> questIds; std::unordered_set<uint32> questIds;
for (uint32 i = 0; i < count; ++i) for (uint32 i = 0; i < query.MissingQuestCount; ++i)
questIds.insert(recvData.read<uint32>()); // quest id questIds.insert(query.MissingQuestPOIs[i]); // quest id
WorldPacket data(SMSG_QUEST_POI_QUERY_RESPONSE, 4 + (4 + 4)*questIds.size()); WorldPacket data(SMSG_QUEST_POI_QUERY_RESPONSE, 4 + (4 + 4 + 40) * questIds.size());
data << uint32(questIds.size()); // count data << uint32(questIds.size()); // count
for (uint32 questId : questIds)
for (auto itr = questIds.begin(); itr != questIds.end(); ++itr)
{ {
uint32 questId = *itr; uint16 const questSlot = _player->FindQuestSlot(questId);
if (questSlot != MAX_QUEST_LOG_SIZE && _player->GetQuestSlotQuestId(questSlot) == questId)
bool questOk = false;
uint16 questSlot = _player->FindQuestSlot(questId);
if (questSlot != MAX_QUEST_LOG_SIZE)
questOk =_player->GetQuestSlotQuestId(questSlot) == questId;
if (questOk)
{ {
QuestPOIVector const* POI = sObjectMgr->GetQuestPOIVector(questId); if (QuestPOIWrapper const* poiWrapper = sObjectMgr->GetQuestPOIWrapper(questId))
if (POI)
{ {
data << uint32(questId); // quest ID if (sWorld->getBoolConfig(CONFIG_CACHE_DATA_QUERIES))
data << uint32(POI->size()); // POI count data.append(poiWrapper->QueryDataBuffer);
else
for (QuestPOIVector::const_iterator itr = POI->begin(); itr != POI->end(); ++itr)
{ {
data << uint32(itr->Id); // POI index ByteBuffer POIByteBuffer = poiWrapper->BuildQueryData();
data << int32(itr->ObjectiveIndex); // objective index data.append(POIByteBuffer);
data << uint32(itr->MapId); // mapid
data << uint32(itr->AreaId); // areaid
data << uint32(itr->FloorId); // floorid
data << uint32(itr->Unk3); // unknown
data << uint32(itr->Unk4); // unknown
data << uint32(itr->points.size()); // POI points count
for (std::vector<QuestPOIPoint>::const_iterator itr2 = itr->points.begin(); itr2 != itr->points.end(); ++itr2)
{
data << int32(itr2->x); // POI point x
data << int32(itr2->y); // POI point y
}
} }
} }
else else
+4 -3
View File
@@ -31,6 +31,7 @@
#include "Player.h" #include "Player.h"
#include "QuestDef.h" #include "QuestDef.h"
#include "QuestPackets.h" #include "QuestPackets.h"
#include "QueryPackets.h"
#include "ScriptMgr.h" #include "ScriptMgr.h"
#include "World.h" #include "World.h"
#include "WorldPacket.h" #include "WorldPacket.h"
@@ -238,14 +239,14 @@ void WorldSession::HandleQuestgiverQueryQuestOpcode(WorldPackets::Quest::QuestGi
} }
} }
void WorldSession::HandleQuestQueryOpcode(WorldPackets::Quest::QueryQuestInfo& packet) void WorldSession::HandleQuestQueryOpcode(WorldPackets::Quest::QueryQuestInfo& query)
{ {
if (!_player) if (!_player)
return; return;
TC_LOG_DEBUG("network", "WORLD: Received CMSG_QUERY_QUEST_INFO QuestID = %u", packet.QuestID); TC_LOG_DEBUG("network", "WORLD: Received CMSG_QUEST_QUERY quest = %u", query.QuestID);
if (Quest const* quest = sObjectMgr->GetQuestTemplate(packet.QuestID)) if (Quest const* quest = sObjectMgr->GetQuestTemplate(query.QuestID))
_player->PlayerTalkClass->SendQuestQueryResponse(quest); _player->PlayerTalkClass->SendQuestQueryResponse(quest);
} }
+172
View File
@@ -20,6 +20,7 @@
#include "Field.h" #include "Field.h"
#include "Log.h" #include "Log.h"
#include "ObjectMgr.h" #include "ObjectMgr.h"
#include "Opcodes.h"
#include "Player.h" #include "Player.h"
#include "QuestPackets.h" #include "QuestPackets.h"
#include "QuestPools.h" #include "QuestPools.h"
@@ -418,3 +419,174 @@ uint32 Quest::RoundXPValue(uint32 xp)
else else
return 50 * ((xp + 25) / 50); return 50 * ((xp + 25) / 50);
} }
void Quest::InitializeQueryData()
{
WorldPacket queryTemp;
for (uint8 loc = LOCALE_enUS; loc < TOTAL_LOCALES; ++loc)
{
queryTemp = BuildQueryData(static_cast<LocaleConstant>(loc));
QueryData[loc] = queryTemp;
}
}
WorldPacket Quest::BuildQueryData(LocaleConstant loc) const
{
WorldPackets::Quest::QueryQuestInfoResponse response;
response.Info.QuestID = GetQuestId();
std::string locQuestTitle = GetTitle();
std::string locQuestDetails = GetDetails();
std::string locQuestObjectives = GetObjectives();
std::string locQuestAreaDescription = GetAreaDescription();
std::string locQuestCompletedText = GetCompletedText();
std::string locQuestGiverTextWindow = GetQuestGiverTextWindow();
std::string locQuestGiverTargetName = GetQuestGiverTargetName();
std::string locQuestTurnTextWindow = GetQuestTurnTextWindow();
std::string locQuestTurnTargetName = GetQuestTurnTargetName();
std::string locQuestObjectiveText[QUEST_OBJECTIVES_COUNT];
for (uint8 i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
locQuestObjectiveText[i] = ObjectiveText[i];
if (QuestLocale const* localeData = sObjectMgr->GetQuestLocale(GetQuestId()))
{
ObjectMgr::GetLocaleString(localeData->Title, loc, locQuestTitle);
ObjectMgr::GetLocaleString(localeData->Details, loc, locQuestDetails);
ObjectMgr::GetLocaleString(localeData->Objectives, loc, locQuestObjectives);
ObjectMgr::GetLocaleString(localeData->AreaDescription, loc, locQuestAreaDescription);
ObjectMgr::GetLocaleString(localeData->CompletedText, loc, locQuestCompletedText);
ObjectMgr::GetLocaleString(localeData->QuestGiverTextWindow, loc, locQuestGiverTextWindow);
ObjectMgr::GetLocaleString(localeData->QuestGiverTargetName, loc, locQuestGiverTargetName);
ObjectMgr::GetLocaleString(localeData->QuestTurnTextWindow, loc, locQuestTurnTextWindow);
ObjectMgr::GetLocaleString(localeData->QuestTurnTargetName, loc, locQuestTurnTargetName);
for (uint8 i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
ObjectMgr::GetLocaleString(localeData->ObjectiveText[i], loc, locQuestObjectiveText[i]);
}
response.Info.QuestType = GetQuestMethod();
response.Info.QuestLevel = GetQuestLevel();
response.Info.QuestMinLevel = GetMinLevel();
response.Info.QuestSortID = GetZoneOrSort();
response.Info.QuestInfoID = GetType();
response.Info.SuggestedGroupNum = GetSuggestedPlayers();
response.Info.RequiredFactionId[0] = GetRepObjectiveFaction();
response.Info.RequiredFactionValue[0] = GetRepObjectiveValue();
response.Info.RequiredFactionId[1] = GetRepObjectiveFaction2();
response.Info.RequiredFactionValue[1] = GetRepObjectiveValue2();
response.Info.RewardNextQuest = GetNextQuestInChain();
response.Info.RewardXPDifficulty = GetXPId();
response.Info.RewardMoney = GetRewOrReqMoney();
response.Info.RewardBonusMoney = GetRewMoneyMaxLevel();
response.Info.RewardDisplaySpell = GetRewSpell();
response.Info.RewardSpell = GetRewSpellCast();
response.Info.RewardHonor = GetRewHonorAddition();
response.Info.RewardKillHonor = GetRewHonorMultiplier();
response.Info.StartItem = GetSrcItemId();
response.Info.Flags = GetFlags();
response.Info.MinimapTargetMark = GetMinimapTargetMark();
response.Info.RewardTitle = GetCharTitleId();
response.Info.RequiredPlayerKills = GetPlayersSlain();
response.Info.RewardTalents = GetBonusTalents();
response.Info.RewardArenaPoints = GetRewArenaPoints();
response.Info.PortraitGiver = GetQuestGiverPortrait();
response.Info.PortraitTurnIn = GetQuestTurnInPortrait();
for (uint8 i = 0; i < QUEST_REWARDS_COUNT; ++i)
{
response.Info.RewardItems[i] = RewardItemId[i];
response.Info.RewardAmount[i] = RewardItemIdCount[i];
}
for (uint8 i = 0; i < QUEST_REWARD_CHOICES_COUNT; ++i)
{
response.Info.UnfilteredChoiceItems[i].ItemID = RewardChoiceItemId[i];
response.Info.UnfilteredChoiceItems[i].Quantity = RewardChoiceItemCount[i];
}
for (uint8 i = 0; i < QUEST_REPUTATIONS_COUNT; ++i) // reward factions ids
response.Info.RewardFactionID[i] = RewardFactionId[i];
for (uint8 i = 0; i < QUEST_REPUTATIONS_COUNT; ++i) // columnid+1 QuestFactionReward.dbc?
response.Info.RewardFactionValue[i] = RewardFactionValueId[i];
for (uint8 i = 0; i < QUEST_REPUTATIONS_COUNT; ++i) // unknown usage
response.Info.RewardFactionValueOverride[i] = RewardFactionValueIdOverride[i];
response.Info.POIContinent = GetPOIContinent();
response.Info.POIx = GetPOIx();
response.Info.POIy = GetPOIy();
response.Info.POIPriority = GetPointOpt();
if (sWorld->getBoolConfig(CONFIG_UI_QUESTLEVELS_IN_DIALOGS))
Quest::AddQuestLevelToTitle(locQuestTitle, GetQuestLevel());
response.Info.LogTitle = locQuestTitle;
response.Info.LogDescription = locQuestObjectives;
response.Info.QuestDescription = locQuestDetails;
response.Info.AreaDescription = locQuestAreaDescription;
response.Info.QuestCompletionLog = locQuestCompletedText;
for (uint8 i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
{
response.Info.RequiredNpcOrGo[i] = RequiredNpcOrGo[i];
response.Info.RequiredNpcOrGoCount[i] = RequiredNpcOrGoCount[i];
response.Info.ItemDrop[i] = ItemDrop[i];
response.Info.ItemDropQuantity[i] = ItemDropQuantity[i];
}
for (uint8 i = 0; i < QUEST_ITEM_OBJECTIVES_COUNT; ++i)
{
response.Info.RequiredItemId[i] = RequiredItemId[i];
response.Info.RequiredItemCount[i] = RequiredItemCount[i];
}
response.Info.RequiredSpell = GetRequiredSpell();
for (uint8 i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
response.Info.ObjectiveText[i] = locQuestObjectiveText[i];
for (uint8 i = 0; i < QUEST_REWARD_CURRENCY_COUNT; ++i)
{
response.Info.RewardCurrencyID[i] = RewardCurrencyId[i];
response.Info.RewardCurrencyQty[i] = RewardCurrencyCount[i];
}
for (uint8 i = 0; i < QUEST_REQUIRED_CURRENCY_COUNT; ++i)
{
response.Info.RequiredCurrencyID[i] = RequiredCurrencyId[i];
response.Info.RequiredCurrencyQty[i] = RequiredCurrencyCount[i];
}
response.Info.PortraitGiverText = locQuestGiverTextWindow;
response.Info.PortraitGiverName = locQuestGiverTargetName;
response.Info.PortraitTurnintext = locQuestTurnTextWindow;
response.Info.PortraitTurnInName = locQuestTurnTargetName;
response.Info.AcceptedSoundKitID = GetSoundAccept();
response.Info.CompleteSoundKitID = GetSoundTurnIn();
response.Write();
response.ShrinkToFit();
return response.Move();
}
void Quest::AddQuestLevelToTitle(std::string& title, int32 level)
{
// Adds the quest level to the front of the quest title
// example: [13] Westfall Stew
std::stringstream questTitlePretty;
questTitlePretty << "[" << level << "] " << title;
title = questTitlePretty.str();
}
+6
View File
@@ -26,6 +26,7 @@
#include <vector> #include <vector>
class Player; class Player;
class WorldPacket;
namespace WorldPackets namespace WorldPackets
{ {
@@ -371,8 +372,13 @@ class TC_GAME_API Quest
void BuildQuestRewards(WorldPackets::Quest::QuestRewards& rewards, Player* player) const; void BuildQuestRewards(WorldPackets::Quest::QuestRewards& rewards, Player* player) const;
static void AddQuestLevelToTitle(std::string& title, int32 level);
void InitializeQueryData();
WorldPacket BuildQueryData(LocaleConstant loc) const;
std::vector<uint32> DependentPreviousQuests; std::vector<uint32> DependentPreviousQuests;
std::vector<uint32> DependentBreadcrumbQuests; std::vector<uint32> DependentBreadcrumbQuests;
WorldPacket QueryData[TOTAL_LOCALES];
// cached data // cached data
private: private:
@@ -19,6 +19,88 @@
#include "Player.h" #include "Player.h"
#include "QueryPackets.h" #include "QueryPackets.h"
void WorldPackets::Query::QueryCreature::Read()
{
_worldPacket >> CreatureID;
_worldPacket >> GUID;
}
WorldPacket const* WorldPackets::Query::QueryCreatureResponse::Write()
{
_worldPacket << uint32(CreatureID | (Allow ? 0x00000000 : 0x80000000)); // creature entry
if (Allow)
{
for (std::size_t i = 0; i < Stats.Name.size(); ++i)
_worldPacket << Stats.Name[i];
for (std::size_t i = 0; i < Stats.NameAlt.size(); ++i)
_worldPacket << Stats.NameAlt[i];
_worldPacket << Stats.Title;
_worldPacket << Stats.CursorName; // "Directions" for guard, string for Icons 2.3.0
_worldPacket.append(Stats.Flags.data(), Stats.Flags.size()); // flags
_worldPacket << uint32(Stats.CreatureType); // CreatureType.dbc
_worldPacket << uint32(Stats.CreatureFamily); // CreatureFamily.dbc
_worldPacket << uint32(Stats.Classification); // Creature Rank (elite, boss, etc)
_worldPacket.append(Stats.ProxyCreatureID.data(), Stats.ProxyCreatureID.size());
_worldPacket.append(Stats.CreatureDisplayID.data(), Stats.CreatureDisplayID.size()); // Modelid
_worldPacket << float(Stats.HpMulti); // dmg/hp modifier
_worldPacket << float(Stats.EnergyMulti); // dmg/mana modifier
_worldPacket << uint8(Stats.Leader);
_worldPacket.append(Stats.QuestItems.data(), Stats.QuestItems.size());
_worldPacket << uint32(Stats.CreatureMovementInfoID); // CreatureMovementInfo.dbc
_worldPacket << uint32(Stats.RequiredExpansion);
}
return &_worldPacket;
}
void WorldPackets::Query::QueryGameObject::Read()
{
_worldPacket >> GameObjectID;
_worldPacket >> GUID;
}
WorldPacket const* WorldPackets::Query::QueryGameObjectResponse::Write()
{
_worldPacket << uint32(GameObjectID | (Allow ? 0x00000000 : 0x80000000));
if (Allow)
{
_worldPacket << uint32(Stats.Type);
_worldPacket << uint32(Stats.DisplayID);
for (std::size_t i = 0; i < Stats.Name.size(); ++i)
_worldPacket << Stats.Name[i];
_worldPacket << Stats.IconName; // 2.0.3, string. Icon name to use instead of default icon for go's (ex: "Attack" makes sword)
_worldPacket << Stats.CastBarCaption; // 2.0.3, string. Text will appear in Cast Bar when using GO (ex: "Collecting")
_worldPacket << Stats.UnkString; // 2.0.3, string
_worldPacket.append(Stats.Data.data(), Stats.Data.size());
_worldPacket << float(Stats.Size); // go size
_worldPacket.append(Stats.QuestItems.data(), Stats.QuestItems.size());
_worldPacket << int32(Stats.RequiredLevel);
}
return &_worldPacket;
}
void WorldPackets::Query::QuestPOIQuery::Read()
{
_worldPacket >> MissingQuestCount;
MissingQuestPOIs.fill(0);
if (MissingQuestCount <= MAX_QUEST_LOG_SIZE)
{
for (std::size_t i = 0; i < MissingQuestCount; ++i)
_worldPacket >> MissingQuestPOIs[i];
}
else
_worldPacket.rfinish();
}
void WorldPackets::Query::DBQueryBulk::Read() void WorldPackets::Query::DBQueryBulk::Read()
{ {
_worldPacket >> TableHash; _worldPacket >> TableHash;
@@ -19,8 +19,11 @@
#define QueryPackets_h__ #define QueryPackets_h__
#include "Packet.h" #include "Packet.h"
#include "CreatureData.h"
#include "GameObjectData.h"
#include "DB2Stores.h" #include "DB2Stores.h"
#include "ObjectGuid.h" #include "ObjectGuid.h"
#include "QuestDef.h"
#include "SharedDefines.h" #include "SharedDefines.h"
class Player; class Player;
@@ -29,6 +32,97 @@ namespace WorldPackets
{ {
namespace Query namespace Query
{ {
class QueryCreature final : public ClientPacket
{
public:
QueryCreature(WorldPacket&& packet) : ClientPacket(CMSG_CREATURE_QUERY, std::move(packet)) { }
void Read() override;
uint32 CreatureID = 0;
ObjectGuid GUID;
};
struct CreatureStats
{
std::array<std::string, 4> Name;
std::array<std::string, 4> NameAlt;
std::string Title;
std::string CursorName;
std::array<uint32, 2> Flags;
uint32 CreatureType = 0;
uint32 CreatureFamily = 0;
uint32 Classification = 0;
std::array<uint32, MAX_KILL_CREDIT> ProxyCreatureID;
std::array<uint32, MAX_CREATURE_MODELS> CreatureDisplayID;
float HpMulti = 0.0f;
float EnergyMulti = 0.0f;
bool Leader = false;
std::array<uint32, MAX_CREATURE_QUEST_ITEMS> QuestItems;
uint32 CreatureMovementInfoID = 0;
uint32 RequiredExpansion = 0;
};
class QueryCreatureResponse final : public ServerPacket
{
public:
QueryCreatureResponse() : ServerPacket(SMSG_CREATURE_QUERY_RESPONSE, 100) { }
WorldPacket const* Write() override;
bool Allow = false;
CreatureStats Stats;
uint32 CreatureID = 0;
};
class QueryGameObject final : public ClientPacket
{
public:
QueryGameObject(WorldPacket&& packet) : ClientPacket(CMSG_GAMEOBJECT_QUERY, std::move(packet)) { }
void Read() override;
uint32 GameObjectID = 0;
ObjectGuid GUID;
};
struct GameObjectStats
{
std::array<std::string, 4> Name;
std::string IconName;
std::string CastBarCaption;
std::string UnkString;
uint32 Type = 0;
uint32 DisplayID = 0;
std::array<uint32, MAX_GAMEOBJECT_DATA> Data;
float Size = 0.0f;
std::array<uint32, MAX_GAMEOBJECT_QUEST_ITEMS> QuestItems;
int32 RequiredLevel = 0;
};
class QueryGameObjectResponse final : public ServerPacket
{
public:
QueryGameObjectResponse() : ServerPacket(SMSG_GAMEOBJECT_QUERY_RESPONSE, 150) { }
WorldPacket const* Write() override;
uint32 GameObjectID = 0;
bool Allow = false;
GameObjectStats Stats;
};
class QuestPOIQuery final : public ClientPacket
{
public:
QuestPOIQuery(WorldPacket&& packet) : ClientPacket(CMSG_QUEST_POI_QUERY, std::move(packet)) { }
void Read() override;
uint32 MissingQuestCount = 0;
std::array<uint32, MAX_QUEST_LOG_SIZE> MissingQuestPOIs;
};
struct DBQueryRecord struct DBQueryRecord
{ {
ObjectGuid GUID; ObjectGuid GUID;
@@ -297,6 +297,138 @@ WorldPacket const* WorldPackets::Quest::QuestGiverOfferRewardMessage::Write()
return &_worldPacket; return &_worldPacket;
} }
WorldPacket const* WorldPackets::Quest::QueryQuestInfoResponse::Write()
{
_worldPacket << uint32(Info.QuestID);
_worldPacket << int32(Info.QuestType);
_worldPacket << int32(Info.QuestLevel);
_worldPacket << int32(Info.QuestMinLevel);
_worldPacket << int32(Info.QuestSortID);
_worldPacket << int32(Info.QuestInfoID);
_worldPacket << uint32(Info.SuggestedGroupNum);
for (uint8 i = 0; i < BG_TEAMS_COUNT; ++i)
{
_worldPacket << uint32(Info.RequiredFactionId[i]);
_worldPacket << int32(Info.RequiredFactionValue[i]);
}
_worldPacket << int32(Info.RewardNextQuest);
_worldPacket << uint32(Info.RewardXPDifficulty);
if ((Info.Flags & QUEST_FLAGS_HIDDEN_REWARDS) != 0)
_worldPacket << int32(0);
else
_worldPacket << int32(Info.RewardMoney);
_worldPacket << uint32(Info.RewardBonusMoney);
_worldPacket << int32(Info.RewardDisplaySpell);
_worldPacket << int32(Info.RewardSpell);
_worldPacket << int32(Info.RewardHonor);
_worldPacket << float(Info.RewardKillHonor);
_worldPacket << uint32(Info.StartItem);
_worldPacket << uint32(Info.Flags);
_worldPacket << uint32(Info.MinimapTargetMark);
_worldPacket << uint32(Info.RewardTitle);
_worldPacket << uint32(Info.RequiredPlayerKills);
_worldPacket << uint32(Info.RewardTalents);
_worldPacket << uint32(Info.RewardArenaPoints);
_worldPacket << uint32(Info.RewardSkillLineID);
_worldPacket << uint32(Info.RewardNumSkillUps);
_worldPacket << uint32(Info.RewardReputationMask);
_worldPacket << uint32(Info.PortraitGiver);
_worldPacket << uint32(Info.PortraitTurnIn);
if ((Info.Flags & QUEST_FLAGS_HIDDEN_REWARDS) != 0)
{
for (uint8 i = 0; i < QUEST_REWARDS_COUNT; ++i)
_worldPacket << int32(0) << uint32(0);
for (uint8 i = 0; i < QUEST_REWARD_CHOICES_COUNT; ++i)
_worldPacket << int32(0) << uint32(0);
}
else
{
for (uint8 i = 0; i < QUEST_REWARDS_COUNT; ++i)
{
_worldPacket << int32(Info.RewardItems[i]);
_worldPacket << uint32(Info.RewardAmount[i]);
}
for (uint8 i = 0; i < QUEST_REWARD_CHOICES_COUNT; ++i)
{
_worldPacket << int32(Info.UnfilteredChoiceItems[i].ItemID);
_worldPacket << uint32(Info.UnfilteredChoiceItems[i].Quantity);
}
}
for (uint8 i = 0; i < QUEST_REPUTATIONS_COUNT; ++i)
_worldPacket << uint32(Info.RewardFactionID[i]);
for (uint8 i = 0; i < QUEST_REPUTATIONS_COUNT; ++i)
_worldPacket << int32(Info.RewardFactionValue[i]);
for (uint8 i = 0; i < QUEST_REPUTATIONS_COUNT; ++i)
_worldPacket << uint32(Info.RewardFactionValueOverride[i]);
_worldPacket << uint32(Info.POIContinent);
_worldPacket << float(Info.POIx);
_worldPacket << float(Info.POIy);
_worldPacket << uint32(Info.POIPriority);
_worldPacket << Info.LogTitle;
_worldPacket << Info.LogDescription;
_worldPacket << Info.QuestDescription;
_worldPacket << Info.AreaDescription;
_worldPacket << Info.QuestCompletionLog;
for (uint8 i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
{
if (Info.RequiredNpcOrGo[i] < 0)
_worldPacket << uint32((Info.RequiredNpcOrGo[i] * (-1)) | 0x80000000); // client expects gameobject template id in form (id|0x80000000)
else
_worldPacket << uint32(Info.RequiredNpcOrGo[i]);
_worldPacket << uint32(Info.RequiredNpcOrGoCount[i]);
_worldPacket << int32(Info.ItemDrop[i]);
_worldPacket << uint32(Info.ItemDropQuantity[i]);
}
for (uint8 i = 0; i < QUEST_ITEM_OBJECTIVES_COUNT; ++i)
{
_worldPacket << int32(Info.RequiredItemId[i]);
_worldPacket << uint32(Info.RequiredItemCount[i]);
}
_worldPacket << uint32(Info.RequiredSpell);
for (uint8 i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
_worldPacket << Info.ObjectiveText[i];
for (uint32 i = 0; i < QUEST_REWARD_CURRENCY_COUNT; ++i)
{
_worldPacket << uint32(Info.RewardCurrencyID[i]);
_worldPacket << uint32(Info.RewardCurrencyQty[i]);
}
for (uint32 i = 0; i < QUEST_REQUIRED_CURRENCY_COUNT; ++i)
{
_worldPacket << uint32(Info.RequiredCurrencyID[i]);
_worldPacket << uint32(Info.RequiredCurrencyQty[i]);
}
_worldPacket << Info.PortraitGiverText;
_worldPacket << Info.PortraitGiverName;
_worldPacket << Info.PortraitTurnintext;
_worldPacket << Info.PortraitTurnInName;
_worldPacket << uint32(Info.AcceptedSoundKitID);
_worldPacket << uint32(Info.CompleteSoundKitID);
return &_worldPacket;
}
ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Quest::QuestRewards const& questRewards) ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Quest::QuestRewards const& questRewards)
{ {
data << uint32(questRewards.ChoiceItemCount); data << uint32(questRewards.ChoiceItemCount);
+96 -7
View File
@@ -182,6 +182,102 @@ namespace WorldPackets
int32 QuestID = 0; int32 QuestID = 0;
}; };
struct QuestInfoChoiceItem
{
int32 ItemID = 0;
int32 Quantity = 0;
int32 DisplayID = 0;
};
struct QuestInfo
{
uint32 QuestID = 0;
int32 QuestType = 0; // Accepted values: 0, 1 or 2. 0 == IsAutoComplete() (skip objectives/details)
int32 QuestLevel = 0; // may be -1, static data, in other cases must be used dynamic level: Player::GetQuestLevel (0 is not known, but assuming this is no longer valid for quest intended for client)
int32 QuestMinLevel = 0;
int32 QuestSortID = 0; // zone or sort to display in quest log
int32 QuestInfoID = 0;
uint32 SuggestedGroupNum = 0;
int32 AllowableRaces = -1;
std::array<uint32, BG_TEAMS_COUNT> RequiredFactionId; // shown in quest log as part of quest objective (same/opposite faction)
std::array<int32, BG_TEAMS_COUNT> RequiredFactionValue; // shown in quest log as part of quest objective (same/opposite faction)
int32 RewardNextQuest = 0; // client will request this quest from NPC, if not 0
uint32 RewardXPDifficulty = 0; // used for calculating rewarded experience
int32 RewardMoney = 0; // reward money (below max lvl)
uint32 RewardBonusMoney = 0; // used in XP calculation at client
int32 RewardDisplaySpell = 0; // reward spell, this spell will be displayed (icon) (cast if RewSpellCast == 0)
int32 RewardSpell = 0;
int32 RewardHonor = 0;
float RewardKillHonor = 0.0f;
uint32 StartItem = 0;
uint32 Flags = 0;
uint32 MinimapTargetMark = 0;
uint32 RewardTitle = 0; // new 2.4.0, player gets this title (id from CharTitles)
uint32 RequiredPlayerKills = 0;
uint32 RewardTalents = 0;
int32 RewardArenaPoints = 0;
uint32 RewardSkillLineID = 0;
uint32 RewardNumSkillUps = 0;
uint32 RewardReputationMask = 0;
uint32 PortraitGiver = 0;
uint32 PortraitTurnIn = 0;
std::array<int32, QUEST_REWARDS_COUNT> RewardItems;
std::array<uint32, QUEST_REWARDS_COUNT> RewardAmount;
std::array<QuestInfoChoiceItem, QUEST_REWARD_CHOICES_COUNT> UnfilteredChoiceItems;
std::array<uint32, QUEST_REPUTATIONS_COUNT> RewardFactionID;
std::array<int32, QUEST_REPUTATIONS_COUNT> RewardFactionValue;
std::array<uint32, QUEST_REPUTATIONS_COUNT> RewardFactionValueOverride;
uint32 POIContinent = 0;
float POIx = 0.0f;
float POIy = 0.0f;
uint32 POIPriority = 0;
std::string LogTitle;
std::string LogDescription;
std::string QuestDescription;
std::string AreaDescription;
std::string QuestCompletionLog; // display in quest objectives window once all objectives are completed
std::array<int32, QUEST_OBJECTIVES_COUNT> RequiredNpcOrGo; // >0 Creature <0 Gameobject
std::array<uint32, QUEST_OBJECTIVES_COUNT> RequiredNpcOrGoCount;
std::array<int32, QUEST_OBJECTIVES_COUNT> ItemDrop;
std::array<uint32, QUEST_OBJECTIVES_COUNT> ItemDropQuantity;
std::array<uint32, QUEST_ITEM_OBJECTIVES_COUNT> RequiredItemId;
std::array<uint32, QUEST_ITEM_OBJECTIVES_COUNT> RequiredItemCount;
uint32 RequiredSpell = 0;
std::array<std::string, QUEST_OBJECTIVES_COUNT> ObjectiveText;
std::array<uint32, QUEST_REWARD_CURRENCY_COUNT> RewardCurrencyID;
std::array<uint32, QUEST_REWARD_CURRENCY_COUNT> RewardCurrencyQty;
std::array<uint32, QUEST_REQUIRED_CURRENCY_COUNT> RequiredCurrencyID;
std::array<uint32, QUEST_REQUIRED_CURRENCY_COUNT> RequiredCurrencyQty;
std::string PortraitGiverText;
std::string PortraitGiverName;
std::string PortraitTurnintext;
std::string PortraitTurnInName;
uint32 AcceptedSoundKitID = 0;
uint32 CompleteSoundKitID = 0;
};
class QueryQuestInfoResponse final : public ServerPacket
{
public:
QueryQuestInfoResponse() : ServerPacket(SMSG_QUEST_QUERY_RESPONSE, 2000) { }
WorldPacket const* Write() override;
QuestInfo Info;
};
struct GossipText struct GossipText
{ {
GossipText(uint32 questID, uint32 questType, int32 questLevel, uint32 questFlags, bool repeatable, std::string questTitle) : GossipText(uint32 questID, uint32 questType, int32 questLevel, uint32 questFlags, bool repeatable, std::string questTitle) :
@@ -229,13 +325,6 @@ namespace WorldPackets
QuestGiverInfo QuestGiver; QuestGiverInfo QuestGiver;
}; };
struct QuestInfoChoiceItem
{
int32 ItemID = 0;
int32 Quantity = 0;
int32 DisplayID = 0;
};
struct QuestRewards struct QuestRewards
{ {
int32 ChoiceItemCount = 0; int32 ChoiceItemCount = 0;
+6 -3
View File
@@ -171,6 +171,9 @@ namespace WorldPackets
namespace Query namespace Query
{ {
class QueryCreature;
class QueryGameObject;
class QuestPOIQuery;
class DBQueryBulk; class DBQueryBulk;
} }
@@ -713,9 +716,9 @@ class TC_GAME_API WorldSession
void HandleQueryTimeOpcode(WorldPacket& recvPacket); void HandleQueryTimeOpcode(WorldPacket& recvPacket);
void HandleCreatureQueryOpcode(WorldPacket& recvPacket); void HandleCreatureQueryOpcode(WorldPackets::Query::QueryCreature& query);
void HandleGameObjectQueryOpcode(WorldPacket& recvPacket); void HandleGameObjectQueryOpcode(WorldPackets::Query::QueryGameObject& query);
void HandleMoveWorldportAckOpcode(WorldPacket& recvPacket); void HandleMoveWorldportAckOpcode(WorldPacket& recvPacket);
void HandleMoveWorldportAck(); // for server-side calls void HandleMoveWorldportAck(); // for server-side calls
@@ -1177,7 +1180,7 @@ class TC_GAME_API WorldSession
void HandleReadyForAccountDataTimes(WorldPacket& recvData); void HandleReadyForAccountDataTimes(WorldPacket& recvData);
void HandleQueryQuestsCompleted(WorldPacket& recvData); void HandleQueryQuestsCompleted(WorldPacket& recvData);
void HandleQuestNPCQuery(WorldPacket& recvData); void HandleQuestNPCQuery(WorldPacket& recvData);
void HandleQuestPOIQuery(WorldPacket& recvData); void HandleQuestPOIQuery(WorldPackets::Query::QuestPOIQuery& query);
void HandleEjectPassenger(WorldPacket& data); void HandleEjectPassenger(WorldPacket& data);
void HandleEnterPlayerVehicle(WorldPacket& data); void HandleEnterPlayerVehicle(WorldPacket& data);
void HandleUpdateProjectilePosition(WorldPacket& recvPacket); void HandleUpdateProjectilePosition(WorldPacket& recvPacket);
+6
View File
@@ -1598,6 +1598,9 @@ void World::LoadConfigSettings(bool reload)
// Whether to use LoS from game objects // Whether to use LoS from game objects
m_bool_configs[CONFIG_CHECK_GOBJECT_LOS] = sConfigMgr->GetBoolDefault("CheckGameObjectLoS", true); m_bool_configs[CONFIG_CHECK_GOBJECT_LOS] = sConfigMgr->GetBoolDefault("CheckGameObjectLoS", true);
// Allow to cache data queries
m_bool_configs[CONFIG_CACHE_DATA_QUERIES] = sConfigMgr->GetBoolDefault("CacheDataQueries", true);
// call ScriptMgr if we're reloading the configuration // call ScriptMgr if we're reloading the configuration
if (reload) if (reload)
sScriptMgr->OnConfigLoad(reload); sScriptMgr->OnConfigLoad(reload);
@@ -2181,6 +2184,9 @@ void World::SetInitialWorldSettings()
TC_LOG_INFO("server.loading", "Loading Item loot..."); TC_LOG_INFO("server.loading", "Loading Item loot...");
sLootItemStorage->LoadStorageFromDB(); sLootItemStorage->LoadStorageFromDB();
TC_LOG_INFO("server.loading", "Initialize query data...");
sObjectMgr->InitializeQueriesData(QUERY_DATA_ALL);
///- Initialize game time and timers ///- Initialize game time and timers
TC_LOG_INFO("server.loading", "Initialize game time and timers"); TC_LOG_INFO("server.loading", "Initialize game time and timers");
GameTime::UpdateGameTimers(); GameTime::UpdateGameTimers();
+1
View File
@@ -185,6 +185,7 @@ enum WorldBoolConfigs
CONFIG_HOTSWAP_PREFIX_CORRECTION_ENABLED, CONFIG_HOTSWAP_PREFIX_CORRECTION_ENABLED,
CONFIG_CHECK_GOBJECT_LOS, CONFIG_CHECK_GOBJECT_LOS,
CONFIG_RESPAWN_DYNAMIC_ESCORTNPC, CONFIG_RESPAWN_DYNAMIC_ESCORTNPC,
CONFIG_CACHE_DATA_QUERIES,
BOOL_CONFIG_VALUE_COUNT BOOL_CONFIG_VALUE_COUNT
}; };
@@ -453,6 +453,7 @@ public:
sObjectMgr->CheckCreatureTemplate(cInfo); sObjectMgr->CheckCreatureTemplate(cInfo);
} }
sObjectMgr->InitializeQueriesData(QUERY_DATA_CREATURES);
handler->SendGlobalGMSysMessage("Creature template reloaded."); handler->SendGlobalGMSysMessage("Creature template reloaded.");
return true; return true;
} }
@@ -543,6 +544,7 @@ public:
{ {
TC_LOG_INFO("misc", "Re-Loading Quest Templates..."); TC_LOG_INFO("misc", "Re-Loading Quest Templates...");
sObjectMgr->LoadQuests(); sObjectMgr->LoadQuests();
sObjectMgr->InitializeQueriesData(QUERY_DATA_QUESTS);
handler->SendGlobalGMSysMessage("DB table `quest_template` (quest definitions) reloaded."); handler->SendGlobalGMSysMessage("DB table `quest_template` (quest definitions) reloaded.");
/// dependent also from `gameobject` but this table not reloaded anyway /// dependent also from `gameobject` but this table not reloaded anyway
@@ -734,6 +736,7 @@ public:
{ {
TC_LOG_INFO("misc", "Re-Loading Quest POI ..." ); TC_LOG_INFO("misc", "Re-Loading Quest POI ..." );
sObjectMgr->LoadQuestPOI(); sObjectMgr->LoadQuestPOI();
sObjectMgr->InitializeQueriesData(QUERY_DATA_POIS);
handler->SendGlobalGMSysMessage("DB Table `quest_poi` and `quest_poi_points` reloaded."); handler->SendGlobalGMSysMessage("DB Table `quest_poi` and `quest_poi_points` reloaded.");
return true; return true;
} }
@@ -1277,6 +1277,17 @@ Account.PasswordChangeSecurity = 0
BirthdayTime = 1222964635 BirthdayTime = 1222964635
#
# CacheDataQueries
# Description: Server caches data queries at startup.
# Can be disabled if not enough memory is available.
# Default: 1 - (Enabled)
# 0 - (Disabled)
#
#
CacheDataQueries = 1
# #
################################################################################################### ###################################################################################################