aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorariel- <ariel-@users.noreply.github.com>2017-02-20 18:08:40 -0300
committerariel- <ariel-@users.noreply.github.com>2017-02-21 03:03:58 -0300
commitdd1aa64563bfb726e1132a135927a02fbb765454 (patch)
tree7b60326913feab118019a8c9e5bc3d8999882f7e /src
parentc274ea8a98e9751d50301e99eb55577ba19155f2 (diff)
Core/Packet: convert query packets into new system.
- Extra c++11-ification of existing code - Refs #18637
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Entities/Creature/Creature.cpp62
-rw-r--r--src/server/game/Entities/GameObject/GameObject.cpp47
-rw-r--r--src/server/game/Entities/Item/ItemTemplate.cpp189
-rw-r--r--src/server/game/Globals/ObjectMgr.cpp72
-rw-r--r--src/server/game/Globals/ObjectMgr.h42
-rw-r--r--src/server/game/Handlers/ItemHandler.cpp25
-rw-r--r--src/server/game/Handlers/QueryHandler.cpp85
-rw-r--r--src/server/game/Handlers/QuestHandler.cpp10
-rw-r--r--src/server/game/Quests/QuestDef.cpp141
-rw-r--r--src/server/game/Server/Packets/AllPackets.h3
-rw-r--r--src/server/game/Server/Packets/QueryPackets.cpp209
-rw-r--r--src/server/game/Server/Packets/QueryPackets.h240
-rw-r--r--src/server/game/Server/Packets/QuestPackets.cpp128
-rw-r--r--src/server/game/Server/Packets/QuestPackets.h114
-rw-r--r--src/server/game/Server/WorldSession.h22
15 files changed, 1028 insertions, 361 deletions
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp
index 93345dee29e..c011325acff 100644
--- a/src/server/game/Entities/Creature/Creature.cpp
+++ b/src/server/game/Entities/Creature/Creature.cpp
@@ -49,6 +49,8 @@
#include "Transport.h"
#include "ScriptedGossip.h"
+#include "Packets/QueryPackets.h"
+
TrainerSpell const* TrainerSpellData::Find(uint32 spell_id) const
{
TrainerSpellMap::const_iterator itr = spellList.find(spell_id);
@@ -158,7 +160,7 @@ void CreatureTemplate::InitializeQueryData()
WorldPacket CreatureTemplate::BuildQueryData(LocaleConstant loc) const
{
- WorldPacket queryTemp(SMSG_CREATURE_QUERY_RESPONSE, 200);
+ WorldPackets::Query::QueryCreatureResponse queryTemp;
std::string locName = Name, locTitle = Title;
if (CreatureLocale const* cl = sObjectMgr->GetCreatureLocale(Entry))
@@ -167,39 +169,35 @@ WorldPacket CreatureTemplate::BuildQueryData(LocaleConstant loc) const
ObjectMgr::GetLocaleString(cl->Title, loc, locTitle);
}
- queryTemp << uint32(Entry); // creature entry
- queryTemp << locName;
- queryTemp << uint8(0) << uint8(0) << uint8(0); // name2, name3, name4, always empty
- queryTemp << locTitle;
- queryTemp << IconName; // "Directions" for guard, string for Icons 2.3.0
- queryTemp << uint32(type_flags); // flags
- queryTemp << uint32(type); // CreatureType.dbc
- queryTemp << uint32(family); // CreatureFamily.dbc
- queryTemp << uint32(rank); // Creature Rank (elite, boss, etc)
- queryTemp << uint32(KillCredit[0]); // new in 3.1, kill credit
- queryTemp << uint32(KillCredit[1]); // new in 3.1, kill credit
- queryTemp << uint32(Modelid1); // Modelid1
- queryTemp << uint32(Modelid2); // Modelid2
- queryTemp << uint32(Modelid3); // Modelid3
- queryTemp << uint32(Modelid4); // Modelid4
- queryTemp << float(ModHealth); // dmg/hp modifier
- queryTemp << float(ModMana); // dmg/mana modifier
- queryTemp << uint8(RacialLeader);
-
- CreatureQuestItemList const* items = sObjectMgr->GetCreatureQuestItemList(Entry);
- if (items)
- {
+ queryTemp.CreatureID = Entry;
+ queryTemp.Allow = true;
+
+ queryTemp.Stats.Name = locName;
+ queryTemp.Stats.NameAlt = locTitle;
+ queryTemp.Stats.CursorName = IconName;
+ queryTemp.Stats.Flags = type_flags;
+ queryTemp.Stats.CreatureType = type;
+ queryTemp.Stats.CreatureFamily = family;
+ queryTemp.Stats.Classification = rank;
+ memcpy(queryTemp.Stats.ProxyCreatureID, KillCredit, sizeof(uint32) * MAX_KILL_CREDIT);
+ 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 (CreatureQuestItemList const* items = sObjectMgr->GetCreatureQuestItemList(Entry))
for (uint32 i = 0; i < MAX_CREATURE_QUEST_ITEMS; ++i)
- queryTemp << (i < items->size() ? uint32((*items)[i]) : uint32(0));
- }
- else
- {
- for (uint32 i = 0; i < MAX_CREATURE_QUEST_ITEMS; ++i)
- queryTemp << uint32(0);
- }
+ if (i < items->size())
+ queryTemp.Stats.QuestItems[i] = (*items)[i];
- queryTemp << uint32(movementId); // CreatureMovementInfo.dbc
- return queryTemp;
+ queryTemp.Stats.CreatureMovementInfoID = movementId;
+ return *queryTemp.Write();
}
bool AssistDelayEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/)
diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp
index 2fc2d44666b..851fdc5edca 100644
--- a/src/server/game/Entities/GameObject/GameObject.cpp
+++ b/src/server/game/Entities/GameObject/GameObject.cpp
@@ -33,6 +33,8 @@
#include "World.h"
#include "Transport.h"
+#include "Packets/QueryPackets.h"
+
void GameObjectTemplate::InitializeQueryData()
{
WorldPacket queryTemp;
@@ -45,7 +47,7 @@ void GameObjectTemplate::InitializeQueryData()
WorldPacket GameObjectTemplate::BuildQueryData(LocaleConstant loc) const
{
- WorldPacket queryTemp(SMSG_GAMEOBJECT_QUERY_RESPONSE, 200);
+ WorldPackets::Query::QueryGameObjectResponse queryTemp;
std::string locName = name;
std::string locIconName = IconName;
@@ -57,30 +59,27 @@ WorldPacket GameObjectTemplate::BuildQueryData(LocaleConstant loc) const
ObjectMgr::GetLocaleString(gameObjectLocale->CastBarCaption, loc, locCastBarCaption);
}
- queryTemp << uint32(entry);
- queryTemp << uint32(type);
- queryTemp << uint32(displayId);
- queryTemp << locName;
- queryTemp << uint8(0) << uint8(0) << uint8(0); // name2, name3, name4
- queryTemp << locIconName; // 2.0.3, string. Icon name to use instead of default icon for go's (ex: "Attack" makes sword)
- queryTemp << locCastBarCaption; // 2.0.3, string. Text will appear in Cast Bar when using GO (ex: "Collecting")
- queryTemp << unk1; // 2.0.3, string
- queryTemp.append(raw.data, MAX_GAMEOBJECT_DATA);
- queryTemp << float(size); // go size
-
- GameObjectQuestItemList const* items = sObjectMgr->GetGameObjectQuestItemList(entry);
- if (items)
- {
- for (size_t i = 0; i < MAX_GAMEOBJECT_QUEST_ITEMS; ++i)
- queryTemp << (i < items->size() ? uint32((*items)[i]) : uint32(0));
- }
- else
- {
- for (size_t i = 0; i < MAX_GAMEOBJECT_QUEST_ITEMS; ++i)
- queryTemp << uint32(0);
- }
+ queryTemp.GameObjectID = entry;
+ queryTemp.Allow = true;
+
+ queryTemp.Stats.Type = type;
+ queryTemp.Stats.DisplayID = displayId;
+ queryTemp.Stats.Name = locName;
+ queryTemp.Stats.IconName = locIconName;
+ queryTemp.Stats.CastBarCaption = locCastBarCaption;
+ queryTemp.Stats.UnkString = unk1;
+ memcpy(queryTemp.Stats.Data, raw.data, sizeof(uint32) * MAX_GAMEOBJECT_DATA);
+ queryTemp.Stats.Size = size;
+
+ for (uint32 i = 0; i < MAX_GAMEOBJECT_QUEST_ITEMS; ++i)
+ queryTemp.Stats.QuestItems[i] = 0;
+
+ if (GameObjectQuestItemList const* items = sObjectMgr->GetGameObjectQuestItemList(entry))
+ for (uint32 i = 0; i < MAX_GAMEOBJECT_QUEST_ITEMS; ++i)
+ if (i < items->size())
+ queryTemp.Stats.QuestItems[i] = (*items)[i];
- return queryTemp;
+ return *queryTemp.Write();
}
GameObject::GameObject() : WorldObject(false), MapObject(),
diff --git a/src/server/game/Entities/Item/ItemTemplate.cpp b/src/server/game/Entities/Item/ItemTemplate.cpp
index e55d0d73132..ee5b34831db 100644
--- a/src/server/game/Entities/Item/ItemTemplate.cpp
+++ b/src/server/game/Entities/Item/ItemTemplate.cpp
@@ -24,6 +24,8 @@
#include "SpellInfo.h"
#include "SpellMgr.h"
+#include "Packets/QueryPackets.h"
+
bool ItemTemplate::CanChangeEquipStateInCombat() const
{
switch (InventoryType)
@@ -160,7 +162,7 @@ void ItemTemplate::InitializeQueryData()
WorldPacket ItemTemplate::BuildQueryData(LocaleConstant loc) const
{
- WorldPacket queryTemp(SMSG_ITEM_QUERY_SINGLE_RESPONSE, 500);
+ WorldPackets::Query::QueryItemSingleResponse response;
std::string locName = Name1;
std::string locDescription = Description;
@@ -171,114 +173,105 @@ WorldPacket ItemTemplate::BuildQueryData(LocaleConstant loc) const
ObjectMgr::GetLocaleString(il->Description, loc, locDescription);
}
- queryTemp << ItemId;
- queryTemp << Class;
- queryTemp << SubClass;
- queryTemp << SoundOverrideSubclass;
- queryTemp << locName;
- queryTemp << uint8(0x00); //Name2; // blizz not send name there, just uint8(0x00); <-- \0 = empty string = empty name...
- queryTemp << uint8(0x00); //Name3; // blizz not send name there, just uint8(0x00);
- queryTemp << uint8(0x00); //Name4; // blizz not send name there, just uint8(0x00);
- queryTemp << DisplayInfoID;
- queryTemp << Quality;
- queryTemp << Flags;
- queryTemp << Flags2;
- queryTemp << BuyPrice;
- queryTemp << SellPrice;
- queryTemp << InventoryType;
- queryTemp << AllowableClass;
- queryTemp << AllowableRace;
- queryTemp << ItemLevel;
- queryTemp << RequiredLevel;
- queryTemp << RequiredSkill;
- queryTemp << RequiredSkillRank;
- queryTemp << RequiredSpell;
- queryTemp << RequiredHonorRank;
- queryTemp << RequiredCityRank;
- queryTemp << RequiredReputationFaction;
- queryTemp << RequiredReputationRank;
- queryTemp << int32(MaxCount);
- queryTemp << int32(Stackable);
- queryTemp << ContainerSlots;
- queryTemp << StatsCount; // item stats count
+ response.ItemID = ItemId;
+ response.Allow = true;
+
+ response.Stats.Class = Class;
+ response.Stats.SubClass = SubClass;
+ response.Stats.SoundOverrideSubclass = SoundOverrideSubclass;
+ response.Stats.Name = locName;
+ response.Stats.DisplayInfoID = DisplayInfoID;
+ response.Stats.Quality = Quality;
+ response.Stats.Flags = Flags;
+ response.Stats.Flags2 = Flags2;
+ response.Stats.BuyPrice = BuyPrice;
+ response.Stats.SellPrice = SellPrice;
+ response.Stats.InventoryType = InventoryType;
+ response.Stats.AllowableClass = AllowableClass;
+ response.Stats.AllowableRace = AllowableRace;
+ response.Stats.ItemLevel = ItemLevel;
+ response.Stats.RequiredLevel = RequiredLevel;
+ response.Stats.RequiredSkill = RequiredSkill;
+ response.Stats.RequiredSkillRank = RequiredSkillRank;
+ response.Stats.RequiredSpell = RequiredSpell;
+ response.Stats.RequiredHonorRank = RequiredHonorRank;
+ response.Stats.RequiredCityRank = RequiredCityRank;
+ response.Stats.RequiredReputationFaction = RequiredReputationFaction;
+ response.Stats.RequiredReputationRank = RequiredReputationRank;
+ response.Stats.MaxCount = MaxCount;
+ response.Stats.Stackable = Stackable;
+ response.Stats.ContainerSlots = ContainerSlots;
+ response.Stats.StatsCount = StatsCount;
for (uint32 i = 0; i < StatsCount; ++i)
{
- queryTemp << ItemStat[i].ItemStatType;
- queryTemp << ItemStat[i].ItemStatValue;
+ response.Stats.ItemStat[i].ItemStatType = ItemStat[i].ItemStatType;
+ response.Stats.ItemStat[i].ItemStatValue = ItemStat[i].ItemStatValue;
}
- queryTemp << ScalingStatDistribution; // scaling stats distribution
- queryTemp << ScalingStatValue; // some kind of flags used to determine stat values column
- for (int i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i)
+
+ response.Stats.ScalingStatDistribution = ScalingStatDistribution;
+ response.Stats.ScalingStatValue = ScalingStatValue;
+
+ for (uint8 i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i)
{
- queryTemp << Damage[i].DamageMin;
- queryTemp << Damage[i].DamageMax;
- queryTemp << Damage[i].DamageType;
+ response.Stats.Damage[i].DamageMin = Damage[i].DamageMin;
+ response.Stats.Damage[i].DamageMax = Damage[i].DamageMax;
+ response.Stats.Damage[i].DamageType = Damage[i].DamageType;
}
- // resistances (7)
- queryTemp << Armor;
- queryTemp << HolyRes;
- queryTemp << FireRes;
- queryTemp << NatureRes;
- queryTemp << FrostRes;
- queryTemp << ShadowRes;
- queryTemp << ArcaneRes;
+ response.Stats.Resistance[SPELL_SCHOOL_NORMAL] = Armor;
+ response.Stats.Resistance[SPELL_SCHOOL_HOLY] = HolyRes;
+ response.Stats.Resistance[SPELL_SCHOOL_FIRE] = FireRes;
+ response.Stats.Resistance[SPELL_SCHOOL_NATURE] = NatureRes;
+ response.Stats.Resistance[SPELL_SCHOOL_FROST] = FrostRes;
+ response.Stats.Resistance[SPELL_SCHOOL_SHADOW] = ShadowRes;
+ response.Stats.Resistance[SPELL_SCHOOL_ARCANE] = ArcaneRes;
- queryTemp << Delay;
- queryTemp << AmmoType;
- queryTemp << RangedModRange;
+ response.Stats.Delay = Delay;
+ response.Stats.AmmoType = AmmoType;
+ response.Stats.RangedModRange = RangedModRange;
for (uint8 s = 0; s < MAX_ITEM_PROTO_SPELLS; ++s)
{
- // spells are validated on template loading
- if (Spells[s].SpellId > 0)
- {
- queryTemp << Spells[s].SpellId;
- queryTemp << Spells[s].SpellTrigger;
- queryTemp << uint32(-abs(Spells[s].SpellCharges));
- queryTemp << uint32(Spells[s].SpellCooldown);
- queryTemp << uint32(Spells[s].SpellCategory);
- queryTemp << uint32(Spells[s].SpellCategoryCooldown);
- }
- else
- {
- queryTemp << uint32(0);
- queryTemp << uint32(0);
- queryTemp << uint32(0);
- queryTemp << uint32(-1);
- queryTemp << uint32(0);
- queryTemp << uint32(-1);
- }
+ response.Stats.Spells[s].SpellId = Spells[s].SpellId;
+ response.Stats.Spells[s].SpellTrigger = Spells[s].SpellTrigger;
+ response.Stats.Spells[s].SpellCharges = Spells[s].SpellCharges;
+ response.Stats.Spells[s].SpellCooldown = Spells[s].SpellCooldown;
+ response.Stats.Spells[s].SpellCategory = Spells[s].SpellCategory;
+ response.Stats.Spells[s].SpellCategoryCooldown = Spells[s].SpellCategoryCooldown;
}
- queryTemp << Bonding;
- queryTemp << locDescription;
- queryTemp << PageText;
- queryTemp << LanguageID;
- queryTemp << PageMaterial;
- queryTemp << StartQuest;
- queryTemp << LockID;
- queryTemp << int32(Material);
- queryTemp << Sheath;
- queryTemp << RandomProperty;
- queryTemp << RandomSuffix;
- queryTemp << Block;
- queryTemp << ItemSet;
- queryTemp << MaxDurability;
- queryTemp << Area;
- queryTemp << Map; // Added in 1.12.x & 2.0.1 client branch
- queryTemp << BagFamily;
- queryTemp << TotemCategory;
- for (int s = 0; s < MAX_ITEM_PROTO_SOCKETS; ++s)
+
+ response.Stats.Bonding = Bonding;
+ response.Stats.Description = locDescription;
+ response.Stats.PageText = PageText;
+ response.Stats.LanguageID = LanguageID;
+ response.Stats.PageMaterial = PageMaterial;
+ response.Stats.StartQuest = StartQuest;
+ response.Stats.LockID = LockID;
+ response.Stats.Material = Material;
+ response.Stats.Sheath = Sheath;
+ response.Stats.RandomProperty = RandomProperty;
+ response.Stats.RandomSuffix = RandomSuffix;
+ response.Stats.Block = Block;
+ response.Stats.ItemSet = ItemSet;
+ response.Stats.MaxDurability = MaxDurability;
+ response.Stats.Area = Area;
+ response.Stats.Map = Map;
+ response.Stats.BagFamily = BagFamily;
+ response.Stats.TotemCategory = TotemCategory;
+
+ for (uint8 s = 0; s < MAX_ITEM_PROTO_SOCKETS; ++s)
{
- queryTemp << Socket[s].Color;
- queryTemp << Socket[s].Content;
+ response.Stats.Socket[s].Color = Socket[s].Color;
+ response.Stats.Socket[s].Content = Socket[s].Content;
}
- queryTemp << socketBonus;
- queryTemp << GemProperties;
- queryTemp << RequiredDisenchantSkill;
- queryTemp << ArmorDamageModifier;
- queryTemp << Duration; // added in 2.4.2.8209, duration (seconds)
- queryTemp << ItemLimitCategory; // WotLK, ItemLimitCategory
- queryTemp << HolidayId; // Holiday.dbc?
- return queryTemp;
+
+ response.Stats.SocketBonus = socketBonus;
+ response.Stats.GemProperties = GemProperties;
+ response.Stats.RequiredDisenchantSkill = RequiredDisenchantSkill;
+ response.Stats.ArmorDamageModifier = ArmorDamageModifier;
+ response.Stats.Duration = Duration;
+ response.Stats.ItemLimitCategory = ItemLimitCategory;
+ response.Stats.HolidayId = HolidayId;
+
+ return *response.Write();
}
diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp
index 1c2ae545ef3..aba664546d6 100644
--- a/src/server/game/Globals/ObjectMgr.cpp
+++ b/src/server/game/Globals/ObjectMgr.cpp
@@ -46,6 +46,8 @@
#include "Vehicle.h"
#include "World.h"
+#include "Packets/QueryPackets.h"
+
ScriptMapMap sSpellScripts;
ScriptMapMap sEventScripts;
ScriptMapMap sWaypointScripts;
@@ -7334,7 +7336,6 @@ void ObjectMgr::LoadQuestPOI()
// 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");
-
if (!result)
{
TC_LOG_ERROR("server.loading", ">> Loaded 0 quest POI definitions. DB table `quest_poi` is empty.");
@@ -7344,8 +7345,7 @@ void ObjectMgr::LoadQuestPOI()
// 0 1 2 3
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)
{
// The first result should have the highest questId
@@ -7365,7 +7365,10 @@ void ObjectMgr::LoadQuestPOI()
if (POIs[questId].size() <= id + 1)
POIs[questId].resize(id + 10);
- QuestPOIPoint point(x, y);
+ QuestPOIBlobPoint point;
+ point.X = x;
+ point.Y = y;
+
POIs[questId][id].push_back(point);
} while (points->NextRow());
}
@@ -7383,15 +7386,30 @@ void ObjectMgr::LoadQuestPOI()
uint32 unk3 = fields[6].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())
{
- POI.points = POIs[questId][id];
- QuestPOIContainer::iterator itr = _questPOIStore.find(questId);
+ POI.QuestPOIBlobPointStats = POIs[questId][id];
+ auto itr = _questPOIStore.find(questId);
if (itr == _questPOIStore.end())
- _questPOIStore[questId] = QuestPOIWrapper();
+ {
+ QuestPOIWrapper wrapper;
+ QuestPOIData data;
+ data.QuestID = questId;
+ wrapper.POIData = data;
+
+ _questPOIStore.emplace(questId, std::move(wrapper));
+ }
- _questPOIStore[questId].DataVector.push_back(POI);
+ _questPOIStore.at(questId).POIData.QuestPOIBlobDataStats.push_back(POI);
}
else
TC_LOG_ERROR("server.loading", "Table quest_poi references unknown quest points for quest %u POI id %u", questId, id);
@@ -9359,35 +9377,35 @@ void ObjectMgr::InitializeQueriesData(QueryDataGroup mask)
// Initialize Quest POI data
if (mask & QUERY_DATA_POIS)
for (auto& poiPair : _questPOIStore)
- poiPair.second.InitializeQueryData(poiPair.first);
+ poiPair.second.InitializeQueryData();
}
-void QuestPOIWrapper::InitializeQueryData(uint32 questId)
+void QuestPOIWrapper::InitializeQueryData()
{
- QueryDataBuffer = BuildQueryData(questId);
+ QueryDataBuffer = BuildQueryData();
}
-ByteBuffer QuestPOIWrapper::BuildQueryData(uint32 questId) const
+ByteBuffer QuestPOIWrapper::BuildQueryData() const
{
ByteBuffer tempBuffer;
- tempBuffer << uint32(questId); // quest ID
- tempBuffer << uint32(DataVector.size()); // POI count
+ tempBuffer << uint32(POIData.QuestID); // quest ID
+ tempBuffer << uint32(POIData.QuestPOIBlobDataStats.size()); // POI count
- for (QuestPOIVector::const_iterator itr = DataVector.begin(); itr != DataVector.end(); ++itr)
+ for (QuestPOIBlobData const& questPOIBlobData : POIData.QuestPOIBlobDataStats)
{
- tempBuffer << uint32(itr->Id); // POI index
- tempBuffer << int32(itr->ObjectiveIndex); // objective index
- tempBuffer << uint32(itr->MapId); // mapid
- tempBuffer << uint32(itr->AreaId); // areaid
- tempBuffer << uint32(itr->FloorId); // floorid
- tempBuffer << uint32(itr->Unk3); // unknown
- tempBuffer << uint32(itr->Unk4); // unknown
- tempBuffer << uint32(itr->points.size()); // POI points count
+ 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 (std::vector<QuestPOIPoint>::const_iterator itr2 = itr->points.begin(); itr2 != itr->points.end(); ++itr2)
+ for (QuestPOIBlobPoint const& questPOIBlobPoint : questPOIBlobData.QuestPOIBlobPointStats)
{
- tempBuffer << int32(itr2->x); // POI point x
- tempBuffer << int32(itr2->y); // POI point y
+ tempBuffer << int32(questPOIBlobPoint.X); // POI point x
+ tempBuffer << int32(questPOIBlobPoint.Y); // POI point y
}
}
diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h
index 8b61cd221ed..37a711110dc 100644
--- a/src/server/game/Globals/ObjectMgr.h
+++ b/src/server/game/Globals/ObjectMgr.h
@@ -590,39 +590,37 @@ typedef std::multimap<uint32, GossipMenuItems> GossipMenuItemsContainer;
typedef std::pair<GossipMenuItemsContainer::const_iterator, GossipMenuItemsContainer::const_iterator> GossipMenuItemsMapBounds;
typedef std::pair<GossipMenuItemsContainer::iterator, GossipMenuItemsContainer::iterator> GossipMenuItemsMapBoundsNonConst;
-struct QuestPOIPoint
+struct QuestPOIBlobPoint
{
- int32 x;
- int32 y;
-
- QuestPOIPoint() : x(0), y(0) { }
- QuestPOIPoint(int32 _x, int32 _y) : x(_x), y(_y) { }
+ int32 X = 0;
+ int32 Y = 0;
};
-struct QuestPOI
+struct QuestPOIBlobData
{
- uint32 Id;
- int32 ObjectiveIndex;
- uint32 MapId;
- uint32 AreaId;
- uint32 FloorId;
- uint32 Unk3;
- uint32 Unk4;
- std::vector<QuestPOIPoint> points;
-
- 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) { }
+ uint32 BlobIndex = 0;
+ int32 ObjectiveIndex = 0;
+ uint32 MapID = 0;
+ uint32 WorldMapAreaID = 0;
+ uint32 Floor = 0;
+ uint32 Unk3 = 0;
+ uint32 Unk4 = 0;
+ std::vector<QuestPOIBlobPoint> QuestPOIBlobPointStats;
};
-typedef std::vector<QuestPOI> QuestPOIVector;
+struct QuestPOIData
+{
+ uint32 QuestID = 0;
+ std::vector<QuestPOIBlobData> QuestPOIBlobDataStats;
+};
struct QuestPOIWrapper
{
- QuestPOIVector DataVector;
+ QuestPOIData POIData;
ByteBuffer QueryDataBuffer;
- void InitializeQueryData(uint32 questId);
- ByteBuffer BuildQueryData(uint32 questId) const;
+ void InitializeQueryData();
+ ByteBuffer BuildQueryData() const;
QuestPOIWrapper() : QueryDataBuffer(0) { }
};
diff --git a/src/server/game/Handlers/ItemHandler.cpp b/src/server/game/Handlers/ItemHandler.cpp
index 7dca74d59d0..721e0a9b54e 100644
--- a/src/server/game/Handlers/ItemHandler.cpp
+++ b/src/server/game/Handlers/ItemHandler.cpp
@@ -26,6 +26,8 @@
#include "Item.h"
#include "SpellInfo.h"
+#include "Packets/QueryPackets.h"
+
void WorldSession::HandleSplitItemOpcode(WorldPacket& recvData)
{
//TC_LOG_DEBUG("network", "WORLD: CMSG_SPLIT_ITEM");
@@ -305,31 +307,26 @@ void WorldSession::HandleDestroyItemOpcode(WorldPacket& recvData)
}
// Only _static_ data send in this packet !!!
-void WorldSession::HandleItemQuerySingleOpcode(WorldPacket& recvData)
+void WorldSession::HandleItemQuerySingleOpcode(WorldPackets::Query::QueryItemSingle& query)
{
- //TC_LOG_DEBUG("network", "WORLD: CMSG_ITEM_QUERY_SINGLE");
- uint32 item;
- recvData >> item;
+ TC_LOG_INFO("network", "STORAGE: Item Query = %u", query.ItemID);
- TC_LOG_INFO("network", "STORAGE: Item Query = %u", item);
-
- ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(item);
- if (itemTemplate)
+ if (ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(query.ItemID))
{
if (sWorld->getBoolConfig(CONFIG_CACHE_DATA_QUERIES))
SendPacket(&itemTemplate->QueryData[static_cast<uint32>(GetSessionDbLocaleIndex())]);
else
{
- WorldPacket queryPacket = itemTemplate->BuildQueryData(GetSessionDbLocaleIndex());
- SendPacket(&queryPacket);
+ WorldPacket response = itemTemplate->BuildQueryData(GetSessionDbLocaleIndex());
+ SendPacket(&response);
}
}
else
{
- TC_LOG_DEBUG("network", "WORLD: CMSG_ITEM_QUERY_SINGLE - NO item INFO! (ENTRY: %u)", item);
- WorldPacket data(SMSG_ITEM_QUERY_SINGLE_RESPONSE, 4);
- data << uint32(item | 0x80000000);
- SendPacket(&data);
+ TC_LOG_DEBUG("network", "WORLD: CMSG_ITEM_QUERY_SINGLE - NO item INFO! (ENTRY: %u)", query.ItemID);
+ WorldPackets::Query::QueryItemSingleResponse response;
+ response.ItemID = query.ItemID;
+ SendPacket(response.Write());
}
}
diff --git a/src/server/game/Handlers/QueryHandler.cpp b/src/server/game/Handlers/QueryHandler.cpp
index 707c733cc00..a05298f71cc 100644
--- a/src/server/game/Handlers/QueryHandler.cpp
+++ b/src/server/game/Handlers/QueryHandler.cpp
@@ -29,6 +29,8 @@
#include "MapManager.h"
#include "CharacterCache.h"
+#include "Packets/QueryPackets.h"
+
void WorldSession::SendNameQueryOpcode(ObjectGuid guid)
{
Player* player = ObjectAccessor::FindConnectedPlayer(guid);
@@ -87,64 +89,54 @@ void WorldSession::SendQueryTimeResponse()
}
/// Only _static_ data is sent in this packet !!!
-void WorldSession::HandleCreatureQueryOpcode(WorldPacket& recvData)
+void WorldSession::HandleCreatureQueryOpcode(WorldPackets::Query::QueryCreature& query)
{
- uint32 entry;
- recvData >> entry;
- ObjectGuid guid;
- recvData >> guid;
-
- CreatureTemplate const* ci = sObjectMgr->GetCreatureTemplate(entry);
- if (ci)
+ if (CreatureTemplate const* ci = sObjectMgr->GetCreatureTemplate(query.CreatureID))
{
- TC_LOG_DEBUG("network", "WORLD: CMSG_CREATURE_QUERY '%s' - Entry: %u.", ci->Name.c_str(), entry);
+ TC_LOG_DEBUG("network", "WORLD: CMSG_CREATURE_QUERY '%s' - Entry: %u.", ci->Name.c_str(), query.CreatureID);
if (sWorld->getBoolConfig(CONFIG_CACHE_DATA_QUERIES))
SendPacket(&ci->QueryData[static_cast<uint32>(GetSessionDbLocaleIndex())]);
else
{
- WorldPacket queryPacket = ci->BuildQueryData(GetSessionDbLocaleIndex());
- SendPacket(&queryPacket);
+ WorldPacket response = ci->BuildQueryData(GetSessionDbLocaleIndex());
+ SendPacket(&response);
}
TC_LOG_DEBUG("network", "WORLD: Sent SMSG_CREATURE_QUERY_RESPONSE");
}
else
{
TC_LOG_DEBUG("network", "WORLD: CMSG_CREATURE_QUERY - NO CREATURE INFO! (%s, ENTRY: %u)",
- guid.ToString().c_str(), entry);
- WorldPacket data(SMSG_CREATURE_QUERY_RESPONSE, 4);
- data << uint32(entry | 0x80000000);
- SendPacket(&data);
+ query.Guid.ToString().c_str(), query.CreatureID);
+
+ WorldPackets::Query::QueryCreatureResponse response;
+ response.CreatureID = query.CreatureID;
+ SendPacket(response.Write());
TC_LOG_DEBUG("network", "WORLD: Sent SMSG_CREATURE_QUERY_RESPONSE");
}
}
/// Only _static_ data is sent in this packet !!!
-void WorldSession::HandleGameObjectQueryOpcode(WorldPacket& recvData)
+void WorldSession::HandleGameObjectQueryOpcode(WorldPackets::Query::QueryGameObject& query)
{
- uint32 entry;
- recvData >> entry;
- ObjectGuid guid;
- recvData >> guid;
-
- const GameObjectTemplate* info = sObjectMgr->GetGameObjectTemplate(entry);
- if (info)
+ if (GameObjectTemplate const* info = sObjectMgr->GetGameObjectTemplate(query.GameObjectID))
{
if (sWorld->getBoolConfig(CONFIG_CACHE_DATA_QUERIES))
SendPacket(&info->QueryData[static_cast<uint32>(GetSessionDbLocaleIndex())]);
else
{
- WorldPacket queryPacket = info->BuildQueryData(GetSessionDbLocaleIndex());
- SendPacket(&queryPacket);
+ WorldPacket response = info->BuildQueryData(GetSessionDbLocaleIndex());
+ SendPacket(&response);
}
TC_LOG_DEBUG("network", "WORLD: Sent SMSG_GAMEOBJECT_QUERY_RESPONSE");
}
else
{
TC_LOG_DEBUG("network", "WORLD: CMSG_GAMEOBJECT_QUERY - Missing gameobject info for (%s, ENTRY: %u)",
- guid.ToString().c_str(), entry);
- WorldPacket data (SMSG_GAMEOBJECT_QUERY_RESPONSE, 4);
- data << uint32(entry | 0x80000000);
- SendPacket(&data);
+ query.Guid.ToString().c_str(), query.GameObjectID);
+
+ WorldPackets::Query::QueryGameObjectResponse response;
+ response.GameObjectID = query.GameObjectID;
+ SendPacket(response.Write());
TC_LOG_DEBUG("network", "WORLD: Sent SMSG_GAMEOBJECT_QUERY_RESPONSE");
}
}
@@ -337,46 +329,29 @@ void WorldSession::HandleCorpseMapPositionQuery(WorldPacket& recvData)
SendPacket(&data);
}
-void WorldSession::HandleQuestPOIQuery(WorldPacket& recvData)
+void WorldSession::HandleQuestPOIQuery(WorldPackets::Query::QuestPOIQuery& query)
{
- uint32 count;
- recvData >> count; // quest count, max=25
-
- if (count > MAX_QUEST_LOG_SIZE)
- {
- recvData.rfinish();
+ if (query.MissingQuestCount > MAX_QUEST_LOG_SIZE)
return;
- }
// 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;
- for (uint32 i = 0; i < count; ++i)
- questIds.insert(recvData.read<uint32>()); // quest id
-
- WorldPacket data(SMSG_QUEST_POI_QUERY_RESPONSE, 4 + (4 + 4 + 40)*questIds.size());
- data << uint32(questIds.size()); // count
+ for (uint32 i = 0; i < query.MissingQuestCount; ++i)
+ questIds.insert(query.MissingQuestPOIs[i]); // quest id
- for (auto itr = questIds.begin(); itr != questIds.end(); ++itr)
+ WorldPacket data(SMSG_QUEST_POI_QUERY_RESPONSE, 4 + (4 + 4 + 40) * questIds.size());
+ for (uint32 questId : questIds)
{
- uint32 questId = *itr;
-
- bool questOk = false;
-
- uint16 questSlot = _player->FindQuestSlot(questId);
-
- if (questSlot != MAX_QUEST_LOG_SIZE)
- questOk =_player->GetQuestSlotQuestId(questSlot) == questId;
-
- if (questOk)
+ uint16 const questSlot = _player->FindQuestSlot(questId);
+ if (questSlot != MAX_QUEST_LOG_SIZE && _player->GetQuestSlotQuestId(questSlot) == questId)
{
if (QuestPOIWrapper const* poiWrapper = sObjectMgr->GetQuestPOIWrapper(questId))
{
-
if (sWorld->getBoolConfig(CONFIG_CACHE_DATA_QUERIES))
data.append(poiWrapper->QueryDataBuffer);
else
{
- ByteBuffer POIByteBuffer = poiWrapper->BuildQueryData(questId);
+ ByteBuffer POIByteBuffer = poiWrapper->BuildQueryData();
data.append(POIByteBuffer);
}
}
diff --git a/src/server/game/Handlers/QuestHandler.cpp b/src/server/game/Handlers/QuestHandler.cpp
index 611b52c5c94..4c464b9df63 100644
--- a/src/server/game/Handlers/QuestHandler.cpp
+++ b/src/server/game/Handlers/QuestHandler.cpp
@@ -31,6 +31,8 @@
#include "ScriptMgr.h"
#include "GameObjectAI.h"
+#include "Packets/QuestPackets.h"
+
void WorldSession::HandleQuestgiverStatusQueryOpcode(WorldPacket& recvData)
{
ObjectGuid guid;
@@ -250,16 +252,14 @@ void WorldSession::HandleQuestgiverQueryQuestOpcode(WorldPacket& recvData)
}
}
-void WorldSession::HandleQuestQueryOpcode(WorldPacket& recvData)
+void WorldSession::HandleQuestQueryOpcode(WorldPackets::Quest::QueryQuestInfo& query)
{
if (!_player)
return;
- uint32 questId;
- recvData >> questId;
- TC_LOG_DEBUG("network", "WORLD: Received CMSG_QUEST_QUERY quest = %u", questId);
+ TC_LOG_DEBUG("network", "WORLD: Received CMSG_QUEST_QUERY quest = %u", query.QuestID);
- if (Quest const* quest = sObjectMgr->GetQuestTemplate(questId))
+ if (Quest const* quest = sObjectMgr->GetQuestTemplate(query.QuestID))
_player->PlayerTalkClass->SendQuestQueryResponse(quest);
}
diff --git a/src/server/game/Quests/QuestDef.cpp b/src/server/game/Quests/QuestDef.cpp
index 5445e3be998..61f7694c724 100644
--- a/src/server/game/Quests/QuestDef.cpp
+++ b/src/server/game/Quests/QuestDef.cpp
@@ -22,6 +22,8 @@
#include "ObjectMgr.h"
#include "Opcodes.h"
+#include "Packets/QuestPackets.h"
+
Quest::Quest(Field* questRecord)
{
EmoteOnIncomplete = 0;
@@ -335,7 +337,7 @@ void Quest::InitializeQueryData()
WorldPacket Quest::BuildQueryData(LocaleConstant loc) const
{
- WorldPacket queryTemp(SMSG_QUEST_QUERY_RESPONSE, 2000);
+ WorldPackets::Quest::QueryQuestInfoResponse response;
std::string locQuestTitle = GetTitle();
std::string locQuestDetails = GetDetails();
@@ -359,110 +361,91 @@ WorldPacket Quest::BuildQueryData(LocaleConstant loc) const
ObjectMgr::GetLocaleString(localeData->ObjectiveText[i], loc, locQuestObjectiveText[i]);
}
- queryTemp << uint32(GetQuestId()); // quest id
- queryTemp << uint32(GetQuestMethod()); // Accepted values: 0, 1 or 2. 0 == IsAutoComplete() (skip objectives/details)
- queryTemp << uint32(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)
- queryTemp << uint32(GetMinLevel()); // min level
- queryTemp << uint32(GetZoneOrSort()); // zone or sort to display in quest log
-
- queryTemp << uint32(GetType()); // quest type
- queryTemp << uint32(GetSuggestedPlayers()); // suggested players count
-
- queryTemp << uint32(GetRepObjectiveFaction()); // shown in quest log as part of quest objective
- queryTemp << uint32(GetRepObjectiveValue()); // shown in quest log as part of quest objective
-
- queryTemp << uint32(GetRepObjectiveFaction2()); // shown in quest log as part of quest objective OPPOSITE faction
- queryTemp << uint32(GetRepObjectiveValue2()); // shown in quest log as part of quest objective OPPOSITE faction
-
- queryTemp << uint32(GetNextQuestInChain()); // client will request this quest from NPC, if not 0
- queryTemp << uint32(GetXPId()); // used for calculating rewarded experience
-
- if (HasFlag(QUEST_FLAGS_HIDDEN_REWARDS))
- queryTemp << uint32(0); // Hide money rewarded
- else
- queryTemp << uint32(GetRewOrReqMoney()); // reward money (below max lvl)
-
- queryTemp << uint32(GetRewMoneyMaxLevel()); // used in XP calculation at client
- queryTemp << uint32(GetRewSpell()); // reward spell, this spell will display (icon) (cast if RewSpellCast == 0)
- queryTemp << int32(GetRewSpellCast()); // cast spell
-
- // rewarded honor points
- queryTemp << uint32(GetRewHonorAddition());
- queryTemp << float(GetRewHonorMultiplier());
- queryTemp << uint32(GetSrcItemId()); // source item id
- queryTemp << uint32(GetFlags() & 0xFFFF); // quest flags
- queryTemp << uint32(GetCharTitleId()); // CharTitleId, new 2.4.0, player gets this title (id from CharTitles)
- queryTemp << uint32(GetPlayersSlain()); // players slain
- queryTemp << uint32(GetBonusTalents()); // bonus talents
- queryTemp << uint32(GetRewArenaPoints()); // bonus arena points
- queryTemp << uint32(0); // review rep show mask
-
- if (HasFlag(QUEST_FLAGS_HIDDEN_REWARDS))
+ response.Info.QuestID = GetQuestId();
+ response.Info.QuestMethod = GetQuestMethod();
+ response.Info.QuestLevel = GetQuestLevel();
+ response.Info.QuestMinLevel = GetMinLevel();
+ response.Info.QuestSortID = GetZoneOrSort();
+
+ response.Info.QuestType = 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.RewardTitleId = GetCharTitleId();
+ response.Info.RequiredPlayerKills = GetPlayersSlain();
+ response.Info.RewardTalents = GetBonusTalents();
+ response.Info.RewardArenaPoints = GetRewArenaPoints();
+
+ for (uint8 i = 0; i < QUEST_REWARDS_COUNT; ++i)
{
- for (uint8 i = 0; i < QUEST_REWARDS_COUNT; ++i)
- queryTemp << uint32(0) << uint32(0);
- for (uint8 i = 0; i < QUEST_REWARD_CHOICES_COUNT; ++i)
- queryTemp << uint32(0) << uint32(0);
+ response.Info.RewardItems[i] = RewardItemId[i];
+ response.Info.RewardAmount[i] = RewardItemIdCount[i];
}
- else
+
+ for (uint8 i = 0; i < QUEST_REWARD_CHOICES_COUNT; ++i)
{
- for (uint8 i = 0; i < QUEST_REWARDS_COUNT; ++i)
- {
- queryTemp << uint32(RewardItemId[i]);
- queryTemp << uint32(RewardItemIdCount[i]);
- }
- for (uint8 i = 0; i < QUEST_REWARD_CHOICES_COUNT; ++i)
- {
- queryTemp << uint32(RewardChoiceItemId[i]);
- queryTemp << uint32(RewardChoiceItemCount[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
- queryTemp << uint32(RewardFactionId[i]);
+ response.Info.RewardFactionID[i] = RewardFactionId[i];
for (uint8 i = 0; i < QUEST_REPUTATIONS_COUNT; ++i) // columnid+1 QuestFactionReward.dbc?
- queryTemp << int32(RewardFactionValueId[i]);
+ response.Info.RewardFactionValue[i] = RewardFactionValueId[i];
for (uint8 i = 0; i < QUEST_REPUTATIONS_COUNT; ++i) // unk (0)
- queryTemp << int32(RewardFactionValueIdOverride[i]);
+ response.Info.RewardFactionValueOverride[i] = RewardFactionValueIdOverride[i];
- queryTemp << uint32(GetPOIContinent());
- queryTemp << float(GetPOIx());
- queryTemp << float(GetPOIy());
- queryTemp << uint32(GetPointOpt());
+ 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());
- queryTemp << locQuestTitle;
- queryTemp << locQuestObjectives;
- queryTemp << locQuestDetails;
- queryTemp << locQuestAreaDescription;
- queryTemp << locQuestCompletedText; // display in quest objectives window once all objectives are completed
+ response.Info.Title = locQuestTitle;
+ response.Info.Objectives = locQuestObjectives;
+ response.Info.Details = locQuestDetails;
+ response.Info.AreaDescription = locQuestAreaDescription;
+ response.Info.CompletedText = locQuestCompletedText;
for (uint8 i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
{
- if (RequiredNpcOrGo[i] < 0)
- queryTemp << uint32((RequiredNpcOrGo[i] * (-1)) | 0x80000000); // client expects gameobject template id in form (id|0x80000000)
- else
- queryTemp << uint32(RequiredNpcOrGo[i]);
-
- queryTemp << uint32(RequiredNpcOrGoCount[i]);
- queryTemp << uint32(ItemDrop[i]);
- queryTemp << uint32(0); // req source count?
+ response.Info.RequiredNpcOrGo[i] = RequiredNpcOrGo[i];
+ response.Info.RequiredNpcOrGoCount[i] = RequiredNpcOrGoCount[i];
+ response.Info.ItemDrop[i] = ItemDrop[i];
}
for (uint8 i = 0; i < QUEST_ITEM_OBJECTIVES_COUNT; ++i)
{
- queryTemp << uint32(RequiredItemId[i]);
- queryTemp << uint32(RequiredItemCount[i]);
+ response.Info.RequiredItemId[i] = RequiredItemId[i];
+ response.Info.RequiredItemCount[i] = RequiredItemCount[i];
}
for (uint8 i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
- queryTemp << locQuestObjectiveText[i];
+ response.Info.ObjectiveText[i] = locQuestObjectiveText[i];
- return queryTemp;
+ return *response.Write();
}
void Quest::AddQuestLevelToTitle(std::string &title, int32 level)
diff --git a/src/server/game/Server/Packets/AllPackets.h b/src/server/game/Server/Packets/AllPackets.h
index ef92b2584ba..ed9f6807ec0 100644
--- a/src/server/game/Server/Packets/AllPackets.h
+++ b/src/server/game/Server/Packets/AllPackets.h
@@ -18,4 +18,7 @@
#ifndef AllPackets_h__
#define AllPackets_h__
+#include "QueryPackets.h"
+#include "QuestPackets.h"
+
#endif // AllPackets_h__
diff --git a/src/server/game/Server/Packets/QueryPackets.cpp b/src/server/game/Server/Packets/QueryPackets.cpp
new file mode 100644
index 00000000000..73c27c659da
--- /dev/null
+++ b/src/server/game/Server/Packets/QueryPackets.cpp
@@ -0,0 +1,209 @@
+/*
+ * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#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)
+ {
+ _worldPacket << Stats.Name;
+ _worldPacket << uint8(0) << uint8(0) << uint8(0); // name2, name3, name4, always empty
+ _worldPacket << Stats.NameAlt;
+ _worldPacket << Stats.CursorName; // "Directions" for guard, string for Icons 2.3.0
+ _worldPacket << uint32(Stats.Flags); // 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, MAX_KILL_CREDIT); // new in 3.1, kill credit
+ _worldPacket.append(Stats.CreatureDisplayID, MAX_CREATURE_MODELS); // Modelid
+ _worldPacket << float(Stats.HpMulti); // dmg/hp modifier
+ _worldPacket << float(Stats.EnergyMulti); // dmg/mana modifier
+ _worldPacket << uint8(Stats.Leader);
+ _worldPacket.append(Stats.QuestItems, MAX_CREATURE_QUEST_ITEMS);
+ _worldPacket << uint32(Stats.CreatureMovementInfoID); // CreatureMovementInfo.dbc
+ }
+
+ 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);
+ _worldPacket << Stats.Name;
+ _worldPacket << uint8(0) << uint8(0) << uint8(0); // name2, name3, name4
+ _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, MAX_GAMEOBJECT_DATA);
+ _worldPacket << float(Stats.Size); // go size
+ _worldPacket.append(Stats.QuestItems, MAX_GAMEOBJECT_QUEST_ITEMS);
+ }
+
+ return &_worldPacket;
+}
+
+void WorldPackets::Query::QueryItemSingle::Read()
+{
+ _worldPacket >> ItemID;
+}
+
+WorldPacket const* WorldPackets::Query::QueryItemSingleResponse::Write()
+{
+ _worldPacket << uint32(ItemID | (Allow ? 0x00000000 : 0x80000000));
+
+ if (Allow)
+ {
+ _worldPacket << Stats.Class;
+ _worldPacket << Stats.SubClass;
+ _worldPacket << Stats.SoundOverrideSubclass;
+ _worldPacket << Stats.Name;
+ _worldPacket << uint8(0x00); //Name2; // blizz not send name there, just uint8(0x00); <-- \0 = empty string = empty name...
+ _worldPacket << uint8(0x00); //Name3; // blizz not send name there, just uint8(0x00);
+ _worldPacket << uint8(0x00); //Name4; // blizz not send name there, just uint8(0x00);
+ _worldPacket << Stats.DisplayInfoID;
+ _worldPacket << Stats.Quality;
+ _worldPacket << Stats.Flags;
+ _worldPacket << Stats.Flags2;
+ _worldPacket << Stats.BuyPrice;
+ _worldPacket << Stats.SellPrice;
+ _worldPacket << Stats.InventoryType;
+ _worldPacket << Stats.AllowableClass;
+ _worldPacket << Stats.AllowableRace;
+ _worldPacket << Stats.ItemLevel;
+ _worldPacket << Stats.RequiredLevel;
+ _worldPacket << Stats.RequiredSkill;
+ _worldPacket << Stats.RequiredSkillRank;
+ _worldPacket << Stats.RequiredSpell;
+ _worldPacket << Stats.RequiredHonorRank;
+ _worldPacket << Stats.RequiredCityRank;
+ _worldPacket << Stats.RequiredReputationFaction;
+ _worldPacket << Stats.RequiredReputationRank;
+ _worldPacket << int32(Stats.MaxCount);
+ _worldPacket << int32(Stats.Stackable);
+ _worldPacket << Stats.ContainerSlots;
+ _worldPacket << Stats.StatsCount; // item stats count
+ for (uint32 i = 0; i < Stats.StatsCount; ++i)
+ {
+ _worldPacket << Stats.ItemStat[i].ItemStatType;
+ _worldPacket << Stats.ItemStat[i].ItemStatValue;
+ }
+ _worldPacket << Stats.ScalingStatDistribution; // scaling stats distribution
+ _worldPacket << Stats.ScalingStatValue; // some kind of flags used to determine stat values column
+ for (uint8 i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i)
+ {
+ _worldPacket << Stats.Damage[i].DamageMin;
+ _worldPacket << Stats.Damage[i].DamageMax;
+ _worldPacket << Stats.Damage[i].DamageType;
+ }
+
+ // resistances (7)
+ for (uint8 i = SPELL_SCHOOL_NORMAL; i < MAX_SPELL_SCHOOL; ++i)
+ _worldPacket << Stats.Resistance[i];
+
+ _worldPacket << Stats.Delay;
+ _worldPacket << Stats.AmmoType;
+ _worldPacket << Stats.RangedModRange;
+
+ for (uint8 s = 0; s < MAX_ITEM_PROTO_SPELLS; ++s)
+ {
+ // spells are validated on template loading
+ if (Stats.Spells[s].SpellId > 0)
+ {
+ _worldPacket << Stats.Spells[s].SpellId;
+ _worldPacket << Stats.Spells[s].SpellTrigger;
+ _worldPacket << uint32(-abs(Stats.Spells[s].SpellCharges));
+ _worldPacket << uint32(Stats.Spells[s].SpellCooldown);
+ _worldPacket << uint32(Stats.Spells[s].SpellCategory);
+ _worldPacket << uint32(Stats.Spells[s].SpellCategoryCooldown);
+ }
+ else
+ {
+ _worldPacket << uint32(0);
+ _worldPacket << uint32(0);
+ _worldPacket << uint32(0);
+ _worldPacket << uint32(-1);
+ _worldPacket << uint32(0);
+ _worldPacket << uint32(-1);
+ }
+ }
+ _worldPacket << Stats.Bonding;
+ _worldPacket << Stats.Description;
+ _worldPacket << Stats.PageText;
+ _worldPacket << Stats.LanguageID;
+ _worldPacket << Stats.PageMaterial;
+ _worldPacket << Stats.StartQuest;
+ _worldPacket << Stats.LockID;
+ _worldPacket << int32(Stats.Material);
+ _worldPacket << Stats.Sheath;
+ _worldPacket << Stats.RandomProperty;
+ _worldPacket << Stats.RandomSuffix;
+ _worldPacket << Stats.Block;
+ _worldPacket << Stats.ItemSet;
+ _worldPacket << Stats.MaxDurability;
+ _worldPacket << Stats.Area;
+ _worldPacket << Stats.Map; // Added in 1.12.x & 2.0.1 client branch
+ _worldPacket << Stats.BagFamily;
+ _worldPacket << Stats.TotemCategory;
+ for (uint8 s = 0; s < MAX_ITEM_PROTO_SOCKETS; ++s)
+ {
+ _worldPacket << Stats.Socket[s].Color;
+ _worldPacket << Stats.Socket[s].Content;
+ }
+ _worldPacket << Stats.SocketBonus;
+ _worldPacket << Stats.GemProperties;
+ _worldPacket << Stats.RequiredDisenchantSkill;
+ _worldPacket << Stats.ArmorDamageModifier;
+ _worldPacket << Stats.Duration; // added in 2.4.2.8209, duration (seconds)
+ _worldPacket << Stats.ItemLimitCategory; // WotLK, ItemLimitCategory
+ _worldPacket << Stats.HolidayId; // Holiday.dbc?
+ }
+
+ return &_worldPacket;
+}
+
+void WorldPackets::Query::QuestPOIQuery::Read()
+{
+ _worldPacket >> MissingQuestCount; // quest count, max=25
+
+ if (MissingQuestCount <= MAX_QUEST_LOG_SIZE)
+ {
+ for (uint8 i = 0; i < MissingQuestCount; ++i)
+ _worldPacket >> MissingQuestPOIs[i];
+ }
+
+ _worldPacket.rfinish();
+}
diff --git a/src/server/game/Server/Packets/QueryPackets.h b/src/server/game/Server/Packets/QueryPackets.h
new file mode 100644
index 00000000000..d7ec602f089
--- /dev/null
+++ b/src/server/game/Server/Packets/QueryPackets.h
@@ -0,0 +1,240 @@
+/*
+ * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef QueryPackets_h__
+#define QueryPackets_h__
+
+#include "Packet.h"
+#include "ObjectGuid.h"
+
+#include "SharedDefines.h"
+#include "Creature.h"
+#include "GameObject.h"
+#include "ItemTemplate.h"
+#include "QuestDef.h"
+
+namespace WorldPackets
+{
+ 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::string Name;
+ std::string NameAlt;
+ std::string CursorName;
+ uint32 Flags = 0;
+ uint32 CreatureType = 0;
+ uint32 CreatureFamily = 0;
+ uint32 Classification = 0;
+ uint32 ProxyCreatureID[MAX_KILL_CREDIT];
+ uint32 CreatureDisplayID[MAX_CREATURE_MODELS];
+ float HpMulti = 0.0f;
+ float EnergyMulti = 0.0f;
+ bool Leader = false;
+ uint32 QuestItems[MAX_CREATURE_QUEST_ITEMS];
+ uint32 CreatureMovementInfoID = 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::string Name;
+ std::string IconName;
+ std::string CastBarCaption;
+ std::string UnkString;
+ uint32 Type = 0;
+ uint32 DisplayID = 0;
+ uint32 Data[MAX_GAMEOBJECT_DATA];
+ float Size = 0.0f;
+ uint32 QuestItems[MAX_GAMEOBJECT_QUEST_ITEMS];
+ };
+
+ 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 QueryItemSingle final : public ClientPacket
+ {
+ public:
+ QueryItemSingle(WorldPacket&& packet) : ClientPacket(CMSG_ITEM_QUERY_SINGLE, std::move(packet)) { }
+
+ void Read() override;
+
+ uint32 ItemID = 0;
+ };
+
+ struct ItemDamageData
+ {
+ float DamageMin = 0.0f;
+ float DamageMax = 0.0f;
+ uint32 DamageType = 0;
+ };
+
+ struct ItemStatData
+ {
+ uint32 ItemStatType = 0;
+ int32 ItemStatValue = 0;
+ };
+
+ struct ItemSpellData
+ {
+ int32 SpellId = -1;
+ uint32 SpellTrigger = 0;
+ int32 SpellCharges = 0;
+ int32 SpellCooldown = -1;
+ uint32 SpellCategory = 0;
+ int32 SpellCategoryCooldown = -1;
+ };
+
+ struct ItemSocketData
+ {
+ uint32 Color = 0;
+ uint32 Content = 0;
+ };
+
+ struct ItemStats
+ {
+ uint32 Class = 0;
+ uint32 SubClass = 0;
+ int32 SoundOverrideSubclass = 0;
+ std::string Name;
+ uint32 DisplayInfoID = 0;
+ uint32 Quality = 0;
+ uint32 Flags = 0;
+ uint32 Flags2 = 0;
+ int32 BuyPrice = 0;
+ uint32 SellPrice = 0;
+ uint32 InventoryType = 0;
+ uint32 AllowableClass = 0;
+ uint32 AllowableRace = 0;
+ uint32 ItemLevel = 0;
+ uint32 RequiredLevel = 0;
+ uint32 RequiredSkill = 0;
+ uint32 RequiredSkillRank = 0;
+ uint32 RequiredSpell = 0;
+ uint32 RequiredHonorRank = 0;
+ uint32 RequiredCityRank = 0;
+ uint32 RequiredReputationFaction = 0;
+ uint32 RequiredReputationRank = 0;
+ int32 MaxCount = 0;
+ int32 Stackable = 0;
+ uint32 ContainerSlots = 0;
+ uint32 StatsCount = 0;
+ ItemStatData ItemStat[MAX_ITEM_PROTO_STATS];
+ uint32 ScalingStatDistribution = 0;
+ uint32 ScalingStatValue = 0;
+ ItemDamageData Damage[MAX_ITEM_PROTO_DAMAGES];
+ uint32 Resistance[MAX_SPELL_SCHOOL];
+ uint32 Delay = 0;
+ uint32 AmmoType = 0;
+ float RangedModRange = 0.0f;
+ ItemSpellData Spells[MAX_ITEM_PROTO_SPELLS];
+ uint32 Bonding = 0;
+ std::string Description;
+ uint32 PageText = 0;
+ uint32 LanguageID = 0;
+ uint32 PageMaterial = 0;
+ uint32 StartQuest = 0;
+ uint32 LockID = 0;
+ int32 Material = 0;
+ uint32 Sheath = 0;
+ int32 RandomProperty = 0;
+ int32 RandomSuffix = 0;
+ uint32 Block = 0;
+ uint32 ItemSet = 0;
+ uint32 MaxDurability = 0;
+ uint32 Area = 0;
+ uint32 Map = 0;
+ uint32 BagFamily = 0;
+ uint32 TotemCategory = 0;
+ ItemSocketData Socket[MAX_ITEM_PROTO_SOCKETS];
+ uint32 SocketBonus = 0;
+ uint32 GemProperties = 0;
+ uint32 RequiredDisenchantSkill = 0;
+ float ArmorDamageModifier = 0.0f;
+ uint32 Duration = 0;
+ uint32 ItemLimitCategory = 0;
+ uint32 HolidayId = 0;
+ };
+
+ class QueryItemSingleResponse final : public ServerPacket
+ {
+ public:
+ QueryItemSingleResponse() : ServerPacket(SMSG_ITEM_QUERY_SINGLE_RESPONSE, 500) { }
+
+ WorldPacket const* Write() override;
+
+ uint32 ItemID = 0;
+ bool Allow = false;
+ ItemStats Stats;
+ };
+
+ class QuestPOIQuery final : public ClientPacket
+ {
+ public:
+ QuestPOIQuery(WorldPacket&& packet) : ClientPacket(CMSG_QUEST_POI_QUERY, std::move(packet)) { }
+
+ void Read() override;
+
+ uint32 MissingQuestCount = 0;
+ uint32 MissingQuestPOIs[MAX_QUEST_LOG_SIZE] = { };
+ };
+ }
+}
+
+#endif // QueryPackets_h__
diff --git a/src/server/game/Server/Packets/QuestPackets.cpp b/src/server/game/Server/Packets/QuestPackets.cpp
new file mode 100644
index 00000000000..68e28ca80ab
--- /dev/null
+++ b/src/server/game/Server/Packets/QuestPackets.cpp
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "QuestPackets.h"
+
+void WorldPackets::Quest::QueryQuestInfo::Read()
+{
+ _worldPacket >> QuestID;
+}
+
+WorldPacket const* WorldPackets::Quest::QueryQuestInfoResponse::Write()
+{
+ _worldPacket << uint32(Info.QuestID);
+ _worldPacket << uint32(Info.QuestMethod);
+ _worldPacket << uint32(Info.QuestLevel);
+ _worldPacket << uint32(Info.QuestMinLevel);
+ _worldPacket << uint32(Info.QuestSortID);
+
+ _worldPacket << uint32(Info.QuestType);
+ _worldPacket << uint32(Info.SuggestedGroupNum);
+
+ for (uint8 i = 0; i < BG_TEAMS_COUNT; ++i)
+ {
+ _worldPacket << uint32(Info.RequiredFactionId[i]);
+ _worldPacket << uint32(Info.RequiredFactionValue[i]);
+ }
+
+ _worldPacket << uint32(Info.RewardNextQuest);
+ _worldPacket << uint32(Info.RewardXPDifficulty);
+
+ if ((Info.Flags & QUEST_FLAGS_HIDDEN_REWARDS) != 0)
+ _worldPacket << uint32(0);
+ else
+ _worldPacket << uint32(Info.RewardMoney);
+
+ _worldPacket << uint32(Info.RewardBonusMoney);
+ _worldPacket << uint32(Info.RewardDisplaySpell);
+ _worldPacket << int32(Info.RewardSpell);
+
+ _worldPacket << uint32(Info.RewardHonor);
+ _worldPacket << float(Info.RewardKillHonor);
+ _worldPacket << uint32(Info.StartItem);
+ _worldPacket << uint32(Info.Flags & 0xFFFF);
+ _worldPacket << uint32(Info.RewardTitleId);
+ _worldPacket << uint32(Info.RequiredPlayerKills);
+ _worldPacket << uint32(Info.RewardTalents);
+ _worldPacket << uint32(Info.RewardArenaPoints);
+ _worldPacket << uint32(0); // review rep show mask
+
+ if ((Info.Flags & QUEST_FLAGS_HIDDEN_REWARDS) != 0)
+ {
+ for (uint8 i = 0; i < QUEST_REWARDS_COUNT; ++i)
+ _worldPacket << uint32(0) << uint32(0);
+ for (uint8 i = 0; i < QUEST_REWARD_CHOICES_COUNT; ++i)
+ _worldPacket << uint32(0) << uint32(0);
+ }
+ else
+ {
+ for (uint8 i = 0; i < QUEST_REWARDS_COUNT; ++i)
+ {
+ _worldPacket << uint32(Info.RewardItems[i]);
+ _worldPacket << uint32(Info.RewardAmount[i]);
+ }
+ for (uint8 i = 0; i < QUEST_REWARD_CHOICES_COUNT; ++i)
+ {
+ _worldPacket << uint32(Info.UnfilteredChoiceItems[i].ItemID);
+ _worldPacket << uint32(Info.UnfilteredChoiceItems[i].Quantity);
+ }
+ }
+
+ for (uint8 i = 0; i < QUEST_REPUTATIONS_COUNT; ++i) // reward factions ids
+ _worldPacket << uint32(Info.RewardFactionID[i]);
+
+ for (uint8 i = 0; i < QUEST_REPUTATIONS_COUNT; ++i) // columnid+1 QuestFactionReward.dbc?
+ _worldPacket << int32(Info.RewardFactionValue[i]);
+
+ for (uint8 i = 0; i < QUEST_REPUTATIONS_COUNT; ++i) // unk (0)
+ _worldPacket << int32(Info.RewardFactionValueOverride[i]);
+
+ _worldPacket << uint32(Info.POIContinent);
+ _worldPacket << float(Info.POIx);
+ _worldPacket << float(Info.POIy);
+ _worldPacket << uint32(Info.POIPriority);
+
+ _worldPacket << Info.Title;
+ _worldPacket << Info.Objectives;
+ _worldPacket << Info.Details;
+ _worldPacket << Info.AreaDescription;
+ _worldPacket << Info.CompletedText;
+
+ 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 << uint32(Info.ItemDrop[i]);
+ _worldPacket << uint32(0); // req source count?
+ }
+
+ for (uint8 i = 0; i < QUEST_ITEM_OBJECTIVES_COUNT; ++i)
+ {
+ _worldPacket << uint32(Info.RequiredItemId[i]);
+ _worldPacket << uint32(Info.RequiredItemCount[i]);
+ }
+
+ for (uint8 i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
+ _worldPacket << Info.ObjectiveText[i];
+
+ return &_worldPacket;
+}
diff --git a/src/server/game/Server/Packets/QuestPackets.h b/src/server/game/Server/Packets/QuestPackets.h
new file mode 100644
index 00000000000..4d6e2121736
--- /dev/null
+++ b/src/server/game/Server/Packets/QuestPackets.h
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef QuestPackets_h__
+#define QuestPackets_h__
+
+#include "Packet.h"
+#include "QuestDef.h"
+
+namespace WorldPackets
+{
+ namespace Quest
+ {
+ class QueryQuestInfo final : public ClientPacket
+ {
+ public:
+ QueryQuestInfo(WorldPacket&& packet) : ClientPacket(CMSG_QUEST_QUERY, std::move(packet)) { }
+
+ void Read() override;
+
+ uint32 QuestID = 0;
+ };
+
+ struct QuestInfoChoiceItem
+ {
+ uint32 ItemID = 0;
+ uint32 Quantity = 0;
+ };
+
+ struct QuestInfo
+ {
+ uint32 QuestID = 0;
+ uint32 QuestMethod = 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)
+ uint32 QuestMinLevel = 0;
+ int32 QuestSortID = 0; // zone or sort to display in quest log
+ uint32 QuestType = 0;
+ uint32 SuggestedGroupNum = 0;
+ int32 AllowableRaces = -1;
+
+ uint32 RequiredFactionId[BG_TEAMS_COUNT] = { }; // shown in quest log as part of quest objective (same/opposite faction)
+ int32 RequiredFactionValue[BG_TEAMS_COUNT] = { }; // shown in quest log as part of quest objective (same/opposite faction)
+
+ uint32 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
+ uint32 RewardDisplaySpell = 0; // reward spell, this spell will be displayed (icon) (cast if RewSpellCast == 0)
+ int32 RewardSpell = 0;
+ uint32 RewardHonor = 0;
+ float RewardKillHonor = 0.0f;
+ uint32 StartItem = 0;
+ uint32 Flags = 0;
+ uint32 RewardTitleId = 0; // new 2.4.0, player gets this title (id from CharTitles)
+ uint32 RequiredPlayerKills = 0;
+ uint32 RewardTalents = 0;
+ int32 RewardArenaPoints = 0;
+
+ uint32 RewardItems[QUEST_REWARDS_COUNT] = { };
+ uint32 RewardAmount[QUEST_REWARDS_COUNT] = { };
+ QuestInfoChoiceItem UnfilteredChoiceItems[QUEST_REWARD_CHOICES_COUNT];
+ uint32 RewardFactionID[QUEST_REPUTATIONS_COUNT] = { };
+ int32 RewardFactionValue[QUEST_REPUTATIONS_COUNT] = { };
+ int32 RewardFactionValueOverride[QUEST_REPUTATIONS_COUNT] = { };
+
+ uint32 POIContinent = 0;
+ float POIx = 0.0f;
+ float POIy = 0.0f;
+ uint32 POIPriority = 0;
+ std::string Title;
+ std::string Objectives;
+ std::string Details;
+ std::string AreaDescription;
+ std::string CompletedText; // display in quest objectives window once all objectives are completed
+
+ int32 RequiredNpcOrGo[QUEST_OBJECTIVES_COUNT] = { }; // >0 Creature <0 Gameobject
+ uint32 RequiredNpcOrGoCount[QUEST_OBJECTIVES_COUNT] = { };
+
+ uint32 ItemDrop[QUEST_SOURCE_ITEM_IDS_COUNT] = { };
+ // uint32 ItemDropQuantity[QUEST_SOURCE_ITEM_IDS_COUNT] = { };
+
+ uint32 RequiredItemId[QUEST_ITEM_OBJECTIVES_COUNT] = { };
+ uint32 RequiredItemCount[QUEST_ITEM_OBJECTIVES_COUNT] = { };
+
+ std::string ObjectiveText[QUEST_OBJECTIVES_COUNT];
+ };
+
+ class QueryQuestInfoResponse final : public ServerPacket
+ {
+ public:
+ QueryQuestInfoResponse() : ServerPacket(SMSG_QUEST_QUERY_RESPONSE, 2000) { }
+
+ WorldPacket const* Write() override;
+
+ QuestInfo Info;
+ };
+ }
+}
+
+#endif // QuestPackets_h__
diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h
index 1e66e832a04..e5ae690246f 100644
--- a/src/server/game/Server/WorldSession.h
+++ b/src/server/game/Server/WorldSession.h
@@ -71,7 +71,19 @@ class RBACData;
namespace WorldPackets
{
+ namespace Query
+ {
+ class QueryCreature;
+ class QueryGameObject;
+ class QueryItemSingle;
+ class QuestPOIQuery;
+ }
+ namespace Quest
+ {
+ class QueryQuestInfo;
+ }
}
+
enum AccountDataType
{
GLOBAL_CONFIG_CACHE = 0, // 0x01 g
@@ -570,9 +582,9 @@ class TC_GAME_API WorldSession
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 HandleMoveWorldportAck(); // for server-side calls
@@ -710,7 +722,7 @@ class TC_GAME_API WorldSession
void HandleSwapInvItemOpcode(WorldPacket& recvPacket);
void HandleDestroyItemOpcode(WorldPacket& recvPacket);
void HandleAutoEquipItemOpcode(WorldPacket& recvPacket);
- void HandleItemQuerySingleOpcode(WorldPacket& recvPacket);
+ void HandleItemQuerySingleOpcode(WorldPackets::Query::QueryItemSingle& query);
void HandleSellItemOpcode(WorldPacket& recvPacket);
void HandleBuyItemInSlotOpcode(WorldPacket& recvPacket);
void HandleBuyItemOpcode(WorldPacket& recvPacket);
@@ -749,7 +761,7 @@ class TC_GAME_API WorldSession
void HandleQuestgiverQueryQuestOpcode(WorldPacket& recvPacket);
void HandleQuestgiverChooseRewardOpcode(WorldPacket& recvPacket);
void HandleQuestgiverRequestRewardOpcode(WorldPacket& recvPacket);
- void HandleQuestQueryOpcode(WorldPacket& recvPacket);
+ void HandleQuestQueryOpcode(WorldPackets::Quest::QueryQuestInfo& query);
void HandleQuestgiverCancel(WorldPacket& recvData);
void HandleQuestLogSwapQuest(WorldPacket& recvData);
void HandleQuestLogRemoveQuest(WorldPacket& recvData);
@@ -970,7 +982,7 @@ class TC_GAME_API WorldSession
void HandleWorldStateUITimerUpdate(WorldPacket& recvData);
void HandleReadyForAccountDataTimes(WorldPacket& recvData);
void HandleQueryQuestsCompleted(WorldPacket& recvData);
- void HandleQuestPOIQuery(WorldPacket& recvData);
+ void HandleQuestPOIQuery(WorldPackets::Query::QuestPOIQuery& query);
void HandleEjectPassenger(WorldPacket& data);
void HandleEnterPlayerVehicle(WorldPacket& data);
void HandleUpdateProjectilePosition(WorldPacket& recvPacket);