From 6ac38a0d652bf3867db3f8fcb9aff44fa58e44f2 Mon Sep 17 00:00:00 2001 From: Charles A Edwards Date: Tue, 30 Aug 2016 11:15:20 +0100 Subject: [PATCH] Update Waypoint System and Commands Update Waypoint System and Commands --- src/game/BattleGround/BattleGround.h | 2 +- src/game/BattleGround/BattleGroundAB.cpp | 15 +- src/game/BattleGround/BattleGroundAB.h | 2 +- src/game/BattleGround/BattleGroundAV.cpp | 15 +- src/game/BattleGround/BattleGroundAV.h | 4 +- src/game/BattleGround/BattleGroundBE.cpp | 41 ---- src/game/BattleGround/BattleGroundBE.h | 1 - src/game/BattleGround/BattleGroundEY.cpp | 9 +- src/game/BattleGround/BattleGroundEY.h | 2 +- src/game/BattleGround/BattleGroundMgr.h | 2 + src/game/BattleGround/BattleGroundNA.cpp | 32 --- src/game/BattleGround/BattleGroundNA.h | 1 - src/game/BattleGround/BattleGroundRL.cpp | 33 --- src/game/BattleGround/BattleGroundRL.h | 1 - src/game/BattleGround/BattleGroundWS.cpp | 23 +- src/game/BattleGround/BattleGroundWS.h | 2 +- src/game/ChatCommands/Level2.cpp | 223 +++++++++--------- src/game/MotionGenerators/MotionMaster.cpp | 36 ++- src/game/MotionGenerators/MotionMaster.h | 8 +- .../WaypointMovementGenerator.cpp | 81 ++++++- src/game/Object/ObjectAccessor.cpp | 2 + src/game/Object/ObjectAccessor.h | 2 + src/game/Object/Unit.cpp | 2 +- src/game/Server/WorldSession.cpp | 2 + src/game/Server/WorldSession.h | 2 + src/game/WorldHandlers/Chat.cpp | 1 - src/game/WorldHandlers/Chat.h | 1 - src/game/WorldHandlers/GameEventMgr.h | 2 + src/game/WorldHandlers/GridMap.cpp | 2 + src/game/WorldHandlers/GridMap.h | 2 + .../WorldHandlers/MapPersistentStateMgr.h | 2 + src/game/WorldHandlers/MiscHandler.cpp | 4 +- src/game/WorldHandlers/ScriptMgr.cpp | 5 + src/game/WorldHandlers/ScriptMgr.h | 14 +- src/game/WorldHandlers/WaypointManager.cpp | 11 +- src/game/WorldHandlers/WaypointManager.h | 12 +- src/game/vmap/MapTree.cpp | 2 + src/game/vmap/VMapManager2.h | 2 + .../SD3/scripts/kalimdor/darkshore.cpp | 13 +- .../SD3/scripts/northrend/borean_tundra.cpp | 116 +++++++++ src/shared/Common/Common.h | 1 + src/shared/Config/Config.cpp | 5 + src/shared/Config/Config.h | 4 + src/shared/Database/SqlDelayThread.h | 2 + src/shared/Database/SqlOperations.h | 2 + src/shared/Log/Log.h | 2 + .../Movemap-Generator/CMakeLists.txt | 16 +- .../vmap-assembler/CMakeLists.txt | 14 +- 48 files changed, 455 insertions(+), 323 deletions(-) diff --git a/src/game/BattleGround/BattleGround.h b/src/game/BattleGround/BattleGround.h index 46b4b1e37..ea92d045e 100644 --- a/src/game/BattleGround/BattleGround.h +++ b/src/game/BattleGround/BattleGround.h @@ -490,7 +490,7 @@ class BattleGround /* Triggers handle */ // must be implemented in BG subclass - virtual void HandleAreaTrigger(Player* /*Source*/, uint32 /*Trigger*/) {} + virtual bool HandleAreaTrigger(Player* /*Source*/, uint32 /*Trigger*/) { return false; } // must be implemented in BG subclass if need AND call base class generic code virtual void HandleKillPlayer(Player* player, Player* killer); virtual void HandleKillUnit(Creature* /*unit*/, Player* /*killer*/) {} diff --git a/src/game/BattleGround/BattleGroundAB.cpp b/src/game/BattleGround/BattleGroundAB.cpp index 5014d1920..ee7cba0cb 100644 --- a/src/game/BattleGround/BattleGroundAB.cpp +++ b/src/game/BattleGround/BattleGroundAB.cpp @@ -183,7 +183,7 @@ void BattleGroundAB::RemovePlayer(Player * /*plr*/, ObjectGuid /*guid*/) { } -void BattleGroundAB::HandleAreaTrigger(Player* source, uint32 trigger) +bool BattleGroundAB::HandleAreaTrigger(Player* source, uint32 trigger) { switch (trigger) { @@ -199,19 +199,10 @@ void BattleGroundAB::HandleAreaTrigger(Player* source, uint32 trigger) else source->LeaveBattleground(); break; - case 3866: // Stables - case 3869: // Gold Mine - case 3867: // Farm - case 3868: // Lumber Mill - case 3870: // Black Smith - case 4020: // Unk1 - case 4021: // Unk2 - // break; default: - // sLog.outError("WARNING: Unhandled AreaTrigger in Battleground: %u", trigger); - // source->GetSession()->SendAreaTriggerMessage("Warning: Unhandled AreaTrigger in Battleground: %u", trigger); - break; + return false; } + return true; } /* type: 0-neutral, 1-contested, 3-occupied diff --git a/src/game/BattleGround/BattleGroundAB.h b/src/game/BattleGround/BattleGroundAB.h index d67574f7e..b487a4210 100644 --- a/src/game/BattleGround/BattleGroundAB.h +++ b/src/game/BattleGround/BattleGroundAB.h @@ -173,7 +173,7 @@ class BattleGroundAB : public BattleGround void AddPlayer(Player* plr) override; virtual void StartingEventOpenDoors() override; void RemovePlayer(Player* plr, ObjectGuid guid) override; - void HandleAreaTrigger(Player* source, uint32 trigger) override; + bool HandleAreaTrigger(Player* source, uint32 trigger) override; virtual void Reset() override; void EndBattleGround(Team winner) override; virtual WorldSafeLocsEntry const* GetClosestGraveYard(Player* player) override; diff --git a/src/game/BattleGround/BattleGroundAV.cpp b/src/game/BattleGround/BattleGroundAV.cpp index 30caa40eb..26f1c4b21 100644 --- a/src/game/BattleGround/BattleGroundAV.cpp +++ b/src/game/BattleGround/BattleGroundAV.cpp @@ -350,7 +350,7 @@ void BattleGroundAV::EndBattleGround(Team winner) BattleGround::EndBattleGround(winner); } -void BattleGroundAV::HandleAreaTrigger(Player* source, uint32 trigger) +bool BattleGroundAV::HandleAreaTrigger(Player* source, uint32 trigger) { // this is wrong way to implement these things. On official it done by gameobject spell cast. switch (trigger) @@ -368,19 +368,10 @@ void BattleGroundAV::HandleAreaTrigger(Player* source, uint32 trigger) else source->LeaveBattleground(); break; - case 3326: - case 3327: - case 3328: - case 3329: - case 3330: - case 3331: - // source->Unmount(); - break; default: - DEBUG_LOG("BattleGroundAV: WARNING: Unhandled AreaTrigger in Battleground: %u", trigger); -// source->GetSession()->SendAreaTriggerMessage("Warning: Unhandled AreaTrigger in Battleground: %u", trigger); - break; + return false; } + return true; } void BattleGroundAV::UpdatePlayerScore(Player* source, uint32 type, uint32 value) diff --git a/src/game/BattleGround/BattleGroundAV.h b/src/game/BattleGround/BattleGroundAV.h index b05570521..b8b86b94e 100644 --- a/src/game/BattleGround/BattleGroundAV.h +++ b/src/game/BattleGround/BattleGroundAV.h @@ -339,8 +339,8 @@ class BattleGroundAV : public BattleGround virtual void StartingEventOpenDoors() override; // world states virtual void FillInitialWorldStates(WorldPacket& data, uint32& count) override; - - void HandleAreaTrigger(Player* source, uint32 trigger) override; + + bool HandleAreaTrigger(Player* source, uint32 trigger) override; virtual void Reset() override; /*general stuff*/ diff --git a/src/game/BattleGround/BattleGroundBE.cpp b/src/game/BattleGround/BattleGroundBE.cpp index 69d3a3c42..fee37b507 100644 --- a/src/game/BattleGround/BattleGroundBE.cpp +++ b/src/game/BattleGround/BattleGroundBE.cpp @@ -96,32 +96,6 @@ bool BattleGroundBE::HandlePlayerUnderMap(Player* player) return true; } -void BattleGroundBE::HandleAreaTrigger(Player* source, uint32 trigger) -{ - // this is wrong way to implement these things. On official it done by gameobject spell cast. - if (GetStatus() != STATUS_IN_PROGRESS) - return; - - // uint32 spellId = 0; - // uint64 buff_guid = 0; - switch (trigger) - { - case 4538: // buff trigger? - // buff_guid = -nonexistingStorage-[BG_BE_OBJECT_BUFF_1]; - break; - case 4539: // buff trigger? - // buff_guid = -nonexistingStorage-[BG_BE_OBJECT_BUFF_2]; - break; - default: - sLog.outError("WARNING: Unhandled AreaTrigger in Battleground: %u", trigger); - source->GetSession()->SendAreaTriggerMessage("Warning: Unhandled AreaTrigger in Battleground: %u", trigger); - break; - } - - // if (buff_guid) - // HandleTriggerBuff(buff_guid, source); -} - void BattleGroundBE::FillInitialWorldStates(WorldPacket& data, uint32& count) { FillInitialWorldState(data, count, 0x9f1, GetAlivePlayersCountByTeam(ALLIANCE)); @@ -138,18 +112,3 @@ void BattleGroundBE::UpdatePlayerScore(Player* source, uint32 type, uint32 value // there is nothing special in this score BattleGround::UpdatePlayerScore(source, type, value); } - -/* -21:45:46 id:231310 [S2C] SMSG_INIT_WORLD_STATES (706 = 0x02C2) len: 86 -0000: 32 02 00 00 76 0e 00 00 00 00 00 00 09 00 f3 09 | 2...v........... -0010: 00 00 01 00 00 00 f1 09 00 00 01 00 00 00 f0 09 | ................ -0020: 00 00 02 00 00 00 d4 08 00 00 00 00 00 00 d8 08 | ................ -0030: 00 00 00 00 00 00 d7 08 00 00 00 00 00 00 d6 08 | ................ -0040: 00 00 00 00 00 00 d5 08 00 00 00 00 00 00 d3 08 | ................ -0050: 00 00 00 00 00 00 | ...... - -spell 32724 - Gold Team -spell 32725 - Green Team -35774 Gold Team -35775 Green Team -*/ diff --git a/src/game/BattleGround/BattleGroundBE.h b/src/game/BattleGround/BattleGroundBE.h index c0a8d9917..8d94cc197 100644 --- a/src/game/BattleGround/BattleGroundBE.h +++ b/src/game/BattleGround/BattleGroundBE.h @@ -45,7 +45,6 @@ class BattleGroundBE : public BattleGround virtual void StartingEventOpenDoors() override; void RemovePlayer(Player* plr, ObjectGuid guid) override; - void HandleAreaTrigger(Player* source, uint32 trigger) override; virtual void FillInitialWorldStates(WorldPacket& d, uint32& count) override; void HandleKillPlayer(Player* player, Player* killer) override; bool HandlePlayerUnderMap(Player* plr) override; diff --git a/src/game/BattleGround/BattleGroundEY.cpp b/src/game/BattleGround/BattleGroundEY.cpp index f1522a0fb..42237a054 100644 --- a/src/game/BattleGround/BattleGroundEY.cpp +++ b/src/game/BattleGround/BattleGroundEY.cpp @@ -298,13 +298,13 @@ void BattleGroundEY::ProcessCaptureEvent(GameObject* go, uint32 towerId, Team te m_towerOwner[towerId] = team; } -void BattleGroundEY::HandleAreaTrigger(Player* source, uint32 trigger) +bool BattleGroundEY::HandleAreaTrigger(Player* source, uint32 trigger) { if (GetStatus() != STATUS_IN_PROGRESS) - return; + return false; if (!source->IsAlive()) // hack code, must be removed later - return; + return false; switch (trigger) { @@ -324,7 +324,10 @@ void BattleGroundEY::HandleAreaTrigger(Player* source, uint32 trigger) if (m_towerOwner[NODE_DRAENEI_RUINS] == source->GetTeam()) EventPlayerCapturedFlag(source, NODE_DRAENEI_RUINS); break; + default: + return false; } + return true; } void BattleGroundEY::Reset() diff --git a/src/game/BattleGround/BattleGroundEY.h b/src/game/BattleGround/BattleGroundEY.h index 8b1fe1f4f..18ac7cd3c 100644 --- a/src/game/BattleGround/BattleGroundEY.h +++ b/src/game/BattleGround/BattleGroundEY.h @@ -264,7 +264,7 @@ class BattleGroundEY : public BattleGround void RemovePlayer(Player* plr, ObjectGuid guid) override; bool HandleEvent(uint32 eventId, GameObject* go) override; void HandleGameObjectCreate(GameObject* go) override; - void HandleAreaTrigger(Player* source, uint32 trigger) override; + bool HandleAreaTrigger(Player* source, uint32 trigger) override; void HandleKillPlayer(Player* player, Player* killer) override; virtual WorldSafeLocsEntry const* GetClosestGraveYard(Player* player) override; diff --git a/src/game/BattleGround/BattleGroundMgr.h b/src/game/BattleGround/BattleGroundMgr.h index dd78655c8..b4e1bb4eb 100644 --- a/src/game/BattleGround/BattleGroundMgr.h +++ b/src/game/BattleGround/BattleGroundMgr.h @@ -33,6 +33,8 @@ #include "BattleGround.h" #include "ace/Recursive_Thread_Mutex.h" +#include + typedef std::map BattleGroundSet; // this container can't be deque, because deque doesn't like removing the last element - if you remove it, it invalidates next iterator and crash appears diff --git a/src/game/BattleGround/BattleGroundNA.cpp b/src/game/BattleGround/BattleGroundNA.cpp index 7162224d4..bb531e0d2 100644 --- a/src/game/BattleGround/BattleGroundNA.cpp +++ b/src/game/BattleGround/BattleGroundNA.cpp @@ -97,41 +97,9 @@ bool BattleGroundNA::HandlePlayerUnderMap(Player* player) return true; } -void BattleGroundNA::HandleAreaTrigger(Player* source, uint32 trigger) -{ - if (GetStatus() != STATUS_IN_PROGRESS) - return; - - // uint32 spellId = 0; - // uint64 buff_guid = 0; - switch (trigger) - { - case 4536: // buff trigger? - case 4537: // buff trigger? - break; - default: - sLog.outError("WARNING: Unhandled AreaTrigger in Battleground: %u", trigger); - source->GetSession()->SendAreaTriggerMessage("Warning: Unhandled AreaTrigger in Battleground: %u", trigger); - break; - } - - // if (buff_guid) - // HandleTriggerBuff(buff_guid, source); -} - void BattleGroundNA::FillInitialWorldStates(WorldPacket& data, uint32& count) { FillInitialWorldState(data, count, 0xa0f, GetAlivePlayersCountByTeam(ALLIANCE)); FillInitialWorldState(data, count, 0xa10, GetAlivePlayersCountByTeam(HORDE)); FillInitialWorldState(data, count, 0xa11, 1); } - -/* -20:12:14 id:036668 [S2C] SMSG_INIT_WORLD_STATES (706 = 0x02C2) len: 86 -0000: 2f 02 00 00 72 0e 00 00 00 00 00 00 09 00 11 0a | /...r........... -0010: 00 00 01 00 00 00 0f 0a 00 00 00 00 00 00 10 0a | ................ -0020: 00 00 00 00 00 00 d4 08 00 00 00 00 00 00 d8 08 | ................ -0030: 00 00 00 00 00 00 d7 08 00 00 00 00 00 00 d6 08 | ................ -0040: 00 00 00 00 00 00 d5 08 00 00 00 00 00 00 d3 08 | ................ -0050: 00 00 00 00 00 00 | ...... -*/ diff --git a/src/game/BattleGround/BattleGroundNA.h b/src/game/BattleGround/BattleGroundNA.h index 04f447e40..b4da99b9d 100644 --- a/src/game/BattleGround/BattleGroundNA.h +++ b/src/game/BattleGround/BattleGroundNA.h @@ -46,7 +46,6 @@ class BattleGroundNA : public BattleGround virtual void StartingEventOpenDoors() override; void RemovePlayer(Player* plr, ObjectGuid guid) override; - void HandleAreaTrigger(Player* source, uint32 trigger) override; virtual void FillInitialWorldStates(WorldPacket& d, uint32& count) override; void HandleKillPlayer(Player* player, Player* killer) override; bool HandlePlayerUnderMap(Player* plr) override; diff --git a/src/game/BattleGround/BattleGroundRL.cpp b/src/game/BattleGround/BattleGroundRL.cpp index 57cf014ff..42d569657 100644 --- a/src/game/BattleGround/BattleGroundRL.cpp +++ b/src/game/BattleGround/BattleGroundRL.cpp @@ -96,42 +96,9 @@ bool BattleGroundRL::HandlePlayerUnderMap(Player* player) return true; } -void BattleGroundRL::HandleAreaTrigger(Player* source, uint32 trigger) -{ - // this is wrong way to implement these things. On official it done by gameobject spell cast. - if (GetStatus() != STATUS_IN_PROGRESS) - return; - - // uint32 spellId = 0; - // uint64 buff_guid = 0; - switch (trigger) - { - case 4696: // buff trigger? - case 4697: // buff trigger? - break; - default: - sLog.outError("WARNING: Unhandled AreaTrigger in Battleground: %u", trigger); - source->GetSession()->SendAreaTriggerMessage("Warning: Unhandled AreaTrigger in Battleground: %u", trigger); - break; - } - - // if (buff_guid) - // HandleTriggerBuff(buff_guid, source); -} - void BattleGroundRL::FillInitialWorldStates(WorldPacket& data, uint32& count) { FillInitialWorldState(data, count, 0xbb8, GetAlivePlayersCountByTeam(ALLIANCE)); FillInitialWorldState(data, count, 0xbb9, GetAlivePlayersCountByTeam(HORDE)); FillInitialWorldState(data, count, 0xbba, 1); } - -/* -Packet S->C, id 600, SMSG_INIT_WORLD_STATES (706), len 86 -0000: 3C 02 00 00 80 0F 00 00 00 00 00 00 09 00 BA 0B | <............... -0010: 00 00 01 00 00 00 B9 0B 00 00 02 00 00 00 B8 0B | ................ -0020: 00 00 00 00 00 00 D8 08 00 00 00 00 00 00 D7 08 | ................ -0030: 00 00 00 00 00 00 D6 08 00 00 00 00 00 00 D5 08 | ................ -0040: 00 00 00 00 00 00 D3 08 00 00 00 00 00 00 D4 08 | ................ -0050: 00 00 00 00 00 00 | ...... -*/ diff --git a/src/game/BattleGround/BattleGroundRL.h b/src/game/BattleGround/BattleGroundRL.h index 5bdc2b5a3..f08aab47b 100644 --- a/src/game/BattleGround/BattleGroundRL.h +++ b/src/game/BattleGround/BattleGroundRL.h @@ -47,7 +47,6 @@ class BattleGroundRL : public BattleGround virtual void StartingEventOpenDoors() override; void RemovePlayer(Player* plr, ObjectGuid guid) override; - void HandleAreaTrigger(Player* source, uint32 trigger) override; void HandleKillPlayer(Player* player, Player* killer) override; bool HandlePlayerUnderMap(Player* plr) override; }; diff --git a/src/game/BattleGround/BattleGroundWS.cpp b/src/game/BattleGround/BattleGroundWS.cpp index c6124e2ca..4859b6dd6 100644 --- a/src/game/BattleGround/BattleGroundWS.cpp +++ b/src/game/BattleGround/BattleGroundWS.cpp @@ -483,23 +483,14 @@ void BattleGroundWS::UpdateTeamScore(Team team) UpdateWorldState(BG_WS_FLAG_CAPTURES_HORDE, m_TeamScores[TEAM_INDEX_HORDE]); } -void BattleGroundWS::HandleAreaTrigger(Player* source, uint32 trigger) +bool BattleGroundWS::HandleAreaTrigger(Player* source, uint32 trigger) { // this is wrong way to implement these things. On official it done by gameobject spell cast. if (GetStatus() != STATUS_IN_PROGRESS) - return; + return false; - // uint32 SpellId = 0; - // uint64 buff_guid = 0; switch (trigger) { - case 3686: // Alliance elixir of speed spawn. Trigger not working, because located inside other areatrigger, can be replaced by IsWithinDist(object, dist) in BattleGround::Update(). - case 3687: // Horde elixir of speed spawn. Trigger not working, because located inside other areatrigger, can be replaced by IsWithinDist(object, dist) in BattleGround::Update(). - case 3706: // Alliance elixir of regeneration spawn - case 3708: // Horde elixir of regeneration spawn - case 3707: // Alliance elixir of berserk spawn - case 3709: // Horde elixir of berserk spawn - break; case 3646: // Alliance Flag spawn if (m_FlagState[TEAM_INDEX_HORDE] && !m_FlagState[TEAM_INDEX_ALLIANCE]) if (GetHordeFlagCarrierGuid() == source->GetObjectGuid()) @@ -510,16 +501,10 @@ void BattleGroundWS::HandleAreaTrigger(Player* source, uint32 trigger) if (GetAllianceFlagCarrierGuid() == source->GetObjectGuid()) EventPlayerCapturedFlag(source); break; - case 3649: // unk1 - case 3688: // unk2 - case 4628: // unk3 - case 4629: // unk4 - break; default: - sLog.outError("WARNING: Unhandled AreaTrigger in Battleground: %u", trigger); - source->GetSession()->SendAreaTriggerMessage("Warning: Unhandled AreaTrigger in Battleground: %u", trigger); - break; + return false; } + return true; } void BattleGroundWS::Reset() diff --git a/src/game/BattleGround/BattleGroundWS.h b/src/game/BattleGround/BattleGroundWS.h index 8fa832753..41e14ae7f 100644 --- a/src/game/BattleGround/BattleGroundWS.h +++ b/src/game/BattleGround/BattleGroundWS.h @@ -139,7 +139,7 @@ class BattleGroundWS : public BattleGround virtual void EventPlayerCapturedFlag(Player* source) override; void RemovePlayer(Player* plr, ObjectGuid guid) override; - void HandleAreaTrigger(Player* source, uint32 trigger) override; + bool HandleAreaTrigger(Player* source, uint32 trigger) override; void HandleKillPlayer(Player* player, Player* killer) override; virtual void Reset() override; void EndBattleGround(Team winner) override; diff --git a/src/game/ChatCommands/Level2.cpp b/src/game/ChatCommands/Level2.cpp index 68703f186..797d70960 100644 --- a/src/game/ChatCommands/Level2.cpp +++ b/src/game/ChatCommands/Level2.cpp @@ -3140,7 +3140,7 @@ bool ChatHandler::HandleWpModifyCommand(char* args) // Did user provide a GUID or did the user select a creature? Creature* targetCreature = getSelectedCreature(); // Expect a visual waypoint to be selected - Creature* wpOwner = nullptr; // Who moves along the waypoint + Creature* wpOwner; // Who moves along the waypoint uint32 wpId = 0; WaypointPathOrigin wpSource = PATH_NO_PATH; int32 wpPathId = 0; @@ -3393,8 +3393,8 @@ bool ChatHandler::HandleWpShowCommand(char* args) } } - Creature* wpOwner = NULL; ///< Npc that is moving - TemporarySummonWaypoint* wpTarget = NULL; // Define here for wp-info command + Creature* wpOwner; ///< Npc that is moving + TemporarySummonWaypoint* wpTarget = nullptr; // Define here for wp-info command // Show info for the selected waypoint (Step one: get moving npc) if (subCmd == "info") @@ -3431,7 +3431,7 @@ bool ChatHandler::HandleWpShowCommand(char* args) wpOwner = targetCreature; // Get the path - WaypointPath* wpPath = NULL; + WaypointPath* wpPath = nullptr; if (wpOrigin != PATH_NO_PATH) // Might have been provided by param wpPath = sWaypointMgr.GetPathFromOrigin(wpOwner->GetEntry(), wpOwner->GetGUIDLow(), wpPathId, wpOrigin); else @@ -3538,65 +3538,112 @@ bool ChatHandler::HandleWpShowCommand(char* args) return false; } +/// [Guid if no selected unit] [pathId [wpOrigin] ] bool ChatHandler::HandleWpExportCommand(char* args) { if (!*args) return false; - // Next arg is: + Creature* wpOwner; + WaypointPathOrigin wpOrigin = PATH_NO_PATH; + int32 wpPathId = 0; - // Did user provide a GUID - // or did the user select a creature? - // -> variable lowguid is filled with the GUID of the NPC - uint32 lowguid = 0; - Creature* target = getSelectedCreature(); - char* arg_str = NULL; - if (target) + if (Creature* targetCreature = getSelectedCreature()) { - if (target->GetEntry() != VISUAL_WAYPOINT) - lowguid = target->GetGUIDLow(); - else + // Check if the user did specify a visual waypoint + if (targetCreature->GetEntry() == VISUAL_WAYPOINT && targetCreature->GetSubtype() == CREATURE_SUBTYPE_TEMPORARY_SUMMON) { - QueryResult* result = WorldDatabase.PQuery("SELECT id FROM creature_movement WHERE wpguid = %u LIMIT 1", target->GetGUIDLow()); - if (!result) + TemporarySummonWaypoint* wpTarget = dynamic_cast(targetCreature); + if (!wpTarget) { - PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM, target->GetGUIDLow()); - return true; + PSendSysMessage(LANG_WAYPOINT_VP_SELECT); + SetSentErrorMessage(true); + return false; } - Field* fields = result->Fetch(); - lowguid = fields[0].GetUInt32();; - delete result; - } - arg_str = strtok(args, " "); + // Who moves along this waypoint? + wpOwner = targetCreature->GetMap()->GetAnyTypeCreature(wpTarget->GetSummonerGuid()); + if (!wpOwner) + { + PSendSysMessage(LANG_WAYPOINT_NOTFOUND_NPC, wpTarget->GetSummonerGuid().GetString().c_str()); + SetSentErrorMessage(true); + return false; + } + wpOrigin = (WaypointPathOrigin)wpTarget->GetPathOrigin(); + wpPathId = wpTarget->GetPathId(); + } + else // normal creature selected + wpOwner = targetCreature; } else { - // user provided - char* guid_str = strtok(args, " "); - if (!guid_str) + uint32 dbGuid; + if (!ExtractUInt32(&args, dbGuid)) { - SendSysMessage(LANG_WAYPOINT_NOGUID); + PSendSysMessage(LANG_WAYPOINT_NOGUID); + SetSentErrorMessage(true); return false; } - lowguid = atoi((char*)guid_str); - arg_str = strtok((char*)NULL, " "); + CreatureData const* data = sObjectMgr.GetCreatureData(dbGuid); + if (!data) + { + PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, dbGuid); + SetSentErrorMessage(true); + return false; + } + + if (m_session->GetPlayer()->GetMapId() != data->mapid) + { + PSendSysMessage(LANG_COMMAND_CREATUREATSAMEMAP, dbGuid); + SetSentErrorMessage(true); + return false; + } + + wpOwner = m_session->GetPlayer()->GetMap()->GetAnyTypeCreature(data->GetObjectGuid(dbGuid)); + if (!wpOwner) + { + PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, dbGuid); + SetSentErrorMessage(true); + return false; + } } - if (!arg_str) + // wpOwner is now known, in case of export by visual waypoint also the to be exported path + char* export_str = ExtractLiteralArg(&args); + if (!export_str) { PSendSysMessage(LANG_WAYPOINT_ARGUMENTREQ, "export"); + SetSentErrorMessage(true); return false; } - PSendSysMessage("DEBUG: wp export, GUID: %u", lowguid); + if (wpOrigin == PATH_NO_PATH) // No WP selected, Extract optional arguments + { + if (ExtractOptInt32(&args, wpPathId, 0)) // Fill path-id and source + { + uint32 src = (uint32)PATH_NO_PATH; + if (ExtractOptUInt32(&args, src, src)) + wpOrigin = (WaypointPathOrigin)src; + else // pathId provided but no destination + { + if (wpPathId != 0) + wpOrigin = PATH_FROM_ENTRY; // Multiple Paths must only be assigned by entry + } + } - QueryResult* result = WorldDatabase.PQuery( - // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 - "SELECT point, position_x, position_y, position_z, orientation, model1, model2, waittime, emote, spell, textid1, textid2, textid3, textid4, textid5, id FROM creature_movement WHERE id = '%u' ORDER BY point", lowguid); + if (wpOrigin == PATH_NO_PATH) + { + if (wpOwner->GetMotionMaster()->GetCurrentMovementGeneratorType() == WAYPOINT_MOTION_TYPE) + if (WaypointMovementGenerator const* wpMMGen = dynamic_cast const*>(wpOwner->GetMotionMaster()->GetCurrent())) + wpMMGen->GetPathInformation(wpPathId, wpOrigin); + if (wpOrigin == PATH_NO_PATH) + sWaypointMgr.GetDefaultPath(wpOwner->GetEntry(), wpOwner->GetGUIDLow(), &wpOrigin); + } + } - if (!result) + WaypointPath const* wpPath = sWaypointMgr.GetPathFromOrigin(wpOwner->GetEntry(), wpOwner->GetGUIDLow(), wpPathId, wpOrigin); + if (!wpPath || wpPath->empty()) { PSendSysMessage(LANG_WAYPOINT_NOTHINGTOEXPORT); SetSentErrorMessage(true); @@ -3604,51 +3651,44 @@ bool ChatHandler::HandleWpExportCommand(char* args) } std::ofstream outfile; - outfile.open(arg_str); + outfile.open(export_str); - do + std::string table; + char const* key_field; + uint32 key; + switch (wpOrigin) { - Field* fields = result->Fetch(); - - outfile << "INSERT INTO creature_movement "; - outfile << "(id, point, position_x, position_y, position_z, orientation, model1, model2, waittime, emote, spell, textid1, textid2, textid3, textid4, textid5) VALUES "; - - outfile << "( "; - outfile << fields[15].GetUInt32(); // id - outfile << ", "; - outfile << fields[0].GetUInt32(); // point - outfile << ", "; - outfile << fields[1].GetFloat(); // position_x - outfile << ", "; - outfile << fields[2].GetFloat(); // position_y - outfile << ", "; - outfile << fields[3].GetUInt32(); // position_z - outfile << ", "; - outfile << fields[4].GetUInt32(); // orientation - outfile << ", "; - outfile << fields[5].GetUInt32(); // model1 - outfile << ", "; - outfile << fields[6].GetUInt32(); // model2 - outfile << ", "; - outfile << fields[7].GetUInt16(); // waittime - outfile << ", "; - outfile << fields[8].GetUInt32(); // emote - outfile << ", "; - outfile << fields[9].GetUInt32(); // spell - outfile << ", "; - outfile << fields[10].GetUInt32(); // textid1 - outfile << ", "; - outfile << fields[11].GetUInt32(); // textid2 - outfile << ", "; - outfile << fields[12].GetUInt32(); // textid3 - outfile << ", "; - outfile << fields[13].GetUInt32(); // textid4 - outfile << ", "; - outfile << fields[14].GetUInt32(); // textid5 - outfile << ");\n "; + case PATH_FROM_ENTRY: key = wpOwner->GetEntry(); key_field = "entry"; table = "creature_movement_template"; break; + case PATH_FROM_GUID: key = wpOwner->GetGUIDLow(); key_field = "id"; table = "creature_movement"; break; + case PATH_FROM_EXTERNAL: key = wpOwner->GetEntry(); key_field = "entry"; table = sWaypointMgr.GetExternalWPTable(); break; + case PATH_NO_PATH: + return false; + } + + outfile << "DELETE FROM " << table << " WHERE " << key_field << "=" << key << ";\n"; + if (wpOrigin != PATH_FROM_EXTERNAL) + outfile << "INSERT INTO " << table << " (" << key_field << ", point, position_x, position_y, position_z, orientation, waittime, script_id) VALUES\n"; + else + outfile << "INSERT INTO " << table << " (" << key_field << ", point, position_x, position_y, position_z, orientation, waittime) VALUES\n"; + + WaypointPath::const_iterator itr = wpPath->begin(); + uint32 countDown = wpPath->size(); + for (; itr != wpPath->end(); ++itr, --countDown) + { + outfile << "(" << key << ","; + outfile << itr->first << ","; + outfile << itr->second.x << ","; + outfile << itr->second.y << ","; + outfile << itr->second.z << ","; + outfile << itr->second.orientation << ","; + outfile << itr->second.delay << ","; + if (wpOrigin != PATH_FROM_EXTERNAL) // Only for normal waypoints + outfile << itr->second.script_id << ")"; + if (countDown > 1) + outfile << ",\n"; + else + outfile << ";\n"; } - while (result->NextRow()); - delete result; PSendSysMessage(LANG_WAYPOINT_EXPORTED); outfile.close(); @@ -3656,33 +3696,6 @@ bool ChatHandler::HandleWpExportCommand(char* args) return true; } -bool ChatHandler::HandleWpImportCommand(char* args) -{ - if (!*args) - return false; - - char* arg_str = strtok(args, " "); - if (!arg_str) - return false; - - std::string line; - std::ifstream infile(arg_str); - if (infile.is_open()) - { - while (! infile.eof()) - { - getline(infile, line); - // cout << line << endl; - QueryResult* result = WorldDatabase.Query(line.c_str()); - delete result; - } - infile.close(); - } - PSendSysMessage(LANG_WAYPOINT_IMPORTED); - - return true; -} - // rename characters bool ChatHandler::HandleCharacterRenameCommand(char* args) { diff --git a/src/game/MotionGenerators/MotionMaster.cpp b/src/game/MotionGenerators/MotionMaster.cpp index 657d45c5c..88e3e96fc 100644 --- a/src/game/MotionGenerators/MotionMaster.cpp +++ b/src/game/MotionGenerators/MotionMaster.cpp @@ -59,8 +59,10 @@ void MotionMaster::Initialize() if (m_owner->GetTypeId() == TYPEID_UNIT && !m_owner->hasUnitState(UNIT_STAT_CONTROLLED)) { MovementGenerator* movement = FactorySelector::selectMovementGenerator((Creature*)m_owner); - push(movement == NULL ? &si_idleMovement : movement); + push(movement == nullptr ? &si_idleMovement : movement); top()->Initialize(*m_owner); + if (top()->GetMovementGeneratorType() == WAYPOINT_MOTION_TYPE) + (static_cast*>(top()))->InitializeWaypointPath(*((Creature*)(m_owner)), 0, PATH_NO_PATH, 0, 0); } else push(&si_idleMovement); @@ -376,20 +378,22 @@ void MotionMaster::MoveFleeing(Unit* enemy, uint32 time) } } -void MotionMaster::MoveWaypoint() +void MotionMaster::MoveWaypoint(int32 id /*=0*/, uint32 source /*=0==PATH_NO_PATH*/, uint32 initialDelay /*=0*/, uint32 overwriteEntry /*=0*/) { if (m_owner->GetTypeId() == TYPEID_UNIT) { if (GetCurrentMovementGeneratorType() == WAYPOINT_MOTION_TYPE) { - sLog.outError("Creature %s (Entry %u) attempt to MoveWaypoint() but creature is already using waypoint", m_owner->GetGuidStr().c_str(), m_owner->GetEntry()); + sLog.outError("%s attempt to MoveWaypoint() but is already using waypoint", m_owner->GetGuidStr().c_str()); return; } Creature* creature = (Creature*)m_owner; - DEBUG_FILTER_LOG(LOG_FILTER_AI_AND_MOVEGENSS, "Creature %s (Entry %u) start MoveWaypoint()", m_owner->GetGuidStr().c_str(), m_owner->GetEntry()); - Mutate(new WaypointMovementGenerator(*creature)); + DEBUG_FILTER_LOG(LOG_FILTER_AI_AND_MOVEGENSS, "%s start MoveWaypoint()", m_owner->GetGuidStr().c_str()); + WaypointMovementGenerator* newWPMMgen = new WaypointMovementGenerator(*creature); + Mutate(newWPMMgen); + newWPMMgen->InitializeWaypointPath(*creature, id, (WaypointPathOrigin)source, initialDelay, overwriteEntry); } else { @@ -469,6 +473,16 @@ void MotionMaster::propagateSpeedChange() } } +bool MotionMaster::SetNextWaypoint(uint32 pointId) +{ + for (Impl::container_type::reverse_iterator rItr = Impl::c.rbegin(); rItr != Impl::c.rend(); ++rItr) + { + if ((*rItr)->GetMovementGeneratorType() == WAYPOINT_MOTION_TYPE) + return (static_cast*>(*rItr))->SetNextWaypoint(pointId); + } + return false; +} + uint32 MotionMaster::getLastReachedWaypoint() const { for (Impl::container_type::const_reverse_iterator rItr = Impl::c.rbegin(); rItr != Impl::c.rend(); ++rItr) @@ -487,6 +501,18 @@ MovementGeneratorType MotionMaster::GetCurrentMovementGeneratorType() const return top()->GetMovementGeneratorType(); } +void MotionMaster::GetWaypointPathInformation(std::ostringstream& oss) const +{ + for (Impl::container_type::const_reverse_iterator rItr = Impl::c.rbegin(); rItr != Impl::c.rend(); ++rItr) + { + if ((*rItr)->GetMovementGeneratorType() == WAYPOINT_MOTION_TYPE) + { + static_cast*>(*rItr)->GetPathInformation(oss); + return; + } + } +} + bool MotionMaster::GetDestination(float& x, float& y, float& z) { if (m_owner->movespline->Finalized()) diff --git a/src/game/MotionGenerators/MotionMaster.h b/src/game/MotionGenerators/MotionMaster.h index 6dee0c5ba..5ad398752 100644 --- a/src/game/MotionGenerators/MotionMaster.h +++ b/src/game/MotionGenerators/MotionMaster.h @@ -55,6 +55,10 @@ enum MovementGeneratorType TIMED_FLEEING_MOTION_TYPE = 13, // FleeingMovementGenerator.h (alt.second part of flee for assistance) FOLLOW_MOTION_TYPE = 14, // TargetedMovementGenerator.h EFFECT_MOTION_TYPE = 15, + + EXTERNAL_WAYPOINT_MOVE = 256, // Only used in CreatureAI::MovementInform when a waypoint is reached. The pathId >= 0 is added as additonal value + EXTERNAL_WAYPOINT_MOVE_START = 512, // Only used in CreatureAI::MovementInform when a waypoint is started. The pathId >= 0 is added as additional value + EXTERNAL_WAYPOINT_FINISHED_LAST = 1024, // Only used in CreatureAI::MovementInform when the waittime of the last wp is finished The pathId >= 0 is added as additional value }; enum MMCleanFlag @@ -113,7 +117,7 @@ class MotionMaster : private std::stack void MovePoint(uint32 id, float x, float y, float z, bool generatePath = true); void MoveSeekAssistance(float x, float y, float z); void MoveSeekAssistanceDistract(uint32 timer); - void MoveWaypoint(); + void MoveWaypoint(int32 id = 0, uint32 source = 0, uint32 initialDelay = 0, uint32 overwriteEntry = 0); void MoveTaxiFlight(uint32 path, uint32 pathnode); void MoveDistract(uint32 timeLimit); void MoveJump(float x, float y, float z, float horizontalSpeed, float max_height, uint32 id = 0); @@ -124,7 +128,9 @@ class MotionMaster : private std::stack MovementGeneratorType GetCurrentMovementGeneratorType() const; void propagateSpeedChange(); + bool SetNextWaypoint(uint32 pointId); uint32 getLastReachedWaypoint() const; + void GetWaypointPathInformation(std::ostringstream& oss) const; bool GetDestination(float& x, float& y, float& z); diff --git a/src/game/MotionGenerators/WaypointMovementGenerator.cpp b/src/game/MotionGenerators/WaypointMovementGenerator.cpp index a93181037..20939384a 100644 --- a/src/game/MotionGenerators/WaypointMovementGenerator.cpp +++ b/src/game/MotionGenerators/WaypointMovementGenerator.cpp @@ -77,6 +77,14 @@ void WaypointMovementGenerator::Initialize(Creature& creature) creature.clearUnitState(UNIT_STAT_WAYPOINT_PAUSED); } +void WaypointMovementGenerator::InitializeWaypointPath(Creature& u, int32 id, WaypointPathOrigin wpSource, uint32 initialDelay, uint32 overwriteEntry) +{ + LoadPath(u, id, wpSource, overwriteEntry); + i_nextMoveTime.Reset(initialDelay); + // Start moving if possible + StartMove(u); +} + void WaypointMovementGenerator::Finalize(Creature& creature) { creature.clearUnitState(UNIT_STAT_ROAMING | UNIT_STAT_ROAMING_MOVE); @@ -156,6 +164,15 @@ void WaypointMovementGenerator::OnArrived(Creature& creature) } // Inform script + if (creature.AI()) + { + uint32 type = WAYPOINT_MOTION_TYPE; + if (m_PathOrigin == PATH_FROM_EXTERNAL && m_pathId > 0) + type = EXTERNAL_WAYPOINT_MOVE + m_pathId; + creature.AI()->MovementInform(type, i_currentNode); + } + + // Wait delay ms Stop(node.delay); } @@ -182,9 +199,25 @@ void WaypointMovementGenerator::StartMove(Creature& creature) if (m_isArrivalDone) { + bool reachedLast = false; ++currPoint; if (currPoint == i_path->end()) + { + reachedLast = true; currPoint = i_path->begin(); + } + + // Inform AI + if (creature.AI() && m_PathOrigin == PATH_FROM_EXTERNAL && m_pathId > 0) + { + if (!reachedLast) + creature.AI()->MovementInform(EXTERNAL_WAYPOINT_MOVE_START + m_pathId, currPoint->first); + else + creature.AI()->MovementInform(EXTERNAL_WAYPOINT_FINISHED_LAST + m_pathId, currPoint->first); + + if (creature.IsDead() || !creature.IsInWorld()) // Might have happened with above calls + return; + } i_currentNode = currPoint->first; } @@ -238,6 +271,20 @@ bool WaypointMovementGenerator::Update(Creature& creature, const uint3 return true; } +bool WaypointMovementGenerator::Stopped(Creature& u) +{ + return !i_nextMoveTime.Passed() || u.hasUnitState(UNIT_STAT_WAYPOINT_PAUSED); +} + +bool WaypointMovementGenerator::CanMove(int32 diff, Creature& u) +{ + i_nextMoveTime.Update(diff); + if (i_nextMoveTime.Passed() && u.hasUnitState(UNIT_STAT_WAYPOINT_PAUSED)) + i_nextMoveTime.Reset(1); + + return i_nextMoveTime.Passed() && !u.hasUnitState(UNIT_STAT_WAYPOINT_PAUSED); +} + bool WaypointMovementGenerator::GetResetPosition(Creature&, float& x, float& y, float& z, float& o) const { // prevent a crash at empty waypoint path. @@ -280,18 +327,10 @@ bool WaypointMovementGenerator::GetResetPosition(Creature&, float& x, return true; } -bool WaypointMovementGenerator::Stopped(Creature& u) +void WaypointMovementGenerator::GetPathInformation(std::ostringstream& oss) const { - return !i_nextMoveTime.Passed() || u.hasUnitState(UNIT_STAT_WAYPOINT_PAUSED); -} - -bool WaypointMovementGenerator::CanMove(int32 diff, Creature& u) -{ - i_nextMoveTime.Update(diff); - if (i_nextMoveTime.Passed() && u.hasUnitState(UNIT_STAT_WAYPOINT_PAUSED)) - i_nextMoveTime.Reset(1); - - return i_nextMoveTime.Passed() && !u.hasUnitState(UNIT_STAT_WAYPOINT_PAUSED); + oss << "WaypointMovement: Last Reached WP: " << m_lastReachedWaypoint << " "; + oss << "(Loaded path " << m_pathId << " from " << WaypointManager::GetOriginString(m_PathOrigin) << ")\n"; } void WaypointMovementGenerator::AddToWaypointPauseTime(int32 waitTimeDiff) @@ -304,6 +343,26 @@ void WaypointMovementGenerator::AddToWaypointPauseTime(int32 waitTimeD } } +bool WaypointMovementGenerator::SetNextWaypoint(uint32 pointId) +{ + if (!i_path || i_path->empty()) + return false; + + WaypointPath::const_iterator currPoint = i_path->find(pointId); + if (currPoint == i_path->end()) + return false; + + // Allow Moving with next tick + // Handle allow movement this way to not interact with PAUSED state. + // If this function is called while PAUSED, it will move properly when unpaused. + i_nextMoveTime.Reset(1); + m_isArrivalDone = false; + + // Set the point + i_currentNode = pointId; + return true; +} + //----------------------------------------------------// uint32 FlightPathMovementGenerator::GetPathAtMapEnd() const { diff --git a/src/game/Object/ObjectAccessor.cpp b/src/game/Object/ObjectAccessor.cpp index 8db68b496..37dd6c805 100644 --- a/src/game/Object/ObjectAccessor.cpp +++ b/src/game/Object/ObjectAccessor.cpp @@ -37,6 +37,8 @@ #include "ObjectGuid.h" #include "World.h" +#include + #include #define CLASS_LOCK MaNGOS::ClassLevelLockable diff --git a/src/game/Object/ObjectAccessor.h b/src/game/Object/ObjectAccessor.h index e04eac5b8..c95e9910d 100644 --- a/src/game/Object/ObjectAccessor.h +++ b/src/game/Object/ObjectAccessor.h @@ -40,6 +40,8 @@ #include "Player.h" #include "Corpse.h" +#include + #include #include diff --git a/src/game/Object/Unit.cpp b/src/game/Object/Unit.cpp index cbf01517b..b79977f72 100644 --- a/src/game/Object/Unit.cpp +++ b/src/game/Object/Unit.cpp @@ -9568,7 +9568,7 @@ bool Unit::SelectHostileTarget() // check if currently selected target is reachable // NOTE: path alrteady generated from AttackStart() - if (!GetMotionMaster()->operator->()->IsReachable()) + if (!GetMotionMaster()->GetCurrent()->IsReachable()) { // remove all taunts RemoveSpellsCausingAura(SPELL_AURA_MOD_TAUNT); diff --git a/src/game/Server/WorldSession.cpp b/src/game/Server/WorldSession.cpp index b877c78b0..c61c1a0f6 100644 --- a/src/game/Server/WorldSession.cpp +++ b/src/game/Server/WorldSession.cpp @@ -58,6 +58,8 @@ #include "Auth/HMACSHA1.h" #include "zlib.h" +#include + // select opcodes appropriate for processing in Map::Update context for current session state static bool MapSessionFilterHelper(WorldSession* session, OpcodeHandler const& opHandle) { diff --git a/src/game/Server/WorldSession.h b/src/game/Server/WorldSession.h index 9d6ff0183..8aa5e21f4 100644 --- a/src/game/Server/WorldSession.h +++ b/src/game/Server/WorldSession.h @@ -37,6 +37,8 @@ #include "Item.h" #include "LFGMgr.h" +#include + struct ItemPrototype; struct AuctionEntry; struct AuctionHouseEntry; diff --git a/src/game/WorldHandlers/Chat.cpp b/src/game/WorldHandlers/Chat.cpp index 35d881a36..1393fae0a 100644 --- a/src/game/WorldHandlers/Chat.cpp +++ b/src/game/WorldHandlers/Chat.cpp @@ -742,7 +742,6 @@ ChatCommand* ChatHandler::getCommandTable() { "add", SEC_GAMEMASTER, false, &ChatHandler::HandleWpAddCommand, "", NULL }, { "modify", SEC_GAMEMASTER, false, &ChatHandler::HandleWpModifyCommand, "", NULL }, { "export", SEC_ADMINISTRATOR, false, &ChatHandler::HandleWpExportCommand, "", NULL }, - { "import", SEC_ADMINISTRATOR, false, &ChatHandler::HandleWpImportCommand, "", NULL }, { NULL, 0, false, NULL, "", NULL } }; diff --git a/src/game/WorldHandlers/Chat.h b/src/game/WorldHandlers/Chat.h index 8c472301e..114870bf6 100644 --- a/src/game/WorldHandlers/Chat.h +++ b/src/game/WorldHandlers/Chat.h @@ -566,7 +566,6 @@ class ChatHandler bool HandleWpModifyCommand(char* args); bool HandleWpShowCommand(char* args); bool HandleWpExportCommand(char* args); - bool HandleWpImportCommand(char* args); bool HandleHelpCommand(char* args); bool HandleCommandsCommand(char* args); diff --git a/src/game/WorldHandlers/GameEventMgr.h b/src/game/WorldHandlers/GameEventMgr.h index 336ca6610..3e0d2a726 100644 --- a/src/game/WorldHandlers/GameEventMgr.h +++ b/src/game/WorldHandlers/GameEventMgr.h @@ -30,6 +30,8 @@ #include "Platform/Define.h" #include "Policies/Singleton.h" +#include + #define max_ge_check_delay 86400 // 1 day in seconds class Creature; diff --git a/src/game/WorldHandlers/GridMap.cpp b/src/game/WorldHandlers/GridMap.cpp index db31b3de5..9f77447d2 100644 --- a/src/game/WorldHandlers/GridMap.cpp +++ b/src/game/WorldHandlers/GridMap.cpp @@ -36,6 +36,8 @@ #include "Policies/Singleton.h" #include "Util.h" +#include + char const* MAP_MAGIC = "MAPS"; char const* MAP_VERSION_MAGIC = "c1.4"; char const* MAP_AREA_MAGIC = "AREA"; diff --git a/src/game/WorldHandlers/GridMap.h b/src/game/WorldHandlers/GridMap.h index de477addd..7c29d2cc6 100644 --- a/src/game/WorldHandlers/GridMap.h +++ b/src/game/WorldHandlers/GridMap.h @@ -35,6 +35,8 @@ #include #include +#include + class Creature; class Unit; class WorldPacket; diff --git a/src/game/WorldHandlers/MapPersistentStateMgr.h b/src/game/WorldHandlers/MapPersistentStateMgr.h index d44838817..5910e10c2 100644 --- a/src/game/WorldHandlers/MapPersistentStateMgr.h +++ b/src/game/WorldHandlers/MapPersistentStateMgr.h @@ -38,6 +38,8 @@ #include "ObjectGuid.h" #include "PoolManager.h" +#include + struct InstanceTemplate; struct MapEntry; struct MapDifficultyEntry; diff --git a/src/game/WorldHandlers/MiscHandler.cpp b/src/game/WorldHandlers/MiscHandler.cpp index 8e72faf49..f6963c652 100644 --- a/src/game/WorldHandlers/MiscHandler.cpp +++ b/src/game/WorldHandlers/MiscHandler.cpp @@ -779,8 +779,8 @@ void WorldSession::HandleAreaTriggerOpcode(WorldPacket& recv_data) if (BattleGround* bg = player->GetBattleGround()) { - bg->HandleAreaTrigger(player, Trigger_ID); - return; + if (bg->HandleAreaTrigger(player, Trigger_ID)) + return; } else if (OutdoorPvP* outdoorPvP = sOutdoorPvPMgr.GetScript(player->GetCachedZoneId())) { diff --git a/src/game/WorldHandlers/ScriptMgr.cpp b/src/game/WorldHandlers/ScriptMgr.cpp index 2c62dc036..17c3f5043 100644 --- a/src/game/WorldHandlers/ScriptMgr.cpp +++ b/src/game/WorldHandlers/ScriptMgr.cpp @@ -2852,6 +2852,11 @@ uint32 GetScriptIdsCount() return sScriptMgr.GetScriptIdsCount(); } +void SetExternalWaypointTable(char const* tableName) +{ + sWaypointMgr.SetExternalWPTable(tableName); +} + bool AddWaypointFromExternal(uint32 entry, int32 pathId, uint32 pointId, float x, float y, float z, float o, uint32 waittime) { return sWaypointMgr.AddExternalNode(entry, pathId, pointId, x, y, z, o, waittime); diff --git a/src/game/WorldHandlers/ScriptMgr.h b/src/game/WorldHandlers/ScriptMgr.h index 7709b67be..37ddc0772 100644 --- a/src/game/WorldHandlers/ScriptMgr.h +++ b/src/game/WorldHandlers/ScriptMgr.h @@ -29,7 +29,8 @@ #include "Policies/Singleton.h" #include "ObjectGuid.h" #include "DBCEnums.h" -#include +//#include <- delete this if the #include below works +#include struct AreaTriggerEntry; struct SpellEntry; @@ -614,6 +615,9 @@ class ScriptMgr void LoadEventIdScripts(); void LoadSpellIdScripts(); + uint32 GetAreaTriggerScriptId(uint32 triggerId) const; + uint32 GetEventIdScriptId(uint32 eventId) const; + bool ReloadScriptBinding(); const char* GetScriptName(uint32 id) const @@ -707,6 +711,14 @@ bool StartEvents_Event(Map* map, uint32 id, Object* source, Object* target, bool #define sScriptMgr MaNGOS::Singleton::Instance() +MANGOS_DLL_SPEC uint32 GetAreaTriggerScriptId(uint32 triggerId); +MANGOS_DLL_SPEC uint32 GetEventIdScriptId(uint32 eventId); +MANGOS_DLL_SPEC uint32 GetScriptId(const char* name); +MANGOS_DLL_SPEC char const* GetScriptName(uint32 id); +MANGOS_DLL_SPEC uint32 GetScriptIdsCount(); +MANGOS_DLL_SPEC void SetExternalWaypointTable(char const* tableName); +MANGOS_DLL_SPEC bool AddWaypointFromExternal(uint32 entry, int32 pathId, uint32 pointId, float x, float y, float z, float o, uint32 waittime); + uint32 GetScriptId(const char* name); char const* GetScriptName(uint32 id); uint32 GetScriptIdsCount(); diff --git a/src/game/WorldHandlers/WaypointManager.cpp b/src/game/WorldHandlers/WaypointManager.cpp index d1f74abfe..79f61f899 100644 --- a/src/game/WorldHandlers/WaypointManager.cpp +++ b/src/game/WorldHandlers/WaypointManager.cpp @@ -112,6 +112,7 @@ void WaypointManager::Load() { barRow.step(); Field* fields = result->Fetch(); + uint32 id = fields[0].GetUInt32(); uint32 point = fields[1].GetUInt32(); @@ -126,7 +127,7 @@ void WaypointManager::Load() if (cData->movementType != WAYPOINT_MOTION_TYPE) creatureNoMoveType.insert(id); - WaypointPath& path = m_pathMap[id]; + WaypointPath& path = m_pathTemplateMap[id << 8]; WaypointNode& node = path[point]; node.x = fields[2].GetFloat(); @@ -391,12 +392,16 @@ void WaypointManager::Load() void WaypointManager::Unload() { for (WaypointPathMap::iterator itr = m_pathMap.begin(); itr != m_pathMap.end(); ++itr) - _clearPath(itr->second); + { _clearPath(itr->second); } m_pathMap.clear(); for (WaypointPathMap::iterator itr = m_pathTemplateMap.begin(); itr != m_pathTemplateMap.end(); ++itr) - _clearPath(itr->second); + { _clearPath(itr->second); } m_pathTemplateMap.clear(); + + for (WaypointPathMap::iterator itr = m_externalPathTemplateMap.begin(); itr != m_externalPathTemplateMap.end(); ++itr) + { _clearPath(itr->second); } + m_externalPathTemplateMap.clear(); } void WaypointManager::_clearPath(WaypointPath& path) diff --git a/src/game/WorldHandlers/WaypointManager.h b/src/game/WorldHandlers/WaypointManager.h index b0e4a8cb9..892e823a9 100644 --- a/src/game/WorldHandlers/WaypointManager.h +++ b/src/game/WorldHandlers/WaypointManager.h @@ -110,8 +110,8 @@ class WaypointManager // Helper function to get a path provided the required information WaypointPath* GetPathFromOrigin(uint32 entry, uint32 lowGuid, int32 pathId, WaypointPathOrigin wpOrigin) { - WaypointPathMap* wpMap = NULL; - uint32 key = 0; + WaypointPathMap* wpMap; + uint32 key; switch (wpOrigin) { @@ -121,19 +121,19 @@ class WaypointManager break; case PATH_FROM_ENTRY: if (pathId >= 0xFF || pathId < 0) - return NULL; + return nullptr; key = (entry << 8) + pathId; wpMap = &m_pathTemplateMap; break; case PATH_FROM_EXTERNAL: if (pathId >= 0xFF || pathId < 0) - return NULL; + return nullptr; key = (entry << 8) + pathId; wpMap = &m_externalPathTemplateMap; break; case PATH_NO_PATH: default: - return NULL; + return nullptr; } WaypointPathMap::iterator find = wpMap->find(key); return find != wpMap->end() ? &find->second : NULL; @@ -197,6 +197,6 @@ class WaypointManager #define sWaypointMgr MaNGOS::Singleton::Instance() /// Accessor for Scripting library -MANGOS_DLL_SPEC bool AddWaypointFromExternal(uint32 entry, int32 pathId, uint32 pointId, float x, float y, float z, float o, uint32 waittime); +bool AddWaypointFromExternal(uint32 entry, int32 pathId, uint32 pointId, float x, float y, float z, float o, uint32 waittime); #endif diff --git a/src/game/vmap/MapTree.cpp b/src/game/vmap/MapTree.cpp index ef90fc426..619c7da30 100644 --- a/src/game/vmap/MapTree.cpp +++ b/src/game/vmap/MapTree.cpp @@ -32,6 +32,8 @@ #include #include +#include + using G3D::Vector3; namespace VMAP diff --git a/src/game/vmap/VMapManager2.h b/src/game/vmap/VMapManager2.h index 149a5456f..6f6797e2e 100644 --- a/src/game/vmap/VMapManager2.h +++ b/src/game/vmap/VMapManager2.h @@ -30,6 +30,8 @@ #include "Platform/Define.h" #include +#include + //=========================================================== #define MAP_FILENAME_EXTENSION2 ".vmtree" diff --git a/src/modules/SD3/scripts/kalimdor/darkshore.cpp b/src/modules/SD3/scripts/kalimdor/darkshore.cpp index 4ef7c21f5..10c57ea59 100644 --- a/src/modules/SD3/scripts/kalimdor/darkshore.cpp +++ b/src/modules/SD3/scripts/kalimdor/darkshore.cpp @@ -367,7 +367,12 @@ enum SAY_AT_CLOSE = -1000326, QUEST_GYROMAST_REV = 2078, NPC_GELKAK = 6667, - FACTION_HOSTILE = 14 + FACTION_HOSTILE = 14, + + TEXT_ID_THRESH_DEFAULT = 718, + TEXT_ID_KEY_READY = 758, + + GOSSIP_ITEM_TURN_KEY = -3000115, }; #define GOSSIP_ITEM_INSERT_KEY "[PH] Insert key" @@ -416,10 +421,12 @@ struct npc_threshwackonator : public CreatureScript { if (pPlayer->GetQuestStatus(QUEST_GYROMAST_REV) == QUEST_STATUS_INCOMPLETE) { - pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_INSERT_KEY, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); + pPlayer->ADD_GOSSIP_ITEM_ID(GOSSIP_ICON_CHAT, GOSSIP_ITEM_TURN_KEY, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); + pPlayer->SEND_GOSSIP_MENU(TEXT_ID_KEY_READY, pCreature->GetObjectGuid()); } + else + pPlayer->SEND_GOSSIP_MENU(TEXT_ID_THRESH_DEFAULT, pCreature->GetObjectGuid()); - pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetObjectGuid()); return true; } diff --git a/src/modules/SD3/scripts/northrend/borean_tundra.cpp b/src/modules/SD3/scripts/northrend/borean_tundra.cpp index 8e51c8ab6..dcb0a62f8 100644 --- a/src/modules/SD3/scripts/northrend/borean_tundra.cpp +++ b/src/modules/SD3/scripts/northrend/borean_tundra.cpp @@ -33,6 +33,7 @@ npc_captured_beryl_sorcerer npc_nexus_drake_hatchling npc_scourged_flamespitter npc_bonker_togglevolt +npc_jenny EndContentData */ #include "precompiled.h" @@ -1128,6 +1129,119 @@ struct npc_bonker_togglevolt : public CreatureScript } }; +/*###### +## npc_jenny +######*/ + +enum +{ + SPELL_CREATES_CARRIED = 46340, + SPELL_DROP_CRATE = 46342, + SPELL_JENNY_CREDIT = 46358, + + NPC_FEZZIX = 25849, + + QUEST_ID_LOADER_UP = 11881, +}; + +struct npc_jenny : public CreatureScript +{ + npc_jenny() : CreatureScript("npc_jenny") {} + + struct npc_jennyAI : public FollowerAI + { + npc_jennyAI(Creature* pCreature) : FollowerAI(pCreature) + { + m_bFollowStarted = false; + m_bEventComplete = false; + Reset(); + } + + bool m_bEventComplete; + bool m_bFollowStarted; + + uint32 m_uiDropDelayTimer; + + void Reset() override + { + m_uiDropDelayTimer = 0; + } + + void AttackedBy(Unit* pAttacker) override + { + if (!m_uiDropDelayTimer) + { + if (DoCastSpellIfCan(m_creature, SPELL_DROP_CRATE) == CAST_OK) + { + m_creature->RemoveAuraHolderFromStack(SPELL_CREATES_CARRIED); + m_uiDropDelayTimer = 10000; + + // check if all crates are dropped + if (!m_creature->HasAura(SPELL_CREATES_CARRIED)) + { + FollowerAI::JustDied(pAttacker); + m_creature->ForcedDespawn(); + } + } + } + } + + void AttackStart(Unit* pWho) override { } + + void MoveInLineOfSight(Unit* pWho) override + { + if (m_bEventComplete) + return; + + if (pWho->GetEntry() == NPC_FEZZIX && m_creature->IsWithinDistInMap(pWho, 10.0f)) + { + if (DoCastSpellIfCan(m_creature, SPELL_JENNY_CREDIT) == CAST_OK) + { + SetFollowComplete(true); + + float fX, fY, fZ; + pWho->GetContactPoint(m_creature, fX, fY, fZ); + m_creature->GetMotionMaster()->MovePoint(0, fX, fY, fZ); + m_creature->ForcedDespawn(15000); + + m_bEventComplete = true; + } + } + } + + void UpdateFollowerAI(const uint32 uiDiff) + { + if (!m_bFollowStarted) + { + if (Player* pSummoner = m_creature->GetCharmerOrOwnerPlayerOrPlayerItself()) + { + StartFollow(pSummoner, pSummoner->getFaction(), GetQuestTemplateStore(QUEST_ID_LOADER_UP)); + + if (DoCastSpellIfCan(m_creature, SPELL_CREATES_CARRIED) == CAST_OK) + m_bFollowStarted = true; + } + } + + if (m_uiDropDelayTimer) + { + if (m_uiDropDelayTimer <= uiDiff) + m_uiDropDelayTimer = 0; + else + m_uiDropDelayTimer -= uiDiff; + } + + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + } + + }; + + CreatureAI* GetAI(Creature* pCreature) override + { + return new npc_jennyAI(pCreature); + } +}; + void AddSC_borean_tundra() { Script* s; @@ -1146,6 +1260,8 @@ void AddSC_borean_tundra() s->RegisterSelf(); s = new npc_bonker_togglevolt(); s->RegisterSelf(); + s = new npc_jenny(); + s->RegisterSelf(); s = new spell_throw_wolf_batt(); s->RegisterSelf(); diff --git a/src/shared/Common/Common.h b/src/shared/Common/Common.h index f42591ac7..13a39c5b5 100644 --- a/src/shared/Common/Common.h +++ b/src/shared/Common/Common.h @@ -88,6 +88,7 @@ #include #include #include +#include #include "Utilities/Errors.h" #include "LockedQueue/LockedQueue.h" diff --git a/src/shared/Config/Config.cpp b/src/shared/Config/Config.cpp index 1c268d84c..441237cb7 100644 --- a/src/shared/Config/Config.cpp +++ b/src/shared/Config/Config.cpp @@ -24,6 +24,11 @@ #include "Config.h" #include +#include + +#include +#include +#include #include "Policies/Singleton.h" diff --git a/src/shared/Config/Config.h b/src/shared/Config/Config.h index 5889569ea..7db4dc664 100644 --- a/src/shared/Config/Config.h +++ b/src/shared/Config/Config.h @@ -28,6 +28,10 @@ #include "Common/Common.h" #include #include "Platform/Define.h" +#include + +#include +#include class ACE_Configuration_Heap; diff --git a/src/shared/Database/SqlDelayThread.h b/src/shared/Database/SqlDelayThread.h index c3fa7f412..9d5f4e0e3 100644 --- a/src/shared/Database/SqlDelayThread.h +++ b/src/shared/Database/SqlDelayThread.h @@ -29,6 +29,8 @@ #include "LockedQueue/LockedQueue.h" #include "Threading/Threading.h" +#include + class Database; class SqlOperation; class SqlConnection; diff --git a/src/shared/Database/SqlOperations.h b/src/shared/Database/SqlOperations.h index 3a4417bec..00b2f9af9 100644 --- a/src/shared/Database/SqlOperations.h +++ b/src/shared/Database/SqlOperations.h @@ -32,6 +32,8 @@ #include #include "Utilities/Callback.h" +#include + /// ---- BASE --- class Database; diff --git a/src/shared/Log/Log.h b/src/shared/Log/Log.h index ded0d77da..09c5fba20 100644 --- a/src/shared/Log/Log.h +++ b/src/shared/Log/Log.h @@ -28,6 +28,8 @@ #include "Common/Common.h" #include "Policies/Singleton.h" +#include + class Config; class ByteBuffer; diff --git a/src/tools/Extractor_projects/Movemap-Generator/CMakeLists.txt b/src/tools/Extractor_projects/Movemap-Generator/CMakeLists.txt index 9d2da1ccd..50ab3573a 100644 --- a/src/tools/Extractor_projects/Movemap-Generator/CMakeLists.txt +++ b/src/tools/Extractor_projects/Movemap-Generator/CMakeLists.txt @@ -67,23 +67,11 @@ else() target_link_libraries(${EXECUTABLE_NAME} ACE) endif() -target_link_libraries(${EXECUTABLE_NAME} g3dlite vmap detour recast zlib shared) - -set(EXECUTABLE_LINK_FLAGS "") - if(UNIX) - if(CMAKE_SYSTEM_NAME MATCHES "FreeBSD") - set(EXECUTABLE_LINK_FLAGS "-Wl,--no-as-needed -lrt -pthread ${EXECUTABLE_LINK_FLAGS}") - elseif(CMAKE_SYSTEM_NAME MATCHES "Linux") - set(EXECUTABLE_LINK_FLAGS "-Wl,--no-as-needed -ldl -pthread -lrt ${EXECUTABLE_LINK_FLAGS}") - endif() + target_link_libraries(${EXECUTABLE_NAME} rt) endif() -if(APPLE) - set(EXECUTABLE_LINK_FLAGS "-framework CoreServices ${EXECUTABLE_LINK_FLAGS}") -endif() - -set_target_properties(${EXECUTABLE_NAME} PROPERTIES LINK_FLAGS "${EXECUTABLE_LINK_FLAGS}") +target_link_libraries(${EXECUTABLE_NAME} g3dlite vmap detour recast zlib shared) #Output the compiled exes to build/bin/$(Configuration)/tools directory on windows by default if(WIN32) diff --git a/src/tools/Extractor_projects/vmap-assembler/CMakeLists.txt b/src/tools/Extractor_projects/vmap-assembler/CMakeLists.txt index b3edd4610..96e65f549 100644 --- a/src/tools/Extractor_projects/vmap-assembler/CMakeLists.txt +++ b/src/tools/Extractor_projects/vmap-assembler/CMakeLists.txt @@ -47,22 +47,20 @@ else() target_link_libraries(${EXECUTABLE_NAME} ACE) endif() +if(UNIX) + target_link_libraries(${EXECUTABLE_NAME} rt dl) +endif() + target_link_libraries(${EXECUTABLE_NAME} vmap g3dlite zlib) set(EXECUTABLE_LINK_FLAGS "") if(UNIX) - if(CMAKE_SYSTEM_NAME MATCHES "FreeBSD") - set(EXECUTABLE_LINK_FLAGS "-Wl,--no-as-needed -lrt -pthread ${EXECUTABLE_LINK_FLAGS}") - elseif(CMAKE_SYSTEM_NAME MATCHES "Linux") - set(EXECUTABLE_LINK_FLAGS "-Wl,--no-as-needed -ldl -pthread -lrt ${EXECUTABLE_LINK_FLAGS}") + if(CMAKE_C_COMPILER MATCHES "clang" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") + set(EXECUTABLE_LINK_FLAGS "-pthread${EXECUTABLE_LINK_FLAGS}") endif() endif() -if(APPLE) - set(EXECUTABLE_LINK_FLAGS "-framework CoreServices ${EXECUTABLE_LINK_FLAGS}") -endif() - set_target_properties(${EXECUTABLE_NAME} PROPERTIES LINK_FLAGS "${EXECUTABLE_LINK_FLAGS}") #Output the compiled exes to build/bin/$(Configuration)/tools directory on windows by default