Core/Movement: Delay creating MoveSplineInit objects used by GenericMovementGenerator to spline launch time

Port From (https://github.com/TrinityCore/TrinityCore/commit/36dde87249e87c5693162a6e890875d828f93d6d)
This commit is contained in:
hondacrx
2022-06-15 15:48:07 -04:00
parent 5ff87102ca
commit f91230ae33
7 changed files with 154 additions and 127 deletions
+6 -4
View File
@@ -234,10 +234,12 @@ namespace Game.Entities
public void MonsterMoveWithSpeed(float x, float y, float z, float speed, bool generatePath = false, bool forceDestination = false) public void MonsterMoveWithSpeed(float x, float y, float z, float speed, bool generatePath = false, bool forceDestination = false)
{ {
MoveSplineInit init = new(this); var initializer = (MoveSplineInit init) =>
init.MoveTo(x, y, z, generatePath, forceDestination); {
init.SetVelocity(speed); init.MoveTo(x, y, z, generatePath, forceDestination);
GetMotionMaster().LaunchMoveSpline(init, 0, MovementGeneratorPriority.Normal, MovementGeneratorType.Point); init.SetVelocity(speed);
};
GetMotionMaster().LaunchMoveSpline(initializer, 0, MovementGeneratorPriority.Normal, MovementGeneratorType.Point);
} }
public void KnockbackFrom(Position origin, float speedXY, float speedZ, SpellEffectExtraData spellEffectExtraData = null) public void KnockbackFrom(Position origin, float speedXY, float speedZ, SpellEffectExtraData spellEffectExtraData = null)
+11 -9
View File
@@ -1108,18 +1108,20 @@ namespace Game.Entities
} }
} }
float height = pos.GetPositionZ() + vehicle.GetBase().GetCollisionHeight(); var initializer = (MoveSplineInit init) =>
{
float height = pos.GetPositionZ() + vehicle.GetBase().GetCollisionHeight();
MoveSplineInit init = new(this); // Creatures without inhabit type air should begin falling after exiting the vehicle
if (IsTypeId(TypeId.Unit) && !CanFly() && height > GetMap().GetWaterOrGroundLevel(GetPhaseShift(), pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ() + vehicle.GetBase().GetCollisionHeight(), ref height))
init.SetFall();
// Creatures without inhabit type air should begin falling after exiting the vehicle init.MoveTo(pos.GetPositionX(), pos.GetPositionY(), height, false);
if (IsTypeId(TypeId.Unit) && !ToCreature().CanFly() && height > GetMap().GetWaterOrGroundLevel(GetPhaseShift(), pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ() + vehicle.GetBase().GetCollisionHeight(), ref height)) init.SetFacing(pos.GetOrientation());
init.SetFall(); init.SetTransportExit();
};
init.MoveTo(pos.GetPositionX(), pos.GetPositionY(), height, false); GetMotionMaster().LaunchMoveSpline(initializer, EventId.VehicleExit, MovementGeneratorPriority.Highest);
init.SetFacing(pos.GetOrientation());
init.SetTransportExit();
GetMotionMaster().LaunchMoveSpline(init, EventId.VehicleExit, MovementGeneratorPriority.Highest);
if (player != null) if (player != null)
player.ResummonPetTemporaryUnSummonedIfAny(); player.ResummonPetTemporaryUnSummonedIfAny();
+9 -7
View File
@@ -718,14 +718,16 @@ namespace Game.Entities
Passenger.SendClearTarget(); // SMSG_BREAK_TARGET Passenger.SendClearTarget(); // SMSG_BREAK_TARGET
Passenger.SetControlled(true, UnitState.Root); // SMSG_FORCE_ROOT - In some cases we send SMSG_SPLINE_MOVE_ROOT here (for creatures) Passenger.SetControlled(true, UnitState.Root); // SMSG_FORCE_ROOT - In some cases we send SMSG_SPLINE_MOVE_ROOT here (for creatures)
// also adds MOVEMENTFLAG_ROOT // also adds MOVEMENTFLAG_ROOT
MoveSplineInit init = new(Passenger); var initializer = (MoveSplineInit init) =>
init.DisableTransportPathTransformations(); {
init.MoveTo(x, y, z, false, true); init.DisableTransportPathTransformations();
init.SetFacing(o); init.MoveTo(x, y, z, false, true);
init.SetTransportEnter(); init.SetFacing(o);
Passenger.GetMotionMaster().LaunchMoveSpline(init, EventId.VehicleBoard, MovementGeneratorPriority.Highest); init.SetTransportEnter();
};
Passenger.GetMotionMaster().LaunchMoveSpline(initializer, EventId.VehicleBoard, MovementGeneratorPriority.Highest);
foreach (var (_, threatRef) in Passenger.GetThreatManager().GetThreatenedByMeList()) foreach (var (_, threatRef) in Passenger.GetThreatManager().GetThreatenedByMeList())
threatRef.GetOwner().GetThreatManager().AddThreat(Target.GetBase(), threatRef.GetThreat(), null, true, true); threatRef.GetOwner().GetThreatManager().AddThreat(Target.GetBase(), threatRef.GetThreat(), null, true, true);
+2 -3
View File
@@ -81,11 +81,10 @@ namespace Game
Log.outError(LogFilter.Network, "HandleMovementOpcodes: guid error"); Log.outError(LogFilter.Network, "HandleMovementOpcodes: guid error");
return; return;
} }
if (!movementInfo.Pos.IsPositionValid()) if (!movementInfo.Pos.IsPositionValid())
{
Log.outError(LogFilter.Network, "HandleMovementOpcodes: Invalid Position");
return; return;
}
if (!mover.MoveSpline.Finalized()) if (!mover.MoveSpline.Finalized())
return; return;
@@ -17,12 +17,13 @@
using Framework.Constants; using Framework.Constants;
using Game.Entities; using Game.Entities;
using System;
namespace Game.Movement namespace Game.Movement
{ {
class GenericMovementGenerator : MovementGenerator class GenericMovementGenerator : MovementGenerator
{ {
MoveSplineInit _splineInit; Action<MoveSplineInit> _splineInit;
MovementGeneratorType _type; MovementGeneratorType _type;
uint _pointId; uint _pointId;
TimeTracker _duration; TimeTracker _duration;
@@ -30,9 +31,9 @@ namespace Game.Movement
uint _arrivalSpellId; uint _arrivalSpellId;
ObjectGuid _arrivalSpellTargetGuid; ObjectGuid _arrivalSpellTargetGuid;
public GenericMovementGenerator(MoveSplineInit splineInit, MovementGeneratorType type, uint id, uint arrivalSpellId = 0, ObjectGuid arrivalSpellTargetGuid = default) public GenericMovementGenerator(Action<MoveSplineInit> initializer, MovementGeneratorType type, uint id, uint arrivalSpellId = 0, ObjectGuid arrivalSpellTargetGuid = default)
{ {
_splineInit = splineInit; _splineInit = initializer;
_type = type; _type = type;
_pointId = id; _pointId = id;
_duration = new(); _duration = new();
@@ -57,7 +58,9 @@ namespace Game.Movement
RemoveFlag(MovementGeneratorFlags.InitializationPending | MovementGeneratorFlags.Deactivated); RemoveFlag(MovementGeneratorFlags.InitializationPending | MovementGeneratorFlags.Deactivated);
AddFlag(MovementGeneratorFlags.Initialized); AddFlag(MovementGeneratorFlags.Initialized);
_duration.Reset((uint)_splineInit.Launch()); MoveSplineInit init = new(owner);
_splineInit(init);
_duration.Reset((uint)init.Launch());
} }
public override void Reset(Unit owner) public override void Reset(Unit owner)
+111 -95
View File
@@ -637,33 +637,41 @@ namespace Game.Movement
else else
{ {
// We are already close enough. We just need to turn toward the target without changing position. // We are already close enough. We just need to turn toward the target without changing position.
MoveSplineInit init = new(_owner); var initializer = (MoveSplineInit init) =>
init.MoveTo(_owner.GetPositionX(), _owner.GetPositionY(), _owner.GetPositionZ()); {
init.SetFacing(target); init.MoveTo(_owner.GetPositionX(), _owner.GetPositionY(), _owner.GetPositionZ());
Add(new GenericMovementGenerator(init, MovementGeneratorType.Effect, id)); Unit refreshedTarget = Global.ObjAccessor.GetUnit(_owner, target.GetGUID());
if (refreshedTarget != null)
init.SetFacing(refreshedTarget);
};
Add(new GenericMovementGenerator(initializer, MovementGeneratorType.Effect, id));
} }
} }
public void MoveLand(uint id, Position pos, float? velocity = null) public void MoveLand(uint id, Position pos, float? velocity = null)
{ {
MoveSplineInit init = new(_owner); var initializer = (MoveSplineInit init) =>
init.MoveTo(pos, false); {
init.SetAnimation(AnimTier.Ground); init.MoveTo(pos, false);
if (velocity.HasValue) init.SetAnimation(AnimTier.Ground);
init.SetVelocity(velocity.Value); if (velocity.HasValue)
init.SetVelocity(velocity.Value);
};
Add(new GenericMovementGenerator(init, MovementGeneratorType.Effect, id)); Add(new GenericMovementGenerator(initializer, MovementGeneratorType.Effect, id));
} }
public void MoveTakeoff(uint id, Position pos, float? velocity = null) public void MoveTakeoff(uint id, Position pos, float? velocity = null)
{ {
MoveSplineInit init = new(_owner); var initializer = (MoveSplineInit init) =>
init.MoveTo(pos, false); {
init.SetAnimation(AnimTier.Hover); init.MoveTo(pos, false);
if (velocity.HasValue) init.SetAnimation(AnimTier.Hover);
init.SetVelocity(velocity.Value); if (velocity.HasValue)
init.SetVelocity(velocity.Value);
};
Add(new GenericMovementGenerator(init, MovementGeneratorType.Effect, id)); Add(new GenericMovementGenerator(initializer, MovementGeneratorType.Effect, id));
} }
public void MoveCharge(float x, float y, float z, float speed = SPEED_CHARGE, uint id = EventId.Charge, bool generatePath = false, Unit target = null, SpellEffectExtraData spellEffectExtraData = null) public void MoveCharge(float x, float y, float z, float speed = SPEED_CHARGE, uint id = EventId.Charge, bool generatePath = false, Unit target = null, SpellEffectExtraData spellEffectExtraData = null)
@@ -723,15 +731,17 @@ namespace Game.Movement
// Use a mmap raycast to get a valid destination. // Use a mmap raycast to get a valid destination.
_owner.MovePositionToFirstCollision(dest, dist, _owner.GetRelativeAngle(origin) + MathF.PI); _owner.MovePositionToFirstCollision(dest, dist, _owner.GetRelativeAngle(origin) + MathF.PI);
MoveSplineInit init = new(_owner); var initializer = (MoveSplineInit init) =>
init.MoveTo(dest.GetPositionX(), dest.GetPositionY(), dest.GetPositionZ(), false); {
init.SetParabolic(max_height, 0); init.MoveTo(dest.GetPositionX(), dest.GetPositionY(), dest.GetPositionZ(), false);
init.SetOrientationFixed(true); init.SetParabolic(max_height, 0);
init.SetVelocity(speedXY); init.SetOrientationFixed(true);
if (spellEffectExtraData != null) init.SetVelocity(speedXY);
init.SetSpellEffectExtraData(spellEffectExtraData); if (spellEffectExtraData != null)
init.SetSpellEffectExtraData(spellEffectExtraData);
};
GenericMovementGenerator movement = new(init, MovementGeneratorType.Effect, 0); GenericMovementGenerator movement = new(initializer, MovementGeneratorType.Effect, 0);
movement.Priority = MovementGeneratorPriority.Highest; movement.Priority = MovementGeneratorPriority.Highest;
movement.AddFlag(MovementGeneratorFlags.PersistOnDeath); movement.AddFlag(MovementGeneratorFlags.PersistOnDeath);
Add(movement); Add(movement);
@@ -765,14 +775,16 @@ namespace Game.Movement
float moveTimeHalf = (float)(speedZ / gravity); float moveTimeHalf = (float)(speedZ / gravity);
float max_height = -MoveSpline.ComputeFallElevation(moveTimeHalf, false, -speedZ); float max_height = -MoveSpline.ComputeFallElevation(moveTimeHalf, false, -speedZ);
MoveSplineInit init = new(_owner); var initializer = (MoveSplineInit init) =>
init.MoveTo(x, y, z, false); {
init.SetParabolic(max_height, 0); init.MoveTo(x, y, z, false);
init.SetVelocity(speedXY); init.SetParabolic(max_height, 0);
if (hasOrientation) init.SetVelocity(speedXY);
init.SetFacing(o); if (hasOrientation)
if (spellEffectExtraData != null) init.SetFacing(o);
init.SetSpellEffectExtraData(spellEffectExtraData); if (spellEffectExtraData != null)
init.SetSpellEffectExtraData(spellEffectExtraData);
};
uint arrivalSpellId = 0; uint arrivalSpellId = 0;
ObjectGuid arrivalSpellTargetGuid = ObjectGuid.Empty; ObjectGuid arrivalSpellTargetGuid = ObjectGuid.Empty;
@@ -782,7 +794,7 @@ namespace Game.Movement
arrivalSpellTargetGuid = arrivalCast.Target; arrivalSpellTargetGuid = arrivalCast.Target;
} }
GenericMovementGenerator movement = new(init, MovementGeneratorType.Effect, id, arrivalSpellId, arrivalSpellTargetGuid); GenericMovementGenerator movement = new(initializer, MovementGeneratorType.Effect, id, arrivalSpellId, arrivalSpellTargetGuid);
movement.Priority = MovementGeneratorPriority.Highest; movement.Priority = MovementGeneratorPriority.Highest;
movement.BaseUnitState = UnitState.Jumping; movement.BaseUnitState = UnitState.Jumping;
Add(movement); Add(movement);
@@ -794,17 +806,17 @@ namespace Game.Movement
if (speedXY < 0.01f) if (speedXY < 0.01f)
return; return;
MoveSplineInit init = new(_owner); var initializer = (MoveSplineInit init) =>
init.MoveTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), false); {
init.SetParabolicVerticalAcceleration(gravity, 0); init.MoveTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), false);
init.SetUncompressed(); init.SetParabolicVerticalAcceleration(gravity, 0);
init.SetVelocity(speedXY); init.SetUncompressed();
init.SetVelocity(speedXY);
if (hasOrientation) if (hasOrientation)
init.SetFacing(pos.GetOrientation()); init.SetFacing(pos.GetOrientation());
if (spellEffectExtraData != null)
if (spellEffectExtraData != null) init.SetSpellEffectExtraData(spellEffectExtraData);
init.SetSpellEffectExtraData(spellEffectExtraData); };
uint arrivalSpellId = 0; uint arrivalSpellId = 0;
ObjectGuid arrivalSpellTargetGuid = default; ObjectGuid arrivalSpellTargetGuid = default;
@@ -814,7 +826,7 @@ namespace Game.Movement
arrivalSpellTargetGuid = arrivalCast.Target; arrivalSpellTargetGuid = arrivalCast.Target;
} }
GenericMovementGenerator movement = new GenericMovementGenerator(init, MovementGeneratorType.Effect, id, arrivalSpellId, arrivalSpellTargetGuid); GenericMovementGenerator movement = new GenericMovementGenerator(initializer, MovementGeneratorType.Effect, id, arrivalSpellId, arrivalSpellTargetGuid);
movement.Priority = MovementGeneratorPriority.Highest; movement.Priority = MovementGeneratorPriority.Highest;
movement.BaseUnitState = UnitState.Jumping; movement.BaseUnitState = UnitState.Jumping;
movement.AddFlag(MovementGeneratorFlags.PersistOnDeath); movement.AddFlag(MovementGeneratorFlags.PersistOnDeath);
@@ -823,61 +835,63 @@ namespace Game.Movement
public void MoveCirclePath(float x, float y, float z, float radius, bool clockwise, byte stepCount) public void MoveCirclePath(float x, float y, float z, float radius, bool clockwise, byte stepCount)
{ {
float step = 2 * MathFunctions.PI / stepCount * (clockwise ? -1.0f : 1.0f); var initializer = (MoveSplineInit init) =>
Position pos = new(x, y, z, 0.0f);
float angle = pos.GetAbsoluteAngle(_owner.GetPositionX(), _owner.GetPositionY());
MoveSplineInit init = new(_owner);
// add the owner's current position as starting point as it gets removed after entering the cycle
init.Path().Add(new Vector3(_owner.GetPositionX(), _owner.GetPositionY(), _owner.GetPositionZ()));
for (byte i = 0; i < stepCount; angle += step, ++i)
{ {
Vector3 point = new(); float step = 2 * MathFunctions.PI / stepCount * (clockwise ? -1.0f : 1.0f);
point.X = (float)(x + radius * Math.Cos(angle)); Position pos = new(x, y, z, 0.0f);
point.Y = (float)(y + radius * Math.Sin(angle)); float angle = pos.GetAbsoluteAngle(_owner.GetPositionX(), _owner.GetPositionY());
// add the owner's current position as starting point as it gets removed after entering the cycle
init.Path().Add(new Vector3(_owner.GetPositionX(), _owner.GetPositionY(), _owner.GetPositionZ()));
for (byte i = 0; i < stepCount; angle += step, ++i)
{
Vector3 point = new();
point.X = (float)(x + radius * Math.Cos(angle));
point.Y = (float)(y + radius * Math.Sin(angle));
if (_owner.IsFlying())
point.Z = z;
else
point.Z = _owner.GetMapHeight(point.X, point.Y, z) + _owner.GetHoverOffset();
init.Path().Add(point);
}
if (_owner.IsFlying()) if (_owner.IsFlying())
point.Z = z; {
init.SetFly();
init.SetCyclic();
init.SetAnimation(AnimTier.Hover);
}
else else
point.Z = _owner.GetMapHeight(point.X, point.Y, z) + _owner.GetHoverOffset(); {
init.SetWalk(true);
init.SetCyclic();
}
};
init.Path().Add(point); Add(new GenericMovementGenerator(initializer, MovementGeneratorType.Effect, 0));
}
if (_owner.IsFlying())
{
init.SetFly();
init.SetCyclic();
init.SetAnimation(AnimTier.Hover);
}
else
{
init.SetWalk(true);
init.SetCyclic();
}
Add(new GenericMovementGenerator(init, MovementGeneratorType.Effect, 0));
} }
void MoveSmoothPath(uint pointId, Vector3[] pathPoints, int pathSize, bool walk = false, bool fly = false) void MoveSmoothPath(uint pointId, Vector3[] pathPoints, int pathSize, bool walk = false, bool fly = false)
{ {
MoveSplineInit init = new(_owner); var initializer = (MoveSplineInit init) =>
if (fly)
{ {
init.SetFly(); init.MovebyPath(pathPoints);
init.SetUncompressed(); init.SetWalk(walk);
init.SetSmooth(); if (fly)
} {
init.SetFly();
init.MovebyPath(pathPoints); init.SetUncompressed();
init.SetWalk(walk); init.SetSmooth();
}
};
// This code is not correct // This code is not correct
// GenericMovementGenerator does not affect UNIT_STATE_ROAMING_MOVE // GenericMovementGenerator does not affect UNIT_STATE_ROAMING_MOVE
// need to call PointMovementGenerator with various pointIds // need to call PointMovementGenerator with various pointIds
Add(new GenericMovementGenerator(init, MovementGeneratorType.Effect, pointId)); Add(new GenericMovementGenerator(initializer, MovementGeneratorType.Effect, pointId));
} }
public void MoveAlongSplineChain(uint pointId, uint dbChainId, bool walk) public void MoveAlongSplineChain(uint pointId, uint dbChainId, bool walk)
@@ -925,8 +939,8 @@ namespace Game.Movement
return; return;
// rooted units don't move (also setting falling+root flag causes client freezes) // rooted units don't move (also setting falling+root flag causes client freezes)
if (_owner.HasUnitState(UnitState.Root | UnitState.Stunned)) if (_owner.HasUnitState(UnitState.Root | UnitState.Stunned))
return; return;
_owner.SetFall(true); _owner.SetFall(true);
@@ -937,11 +951,13 @@ namespace Game.Movement
return; return;
} }
MoveSplineInit init = new(_owner); var initializer = (MoveSplineInit init) =>
init.MoveTo(_owner.GetPositionX(), _owner.GetPositionY(), tz + _owner.GetHoverOffset(), false); {
init.SetFall(); init.MoveTo(_owner.GetPositionX(), _owner.GetPositionY(), tz + _owner.GetHoverOffset(), false);
init.SetFall();
};
GenericMovementGenerator movement = new(init, MovementGeneratorType.Effect, id); GenericMovementGenerator movement = new(initializer, MovementGeneratorType.Effect, id);
movement.Priority = MovementGeneratorPriority.Highest; movement.Priority = MovementGeneratorPriority.Highest;
Add(movement); Add(movement);
} }
@@ -1031,7 +1047,7 @@ namespace Game.Movement
Add(new FormationMovementGenerator(leader, range, angle, point1, point2), MovementSlot.Default); Add(new FormationMovementGenerator(leader, range, angle, point1, point2), MovementSlot.Default);
} }
public void LaunchMoveSpline(MoveSplineInit init, uint id = 0, MovementGeneratorPriority priority = MovementGeneratorPriority.Normal, MovementGeneratorType type = MovementGeneratorType.Effect) public void LaunchMoveSpline(Action<MoveSplineInit> initializer, uint id = 0, MovementGeneratorPriority priority = MovementGeneratorPriority.Normal, MovementGeneratorType type = MovementGeneratorType.Effect)
{ {
if (IsInvalidMovementGeneratorType(type)) if (IsInvalidMovementGeneratorType(type))
{ {
@@ -1039,7 +1055,7 @@ namespace Game.Movement
return; return;
} }
GenericMovementGenerator movement = new(init, type, id); GenericMovementGenerator movement = new(initializer, type, id);
movement.Priority = priority; movement.Priority = priority;
Add(movement); Add(movement);
} }
@@ -1262,7 +1278,7 @@ namespace Game.Movement
public uint? ProgressCurveId; public uint? ProgressCurveId;
public uint? ParabolicCurveId; public uint? ParabolicCurveId;
} }
public struct ChaseRange public struct ChaseRange
{ {
// this contains info that informs how we should path! // this contains info that informs how we should path!
+8 -5
View File
@@ -2039,11 +2039,14 @@ namespace Scripts.World.NpcSpecial
break; break;
} }
MoveSplineInit init = new(who); var initializer = (MoveSplineInit init) =>
init.DisableTransportPathTransformations(); {
init.MoveTo(x, y, z, false); init.DisableTransportPathTransformations();
init.SetFacing(o); init.MoveTo(x, y, z, false);
who.GetMotionMaster().LaunchMoveSpline(init, EventId.VehicleBoard, MovementGeneratorPriority.Highest); init.SetFacing(o);
};
who.GetMotionMaster().LaunchMoveSpline(initializer, EventId.VehicleBoard, MovementGeneratorPriority.Highest);
who.m_Events.AddEvent(new CastFoodSpell(who, SpellIds.ChairSpells[who.GetEntry()]), who.m_Events.CalculateTime(TimeSpan.FromSeconds(1))); who.m_Events.AddEvent(new CastFoodSpell(who, SpellIds.ChairSpells[who.GetEntry()]), who.m_Events.CalculateTime(TimeSpan.FromSeconds(1)));
Creature creature = who.ToCreature(); Creature creature = who.ToCreature();
if (creature) if (creature)