From b09ee8e5712102de2235dd5b2224e4184f2c208c Mon Sep 17 00:00:00 2001 From: tomrus88 Date: Sat, 14 Nov 2009 19:56:01 +0300 Subject: [PATCH] - Implemented quest POI's. May be not perfect, but it works :P --- sql/330/2_quest_poi.sql | 43 ++++++++++++++++++++++++++ src/game/ObjectMgr.cpp | 59 ++++++++++++++++++++++++++++++++++++ src/game/ObjectMgr.h | 34 +++++++++++++++++++++ src/game/QueryHandler.cpp | 63 +++++++++++++++++++++++++++++++++++++-- src/game/World.cpp | 3 ++ 5 files changed, 199 insertions(+), 3 deletions(-) create mode 100644 sql/330/2_quest_poi.sql diff --git a/sql/330/2_quest_poi.sql b/sql/330/2_quest_poi.sql new file mode 100644 index 000000000..03e3360eb --- /dev/null +++ b/sql/330/2_quest_poi.sql @@ -0,0 +1,43 @@ +DROP TABLE IF EXIST `quest_poi`; +CREATE TABLE `quest_poi` ( + `questid` int(11) unsigned NOT NULL DEFAULT '0', + `objIndex` int(11) NOT NULL DEFAULT '0', + `mapId` int(11) unsigned NOT NULL DEFAULT '0', + `unk1` int(11) unsigned NOT NULL DEFAULT '0', + PRIMARY KEY (`questid`,`objIndex`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +DROP TABLE IF EXIST `quest_poi_points`; +CREATE TABLE `quest_poi_points` ( + `questId` int(11) unsigned NOT NULL DEFAULT '0', + `objIndex` int(11) NOT NULL DEFAULT '0', + `x` int(11) NOT NULL DEFAULT '0', + `y` int(11) NOT NULL DEFAULT '0', + KEY `idx` (`questId`,`objIndex`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- Sample data for quest 456 +INSERT INTO quest_poi VALUES (456, 0, 1, 0); +INSERT INTO quest_poi VALUES (456, 1, 1, 0); +INSERT INTO quest_poi VALUES (456, -1, 1, 0); + +INSERT INTO quest_poi_points VALUES (456, 0, 0x28CF, 0x0217); +INSERT INTO quest_poi_points VALUES (456, 0, 0x29F4, 0x02AA); +INSERT INTO quest_poi_points VALUES (456, 0, 0x2841, 0x0398); +INSERT INTO quest_poi_points VALUES (456, 0, 0x2806, 0x034C); +INSERT INTO quest_poi_points VALUES (456, 0, 0x281B, 0x02DE); +INSERT INTO quest_poi_points VALUES (456, 0, 0x283C, 0x029B); +INSERT INTO quest_poi_points VALUES (456, 0, 0x284C, 0x028A); +INSERT INTO quest_poi_points VALUES (456, 0, 0x28B0, 0x0228); + +INSERT INTO quest_poi_points VALUES (456, 1, 0x28A0, 0x0258); +INSERT INTO quest_poi_points VALUES (456, 1, 0x290E, 0x0366); +INSERT INTO quest_poi_points VALUES (456, 1, 0x28CA, 0x03BC); +INSERT INTO quest_poi_points VALUES (456, 1, 0x288F, 0x03F6); +INSERT INTO quest_poi_points VALUES (456, 1, 0x284D, 0x03B8); +INSERT INTO quest_poi_points VALUES (456, 1, 0x2828, 0x0395); +INSERT INTO quest_poi_points VALUES (456, 1, 0x2806, 0x034C); +INSERT INTO quest_poi_points VALUES (456, 1, 0x281B, 0x02DE); +INSERT INTO quest_poi_points VALUES (456, 1, 0x284C, 0x028A); + +INSERT INTO quest_poi_points VALUES (456, -1, 0x2859, 0x033A); diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp index 11b577fdd..1a6b7809f 100644 --- a/src/game/ObjectMgr.cpp +++ b/src/game/ObjectMgr.cpp @@ -6380,6 +6380,65 @@ void ObjectMgr::LoadPointsOfInterest() sLog.outString(">> Loaded %u Points of Interest definitions", count); } +void ObjectMgr::LoadQuestPOI() +{ + uint32 count = 0; + + // 0 1 2 3 + QueryResult *result = WorldDatabase.Query("SELECT questId, objIndex, mapId, unk1 FROM quest_poi"); + + if(!result) + { + barGoLink bar(1); + + bar.step(); + + sLog.outString(); + sLog.outErrorDb(">> Loaded 0 quest POI definitions. DB table `quest_poi` is empty."); + return; + } + + barGoLink bar(result->GetRowCount()); + + do + { + Field *fields = result->Fetch(); + bar.step(); + + uint32 questId = fields[0].GetUInt32(); + int32 objIndex = fields[1].GetInt32(); + uint32 mapId = fields[2].GetUInt32(); + uint32 unk1 = fields[3].GetUInt32(); + + QuestPOI POI(objIndex, mapId, unk1); + + QueryResult *points = WorldDatabase.PQuery("SELECT x, y FROM quest_poi_points WHERE questId='%u' AND objIndex='%i'", questId, objIndex); + + if(points) + { + do + { + Field *pointFields = points->Fetch(); + int32 x = pointFields[0].GetInt32(); + int32 y = pointFields[1].GetInt32(); + QuestPOIPoint point(x, y); + POI.points.push_back(point); + } while (points->NextRow()); + + delete points; + } + + mQuestPOIMap[questId].push_back(POI); + + ++count; + } while (result->NextRow()); + + delete result; + + sLog.outString(); + sLog.outString(">> Loaded %u quest POI definitions", count); +} + void ObjectMgr::LoadNPCSpellClickSpells() { uint32 count = 0; diff --git a/src/game/ObjectMgr.h b/src/game/ObjectMgr.h index e4c90aadb..6946b2593 100644 --- a/src/game/ObjectMgr.h +++ b/src/game/ObjectMgr.h @@ -216,6 +216,29 @@ struct PointOfInterest std::string icon_name; }; +struct QuestPOIPoint +{ + int32 x; + int32 y; + + QuestPOIPoint() : x(0), y(0) {} + QuestPOIPoint(int32 _x, int32 _y) : x(_x), y(_y) {} +}; + +struct QuestPOI +{ + int32 ObjectiveIndex; + uint32 MapId; + uint32 Unk1; + std::vector points; + + QuestPOI() : ObjectiveIndex(0), MapId(0), Unk1(0) {} + QuestPOI(int32 objIndex, uint32 mapId, uint32 unk1) : ObjectiveIndex(objIndex), MapId(mapId), Unk1(unk1) {} +}; + +typedef std::vector QuestPOIVector; +typedef UNORDERED_MAP QuestPOIMap; + #define WEATHER_SEASONS 4 struct WeatherSeasonChances { @@ -479,6 +502,14 @@ class ObjectMgr return NULL; } + QuestPOIVector const* GetQuestPOIVector(uint32 questId) + { + QuestPOIMap::const_iterator itr = mQuestPOIMap.find(questId); + if(itr != mQuestPOIMap.end()) + return &itr->second; + return NULL; + } + void LoadGuilds(); void LoadArenaTeams(); void LoadGroups(); @@ -551,6 +582,7 @@ class ObjectMgr void LoadReputationOnKill(); void LoadPointsOfInterest(); + void LoadQuestPOI(); void LoadNPCSpellClickSpells(); @@ -843,6 +875,8 @@ class ObjectMgr PointOfInterestMap mPointsOfInterest; + QuestPOIMap mQuestPOIMap; + WeatherZoneMap mWeatherZoneMap; //character reserved names diff --git a/src/game/QueryHandler.cpp b/src/game/QueryHandler.cpp index 5241f8f73..1d425a341 100644 --- a/src/game/QueryHandler.cpp +++ b/src/game/QueryHandler.cpp @@ -489,9 +489,66 @@ void WorldSession::HandleQueryQuestsCompleted( WorldPacket & recv_data ) void WorldSession::HandleQuestPOIQuery(WorldPacket& recv_data) { - recv_data.read_skip(); + uint32 count; + recv_data >> count; // quest count, max=25 - WorldPacket data(SMSG_QUEST_POI_QUERY_RESPONSE, 4); - data << uint32(0); // count + if(count >= MAX_QUEST_LOG_SIZE) + return; + + WorldPacket data(SMSG_QUEST_POI_QUERY_RESPONSE, 4+(4+4)*count); + data << uint32(count); // count + + for(int i = 0; i < count; ++i) + { + uint32 questId; + recv_data >> questId; // quest id + + bool questOk = false; + + uint16 questSlot = _player->FindQuestSlot(questId); + + if(questSlot != MAX_QUEST_LOG_SIZE) + questOk =_player->GetQuestSlotQuestId(questSlot) == questId; + + if(questOk) + { + QuestPOIVector const *POI = sObjectMgr.GetQuestPOIVector(questId); + + if(POI) + { + data << uint32(questId); // quest ID + data << uint32(POI->size()); // POI count + + int index = 0; + for(QuestPOIVector::const_iterator itr = POI->begin(); itr != POI->end(); ++itr) + { + data << uint32(index); // POI index + data << int32(itr->ObjectiveIndex); // objective index + data << uint32(itr->MapId); // mapid + data << uint32(itr->Unk1); // unknown + data << uint32(itr->points.size()); // POI points count + + for(std::vector::const_iterator itr2 = itr->points.begin(); itr2 != itr->points.end(); ++itr2) + { + data << int32(itr2->x); // POI point x + data << int32(itr2->y); // POI point y + } + ++index; + } + } + else + { + data << uint32(questId); // quest ID + data << uint32(0); // POI count + } + } + else + { + data << uint32(questId); // quest ID + data << uint32(0); // POI count + } + } + + data.hexlike(); SendPacket(&data); } diff --git a/src/game/World.cpp b/src/game/World.cpp index 4491e4cf5..b931196d7 100644 --- a/src/game/World.cpp +++ b/src/game/World.cpp @@ -1284,6 +1284,9 @@ void World::SetInitialWorldSettings() sLog.outString( "Loading Quests..." ); sObjectMgr.LoadQuests(); // must be loaded after DBCs, creature_template, item_template, gameobject tables + sLog.outString( "Loading Quest POI" ); + sObjectMgr.LoadQuestPOI(); + sLog.outString( "Loading Quests Relations..." ); sLog.outString(); sObjectMgr.LoadQuestRelations(); // must be after quest load