aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/server/game/Movement/MotionMaster.cpp10
-rw-r--r--src/server/game/Movement/MotionMaster.h12
-rw-r--r--src/server/game/Movement/MovementGenerators/IdleMovementGenerator.cpp43
-rwxr-xr-xsrc/server/game/Movement/MovementGenerators/IdleMovementGenerator.h13
-rw-r--r--src/server/scripts/BrokenIsles/zone_mardum.cpp2
-rw-r--r--src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lurker_below.cpp2
6 files changed, 57 insertions, 25 deletions
diff --git a/src/server/game/Movement/MotionMaster.cpp b/src/server/game/Movement/MotionMaster.cpp
index ae052640a86..7c25d871900 100644
--- a/src/server/game/Movement/MotionMaster.cpp
+++ b/src/server/game/Movement/MotionMaster.cpp
@@ -1135,13 +1135,13 @@ void MotionMaster::MovePath(WaypointPath const& path, bool repeatable, Optional<
wanderDistanceAtPathEnds, followPathBackwardsFromEndToStart, generatePath), MOTION_SLOT_DEFAULT);
}
-void MotionMaster::MoveRotate(uint32 id, uint32 time, RotateDirection direction)
+void MotionMaster::MoveRotate(uint32 id, RotateDirection direction, Optional<Milliseconds> time /*= {}*/,
+ Optional<float> turnSpeed /*= {}*/, Optional<float> totalTurnAngle /*= {}*/)
{
- if (!time)
- return;
+ TC_LOG_DEBUG("movement.motionmaster", "MotionMaster::MoveRotate: '{}', starts rotate (time: {}ms, turnSpeed: {}, totalTurnAngle: {}, direction: {})",
+ _owner->GetGUID().ToString(), time.value_or(0ms).count(), turnSpeed, totalTurnAngle, direction);
- TC_LOG_DEBUG("movement.motionmaster", "MotionMaster::MoveRotate: '{}', starts rotate (time: {}, direction: {})", _owner->GetGUID().ToString(), time, direction);
- Add(new RotateMovementGenerator(id, time, direction));
+ Add(new RotateMovementGenerator(id, direction, time, turnSpeed, totalTurnAngle));
}
void MotionMaster::MoveFormation(Unit* leader, float range, float angle, uint32 point1, uint32 point2)
diff --git a/src/server/game/Movement/MotionMaster.h b/src/server/game/Movement/MotionMaster.h
index dd9c322b706..840a8a08116 100644
--- a/src/server/game/Movement/MotionMaster.h
+++ b/src/server/game/Movement/MotionMaster.h
@@ -205,7 +205,17 @@ class TC_GAME_API MotionMaster
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);
+
+ /**
+ * \brief Makes the Unit turn in place
+ * \param id Movement identifier, later passed to script MovementInform hooks
+ * \param direction Rotation direction
+ * \param time How long should this movement last, infinite if not set
+ * \param turnSpeed How fast should the unit rotate, in radians per second. Uses unit's turn speed if not set
+ * \param totalTurnAngle Total angle of the entire movement, infinite if not set
+ */
+ void MoveRotate(uint32 id, RotateDirection direction, Optional<Milliseconds> time = {},
+ Optional<float> turnSpeed = {}, Optional<float> totalTurnAngle = {});
void MoveFormation(Unit* leader, float range, float angle, uint32 point1, uint32 point2);
void LaunchMoveSpline(std::function<void(Movement::MoveSplineInit& init)>&& initializer, uint32 id = 0, MovementGeneratorPriority priority = MOTION_PRIORITY_NORMAL, MovementGeneratorType type = EFFECT_MOTION_TYPE);
diff --git a/src/server/game/Movement/MovementGenerators/IdleMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/IdleMovementGenerator.cpp
index 08d32016438..7aa6a59178c 100644
--- a/src/server/game/Movement/MovementGenerators/IdleMovementGenerator.cpp
+++ b/src/server/game/Movement/MovementGenerators/IdleMovementGenerator.cpp
@@ -62,7 +62,9 @@ MovementGeneratorType IdleMovementGenerator::GetMovementGeneratorType() const
//----------------------------------------------------//
-RotateMovementGenerator::RotateMovementGenerator(uint32 id, uint32 time, RotateDirection direction) : _id(id), _duration(time), _maxDuration(time), _direction(direction)
+RotateMovementGenerator::RotateMovementGenerator(uint32 id, RotateDirection direction, Optional<Milliseconds> duration,
+ Optional<float> turnSpeed, Optional<float> totalTurnAngle) : _id(id), _duration(duration), _turnSpeed(turnSpeed), _totalTurnAngle(totalTurnAngle),
+ _direction(direction), _diffSinceLastUpdate(0)
{
Mode = MOTION_MODE_DEFAULT;
Priority = MOTION_PRIORITY_NORMAL;
@@ -95,23 +97,34 @@ void RotateMovementGenerator::Reset(Unit* owner)
bool RotateMovementGenerator::Update(Unit* owner, uint32 diff)
{
- if (!owner)
- return false;
+ _diffSinceLastUpdate += diff;
- float angle = owner->GetOrientation();
- angle += (float(diff) * static_cast<float>(M_PI * 2) / _maxDuration) * (_direction == ROTATE_DIRECTION_LEFT ? 1.0f : -1.0f);
- angle = std::clamp(angle, 0.0f, static_cast<float>(M_PI * 2));
+ float currentAngle = owner->GetOrientation();
+ float angleDelta = _turnSpeed.value_or(owner->GetSpeed(MOVE_TURN_RATE)) * (float(_diffSinceLastUpdate) / float(IN_MILLISECONDS));
- Movement::MoveSplineInit init(owner);
- init.MoveTo(PositionToVector3(*owner), false);
- if (!owner->GetTransGUID().IsEmpty())
- init.DisableTransportPathTransformations();
- init.SetFacing(angle);
- init.Launch();
+ if (_duration)
+ _duration->Update(diff);
+
+ if (_totalTurnAngle)
+ _totalTurnAngle = *_totalTurnAngle - angleDelta;
+
+ bool expired = (_duration && _duration->Passed()) || (_totalTurnAngle && _totalTurnAngle < 0.0f);
+
+ if (angleDelta >= MIN_ANGLE_DELTA_FOR_FACING_UPDATE || expired)
+ {
+ float newAngle = Position::NormalizeOrientation(currentAngle + angleDelta * (_direction == ROTATE_DIRECTION_LEFT ? 1.0f : -1.0f));
+
+ Movement::MoveSplineInit init(owner);
+ init.MoveTo(PositionToVector3(owner->GetPosition()), false);
+ if (!owner->GetTransGUID().IsEmpty())
+ init.DisableTransportPathTransformations();
+ init.SetFacing(newAngle);
+ init.Launch();
+
+ _diffSinceLastUpdate = 0;
+ }
- if (_duration > diff)
- _duration -= diff;
- else
+ if (expired)
{
AddFlag(MOVEMENTGENERATOR_FLAG_INFORM_ENABLED);
return false;
diff --git a/src/server/game/Movement/MovementGenerators/IdleMovementGenerator.h b/src/server/game/Movement/MovementGenerators/IdleMovementGenerator.h
index a5c3939c96e..d525b9200f8 100755
--- a/src/server/game/Movement/MovementGenerators/IdleMovementGenerator.h
+++ b/src/server/game/Movement/MovementGenerators/IdleMovementGenerator.h
@@ -19,6 +19,8 @@
#define TRINITY_IDLEMOVEMENTGENERATOR_H
#include "MovementGenerator.h"
+#include "Optional.h"
+#include "Timer.h"
enum RotateDirection : uint8;
@@ -38,7 +40,10 @@ class IdleMovementGenerator : public MovementGenerator
class RotateMovementGenerator : public MovementGenerator
{
public:
- explicit RotateMovementGenerator(uint32 id, uint32 time, RotateDirection direction);
+ static constexpr float MIN_ANGLE_DELTA_FOR_FACING_UPDATE = 0.05f;
+
+ explicit RotateMovementGenerator(uint32 id, RotateDirection direction, Optional<Milliseconds> duration,
+ Optional<float> turnSpeed, Optional<float> totalTurnAngle);
void Initialize(Unit*) override;
void Reset(Unit*) override;
@@ -48,8 +53,12 @@ class RotateMovementGenerator : public MovementGenerator
MovementGeneratorType GetMovementGeneratorType() const override;
private:
- uint32 _id, _duration, _maxDuration;
+ uint32 _id;
+ Optional<TimeTracker> _duration;
+ Optional<float> _turnSpeed; ///< radians per sec
+ Optional<float> _totalTurnAngle;
RotateDirection _direction;
+ uint32 _diffSinceLastUpdate;
};
class DistractMovementGenerator : public MovementGenerator
diff --git a/src/server/scripts/BrokenIsles/zone_mardum.cpp b/src/server/scripts/BrokenIsles/zone_mardum.cpp
index fb88ff8bf2c..66a862bf8ee 100644
--- a/src/server/scripts/BrokenIsles/zone_mardum.cpp
+++ b/src/server/scripts/BrokenIsles/zone_mardum.cpp
@@ -1126,7 +1126,7 @@ struct npc_baleful_beaming_eye : public ScriptedAI
me->SetDisplayId(DISPLAYID_BALEFUL_EYE, true);
DoCastSelf(SPELL_BALEFUL_BEAMING_EYE_CREATE_AT);
// ToDo: rotation isn't changing orientation, turnspeed should be random
- me->GetMotionMaster()->MoveRotate(0, 10000, RAND(ROTATE_DIRECTION_LEFT, ROTATE_DIRECTION_RIGHT));
+ me->GetMotionMaster()->MoveRotate(0, RAND(ROTATE_DIRECTION_LEFT, ROTATE_DIRECTION_RIGHT), 10s);
}
};
diff --git a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lurker_below.cpp b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lurker_below.cpp
index a89ec5c1ec0..f645ab15b64 100644
--- a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lurker_below.cpp
+++ b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lurker_below.cpp
@@ -227,7 +227,7 @@ struct boss_the_lurker_below : public BossAI
{
Talk(EMOTE_SPOUT);
me->SetReactState(REACT_PASSIVE);
- me->GetMotionMaster()->MoveRotate(0, 20000, urand(0, 1) ? ROTATE_DIRECTION_LEFT : ROTATE_DIRECTION_RIGHT);
+ me->GetMotionMaster()->MoveRotate(0, urand(0, 1) ? ROTATE_DIRECTION_LEFT : ROTATE_DIRECTION_RIGHT, 20s, float(M_PI) / 7.0f);
SpoutTimer = 45000;
WhirlTimer = 20000; // whirl directly after spout
RotTimer = 20000;