aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Movement/MotionMaster.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/game/Movement/MotionMaster.cpp')
-rw-r--r--src/server/game/Movement/MotionMaster.cpp196
1 files changed, 107 insertions, 89 deletions
diff --git a/src/server/game/Movement/MotionMaster.cpp b/src/server/game/Movement/MotionMaster.cpp
index b0a8aa1fa70..e7dc9d6f632 100644
--- a/src/server/game/Movement/MotionMaster.cpp
+++ b/src/server/game/Movement/MotionMaster.cpp
@@ -27,6 +27,7 @@
#include "Map.h"
#include "MoveSpline.h"
#include "MoveSplineInit.h"
+#include "ObjectAccessor.h"
#include "PathGenerator.h"
#include "PetDefines.h"
#include "Player.h"
@@ -687,10 +688,13 @@ void MotionMaster::MoveCloserAndStop(uint32 id, Unit* target, float distance)
else
{
// We are already close enough. We just need to turn toward the target without changing position.
- Movement::MoveSplineInit init(_owner);
- init.MoveTo(_owner->GetPositionX(), _owner->GetPositionY(), _owner->GetPositionZ());
- init.SetFacing(target);
- Add(new GenericMovementGenerator(std::move(init), EFFECT_MOTION_TYPE, id));
+ std::function<void(Movement::MoveSplineInit&)> initializer = [=, target = target->GetGUID()](Movement::MoveSplineInit& init)
+ {
+ init.MoveTo(_owner->GetPositionX(), _owner->GetPositionY(), _owner->GetPositionZ());
+ if (Unit const* refreshedTarget = ObjectAccessor::GetUnit(*_owner, target))
+ init.SetFacing(refreshedTarget);
+ };
+ Add(new GenericMovementGenerator(std::move(initializer), EFFECT_MOTION_TYPE, id));
}
}
@@ -698,24 +702,28 @@ void MotionMaster::MoveLand(uint32 id, Position const& pos, Optional<float> velo
{
TC_LOG_DEBUG("movement.motionmaster", "MotionMaster::MoveLand: '%s', landing point Id: %u (X: %f, Y: %f, Z: %f)", _owner->GetGUID().ToString().c_str(), id, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ());
- Movement::MoveSplineInit init(_owner);
- init.MoveTo(PositionToVector3(pos), false);
- init.SetAnimation(AnimTier::Ground);
- if (velocity)
- init.SetVelocity(*velocity);
- Add(new GenericMovementGenerator(std::move(init), EFFECT_MOTION_TYPE, id));
+ std::function<void(Movement::MoveSplineInit&)> initializer = [=](Movement::MoveSplineInit& init)
+ {
+ init.MoveTo(PositionToVector3(pos), false);
+ init.SetAnimation(AnimTier::Ground);
+ if (velocity)
+ init.SetVelocity(*velocity);
+ };
+ Add(new GenericMovementGenerator(std::move(initializer), EFFECT_MOTION_TYPE, id));
}
void MotionMaster::MoveTakeoff(uint32 id, Position const& pos, Optional<float> velocity /*= {}*/)
{
TC_LOG_DEBUG("movement.motionmaster", "MotionMaster::MoveTakeoff: '%s', landing point Id: %u (X: %f, Y: %f, Z: %f)", _owner->GetGUID().ToString().c_str(), id, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ());
- Movement::MoveSplineInit init(_owner);
- init.MoveTo(PositionToVector3(pos), false);
- init.SetAnimation(AnimTier::Hover);
- if (velocity)
- init.SetVelocity(*velocity);
- Add(new GenericMovementGenerator(std::move(init), EFFECT_MOTION_TYPE, id));
+ std::function<void(Movement::MoveSplineInit&)> initializer = [=](Movement::MoveSplineInit& init)
+ {
+ init.MoveTo(PositionToVector3(pos), false);
+ init.SetAnimation(AnimTier::Hover);
+ if (velocity)
+ init.SetVelocity(*velocity);
+ };
+ Add(new GenericMovementGenerator(std::move(initializer), EFFECT_MOTION_TYPE, id));
}
void MotionMaster::MoveCharge(float x, float y, float z, float speed /*= SPEED_CHARGE*/, uint32 id /*= EVENT_CHARGE*/, bool generatePath /*= false*/,
@@ -778,15 +786,17 @@ void MotionMaster::MoveKnockbackFrom(Position const& origin, float speedXY, floa
// Use a mmap raycast to get a valid destination.
_owner->MovePositionToFirstCollision(dest, dist, _owner->GetRelativeAngle(origin) + float(M_PI));
- Movement::MoveSplineInit init(_owner);
- init.MoveTo(dest.GetPositionX(), dest.GetPositionY(), dest.GetPositionZ(), false);
- init.SetParabolic(max_height, 0);
- init.SetOrientationFixed(true);
- init.SetVelocity(speedXY);
- if (spellEffectExtraData)
- init.SetSpellEffectExtraData(*spellEffectExtraData);
+ std::function<void(Movement::MoveSplineInit&)> initializer = [=, effect = (spellEffectExtraData ? Optional<Movement::SpellEffectExtraData>(*spellEffectExtraData) : Optional<Movement::SpellEffectExtraData>())](Movement::MoveSplineInit& init)
+ {
+ init.MoveTo(dest.GetPositionX(), dest.GetPositionY(), dest.GetPositionZ(), false);
+ init.SetParabolic(max_height, 0);
+ init.SetOrientationFixed(true);
+ init.SetVelocity(speedXY);
+ if (effect)
+ init.SetSpellEffectExtraData(*effect);
+ };
- GenericMovementGenerator* movement = new GenericMovementGenerator(std::move(init), EFFECT_MOTION_TYPE, 0);
+ GenericMovementGenerator* movement = new GenericMovementGenerator(std::move(initializer), EFFECT_MOTION_TYPE, 0);
movement->Priority = MOTION_PRIORITY_HIGHEST;
movement->AddFlag(MOVEMENTGENERATOR_FLAG_PERSIST_ON_DEATH);
Add(movement);
@@ -825,14 +835,16 @@ void MotionMaster::MoveJump(float x, float y, float z, float o, float speedXY, f
float moveTimeHalf = speedZ / Movement::gravity;
float max_height = -Movement::computeFallElevation(moveTimeHalf, false, -speedZ);
- Movement::MoveSplineInit init(_owner);
- init.MoveTo(x, y, z, false);
- init.SetParabolic(max_height, 0);
- init.SetVelocity(speedXY);
- if (hasOrientation)
- init.SetFacing(o);
- if (spellEffectExtraData)
- init.SetSpellEffectExtraData(*spellEffectExtraData);
+ std::function<void(Movement::MoveSplineInit&)> initializer = [=, effect = (spellEffectExtraData ? Optional<Movement::SpellEffectExtraData>(*spellEffectExtraData) : Optional<Movement::SpellEffectExtraData>())](Movement::MoveSplineInit& init)
+ {
+ init.MoveTo(x, y, z, false);
+ init.SetParabolic(max_height, 0);
+ init.SetVelocity(speedXY);
+ if (hasOrientation)
+ init.SetFacing(o);
+ if (effect)
+ init.SetSpellEffectExtraData(*effect);
+ };
uint32 arrivalSpellId = 0;
ObjectGuid arrivalSpellTargetGuid;
@@ -842,7 +854,7 @@ void MotionMaster::MoveJump(float x, float y, float z, float o, float speedXY, f
arrivalSpellTargetGuid = arrivalCast->Target;
}
- GenericMovementGenerator* movement = new GenericMovementGenerator(std::move(init), EFFECT_MOTION_TYPE, id, arrivalSpellId, arrivalSpellTargetGuid);
+ GenericMovementGenerator* movement = new GenericMovementGenerator(std::move(initializer), EFFECT_MOTION_TYPE, id, arrivalSpellId, arrivalSpellTargetGuid);
movement->Priority = MOTION_PRIORITY_HIGHEST;
movement->BaseUnitState = UNIT_STATE_JUMPING;
Add(movement);
@@ -855,15 +867,17 @@ void MotionMaster::MoveJumpWithGravity(Position const& pos, float speedXY, float
if (speedXY < 0.01f)
return;
- Movement::MoveSplineInit init(_owner);
- init.MoveTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), false);
- init.SetParabolicVerticalAcceleration(gravity, 0);
- init.SetUncompressed();
- init.SetVelocity(speedXY);
- if (hasOrientation)
- init.SetFacing(pos.GetOrientation());
- if (spellEffectExtraData)
- init.SetSpellEffectExtraData(*spellEffectExtraData);
+ std::function<void(Movement::MoveSplineInit&)> initializer = [=, effect = (spellEffectExtraData ? Optional<Movement::SpellEffectExtraData>(*spellEffectExtraData) : Optional<Movement::SpellEffectExtraData>())](Movement::MoveSplineInit& init)
+ {
+ init.MoveTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), false);
+ init.SetParabolicVerticalAcceleration(gravity, 0);
+ init.SetUncompressed();
+ init.SetVelocity(speedXY);
+ if (hasOrientation)
+ init.SetFacing(pos.GetOrientation());
+ if (effect)
+ init.SetSpellEffectExtraData(*effect);
+ };
uint32 arrivalSpellId = 0;
ObjectGuid arrivalSpellTargetGuid;
@@ -873,7 +887,7 @@ void MotionMaster::MoveJumpWithGravity(Position const& pos, float speedXY, float
arrivalSpellTargetGuid = arrivalCast->Target;
}
- GenericMovementGenerator* movement = new GenericMovementGenerator(std::move(init), EFFECT_MOTION_TYPE, id, arrivalSpellId, arrivalSpellTargetGuid);
+ GenericMovementGenerator* movement = new GenericMovementGenerator(std::move(initializer), EFFECT_MOTION_TYPE, id, arrivalSpellId, arrivalSpellTargetGuid);
movement->Priority = MOTION_PRIORITY_HIGHEST;
movement->BaseUnitState = UNIT_STATE_JUMPING;
movement->AddFlag(MOVEMENTGENERATOR_FLAG_PERSIST_ON_DEATH);
@@ -882,67 +896,69 @@ void MotionMaster::MoveJumpWithGravity(Position const& pos, float speedXY, float
void MotionMaster::MoveCirclePath(float x, float y, float z, float radius, bool clockwise, uint8 stepCount)
{
- float step = 2 * float(M_PI) / stepCount * (clockwise ? -1.0f : 1.0f);
- Position const& pos = { x, y, z, 0.0f };
- float angle = pos.GetAbsoluteAngle(_owner->GetPositionX(), _owner->GetPositionY());
+ std::function<void(Movement::MoveSplineInit&)> initializer = [=](Movement::MoveSplineInit& init)
+ {
+ float step = 2 * float(M_PI) / stepCount * (clockwise ? -1.0f : 1.0f);
+ Position const& pos = { x, y, z, 0.0f };
+ float angle = pos.GetAbsoluteAngle(_owner->GetPositionX(), _owner->GetPositionY());
- Movement::MoveSplineInit init(_owner);
+ // add the owner's current position as starting point as it gets removed after entering the cycle
+ init.Path().push_back(G3D::Vector3(_owner->GetPositionX(), _owner->GetPositionY(), _owner->GetPositionZ()));
- // add the owner's current position as starting point as it gets removed after entering the cycle
- init.Path().push_back(G3D::Vector3(_owner->GetPositionX(), _owner->GetPositionY(), _owner->GetPositionZ()));
+ for (uint8 i = 0; i < stepCount; angle += step, ++i)
+ {
+ G3D::Vector3 point;
+ point.x = x + radius * cosf(angle);
+ point.y = y + radius * sinf(angle);
- for (uint8 i = 0; i < stepCount; angle += step, ++i)
- {
- G3D::Vector3 point;
- point.x = x + radius * cosf(angle);
- point.y = y + radius * sinf(angle);
+ if (_owner->IsFlying())
+ point.z = z;
+ else
+ point.z = _owner->GetMapHeight(point.x, point.y, z) + _owner->GetHoverOffset();
+
+ init.Path().push_back(point);
+ }
if (_owner->IsFlying())
- point.z = z;
+ {
+ init.SetFly();
+ init.SetCyclic();
+ init.SetAnimation(AnimTier::Hover);
+ }
else
- point.z = _owner->GetMapHeight(point.x, point.y, z) + _owner->GetHoverOffset();
-
- init.Path().push_back(point);
- }
-
- if (_owner->IsFlying())
- {
- init.SetFly();
- init.SetCyclic();
- init.SetAnimation(AnimTier::Hover);
- }
- else
- {
- init.SetWalk(true);
- init.SetCyclic();
- }
+ {
+ init.SetWalk(true);
+ init.SetCyclic();
+ }
+ };
- Add(new GenericMovementGenerator(std::move(init), EFFECT_MOTION_TYPE, 0));
+ Add(new GenericMovementGenerator(std::move(initializer), EFFECT_MOTION_TYPE, 0));
}
void MotionMaster::MoveSmoothPath(uint32 pointId, Position const* pathPoints, size_t pathSize, bool walk, bool fly)
{
- Movement::MoveSplineInit init(_owner);
- if (fly)
- {
- init.SetFly();
- init.SetUncompressed();
- init.SetSmooth();
- }
-
Movement::PointsArray path;
path.reserve(pathSize);
std::transform(pathPoints, pathPoints + pathSize, std::back_inserter(path), [](Position const& point)
{
return G3D::Vector3(point.GetPositionX(), point.GetPositionY(), point.GetPositionZ());
});
- init.MovebyPath(path);
- init.SetWalk(walk);
+ std::function<void(Movement::MoveSplineInit&)> initializer = [=](Movement::MoveSplineInit& init)
+ {
+ init.MovebyPath(path);
+ init.SetWalk(walk);
+ if (fly)
+ {
+ init.SetFly();
+ init.SetUncompressed();
+ init.SetSmooth();
+ }
+ };
// This code is not correct
// GenericMovementGenerator does not affect UNIT_STATE_ROAMING_MOVE
// need to call PointMovementGenerator with various pointIds
- Add(new GenericMovementGenerator(std::move(init), EFFECT_MOTION_TYPE, pointId));
+ Add(new GenericMovementGenerator(std::move(initializer), EFFECT_MOTION_TYPE, pointId));
}
void MotionMaster::MoveAlongSplineChain(uint32 pointId, uint16 dbChainId, bool walk)
@@ -1005,11 +1021,13 @@ void MotionMaster::MoveFall(uint32 id/* = 0*/)
return;
}
- Movement::MoveSplineInit init(_owner);
- init.MoveTo(_owner->GetPositionX(), _owner->GetPositionY(), tz + _owner->GetHoverOffset(), false);
- init.SetFall();
+ std::function<void(Movement::MoveSplineInit&)> initializer = [=](Movement::MoveSplineInit& init)
+ {
+ init.MoveTo(_owner->GetPositionX(), _owner->GetPositionY(), tz + _owner->GetHoverOffset(), false);
+ init.SetFall();
+ };
- GenericMovementGenerator* movement = new GenericMovementGenerator(std::move(init), EFFECT_MOTION_TYPE, id);
+ GenericMovementGenerator* movement = new GenericMovementGenerator(std::move(initializer), EFFECT_MOTION_TYPE, id);
movement->Priority = MOTION_PRIORITY_HIGHEST;
Add(movement);
}
@@ -1106,7 +1124,7 @@ void MotionMaster::MoveFormation(Unit* leader, float range, float angle, uint32
}
}
-void MotionMaster::LaunchMoveSpline(Movement::MoveSplineInit&& init, uint32 id/*= 0*/, MovementGeneratorPriority priority/* = MOTION_PRIORITY_NORMAL*/, MovementGeneratorType type/*= EFFECT_MOTION_TYPE*/)
+void MotionMaster::LaunchMoveSpline(std::function<void(Movement::MoveSplineInit& init)>&& initializer, uint32 id/*= 0*/, MovementGeneratorPriority priority/* = MOTION_PRIORITY_NORMAL*/, MovementGeneratorType type/*= EFFECT_MOTION_TYPE*/)
{
if (IsInvalidMovementGeneratorType(type))
{
@@ -1116,7 +1134,7 @@ void MotionMaster::LaunchMoveSpline(Movement::MoveSplineInit&& init, uint32 id/*
TC_LOG_DEBUG("movement.motionmaster", "MotionMaster::LaunchMoveSpline: '%s', initiates spline Id: %u (Type: %u, Priority: %u)", _owner->GetGUID().ToString().c_str(), id, type, priority);
- GenericMovementGenerator* movement = new GenericMovementGenerator(std::move(init), type, id);
+ GenericMovementGenerator* movement = new GenericMovementGenerator(std::move(initializer), type, id);
movement->Priority = priority;
Add(movement);
}