Core/Quests: converted SMSG_QUEST_POI_QUERY_RESPONSE to packet class and ported quest poi data for all quests from classic
This commit is contained in:
1 parent
faef256861
commit
3e73122965
6 files changed
+122169
-146
No files matched your search
File diff suppressed because it is too large.
Load diff
@@ -7770,12 +7770,8 @@ void ObjectMgr::LoadQuestPOI()
|
||||
|
||||
_questPOIStore.clear(); // need for reload case
|
||||
|
||||
uint32 count = 0;
|
||||
|
||||
// 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");
|
||||
// 0 1 2 3 4 5 6 7 8
|
||||
QueryResult result = WorldDatabase.Query("SELECT QuestID, BlobIndex, Idx1, ObjectiveIndex, MapID, WorldMapAreaID, Floor, Priority, Flags FROM quest_poi ORDER BY QuestID, Idx1");
|
||||
if (!result)
|
||||
{
|
||||
TC_LOG_ERROR("server.loading", ">> Loaded 0 quest POI definitions. DB table `quest_poi` is empty.");
|
||||
@@ -7783,83 +7779,60 @@ 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");
|
||||
QueryResult pointsResult = WorldDatabase.Query("SELECT QuestID, Idx1, X, Y FROM quest_poi_points ORDER BY QuestID DESC, Idx1, Idx2");
|
||||
|
||||
std::vector<std::vector<std::vector<QuestPOIBlobPoint>>> POIs;
|
||||
std::unordered_map<int32, std::map<int32, std::vector<QuestPOIBlobPoint>>> allPoints;
|
||||
|
||||
if (points)
|
||||
|
||||
if (pointsResult)
|
||||
{
|
||||
// The first result should have the highest questId
|
||||
Field* fields = points->Fetch();
|
||||
uint32 questIdMax = fields[0].GetUInt32();
|
||||
POIs.resize(questIdMax + 1);
|
||||
|
||||
do
|
||||
{
|
||||
fields = points->Fetch();
|
||||
Field* fields = pointsResult->Fetch();
|
||||
|
||||
uint32 questId = fields[0].GetUInt32();
|
||||
uint32 id = fields[1].GetUInt32();
|
||||
int32 QuestID = fields[0].GetInt32();
|
||||
int32 Idx1 = fields[1].GetInt32();
|
||||
int32 x = fields[2].GetInt32();
|
||||
int32 y = fields[3].GetInt32();
|
||||
|
||||
if (POIs[questId].size() <= id + 1) POIs[questId].resize(id + 10);
|
||||
|
||||
QuestPOIBlobPoint point;
|
||||
point.X = x;
|
||||
point.Y = y;
|
||||
|
||||
POIs[questId][id].push_back(point);
|
||||
} while (points->NextRow());
|
||||
allPoints[QuestID][Idx1].emplace_back(x, y);
|
||||
} while (pointsResult->NextRow());
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
Field* fields = result->Fetch();
|
||||
|
||||
uint32 questId = fields[0].GetUInt32();
|
||||
uint32 id = fields[1].GetUInt32();
|
||||
int32 objIndex = fields[2].GetInt32();
|
||||
uint32 mapId = fields[3].GetUInt32();
|
||||
uint32 WorldMapAreaId = fields[4].GetUInt32();
|
||||
uint32 FloorId = fields[5].GetUInt32();
|
||||
uint32 Priority = fields[6].GetUInt32();
|
||||
uint32 Flags = fields[7].GetUInt32();
|
||||
int32 questID = fields[0].GetInt32();
|
||||
int32 blobIndex = fields[1].GetInt32();
|
||||
int32 idx1 = fields[2].GetInt32();
|
||||
int32 objectiveIndex = fields[3].GetInt32();
|
||||
int32 mapID = fields[4].GetInt32();
|
||||
int32 worldMapAreaID = fields[5].GetInt32();
|
||||
int32 floor = fields[6].GetInt32();
|
||||
int32 priority = fields[7].GetInt32();
|
||||
int32 flags = fields[8].GetInt32();
|
||||
|
||||
QuestPOIBlobData POI;
|
||||
POI.BlobIndex = id;
|
||||
POI.ObjectiveIndex = objIndex;
|
||||
POI.MapID = mapId;
|
||||
POI.WorldMapAreaID = WorldMapAreaId;
|
||||
POI.Floor = FloorId;
|
||||
POI.Priority = Priority;
|
||||
POI.Flags = Flags;
|
||||
if (!GetQuestTemplate(questID))
|
||||
TC_LOG_ERROR("sql.sql", "`quest_poi` quest id (%i) Idx1 (%i) does not exist in `quest_template`", questID, idx1);
|
||||
|
||||
if (questId < POIs.size() && id < POIs[questId].size())
|
||||
if (std::map<int32, std::vector<QuestPOIBlobPoint>>* blobs = Trinity::Containers::MapGetValuePtr(allPoints, questID))
|
||||
{
|
||||
POI.QuestPOIBlobPointStats = POIs[questId][id];
|
||||
auto itr = _questPOIStore.find(questId);
|
||||
if (itr == _questPOIStore.end())
|
||||
{
|
||||
QuestPOIWrapper wrapper;
|
||||
QuestPOIData data;
|
||||
data.QuestID = questId;
|
||||
wrapper.POIData = data;
|
||||
QuestPOIData& poiData = _questPOIStore[questID];
|
||||
poiData.QuestID = questID;
|
||||
|
||||
_questPOIStore.emplace(questId, std::move(wrapper));
|
||||
}
|
||||
|
||||
_questPOIStore.at(questId).POIData.QuestPOIBlobDataStats.push_back(POI);
|
||||
}
|
||||
if (std::vector<QuestPOIBlobPoint>* points = Trinity::Containers::MapGetValuePtr(*blobs, idx1))
|
||||
poiData.Blobs.emplace_back(blobIndex, objectiveIndex, mapID, worldMapAreaID, floor, priority, flags, std::move(*points));
|
||||
else
|
||||
TC_LOG_ERROR("sql.sql", "Table quest_poi references unknown quest points for quest %u POI id %u", questId,
|
||||
id);
|
||||
{
|
||||
// Some POIs can reference empty blobs according to sniff data
|
||||
poiData.Blobs.emplace_back(blobIndex, objectiveIndex, mapID, worldMapAreaID, floor, priority, flags, std::move(std::vector<QuestPOIBlobPoint>()));
|
||||
}
|
||||
}
|
||||
|
||||
++count;
|
||||
} while (result->NextRow());
|
||||
|
||||
TC_LOG_INFO("server.loading", ">> Loaded %u quest POI definitions in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
|
||||
TC_LOG_INFO("server.loading", ">> Loaded %u quest POI definitions in %u ms", uint32(_questPOIStore.size()), GetMSTimeDiffToNow(oldMSTime));
|
||||
}
|
||||
|
||||
void ObjectMgr::LoadQuestMoneyRewards()
|
||||
@@ -10013,6 +9986,11 @@ CreatureTemplate const* ObjectMgr::GetCreatureTemplate(uint32 entry) const
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QuestPOIData const* ObjectMgr::GetQuestPOIData(int32 questId)
|
||||
{
|
||||
return Trinity::Containers::MapGetValuePtr(_questPOIStore, questId);
|
||||
}
|
||||
|
||||
VehicleAccessoryList const* ObjectMgr::GetVehicleAccessoryList(Vehicle* veh) const
|
||||
{
|
||||
if (Creature* cre = veh->GetBase()->ToCreature())
|
||||
@@ -10416,36 +10394,10 @@ void ObjectMgr::InitializeQueriesData(QueryDataGroup mask)
|
||||
TC_LOG_INFO("server.loading", ">> Initialized query cache data in %u ms", GetMSTimeDiffToNow(oldMSTime));
|
||||
}
|
||||
|
||||
void QuestPOIWrapper::InitializeQueryData()
|
||||
void QuestPOIData::InitializeQueryData()
|
||||
{
|
||||
QueryDataBuffer = BuildQueryData();
|
||||
}
|
||||
|
||||
ByteBuffer QuestPOIWrapper::BuildQueryData() const
|
||||
{
|
||||
ByteBuffer tempBuffer;
|
||||
tempBuffer << uint32(POIData.QuestID); // quest ID
|
||||
tempBuffer << uint32(POIData.QuestPOIBlobDataStats.size()); // POI count
|
||||
|
||||
for (QuestPOIBlobData const& questPOIBlobData : POIData.QuestPOIBlobDataStats)
|
||||
{
|
||||
tempBuffer << uint32(questPOIBlobData.BlobIndex); // POI index
|
||||
tempBuffer << int32(questPOIBlobData.ObjectiveIndex); // objective index
|
||||
tempBuffer << uint32(questPOIBlobData.MapID); // mapid
|
||||
tempBuffer << uint32(questPOIBlobData.WorldMapAreaID); // areaid
|
||||
tempBuffer << uint32(questPOIBlobData.Floor); // floorid
|
||||
tempBuffer << uint32(questPOIBlobData.Priority); // priority
|
||||
tempBuffer << uint32(questPOIBlobData.Flags); // flags
|
||||
tempBuffer << uint32(questPOIBlobData.QuestPOIBlobPointStats.size()); // POI points count
|
||||
|
||||
for (QuestPOIBlobPoint const& questPOIBlobPoint : questPOIBlobData.QuestPOIBlobPointStats)
|
||||
{
|
||||
tempBuffer << int32(questPOIBlobPoint.X); // POI point x
|
||||
tempBuffer << int32(questPOIBlobPoint.Y); // POI point y
|
||||
}
|
||||
}
|
||||
|
||||
return tempBuffer;
|
||||
QueryDataBuffer << *this;
|
||||
QueryDataBuffer.shrink_to_fit();
|
||||
}
|
||||
|
||||
void ObjectMgr::LoadSummonPropertiesParameters()
|
||||
|
||||
@@ -816,40 +816,40 @@ typedef std::pair<GossipMenuItemsContainer::iterator, GossipMenuItemsContainer::
|
||||
|
||||
struct QuestPOIBlobPoint
|
||||
{
|
||||
int32 X = 0;
|
||||
int32 Y = 0;
|
||||
int32 X;
|
||||
int32 Y;
|
||||
|
||||
QuestPOIBlobPoint() : X(0), Y(0) { }
|
||||
QuestPOIBlobPoint(int32 x, int32 y) : X(x), Y(y) { }
|
||||
};
|
||||
|
||||
struct QuestPOIBlobData
|
||||
{
|
||||
uint32 BlobIndex = 0;
|
||||
int32 ObjectiveIndex = 0;
|
||||
uint32 MapID = 0;
|
||||
uint32 WorldMapAreaID = 0;
|
||||
uint32 Floor = 0;
|
||||
uint32 Priority = 0;
|
||||
uint32 Flags = 0;
|
||||
std::vector<QuestPOIBlobPoint> QuestPOIBlobPointStats;
|
||||
int32 BlobIndex;
|
||||
int32 ObjectiveIndex;
|
||||
int32 MapID;
|
||||
int32 WorldMapAreaID;
|
||||
int32 Floor;
|
||||
int32 Priority;
|
||||
int32 Flags;
|
||||
std::vector<QuestPOIBlobPoint> Points;
|
||||
|
||||
QuestPOIBlobData():
|
||||
BlobIndex(0), ObjectiveIndex(0), MapID(0), WorldMapAreaID(0), Floor(0), Priority(0), Flags(0) { }
|
||||
QuestPOIBlobData(int32 blobIndex, int32 objectiveIndex, int32 mapId, int32 worldMapAreaId, int32 floor, int32 priority, int32 flags, std::vector<QuestPOIBlobPoint> points) :
|
||||
BlobIndex(blobIndex), ObjectiveIndex(objectiveIndex), MapID(mapId), WorldMapAreaID(worldMapAreaId), Floor(floor), Priority(priority), Flags(flags), Points(std::move(points)) { }
|
||||
};
|
||||
|
||||
struct QuestPOIData
|
||||
{
|
||||
uint32 QuestID = 0;
|
||||
std::vector<QuestPOIBlobData> QuestPOIBlobDataStats;
|
||||
};
|
||||
|
||||
struct QuestPOIWrapper
|
||||
{
|
||||
QuestPOIData POIData;
|
||||
ByteBuffer QueryDataBuffer;
|
||||
std::vector<QuestPOIBlobData> Blobs;
|
||||
|
||||
void InitializeQueryData();
|
||||
ByteBuffer BuildQueryData() const;
|
||||
|
||||
QuestPOIWrapper() : QueryDataBuffer(0) { }
|
||||
ByteBuffer QueryDataBuffer;
|
||||
};
|
||||
|
||||
typedef std::unordered_map<uint32, QuestPOIWrapper> QuestPOIContainer;
|
||||
typedef std::unordered_map<uint32, QuestPOIData> QuestPOIContainer;
|
||||
|
||||
struct QuestGreeting
|
||||
{
|
||||
@@ -1130,13 +1130,7 @@ class TC_GAME_API ObjectMgr
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QuestPOIWrapper const* GetQuestPOIWrapper(uint32 questId)
|
||||
{
|
||||
QuestPOIContainer::const_iterator itr = _questPOIStore.find(questId);
|
||||
if (itr != _questPOIStore.end())
|
||||
return &itr->second;
|
||||
return nullptr;
|
||||
}
|
||||
QuestPOIData const* GetQuestPOIData(int32 questId);
|
||||
|
||||
VehicleAccessoryList const* GetVehicleAccessoryList(Vehicle* veh) const;
|
||||
|
||||
|
||||
@@ -363,37 +363,13 @@ void WorldSession::HandleQuestPOIQuery(WorldPackets::Query::QuestPOIQuery& query
|
||||
for (uint32 i = 0; i < query.MissingQuestCount; ++i)
|
||||
questIds.insert(query.MissingQuestPOIs[i]); // quest id
|
||||
|
||||
WorldPacket data(SMSG_QUEST_POI_QUERY_RESPONSE, 4 + (4 + 4 + 40) * questIds.size());
|
||||
data << uint32(questIds.size()); // count
|
||||
WorldPackets::Query::QuestPOIQueryResponse response;
|
||||
for (uint32 questId : questIds)
|
||||
{
|
||||
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();
|
||||
data.append(POIByteBuffer);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
data << uint32(questId); // quest ID
|
||||
data << uint32(0); // POI count
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
data << uint32(questId); // quest ID
|
||||
data << uint32(0); // POI count
|
||||
}
|
||||
}
|
||||
if (_player->FindQuestSlot(questId) != MAX_QUEST_LOG_SIZE)
|
||||
if (QuestPOIData const* poiData = sObjectMgr->GetQuestPOIData(questId))
|
||||
response.QuestPOIDataStats.push_back(poiData);
|
||||
|
||||
SendPacket(&data);
|
||||
SendPacket(response.Write());
|
||||
}
|
||||
|
||||
void WorldSession::HandleDBQueryBulk(WorldPackets::Query::DBQueryBulk& packet)
|
||||
|
||||
@@ -16,8 +16,36 @@
|
||||
*/
|
||||
|
||||
#include "CharacterCache.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "Player.h"
|
||||
#include "QueryPackets.h"
|
||||
#include "World.h"
|
||||
|
||||
ByteBuffer& operator<<(ByteBuffer& data, QuestPOIData const& questPOIData)
|
||||
{
|
||||
data << int32(questPOIData.QuestID);
|
||||
data << int32(questPOIData.Blobs.size());
|
||||
|
||||
for (QuestPOIBlobData const& questPOIBlobData : questPOIData.Blobs)
|
||||
{
|
||||
data << int32(questPOIBlobData.BlobIndex);
|
||||
data << int32(questPOIBlobData.ObjectiveIndex);
|
||||
data << int32(questPOIBlobData.MapID);
|
||||
data << int32(questPOIBlobData.WorldMapAreaID);
|
||||
data << int32(questPOIBlobData.Floor);
|
||||
data << int32(questPOIBlobData.Priority);
|
||||
data << int32(questPOIBlobData.Flags);
|
||||
data << int32(questPOIBlobData.Points.size());
|
||||
|
||||
for (QuestPOIBlobPoint const& questPOIBlobPoint : questPOIBlobData.Points)
|
||||
{
|
||||
data << int32(questPOIBlobPoint.X);
|
||||
data << int32(questPOIBlobPoint.Y);
|
||||
}
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void WorldPackets::Query::QueryCreature::Read()
|
||||
{
|
||||
@@ -101,6 +129,23 @@ void WorldPackets::Query::QuestPOIQuery::Read()
|
||||
_worldPacket.rfinish();
|
||||
}
|
||||
|
||||
WorldPacket const* WorldPackets::Query::QuestPOIQueryResponse::Write()
|
||||
{
|
||||
_worldPacket << int32(QuestPOIDataStats.size());
|
||||
|
||||
bool useCache = sWorld->getBoolConfig(CONFIG_CACHE_DATA_QUERIES);
|
||||
|
||||
for (QuestPOIData const* questPOIData : QuestPOIDataStats)
|
||||
{
|
||||
if (useCache)
|
||||
_worldPacket.append(questPOIData->QueryDataBuffer);
|
||||
else
|
||||
_worldPacket << *questPOIData;
|
||||
}
|
||||
|
||||
return &_worldPacket;
|
||||
}
|
||||
|
||||
void WorldPackets::Query::DBQueryBulk::Read()
|
||||
{
|
||||
_worldPacket >> TableHash;
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "SharedDefines.h"
|
||||
|
||||
class Player;
|
||||
struct QuestPOIData;
|
||||
|
||||
namespace WorldPackets
|
||||
{
|
||||
@@ -124,6 +125,16 @@ namespace WorldPackets
|
||||
std::array<uint32, MAX_QUEST_LOG_SIZE> MissingQuestPOIs = {};
|
||||
};
|
||||
|
||||
class QuestPOIQueryResponse final : public ServerPacket
|
||||
{
|
||||
public:
|
||||
explicit QuestPOIQueryResponse() : ServerPacket(SMSG_QUEST_POI_QUERY_RESPONSE, 4 + 4) { }
|
||||
|
||||
WorldPacket const* Write() override;
|
||||
|
||||
std::vector<QuestPOIData const*> QuestPOIDataStats;
|
||||
};
|
||||
|
||||
struct DBQueryRecord
|
||||
{
|
||||
ObjectGuid GUID;
|
||||
@@ -191,4 +202,6 @@ namespace WorldPackets
|
||||
}
|
||||
}
|
||||
|
||||
ByteBuffer& operator<<(ByteBuffer& data, QuestPOIData const& questPOIData);
|
||||
|
||||
#endif // QueryPackets_h__
|
||||
Reference in new issue
Block a user