aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Movement
diff options
context:
space:
mode:
authorccrs <ccrs@users.noreply.github.com>2017-08-12 01:40:25 +0200
committerGitHub <noreply@github.com>2017-08-12 01:40:25 +0200
commit7fff83d67526efff63867d41b9e036a19a9287b3 (patch)
tree0462cb16ac0099318ab9ce07dc6cc099e141375e /src/server/game/Movement
parent00329fe9a505c437af0b7591d8321bf3b77ad7fb (diff)
Core/Movement: waypoint movement (#20121)
Following the work done in #19361 this is the cleanup and improvement of the related logic of waypoint management. Ref 28050f3 #18020 (taking the good parts and ignoring the incomplete work)
Diffstat (limited to 'src/server/game/Movement')
-rw-r--r--src/server/game/Movement/MotionMaster.cpp40
-rw-r--r--src/server/game/Movement/MotionMaster.h8
-rwxr-xr-xsrc/server/game/Movement/MovementGenerator.h3
-rwxr-xr-xsrc/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp7
-rw-r--r--src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp4
-rwxr-xr-xsrc/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp264
-rwxr-xr-xsrc/server/game/Movement/MovementGenerators/WaypointMovementGenerator.h88
-rw-r--r--src/server/game/Movement/Waypoints/WaypointDefines.h71
-rw-r--r--src/server/game/Movement/Waypoints/WaypointManager.cpp99
-rw-r--r--src/server/game/Movement/Waypoints/WaypointManager.h38
10 files changed, 356 insertions, 266 deletions
diff --git a/src/server/game/Movement/MotionMaster.cpp b/src/server/game/Movement/MotionMaster.cpp
index 003c9708628..c0450f97563 100644
--- a/src/server/game/Movement/MotionMaster.cpp
+++ b/src/server/game/Movement/MotionMaster.cpp
@@ -17,25 +17,28 @@
*/
#include "MotionMaster.h"
+#include "ConfusedMovementGenerator.h"
#include "Creature.h"
#include "CreatureAISelector.h"
#include "DBCStores.h"
-#include "Log.h"
-#include "Map.h"
-#include "PathGenerator.h"
-#include "ScriptSystem.h"
-#include "ConfusedMovementGenerator.h"
#include "FleeingMovementGenerator.h"
+#include "FormationMovementGenerator.h"
#include "HomeMovementGenerator.h"
#include "IdleMovementGenerator.h"
+#include "Log.h"
+#include "Map.h"
+#include "MoveSpline.h"
+#include "MoveSplineInit.h"
+#include "PathGenerator.h"
+#include "Player.h"
#include "PointMovementGenerator.h"
-#include "TargetedMovementGenerator.h"
-#include "WaypointMovementGenerator.h"
#include "RandomMovementGenerator.h"
+#include "ScriptSystem.h"
#include "SplineChainMovementGenerator.h"
-#include "FormationMovementGenerator.h"
-#include "MoveSpline.h"
-#include "MoveSplineInit.h"
+#include "TargetedMovementGenerator.h"
+#include "Unit.h"
+#include "WaypointDefines.h"
+#include "WaypointMovementGenerator.h"
inline MovementGenerator* GetIdleMovementGenerator()
{
@@ -672,16 +675,21 @@ void MotionMaster::MoveDistract(uint32 timer)
Mutate(mgen, MOTION_SLOT_CONTROLLED);
}
-void MotionMaster::MovePath(uint32 path_id, bool repeatable)
+void MotionMaster::MovePath(uint32 pathId, bool repeatable)
{
- if (!path_id)
+ if (!pathId)
return;
- Mutate(new WaypointMovementGenerator<Creature>(path_id, repeatable), MOTION_SLOT_IDLE);
+ Mutate(new WaypointMovementGenerator<Creature>(pathId, repeatable), MOTION_SLOT_IDLE);
+
+ TC_LOG_DEBUG("misc", "%s (GUID: %u) starts moving over path(Id:%u, repeatable: %s).", _owner->GetTypeId() == TYPEID_PLAYER ? "Player" : "Creature", _owner->GetGUID().GetCounter(), pathId, repeatable ? "YES" : "NO");
+}
+
+void MotionMaster::MovePath(WaypointPath& path, bool repeatable)
+{
+ Mutate(new WaypointMovementGenerator<Creature>(path, repeatable), MOTION_SLOT_IDLE);
- TC_LOG_DEBUG("misc", "%s (GUID: %u) starts moving over path(Id:%u, repeatable: %s).",
- _owner->GetTypeId() == TYPEID_PLAYER ? "Player" : "Creature",
- _owner->GetGUID().GetCounter(), path_id, repeatable ? "YES" : "NO");
+ TC_LOG_DEBUG("misc", "%s (GUID: %u) start moving over path(repeatable: %s)", _owner->GetTypeId() == TYPEID_PLAYER ? "Player" : "Creature", _owner->GetGUID().GetCounter(), repeatable ? "YES" : "NO");
}
void MotionMaster::MoveRotate(uint32 time, RotateDirection direction)
diff --git a/src/server/game/Movement/MotionMaster.h b/src/server/game/Movement/MotionMaster.h
index d33739781b2..dcee98cdaaa 100644
--- a/src/server/game/Movement/MotionMaster.h
+++ b/src/server/game/Movement/MotionMaster.h
@@ -31,6 +31,7 @@ class Unit;
class PathGenerator;
struct SplineChainLink;
struct SplineChainResumeInfo;
+struct WaypointPath;
// Creature Entry ID used for waypoints show, visible only for GMs
#define VISUAL_WAYPOINT 1
@@ -61,9 +62,9 @@ enum MovementGeneratorType : uint8
MAX_MOTION_TYPE // limit
};
-enum MovementSlot
+enum MovementSlot : uint8
{
- MOTION_SLOT_IDLE,
+ MOTION_SLOT_IDLE = 0,
MOTION_SLOT_ACTIVE,
MOTION_SLOT_CONTROLLED,
MAX_MOTION_SLOT
@@ -160,7 +161,8 @@ class TC_GAME_API MotionMaster
void MoveSeekAssistanceDistract(uint32 timer);
void MoveTaxiFlight(uint32 path, uint32 pathnode);
void MoveDistract(uint32 time);
- void MovePath(uint32 path_id, bool repeatable);
+ void MovePath(uint32 pathId, bool repeatable);
+ void MovePath(WaypointPath& path, bool repeatable);
void MoveRotate(uint32 time, RotateDirection direction);
void MoveFormation(uint32 id, Position destination, uint32 moveType, bool forceRun = false, bool forceOrientation = false);
diff --git a/src/server/game/Movement/MovementGenerator.h b/src/server/game/Movement/MovementGenerator.h
index 8f75e3a2361..39b2a16cc8b 100755
--- a/src/server/game/Movement/MovementGenerator.h
+++ b/src/server/game/Movement/MovementGenerator.h
@@ -36,10 +36,11 @@ class TC_GAME_API MovementGenerator
virtual void Finalize(Unit*) = 0;
virtual void Reset(Unit*) = 0;
virtual bool Update(Unit*, uint32 diff) = 0;
-
virtual MovementGeneratorType GetMovementGeneratorType() const = 0;
virtual void UnitSpeedChanged() { }
+ virtual void Pause(uint32/* timer = 0*/) { } // timer in ms
+ virtual void Resume(uint32/* overrideTimer = 0*/) { } // timer in ms
// used by Evade code for select point to evade with expected restart default movement
virtual bool GetResetPosition(Unit*, float& /*x*/, float& /*y*/, float& /*z*/) { return false; }
diff --git a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp
index a952421833d..7da90e2d515 100755
--- a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp
+++ b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp
@@ -18,7 +18,6 @@
#include "CreatureAI.h"
#include "Creature.h"
-#include "CreatureGroups.h"
#include "Player.h"
#include "MoveSplineInit.h"
#include "MoveSpline.h"
@@ -55,8 +54,7 @@ void PointMovementGenerator<T>::DoInitialize(T* owner)
// Call for creature group update
if (Creature* creature = owner->ToCreature())
- if (creature->GetFormation() && creature->GetFormation()->getLeader() == creature)
- creature->GetFormation()->LeaderMoveTo(Position(_x, _y, _z), _movementId);
+ creature->SignalFormationMovement(Position(_x, _y, _z), _movementId);
}
template<class T>
@@ -90,8 +88,7 @@ bool PointMovementGenerator<T>::DoUpdate(T* owner, uint32 /*diff*/)
// Call for creature group update
if (Creature* creature = owner->ToCreature())
- if (creature->GetFormation() && creature->GetFormation()->getLeader() == creature)
- creature->GetFormation()->LeaderMoveTo(Position(_x, _y, _z), _movementId);
+ creature->SignalFormationMovement(Position(_x, _y, _z), _movementId);
}
return !owner->movespline->Finalized();
diff --git a/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp
index 0a1972c0972..b2a9e5b83b9 100644
--- a/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp
+++ b/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp
@@ -18,7 +18,6 @@
#include "RandomMovementGenerator.h"
#include "Creature.h"
-#include "CreatureGroups.h"
#include "Map.h"
#include "MoveSplineInit.h"
#include "MoveSpline.h"
@@ -116,8 +115,7 @@ void RandomMovementGenerator<Creature>::SetRandomLocation(Creature* owner)
_timer.Reset(traveltime + resetTimer);
// Call for creature group update
- if (owner->GetFormation() && owner->GetFormation()->getLeader() == owner)
- owner->GetFormation()->LeaderMoveTo(position);
+ owner->SignalFormationMovement(position);
}
template<class T>
diff --git a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp
index f292c0a8091..3ca1d581982 100755
--- a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp
+++ b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp
@@ -17,99 +17,128 @@
*/
#include "WaypointMovementGenerator.h"
+#include "Creature.h"
#include "CreatureAI.h"
-#include "CreatureGroups.h"
#include "Log.h"
#include "MapManager.h"
#include "MoveSpline.h"
#include "MoveSplineInit.h"
#include "ObjectMgr.h"
+#include "Player.h"
#include "Transport.h"
+#include "WaypointDefines.h"
+#include "WaypointManager.h"
#include "World.h"
+WaypointMovementGenerator<Creature>::WaypointMovementGenerator(WaypointPath& path, bool repeating)
+{
+ _path = &path;
+ _nextMoveTime = 0;
+ _recalculateSpeed = false;
+ _isArrivalDone = false;
+ _pathId = 0;
+ _repeating = repeating;
+ _loadedFromDB = false;
+ _stalled = false;
+}
+
void WaypointMovementGenerator<Creature>::LoadPath(Creature* creature)
{
- if (!path_id)
- path_id = creature->GetWaypointPath();
+ if (_loadedFromDB)
+ {
+ if (!_pathId)
+ _pathId = creature->GetWaypointPath();
- i_path = sWaypointMgr->GetPath(path_id);
+ _path = sWaypointMgr->GetPath(_pathId);
+ }
- if (!i_path)
+ if (!_path)
{
// No path id found for entry
- TC_LOG_ERROR("sql.sql", "WaypointMovementGenerator::LoadPath: creature %s (Entry: %u GUID: %u DB GUID: %u) doesn't have waypoint path id: %u", creature->GetName().c_str(), creature->GetEntry(), creature->GetGUID().GetCounter(), creature->GetSpawnId(), path_id);
+ TC_LOG_ERROR("sql.sql", "WaypointMovementGenerator::LoadPath: creature %s (Entry: %u GUID: %u DB GUID: %u) doesn't have waypoint path id: %u", creature->GetName().c_str(), creature->GetEntry(), creature->GetGUID().GetCounter(), creature->GetSpawnId(), _pathId);
return;
}
- StartMoveNow(creature);
+ _nextMoveTime.Reset(3000);
+
+ if (CanMove(creature))
+ StartMoveNow(creature);
}
void WaypointMovementGenerator<Creature>::DoInitialize(Creature* creature)
{
LoadPath(creature);
- creature->AddUnitState(UNIT_STATE_ROAMING|UNIT_STATE_ROAMING_MOVE);
}
void WaypointMovementGenerator<Creature>::DoFinalize(Creature* creature)
{
- creature->ClearUnitState(UNIT_STATE_ROAMING|UNIT_STATE_ROAMING_MOVE);
+ creature->ClearUnitState(UNIT_STATE_ROAMING | UNIT_STATE_ROAMING_MOVE);
creature->SetWalk(false);
}
void WaypointMovementGenerator<Creature>::DoReset(Creature* creature)
{
- creature->AddUnitState(UNIT_STATE_ROAMING|UNIT_STATE_ROAMING_MOVE);
- StartMoveNow(creature);
+ if (CanMove(creature))
+ StartMoveNow(creature);
}
void WaypointMovementGenerator<Creature>::OnArrived(Creature* creature)
{
- if (!i_path || i_path->empty())
+ if (!_path || _path->nodes.empty())
return;
- if (m_isArrivalDone)
- return;
-
- m_isArrivalDone = true;
- if (i_path->at(i_currentNode)->event_id && urand(0, 99) < i_path->at(i_currentNode)->event_chance)
+ WaypointNode const &waypoint = _path->nodes.at(_currentNode);
+ if (waypoint.delay)
{
- TC_LOG_DEBUG("maps.script", "Creature movement start script %u at point %u for %s.", i_path->at(i_currentNode)->event_id, i_currentNode, creature->GetGUID().ToString().c_str());
creature->ClearUnitState(UNIT_STATE_ROAMING_MOVE);
- creature->GetMap()->ScriptsStart(sWaypointScripts, i_path->at(i_currentNode)->event_id, creature, nullptr);
+ _nextMoveTime.Reset(waypoint.delay);
}
- // Inform script
- MovementInform(creature);
- creature->UpdateWaypointID(i_currentNode);
-
- if (i_path->at(i_currentNode)->delay)
+ if (waypoint.eventId && urand(0, 99) < waypoint.eventChance)
{
+ TC_LOG_DEBUG("maps.script", "Creature movement start script %u at point %u for %s.", waypoint.eventId, _currentNode, creature->GetGUID().ToString().c_str());
creature->ClearUnitState(UNIT_STATE_ROAMING_MOVE);
- Stop(i_path->at(i_currentNode)->delay);
+ creature->GetMap()->ScriptsStart(sWaypointScripts, waypoint.eventId, creature, nullptr);
+ }
+
+ // inform AI
+ if (creature->AI())
+ {
+ creature->AI()->MovementInform(WAYPOINT_MOTION_TYPE, _currentNode);
+
+ ASSERT(_currentNode < _path->nodes.size(), "WaypointMovementGenerator::OnArrived: tried to reference a node id (%u) which is not included in path (%u)", _currentNode, _path->id);
+ creature->AI()->WaypointReached(_path->nodes[_currentNode].id, _path->id);
}
+
+ creature->UpdateWaypointID(_currentNode);
}
bool WaypointMovementGenerator<Creature>::StartMove(Creature* creature)
{
- if (!i_path || i_path->empty())
+ if (!creature || !creature->IsAlive())
return false;
- // Dont allow dead creatures to move
- if (!creature->IsAlive())
+ if (!_path || _path->nodes.empty())
return false;
- if (Stopped())
+ // if the owner is the leader of its formation, check members status
+ if (creature->IsFormationLeader() && !creature->IsFormationLeaderMoveAllowed())
+ {
+ _nextMoveTime.Reset(1000);
return true;
+ }
- bool transportPath = creature->HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT) && creature->GetTransGUID();
+ bool transportPath = creature->HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT) && !creature->GetTransGUID().IsEmpty();
- if (m_isArrivalDone)
+ if (_isArrivalDone)
{
- if ((i_currentNode == i_path->size() - 1) && !repeating) // If that's our last waypoint
+ if ((_currentNode == _path->nodes.size() - 1) && !_repeating) // If that's our last waypoint
{
- float x = i_path->at(i_currentNode)->x;
- float y = i_path->at(i_currentNode)->y;
- float z = i_path->at(i_currentNode)->z;
+ WaypointNode const &waypoint = _path->nodes.at(_currentNode);
+
+ float x = waypoint.x;
+ float y = waypoint.y;
+ float z = waypoint.z;
float o = creature->GetOrientation();
if (!transportPath)
@@ -127,21 +156,27 @@ bool WaypointMovementGenerator<Creature>::StartMove(Creature* creature)
transportPath = false;
// else if (vehicle) - this should never happen, vehicle offsets are const
}
-
- creature->GetMotionMaster()->Initialize();
return false;
}
- i_currentNode = (i_currentNode+1) % i_path->size();
+ _currentNode = (_currentNode + 1) % _path->nodes.size();
+
+ // inform AI
+ if (creature->AI())
+ {
+ ASSERT(_currentNode < _path->nodes.size(), "WaypointMovementGenerator::StartMove: tried to reference a node id (%u) which is not included in path (%u)", _currentNode, _path->id);
+ creature->AI()->WaypointStarted(_path->nodes[_currentNode].id, _path->id);
+ }
}
- WaypointData const* node = i_path->at(i_currentNode);
+ WaypointNode const &waypoint = _path->nodes.at(_currentNode);
+ Position formationDest(waypoint.x, waypoint.y, waypoint.z, (waypoint.orientation && waypoint.delay) ? waypoint.orientation : 0.0f);
- m_isArrivalDone = false;
+ _isArrivalDone = false;
+ _recalculateSpeed = false;
creature->AddUnitState(UNIT_STATE_ROAMING_MOVE);
- Position formationDest(node->x, node->y, node->z, (node->orientation && node->delay) ? node->orientation : 0.0f);
Movement::MoveSplineInit init(creature);
//! If creature is on transport, we assume waypoints set in DB are already transport offsets
@@ -158,13 +193,13 @@ bool WaypointMovementGenerator<Creature>::StartMove(Creature* creature)
//! Do not use formationDest here, MoveTo requires transport offsets due to DisableTransportPathTransformations() call
//! but formationDest contains global coordinates
- init.MoveTo(node->x, node->y, node->z);
+ init.MoveTo(waypoint.x, waypoint.y, waypoint.z);
//! Accepts angles such as 0.00001 and -0.00001, 0 must be ignored, default value in waypoint table
- if (node->orientation && node->delay)
- init.SetFacing(node->orientation);
+ if (waypoint.orientation && waypoint.delay)
+ init.SetFacing(waypoint.orientation);
- switch (node->move_type)
+ switch (waypoint.moveType)
{
case WAYPOINT_MOVE_TYPE_LAND:
init.SetAnimation(Movement::ToGround);
@@ -178,47 +213,57 @@ bool WaypointMovementGenerator<Creature>::StartMove(Creature* creature)
case WAYPOINT_MOVE_TYPE_WALK:
init.SetWalk(true);
break;
+ default:
+ break;
}
init.Launch();
- // Call for creature group update
- if (creature->GetFormation() && creature->GetFormation()->getLeader() == creature)
- creature->GetFormation()->LeaderMoveTo(formationDest, node->id, node->move_type, (node->orientation && node->delay) ? true : false);
+ // inform formation
+ creature->SignalFormationMovement(formationDest, waypoint.id, waypoint.moveType, (waypoint.orientation && waypoint.delay) ? true : false);
return true;
}
bool WaypointMovementGenerator<Creature>::DoUpdate(Creature* creature, uint32 diff)
{
- // Waypoint movement can be switched on/off
- // This is quite handy for escort quests and other stuff
- if (creature->HasUnitState(UNIT_STATE_NOT_MOVE))
+ if (!creature || !creature->IsAlive())
+ return false;
+
+ if (_stalled || creature->HasUnitState(UNIT_STATE_NOT_MOVE) || creature->IsMovementPreventedByCasting())
{
- creature->ClearUnitState(UNIT_STATE_ROAMING_MOVE);
+ creature->StopMoving();
return true;
}
+
// prevent a crash at empty waypoint path.
- if (!i_path || i_path->empty())
+ if (!_path || _path->nodes.empty())
return false;
- if (Stopped())
+ if (!_nextMoveTime.Passed())
{
- if (CanMove(diff))
- return StartMove(creature);
+ _nextMoveTime.Update(diff);
+ if (_nextMoveTime.Passed())
+ return StartMoveNow(creature);
}
else
{
// Set home position at place on waypoint movement.
- if (!creature->HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT) || !creature->GetTransGUID())
+ if (!creature->HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT) || creature->GetTransGUID().IsEmpty())
creature->SetHomePosition(creature->GetPosition());
- if (creature->IsStopped())
- Stop(sWorld->getIntConfig(CONFIG_CREATURE_STOP_FOR_PLAYER));
- else if (creature->movespline->Finalized())
+ if (creature->movespline->Finalized())
{
OnArrived(creature);
- return StartMove(creature);
+ _isArrivalDone = true;
+
+ if (_nextMoveTime.Passed())
+ return StartMove(creature);
+ }
+ else if (_recalculateSpeed)
+ {
+ if (_nextMoveTime.Passed())
+ StartMove(creature);
}
}
return true;
@@ -227,38 +272,61 @@ bool WaypointMovementGenerator<Creature>::DoUpdate(Creature* creature, uint32 di
void WaypointMovementGenerator<Creature>::MovementInform(Creature* creature)
{
if (creature->AI())
- creature->AI()->MovementInform(WAYPOINT_MOTION_TYPE, i_currentNode);
+ creature->AI()->MovementInform(WAYPOINT_MOTION_TYPE, _currentNode);
}
bool WaypointMovementGenerator<Creature>::GetResetPos(Creature*, float& x, float& y, float& z)
{
// prevent a crash at empty waypoint path.
- if (!i_path || i_path->empty())
+ if (!_path || _path->nodes.empty())
return false;
- WaypointData const* node = i_path->at(i_currentNode);
- x = node->x; y = node->y; z = node->z;
+ WaypointNode const &waypoint = _path->nodes.at(_currentNode);
+
+ x = waypoint.x;
+ y = waypoint.y;
+ z = waypoint.z;
return true;
}
+void WaypointMovementGenerator<Creature>::Pause(uint32 timer/* = 0*/)
+{
+ _stalled = timer ? false : true;
+ _nextMoveTime.Reset(timer ? timer : 1);
+}
+
+void WaypointMovementGenerator<Creature>::Resume(uint32 overrideTimer/* = 0*/)
+{
+ _stalled = false;
+ if (overrideTimer)
+ _nextMoveTime.Reset(overrideTimer);
+}
+
+bool WaypointMovementGenerator<Creature>::CanMove(Creature* creature)
+{
+ return _nextMoveTime.Passed() && !creature->HasUnitState(UNIT_STATE_NOT_MOVE) && !creature->IsMovementPreventedByCasting();
+}
//----------------------------------------------------//
+#define FLIGHT_TRAVEL_UPDATE 100
+#define TIMEDIFF_NEXT_WP 250
+#define SKIP_SPLINE_POINT_DISTANCE_SQ (40.f * 40.f)
+#define PLAYER_FLIGHT_SPEED 32.0f
+
uint32 FlightPathMovementGenerator::GetPathAtMapEnd() const
{
- if (i_currentNode >= i_path.size())
- return i_path.size();
+ if (_currentNode >= _path.size())
+ return _path.size();
- uint32 curMapId = i_path[i_currentNode]->MapID;
- for (uint32 i = i_currentNode; i < i_path.size(); ++i)
- if (i_path[i]->MapID != curMapId)
- return i;
+ uint32 curMapId = _path[_currentNode]->MapID;
+ for (uint32 itr = _currentNode; itr < _path.size(); ++itr)
+ if (_path[itr]->MapID != curMapId)
+ return itr;
- return i_path.size();
+ return _path.size();
}
-#define SKIP_SPLINE_POINT_DISTANCE_SQ (40.0f * 40.0f)
-
bool IsNodeIncludedInShortenedPath(TaxiPathNodeEntry const* p1, TaxiPathNodeEntry const* p2)
{
return p1->MapID != p2->MapID || std::pow(p1->LocX - p2->LocX, 2) + std::pow(p1->LocY - p2->LocY, 2) > SKIP_SPLINE_POINT_DISTANCE_SQ;
@@ -283,24 +351,24 @@ void FlightPathMovementGenerator::LoadPath(Player* player)
bool passedPreviousSegmentProximityCheck = false;
for (uint32 i = 0; i < nodes.size(); ++i)
{
- if (passedPreviousSegmentProximityCheck || !src || i_path.empty() || IsNodeIncludedInShortenedPath(i_path[i_path.size() - 1], nodes[i]))
+ if (passedPreviousSegmentProximityCheck || !src || _path.empty() || IsNodeIncludedInShortenedPath(_path[_path.size() - 1], nodes[i]))
{
if ((!src || (IsNodeIncludedInShortenedPath(start, nodes[i]) && i >= 2)) &&
(dst == taxi.size() - 1 || (IsNodeIncludedInShortenedPath(end, nodes[i]) && i < nodes.size() - 1)))
{
passedPreviousSegmentProximityCheck = true;
- i_path.push_back(nodes[i]);
+ _path.push_back(nodes[i]);
}
}
else
{
- i_path.pop_back();
+ _path.pop_back();
--_pointsForPathSwitch.back().PathIndex;
}
}
}
- _pointsForPathSwitch.push_back({ uint32(i_path.size() - 1), int32(cost) });
+ _pointsForPathSwitch.push_back({ uint32(_path.size() - 1), int32(cost) });
}
}
@@ -331,8 +399,6 @@ void FlightPathMovementGenerator::DoFinalize(Player* player)
player->RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_TAXI_BENCHMARK);
}
-#define PLAYER_FLIGHT_SPEED 32.0f
-
void FlightPathMovementGenerator::DoReset(Player* player)
{
player->getHostileRefManager().setOnlineOfflineState(false);
@@ -343,7 +409,7 @@ void FlightPathMovementGenerator::DoReset(Player* player)
uint32 end = GetPathAtMapEnd();
for (uint32 i = GetCurrentNode(); i != end; ++i)
{
- G3D::Vector3 vertice(i_path[i]->LocX, i_path[i]->LocY, i_path[i]->LocZ);
+ G3D::Vector3 vertice(_path[i]->LocX, _path[i]->LocY, _path[i]->LocZ);
init.Path().push_back(vertice);
}
init.SetFirstPointId(GetCurrentNode());
@@ -355,13 +421,13 @@ void FlightPathMovementGenerator::DoReset(Player* player)
bool FlightPathMovementGenerator::DoUpdate(Player* player, uint32 /*diff*/)
{
uint32 pointId = (uint32)player->movespline->currentPathIdx();
- if (pointId > i_currentNode)
+ if (pointId > _currentNode)
{
bool departureEvent = true;
do
{
- DoEventIfAny(player, i_path[i_currentNode], departureEvent);
- while (!_pointsForPathSwitch.empty() && _pointsForPathSwitch.front().PathIndex <= i_currentNode)
+ DoEventIfAny(player, _path[_currentNode], departureEvent);
+ while (!_pointsForPathSwitch.empty() && _pointsForPathSwitch.front().PathIndex <= _currentNode)
{
_pointsForPathSwitch.pop_front();
player->m_taxi.NextTaxiDestination();
@@ -372,31 +438,31 @@ bool FlightPathMovementGenerator::DoUpdate(Player* player, uint32 /*diff*/)
}
}
- if (pointId == i_currentNode)
+ if (pointId == _currentNode)
break;
- if (i_currentNode == _preloadTargetNode)
+ if (_currentNode == _preloadTargetNode)
PreloadEndGrid();
- i_currentNode += (uint32)departureEvent;
+ _currentNode += departureEvent ? 1 : 0;
departureEvent = !departureEvent;
}
while (true);
}
- return i_currentNode < (i_path.size() - 1);
+ return _currentNode < (_path.size() - 1);
}
void FlightPathMovementGenerator::SetCurrentNodeAfterTeleport()
{
- if (i_path.empty() || i_currentNode >= i_path.size())
+ if (_path.empty() || _currentNode >= _path.size())
return;
- uint32 map0 = i_path[i_currentNode]->MapID;
- for (size_t i = i_currentNode + 1; i < i_path.size(); ++i)
+ uint32 map0 = _path[_currentNode]->MapID;
+ for (size_t i = _currentNode + 1; i < _path.size(); ++i)
{
- if (i_path[i]->MapID != map0)
+ if (_path[i]->MapID != map0)
{
- i_currentNode = i;
+ _currentNode = i;
return;
}
}
@@ -413,7 +479,7 @@ void FlightPathMovementGenerator::DoEventIfAny(Player* player, TaxiPathNodeEntry
bool FlightPathMovementGenerator::GetResetPos(Player*, float& x, float& y, float& z)
{
- TaxiPathNodeEntry const* node = i_path[i_currentNode];
+ TaxiPathNodeEntry const* node = _path[_currentNode];
x = node->LocX;
y = node->LocY;
z = node->LocZ;
@@ -424,11 +490,11 @@ void FlightPathMovementGenerator::InitEndGridInfo()
{
/*! Storage to preload flightmaster grid at end of flight. For multi-stop flights, this will
be reinitialized for each flightmaster at the end of each spline (or stop) in the flight. */
- uint32 nodeCount = i_path.size(); //! Number of nodes in path.
- _endMapId = i_path[nodeCount - 1]->MapID; //! MapId of last node
+ uint32 nodeCount = _path.size(); //! Number of nodes in path.
+ _endMapId = _path[nodeCount - 1]->MapID; //! MapId of last node
_preloadTargetNode = nodeCount - 3;
- _endGridX = i_path[nodeCount - 1]->LocX;
- _endGridY = i_path[nodeCount - 1]->LocY;
+ _endGridX = _path[nodeCount - 1]->LocX;
+ _endGridY = _path[nodeCount - 1]->LocY;
}
void FlightPathMovementGenerator::PreloadEndGrid()
@@ -439,7 +505,7 @@ void FlightPathMovementGenerator::PreloadEndGrid()
// Load the grid
if (endMap)
{
- TC_LOG_DEBUG("misc", "Preloading rid (%f, %f) for map %u at node index %u/%u", _endGridX, _endGridY, _endMapId, _preloadTargetNode, (uint32)(i_path.size() - 1));
+ TC_LOG_DEBUG("misc", "Preloading rid (%f, %f) for map %u at node index %u/%u", _endGridX, _endGridY, _endMapId, _preloadTargetNode, (uint32)(_path.size() - 1));
endMap->LoadGrid(_endGridX, _endGridY);
}
else
diff --git a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.h b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.h
index 7426a166ea1..2ea92f021da 100755
--- a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.h
+++ b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.h
@@ -19,98 +19,91 @@
#ifndef TRINITY_WAYPOINTMOVEMENTGENERATOR_H
#define TRINITY_WAYPOINTMOVEMENTGENERATOR_H
-/** @page PathMovementGenerator is used to generate movements
+/**
+ * @page PathMovementGenerator is used to generate movements
* of waypoints and flight paths. Each serves the purpose
* of generate activities so that it generates updated
* packets for the players.
*/
-#include "MovementGenerator.h"
-#include "Creature.h"
#include "DBCStructure.h"
-#include "Player.h"
+#include "MovementGenerator.h"
#include "Timer.h"
-#include "WaypointManager.h"
-#define FLIGHT_TRAVEL_UPDATE 100
-#define TIMEDIFF_NEXT_WP 250
+class Creature;
+class Player;
+struct WaypointPath;
-template<class T, class P>
+template<class Entity, class BasePath>
class PathMovementBase
{
public:
- PathMovementBase() : i_path(), i_currentNode(0) { }
+ PathMovementBase() : _path(), _currentNode(0) { }
virtual ~PathMovementBase() { };
- uint32 GetCurrentNode() const { return i_currentNode; }
+ uint32 GetCurrentNode() const { return _currentNode; }
protected:
- P i_path;
- uint32 i_currentNode;
+ BasePath _path;
+ uint32 _currentNode;
};
template<class T>
class WaypointMovementGenerator;
template<>
-class WaypointMovementGenerator<Creature> : public MovementGeneratorMedium< Creature, WaypointMovementGenerator<Creature> >,
- public PathMovementBase<Creature, WaypointPath const*>
+class WaypointMovementGenerator<Creature> : public MovementGeneratorMedium<Creature, WaypointMovementGenerator<Creature>>, public PathMovementBase<Creature, WaypointPath const*>
{
public:
- WaypointMovementGenerator(uint32 _path_id = 0, bool _repeating = true)
- : i_nextMoveTime(0), m_isArrivalDone(false), path_id(_path_id), repeating(_repeating) { }
- ~WaypointMovementGenerator() { i_path = nullptr; }
+ explicit WaypointMovementGenerator(uint32 pathId = 0, bool repeating = true) : _nextMoveTime(0), _recalculateSpeed(false), _isArrivalDone(false), _pathId(pathId), _repeating(repeating), _loadedFromDB(true), _stalled(false) { }
+ explicit WaypointMovementGenerator(WaypointPath& path, bool repeating = true);
+
+ ~WaypointMovementGenerator() { _path = nullptr; }
+
void DoInitialize(Creature*);
void DoFinalize(Creature*);
void DoReset(Creature*);
bool DoUpdate(Creature*, uint32 diff);
- void MovementInform(Creature*);
-
MovementGeneratorType GetMovementGeneratorType() const override { return WAYPOINT_MOTION_TYPE; }
+ void UnitSpeedChanged() override { _recalculateSpeed = true; }
+ void Pause(uint32 timer = 0) override;
+ void Resume(uint32 overrideTimer = 0) override;
- // now path movement implmementation
- void LoadPath(Creature*);
+ void MovementInform(Creature*);
bool GetResetPos(Creature*, float& x, float& y, float& z);
private:
-
- void Stop(int32 time) { i_nextMoveTime.Reset(time);}
-
- bool Stopped() { return !i_nextMoveTime.Passed();}
-
- bool CanMove(int32 diff)
- {
- i_nextMoveTime.Update(diff);
- return i_nextMoveTime.Passed();
- }
-
+ void LoadPath(Creature*);
void OnArrived(Creature*);
bool StartMove(Creature*);
-
- void StartMoveNow(Creature* creature)
+ bool CanMove(Creature*);
+ bool StartMoveNow(Creature* creature)
{
- i_nextMoveTime.Reset(0);
- StartMove(creature);
+ _nextMoveTime.Reset(0);
+ return StartMove(creature);
}
- TimeTrackerSmall i_nextMoveTime;
- bool m_isArrivalDone;
- uint32 path_id;
- bool repeating;
+ TimeTrackerSmall _nextMoveTime;
+ bool _recalculateSpeed;
+ bool _isArrivalDone;
+ uint32 _pathId;
+ bool _repeating;
+ bool _loadedFromDB;
+ bool _stalled;
};
-/** FlightPathMovementGenerator generates movement of the player for the paths
+/**
+ * FlightPathMovementGenerator generates movement of the player for the paths
* and hence generates ground and activities for the player.
*/
-class FlightPathMovementGenerator : public MovementGeneratorMedium< Player, FlightPathMovementGenerator >,
- public PathMovementBase<Player, TaxiPathNodeList>
+class FlightPathMovementGenerator : public MovementGeneratorMedium<Player, FlightPathMovementGenerator>, public PathMovementBase<Player, TaxiPathNodeList>
{
public:
explicit FlightPathMovementGenerator(uint32 startNode = 0)
{
- i_currentNode = startNode;
+ _currentNode = startNode;
_endGridX = 0.0f;
_endGridY = 0.0f;
_endMapId = 0;
@@ -123,15 +116,14 @@ class FlightPathMovementGenerator : public MovementGeneratorMedium< Player, Flig
bool DoUpdate(Player*, uint32);
MovementGeneratorType GetMovementGeneratorType() const override { return FLIGHT_MOTION_TYPE; }
- TaxiPathNodeList const& GetPath() { return i_path; }
+ TaxiPathNodeList const& GetPath() { return _path; }
uint32 GetPathAtMapEnd() const;
- bool HasArrived() const { return (i_currentNode >= i_path.size()); }
+ bool HasArrived() const { return (_currentNode >= _path.size()); }
void SetCurrentNodeAfterTeleport();
- void SkipCurrentNode() { ++i_currentNode; }
+ void SkipCurrentNode() { ++_currentNode; }
void DoEventIfAny(Player* player, TaxiPathNodeEntry const* node, bool departure);
bool GetResetPos(Player*, float& x, float& y, float& z);
-
void InitEndGridInfo();
void PreloadEndGrid();
diff --git a/src/server/game/Movement/Waypoints/WaypointDefines.h b/src/server/game/Movement/Waypoints/WaypointDefines.h
new file mode 100644
index 00000000000..dbb7a15fa5c
--- /dev/null
+++ b/src/server/game/Movement/Waypoints/WaypointDefines.h
@@ -0,0 +1,71 @@
+/*
+ * 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 TRINITY_WAYPOINTDEFINES_H
+#define TRINITY_WAYPOINTDEFINES_H
+
+#include "Define.h"
+#include <vector>
+
+enum WaypointMoveType
+{
+ WAYPOINT_MOVE_TYPE_WALK,
+ WAYPOINT_MOVE_TYPE_RUN,
+ WAYPOINT_MOVE_TYPE_LAND,
+ WAYPOINT_MOVE_TYPE_TAKEOFF,
+
+ WAYPOINT_MOVE_TYPE_MAX
+};
+
+struct WaypointNode
+{
+ WaypointNode() : id(0), x(0.f), y(0.f), z(0.f), orientation(0.f), delay(0), eventId(0), moveType(WAYPOINT_MOVE_TYPE_RUN), eventChance(0) { }
+ WaypointNode(uint32 _id, float _x, float _y, float _z, float _orientation = 0.f, uint32 _delay = 0)
+ {
+ id = _id;
+ x = _x;
+ y = _y;
+ z = _z;
+ orientation = _orientation;
+ delay = _delay;
+ eventId = 0;
+ moveType = WAYPOINT_MOVE_TYPE_WALK;
+ eventChance = 100;
+ }
+
+ uint32 id;
+ float x, y, z, orientation;
+ uint32 delay;
+ uint32 eventId;
+ uint32 moveType;
+ uint8 eventChance;
+};
+
+struct WaypointPath
+{
+ WaypointPath() : id(0) { }
+ WaypointPath(uint32 _id, std::vector<WaypointNode>&& _nodes)
+ {
+ id = _id;
+ nodes = _nodes;
+ }
+
+ std::vector<WaypointNode> nodes;
+ uint32 id;
+};
+
+#endif
diff --git a/src/server/game/Movement/Waypoints/WaypointManager.cpp b/src/server/game/Movement/Waypoints/WaypointManager.cpp
index 76c6228d302..3112459245f 100644
--- a/src/server/game/Movement/Waypoints/WaypointManager.cpp
+++ b/src/server/game/Movement/Waypoints/WaypointManager.cpp
@@ -16,27 +16,12 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include "WaypointManager.h"
#include "DatabaseEnv.h"
#include "GridDefines.h"
-#include "WaypointManager.h"
#include "MapManager.h"
#include "Log.h"
-WaypointMgr::WaypointMgr() { }
-
-WaypointMgr::~WaypointMgr()
-{
- for (WaypointPathContainer::iterator itr = _waypointStore.begin(); itr != _waypointStore.end(); ++itr)
- {
- for (WaypointPath::const_iterator it = itr->second.begin(); it != itr->second.end(); ++it)
- delete *it;
-
- itr->second.clear();
- }
-
- _waypointStore.clear();
-}
-
void WaypointMgr::Load()
{
uint32 oldMSTime = getMSTime();
@@ -55,11 +40,7 @@ void WaypointMgr::Load()
do
{
Field* fields = result->Fetch();
- WaypointData* wp = new WaypointData();
-
uint32 pathId = fields[0].GetUInt32();
- WaypointPath& path = _waypointStore[pathId];
-
float x = fields[2].GetFloat();
float y = fields[3].GetFloat();
float z = fields[4].GetFloat();
@@ -68,25 +49,27 @@ void WaypointMgr::Load()
Trinity::NormalizeMapCoord(x);
Trinity::NormalizeMapCoord(y);
- wp->id = fields[1].GetUInt32();
- wp->x = x;
- wp->y = y;
- wp->z = z;
- wp->orientation = o;
- wp->move_type = fields[6].GetUInt32();
+ WaypointNode waypoint;
+ waypoint.id = fields[1].GetUInt32();
+ waypoint.x = x;
+ waypoint.y = y;
+ waypoint.z = z;
+ waypoint.orientation = o;
+ waypoint.moveType = fields[6].GetUInt32();
- if (wp->move_type >= WAYPOINT_MOVE_TYPE_MAX)
+ if (waypoint.moveType >= WAYPOINT_MOVE_TYPE_MAX)
{
- TC_LOG_ERROR("sql.sql", "Waypoint %u in waypoint_data has invalid move_type, ignoring", wp->id);
- delete wp;
+ TC_LOG_ERROR("sql.sql", "Waypoint %u in waypoint_data has invalid move_type, ignoring", waypoint.id);
continue;
}
- wp->delay = fields[7].GetUInt32();
- wp->event_id = fields[8].GetUInt32();
- wp->event_chance = fields[9].GetInt16();
+ waypoint.delay = fields[7].GetUInt32();
+ waypoint.eventId = fields[8].GetUInt32();
+ waypoint.eventChance = fields[9].GetInt16();
- path.push_back(wp);
+ WaypointPath& path = _waypointStore[pathId];
+ path.id = pathId;
+ path.nodes.push_back(std::move(waypoint));
++count;
}
while (result->NextRow());
@@ -102,14 +85,9 @@ WaypointMgr* WaypointMgr::instance()
void WaypointMgr::ReloadPath(uint32 id)
{
- WaypointPathContainer::iterator itr = _waypointStore.find(id);
+ auto itr = _waypointStore.find(id);
if (itr != _waypointStore.end())
- {
- for (WaypointPath::const_iterator it = itr->second.begin(); it != itr->second.end(); ++it)
- delete *it;
-
_waypointStore.erase(itr);
- }
PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_WAYPOINT_DATA_BY_ID);
@@ -120,13 +98,10 @@ void WaypointMgr::ReloadPath(uint32 id)
if (!result)
return;
- WaypointPath& path = _waypointStore[id];
-
+ std::vector<WaypointNode> values;
do
{
Field* fields = result->Fetch();
- WaypointData* wp = new WaypointData();
-
float x = fields[1].GetFloat();
float y = fields[2].GetFloat();
float z = fields[3].GetFloat();
@@ -135,26 +110,36 @@ void WaypointMgr::ReloadPath(uint32 id)
Trinity::NormalizeMapCoord(x);
Trinity::NormalizeMapCoord(y);
- wp->id = fields[0].GetUInt32();
- wp->x = x;
- wp->y = y;
- wp->z = z;
- wp->orientation = o;
- wp->move_type = fields[5].GetUInt32();
+ WaypointNode waypoint;
+ waypoint.id = fields[0].GetUInt32();
+ waypoint.x = x;
+ waypoint.y = y;
+ waypoint.z = z;
+ waypoint.orientation = o;
+ waypoint.moveType = fields[5].GetUInt32();
- if (wp->move_type >= WAYPOINT_MOVE_TYPE_MAX)
+ if (waypoint.moveType >= WAYPOINT_MOVE_TYPE_MAX)
{
- TC_LOG_ERROR("sql.sql", "Waypoint %u in waypoint_data has invalid move_type, ignoring", wp->id);
- delete wp;
+ TC_LOG_ERROR("sql.sql", "Waypoint %u in waypoint_data has invalid move_type, ignoring", waypoint.id);
continue;
}
- wp->delay = fields[6].GetUInt32();
- wp->event_id = fields[7].GetUInt32();
- wp->event_chance = fields[8].GetUInt8();
-
- path.push_back(wp);
+ waypoint.delay = fields[6].GetUInt32();
+ waypoint.eventId = fields[7].GetUInt32();
+ waypoint.eventChance = fields[8].GetUInt8();
+ values.push_back(std::move(waypoint));
}
while (result->NextRow());
+
+ _waypointStore[id] = WaypointPath(id, std::move(values));
+}
+
+WaypointPath const* WaypointMgr::GetPath(uint32 id) const
+{
+ auto itr = _waypointStore.find(id);
+ if (itr != _waypointStore.end())
+ return &itr->second;
+
+ return nullptr;
}
diff --git a/src/server/game/Movement/Waypoints/WaypointManager.h b/src/server/game/Movement/Waypoints/WaypointManager.h
index f62805594ef..769e45432e7 100644
--- a/src/server/game/Movement/Waypoints/WaypointManager.h
+++ b/src/server/game/Movement/Waypoints/WaypointManager.h
@@ -20,32 +20,10 @@
#define TRINITY_WAYPOINTMANAGER_H
#include "Define.h"
+#include "WaypointDefines.h"
#include <vector>
#include <unordered_map>
-enum WaypointMoveType
-{
- WAYPOINT_MOVE_TYPE_WALK,
- WAYPOINT_MOVE_TYPE_RUN,
- WAYPOINT_MOVE_TYPE_LAND,
- WAYPOINT_MOVE_TYPE_TAKEOFF,
-
- WAYPOINT_MOVE_TYPE_MAX
-};
-
-struct WaypointData
-{
- uint32 id;
- float x, y, z, orientation;
- uint32 delay;
- uint32 event_id;
- uint32 move_type;
- uint8 event_chance;
-};
-
-typedef std::vector<WaypointData*> WaypointPath;
-typedef std::unordered_map<uint32, WaypointPath> WaypointPathContainer;
-
class TC_GAME_API WaypointMgr
{
public:
@@ -58,20 +36,12 @@ class TC_GAME_API WaypointMgr
void Load();
// Returns the path from a given id
- WaypointPath const* GetPath(uint32 id) const
- {
- WaypointPathContainer::const_iterator itr = _waypointStore.find(id);
- if (itr != _waypointStore.end())
- return &itr->second;
-
- return nullptr;
- }
+ WaypointPath const* GetPath(uint32 id) const;
private:
- WaypointMgr();
- ~WaypointMgr();
+ WaypointMgr() { }
- WaypointPathContainer _waypointStore;
+ std::unordered_map<uint32, WaypointPath> _waypointStore;
};
#define sWaypointMgr WaypointMgr::instance()