aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2023-03-07 20:13:28 +0100
committerShauren <shauren.trinity@gmail.com>2023-03-07 20:13:28 +0100
commitcf2e0e2faad78617012e8259352d08e7a62e6026 (patch)
tree03022a2d8034780655ef4b89318afa063f55822a /src
parent705d5701bf17f1787d2646c55c994b0404659991 (diff)
Core/Movement: New waypoint movement features
* Allow going backwards on a repeatable waypoint path (instead of going directly to first point) * Allow triggering random movement on path ends * Max duration of waypoint movement * Skipping mmap usage * Forced speed for whole path * Forced run/walk for whole path
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Movement/MotionMaster.cpp24
-rw-r--r--src/server/game/Movement/MotionMaster.h12
-rw-r--r--src/server/game/Movement/MovementGenerator.cpp2
-rw-r--r--src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp89
-rwxr-xr-xsrc/server/game/Movement/MovementGenerators/WaypointMovementGenerator.h24
5 files changed, 131 insertions, 20 deletions
diff --git a/src/server/game/Movement/MotionMaster.cpp b/src/server/game/Movement/MotionMaster.cpp
index 036182a5131..8066b635e0b 100644
--- a/src/server/game/Movement/MotionMaster.cpp
+++ b/src/server/game/Movement/MotionMaster.cpp
@@ -596,12 +596,12 @@ void MotionMaster::MoveTargetedHome()
}
}
-void MotionMaster::MoveRandom(float wanderDistance, Optional<Milliseconds> duration)
+void MotionMaster::MoveRandom(float wanderDistance, Optional<Milliseconds> duration, MovementSlot slot /*= MOTION_SLOT_DEFAULT*/)
{
if (_owner->GetTypeId() == TYPEID_UNIT)
{
TC_LOG_DEBUG("movement.motionmaster", "MotionMaster::MoveRandom: '{}', started random movement (spawnDist: {})", _owner->GetGUID().ToString(), wanderDistance);
- Add(new RandomMovementGenerator<Creature>(wanderDistance, duration), MOTION_SLOT_DEFAULT);
+ Add(new RandomMovementGenerator<Creature>(wanderDistance, duration), slot);
}
}
@@ -1075,19 +1075,27 @@ void MotionMaster::MoveDistract(uint32 timer, float orientation)
Add(new DistractMovementGenerator(timer, orientation));
}
-void MotionMaster::MovePath(uint32 pathId, bool repeatable)
+void MotionMaster::MovePath(uint32 pathId, bool repeatable, Optional<Milliseconds> duration, Optional<float> speed,
+ MovementWalkRunSpeedSelectionMode speedSelectionMode, Optional<std::pair<Milliseconds, Milliseconds>> waitTimeRangeAtPathEnd,
+ Optional<float> wanderDistanceAtPathEnds, bool followPathBackwardsFromEndToStart, bool generatePath)
{
if (!pathId)
return;
- TC_LOG_DEBUG("movement.motionmaster", "MotionMaster::MovePath: '{}', starts moving over path Id: {} (repeatable: {})", _owner->GetGUID().ToString(), pathId, repeatable ? "YES" : "NO");
- Add(new WaypointMovementGenerator<Creature>(pathId, repeatable), MOTION_SLOT_DEFAULT);
+ TC_LOG_DEBUG("movement.motionmaster", "MotionMaster::MovePath: '{}', starts moving over path Id: {} (repeatable: {})",
+ _owner->GetGUID().ToString(), pathId, repeatable ? "YES" : "NO");
+ Add(new WaypointMovementGenerator<Creature>(pathId, repeatable, duration, speed, speedSelectionMode, waitTimeRangeAtPathEnd,
+ wanderDistanceAtPathEnds, followPathBackwardsFromEndToStart, generatePath), MOTION_SLOT_DEFAULT);
}
-void MotionMaster::MovePath(WaypointPath& path, bool repeatable)
+void MotionMaster::MovePath(WaypointPath const& path, bool repeatable, Optional<Milliseconds> duration, Optional<float> speed,
+ MovementWalkRunSpeedSelectionMode speedSelectionMode, Optional<std::pair<Milliseconds, Milliseconds>> waitTimeRangeAtPathEnd,
+ Optional<float> wanderDistanceAtPathEnds, bool followPathBackwardsFromEndToStart, bool generatePath)
{
- TC_LOG_DEBUG("movement.motionmaster", "MotionMaster::MovePath: '{}', starts moving over path Id: {} (repeatable: {})", _owner->GetGUID().ToString(), path.id, repeatable ? "YES" : "NO");
- Add(new WaypointMovementGenerator<Creature>(path, repeatable), MOTION_SLOT_DEFAULT);
+ TC_LOG_DEBUG("movement.motionmaster", "MotionMaster::MovePath: '{}', starts moving over path Id: {} (repeatable: {})",
+ _owner->GetGUID().ToString(), path.id, repeatable ? "YES" : "NO");
+ Add(new WaypointMovementGenerator<Creature>(path, repeatable, duration, speed, speedSelectionMode, waitTimeRangeAtPathEnd,
+ wanderDistanceAtPathEnds, followPathBackwardsFromEndToStart, generatePath), MOTION_SLOT_DEFAULT);
}
void MotionMaster::MoveRotate(uint32 id, uint32 time, RotateDirection direction)
diff --git a/src/server/game/Movement/MotionMaster.h b/src/server/game/Movement/MotionMaster.h
index 326d166dd0e..743f988ac22 100644
--- a/src/server/game/Movement/MotionMaster.h
+++ b/src/server/game/Movement/MotionMaster.h
@@ -156,7 +156,7 @@ class TC_GAME_API MotionMaster
void MoveIdle();
void MoveTargetedHome();
- void MoveRandom(float wanderDistance = 0.0f, Optional<Milliseconds> duration = {});
+ void MoveRandom(float wanderDistance = 0.0f, Optional<Milliseconds> duration = {}, MovementSlot slot = MOTION_SLOT_DEFAULT);
void MoveFollow(Unit* target, float dist, ChaseAngle angle, Optional<Milliseconds> duration = {}, MovementSlot slot = MOTION_SLOT_ACTIVE);
void MoveChase(Unit* target, Optional<ChaseRange> dist = {}, Optional<ChaseAngle> angle = {});
void MoveChase(Unit* target, float dist, float angle) { MoveChase(target, ChaseRange(dist), ChaseAngle(angle)); }
@@ -194,8 +194,14 @@ class TC_GAME_API MotionMaster
void MoveSeekAssistanceDistract(uint32 timer);
void MoveTaxiFlight(uint32 path, uint32 pathnode);
void MoveDistract(uint32 time, float orientation);
- void MovePath(uint32 pathId, bool repeatable);
- void MovePath(WaypointPath& path, bool repeatable);
+ void MovePath(uint32 pathId, bool repeatable, Optional<Milliseconds> duration = {}, Optional<float> speed = {},
+ MovementWalkRunSpeedSelectionMode speedSelectionMode = MovementWalkRunSpeedSelectionMode::Default,
+ Optional<std::pair<Milliseconds, Milliseconds>> waitTimeRangeAtPathEnd = {}, Optional<float> wanderDistanceAtPathEnds = {},
+ bool followPathBackwardsFromEndToStart = false, bool generatePath = true);
+ void MovePath(WaypointPath const& path, bool repeatable, Optional<Milliseconds> duration = {}, Optional<float> speed = {},
+ MovementWalkRunSpeedSelectionMode speedSelectionMode = MovementWalkRunSpeedSelectionMode::Default,
+ Optional<std::pair<Milliseconds, Milliseconds>> waitTimeRangeAtPathEnd = {}, Optional<float> wanderDistanceAtPathEnds = {},
+ bool followPathBackwardsFromEndToStart = false, bool generatePath = true);
void MoveRotate(uint32 id, uint32 time, RotateDirection direction);
void MoveFormation(Unit* leader, float range, float angle, uint32 point1, uint32 point2);
diff --git a/src/server/game/Movement/MovementGenerator.cpp b/src/server/game/Movement/MovementGenerator.cpp
index b98f9fa6bb1..455f91795a5 100644
--- a/src/server/game/Movement/MovementGenerator.cpp
+++ b/src/server/game/Movement/MovementGenerator.cpp
@@ -57,5 +57,5 @@ WaypointMovementFactory::WaypointMovementFactory() : MovementGeneratorCreator(WA
MovementGenerator* WaypointMovementFactory::Create(Unit* /*object*/) const
{
- return new WaypointMovementGenerator<Creature>();
+ return new WaypointMovementGenerator<Creature>(0, true);
}
diff --git a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp
index 8dc59342aae..5b67247eff0 100644
--- a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp
+++ b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp
@@ -21,6 +21,7 @@
#include "Errors.h"
#include "Log.h"
#include "Map.h"
+#include "MotionMaster.h"
#include "MovementDefines.h"
#include "MoveSpline.h"
#include "MoveSplineInit.h"
@@ -29,15 +30,29 @@
#include "WaypointManager.h"
#include <sstream>
-WaypointMovementGenerator<Creature>::WaypointMovementGenerator(uint32 pathId, bool repeating) : _nextMoveTime(0), _pathId(pathId), _repeating(repeating), _loadedFromDB(true)
+WaypointMovementGenerator<Creature>::WaypointMovementGenerator(uint32 pathId, bool repeating, Optional<Milliseconds> duration, Optional<float> speed,
+ MovementWalkRunSpeedSelectionMode speedSelectionMode, Optional<std::pair<Milliseconds, Milliseconds>> waitTimeRangeAtPathEnd,
+ Optional<float> wanderDistanceAtPathEnds, bool followPathBackwardsFromEndToStart, bool generatePath)
+ : _nextMoveTime(0), _pathId(pathId), _repeating(repeating), _loadedFromDB(true),
+ _speed(speed), _speedSelectionMode(speedSelectionMode), _waitTimeRangeAtPathEnd(std::move(waitTimeRangeAtPathEnd)),
+ _wanderDistanceAtPathEnds(wanderDistanceAtPathEnds), _followPathBackwardsFromEndToStart(followPathBackwardsFromEndToStart), _isReturningToStart(false),
+ _generatePath(generatePath)
{
Mode = MOTION_MODE_DEFAULT;
Priority = MOTION_PRIORITY_NORMAL;
Flags = MOVEMENTGENERATOR_FLAG_INITIALIZATION_PENDING;
BaseUnitState = UNIT_STATE_ROAMING;
+ if (duration)
+ _duration.emplace(*duration);
}
-WaypointMovementGenerator<Creature>::WaypointMovementGenerator(WaypointPath& path, bool repeating) : _nextMoveTime(0), _pathId(0), _repeating(repeating), _loadedFromDB(false)
+WaypointMovementGenerator<Creature>::WaypointMovementGenerator(WaypointPath const& path, bool repeating, Optional<Milliseconds> duration, Optional<float> speed,
+ MovementWalkRunSpeedSelectionMode speedSelectionMode, Optional<std::pair<Milliseconds, Milliseconds>> waitTimeRangeAtPathEnd,
+ Optional<float> wanderDistanceAtPathEnds, bool followPathBackwardsFromEndToStart, bool generatePath)
+ : _nextMoveTime(0), _pathId(0), _repeating(repeating), _loadedFromDB(false),
+ _speed(speed), _speedSelectionMode(speedSelectionMode), _waitTimeRangeAtPathEnd(std::move(waitTimeRangeAtPathEnd)),
+ _wanderDistanceAtPathEnds(wanderDistanceAtPathEnds), _followPathBackwardsFromEndToStart(followPathBackwardsFromEndToStart), _isReturningToStart(false),
+ _generatePath(generatePath)
{
_path = &path;
@@ -45,8 +60,12 @@ WaypointMovementGenerator<Creature>::WaypointMovementGenerator(WaypointPath& pat
Priority = MOTION_PRIORITY_NORMAL;
Flags = MOVEMENTGENERATOR_FLAG_INITIALIZATION_PENDING;
BaseUnitState = UNIT_STATE_ROAMING;
+ if (duration)
+ _duration.emplace(*duration);
}
+WaypointMovementGenerator<Creature>::~WaypointMovementGenerator() = default;
+
MovementGeneratorType WaypointMovementGenerator<Creature>::GetMovementGeneratorType() const
{
return WAYPOINT_MOTION_TYPE;
@@ -139,6 +158,17 @@ bool WaypointMovementGenerator<Creature>::DoUpdate(Creature* owner, uint32 diff)
if (HasFlag(MOVEMENTGENERATOR_FLAG_FINALIZED | MOVEMENTGENERATOR_FLAG_PAUSED) || !_path || _path->nodes.empty())
return true;
+ if (_duration)
+ {
+ _duration->Update(diff);
+ if (_duration->Passed())
+ {
+ RemoveFlag(MOVEMENTGENERATOR_FLAG_TRANSITORY);
+ AddFlag(MOVEMENTGENERATOR_FLAG_INFORM_ENABLED);
+ return false;
+ }
+ }
+
if (owner->HasUnitState(UNIT_STATE_NOT_MOVE | UNIT_STATE_LOST_CONTROL) || owner->IsMovementPreventedByCasting())
{
AddFlag(MOVEMENTGENERATOR_FLAG_INTERRUPTED);
@@ -248,6 +278,20 @@ void WaypointMovementGenerator<Creature>::OnArrived(Creature* owner)
_nextMoveTime.Reset(waypoint.delay);
}
+ if (_waitTimeRangeAtPathEnd && _followPathBackwardsFromEndToStart
+ && ((_isReturningToStart && _currentNode == 0) || (!_isReturningToStart && _currentNode == _path->nodes.size() - 1)))
+ {
+ owner->ClearUnitState(UNIT_STATE_ROAMING_MOVE);
+ Milliseconds waitTime = randtime(_waitTimeRangeAtPathEnd->first, _waitTimeRangeAtPathEnd->second);
+ if (_duration)
+ _duration->Update(waitTime); // count the random movement time as part of waypoing movement action
+
+ if (_wanderDistanceAtPathEnds)
+ owner->GetMotionMaster()->MoveRandom(*_wanderDistanceAtPathEnds, waitTime, MOTION_SLOT_ACTIVE);
+ else
+ _nextMoveTime.Reset(waitTime);
+ }
+
if (waypoint.eventId && urand(0, 99) < waypoint.eventChance)
{
TC_LOG_DEBUG("maps.script", "Creature movement start script {} at point {} for {}.", waypoint.eventId, _currentNode, owner->GetGUID().ToString());
@@ -343,7 +387,7 @@ void WaypointMovementGenerator<Creature>::StartMove(Creature* owner, bool relaun
//! Do not use formationDest here, MoveTo requires transport offsets due to DisableTransportPathTransformations() call
//! but formationDest contains global coordinates
- init.MoveTo(waypoint.x, waypoint.y, waypoint.z);
+ init.MoveTo(waypoint.x, waypoint.y, waypoint.z, _generatePath);
if (waypoint.orientation.has_value() && waypoint.delay > 0)
init.SetFacing(*waypoint.orientation);
@@ -365,6 +409,22 @@ void WaypointMovementGenerator<Creature>::StartMove(Creature* owner, bool relaun
default:
break;
}
+ switch (_speedSelectionMode) // overrides move type from each waypoint if set
+ {
+ case MovementWalkRunSpeedSelectionMode::Default:
+ break;
+ case MovementWalkRunSpeedSelectionMode::ForceRun:
+ init.SetWalk(false);
+ break;
+ case MovementWalkRunSpeedSelectionMode::ForceWalk:
+ init.SetWalk(true);
+ break;
+ default:
+ break;
+ }
+
+ if (_speed)
+ init.SetVelocity(*_speed);
init.Launch();
@@ -377,7 +437,28 @@ bool WaypointMovementGenerator<Creature>::ComputeNextNode()
if ((_currentNode == _path->nodes.size() - 1) && !_repeating)
return false;
- _currentNode = (_currentNode + 1) % _path->nodes.size();
+ if (!_followPathBackwardsFromEndToStart || _path->nodes.size() < 2)
+ _currentNode = (_currentNode + 1) % _path->nodes.size();
+ else
+ {
+ if (!_isReturningToStart)
+ {
+ if (++_currentNode >= _path->nodes.size())
+ {
+ _currentNode -= 2;
+ _isReturningToStart = true;
+ }
+ }
+ else
+ {
+ if (_currentNode-- == 0)
+ {
+ _currentNode = 1;
+ _isReturningToStart = false;
+ }
+ }
+ }
+
return true;
}
diff --git a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.h b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.h
index e265c62522b..3764a9629f0 100755
--- a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.h
+++ b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.h
@@ -30,12 +30,19 @@ 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:
- explicit WaypointMovementGenerator(uint32 pathId = 0, bool repeating = true);
- explicit WaypointMovementGenerator(WaypointPath& path, bool repeating = true);
- ~WaypointMovementGenerator() { _path = nullptr; }
+ explicit WaypointMovementGenerator(uint32 pathId, bool repeating, Optional<Milliseconds> duration = {}, Optional<float> speed = {},
+ MovementWalkRunSpeedSelectionMode speedSelectionMode = MovementWalkRunSpeedSelectionMode::Default,
+ Optional<std::pair<Milliseconds, Milliseconds>> waitTimeRangeAtPathEnd = {}, Optional<float> wanderDistanceAtPathEnds = {},
+ bool followPathBackwardsFromEndToStart = false, bool generatePath = true);
+ explicit WaypointMovementGenerator(WaypointPath const& path, bool repeating, Optional<Milliseconds> duration, Optional<float> speed,
+ MovementWalkRunSpeedSelectionMode speedSelectionMode,
+ Optional<std::pair<Milliseconds, Milliseconds>> waitTimeRangeAtPathEnd, Optional<float> wanderDistanceAtPathEnds,
+ bool followPathBackwardsFromEndToStart, bool generatePath);
+ ~WaypointMovementGenerator();
MovementGeneratorType GetMovementGeneratorType() const override;
@@ -72,6 +79,15 @@ class WaypointMovementGenerator<Creature> : public MovementGeneratorMedium<Creat
uint32 _pathId;
bool _repeating;
bool _loadedFromDB;
+
+ Optional<TimeTracker> _duration;
+ Optional<float> _speed;
+ MovementWalkRunSpeedSelectionMode _speedSelectionMode;
+ Optional<std::pair<Milliseconds, Milliseconds>> _waitTimeRangeAtPathEnd;
+ Optional<float> _wanderDistanceAtPathEnds;
+ bool _followPathBackwardsFromEndToStart;
+ bool _isReturningToStart;
+ bool _generatePath;
};
#endif