diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/Entities/Creature/Creature.cpp | 62 | ||||
-rw-r--r-- | src/server/game/Entities/GameObject/GameObject.cpp | 47 | ||||
-rw-r--r-- | src/server/game/Entities/Item/ItemTemplate.cpp | 189 | ||||
-rw-r--r-- | src/server/game/Globals/ObjectMgr.cpp | 72 | ||||
-rw-r--r-- | src/server/game/Globals/ObjectMgr.h | 42 | ||||
-rw-r--r-- | src/server/game/Handlers/ItemHandler.cpp | 25 | ||||
-rw-r--r-- | src/server/game/Handlers/QueryHandler.cpp | 85 | ||||
-rw-r--r-- | src/server/game/Handlers/QuestHandler.cpp | 10 | ||||
-rw-r--r-- | src/server/game/Quests/QuestDef.cpp | 141 | ||||
-rw-r--r-- | src/server/game/Server/Packets/AllPackets.h | 3 | ||||
-rw-r--r-- | src/server/game/Server/Packets/QueryPackets.cpp | 209 | ||||
-rw-r--r-- | src/server/game/Server/Packets/QueryPackets.h | 240 | ||||
-rw-r--r-- | src/server/game/Server/Packets/QuestPackets.cpp | 128 | ||||
-rw-r--r-- | src/server/game/Server/Packets/QuestPackets.h | 114 | ||||
-rw-r--r-- | src/server/game/Server/WorldSession.h | 22 |
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); |