Core/Misc: movement cleanup

Port From (https://github.com/TrinityCore/TrinityCore/commit/4793b073eec2af32622ff703911721100730e868)
This commit is contained in:
hondacrx
2021-09-26 12:17:10 -04:00
parent e747de7608
commit 569e20ebc1
12 changed files with 76 additions and 48 deletions
+4 -3
View File
@@ -97,10 +97,11 @@ namespace Game.AI
return new NullCreatureAI(creature); return new NullCreatureAI(creature);
} }
public static IMovementGenerator SelectMovementAI(Creature creature) public static IMovementGenerator SelectMovementAI(Unit unit)
{ {
MovementGeneratorType type = MovementGeneratorType.Idle; MovementGeneratorType type = unit.GetDefaultMovementType();
if (creature.GetPlayerMovingMe() == null) Creature creature = unit.ToCreature();
if (creature != null && creature.GetPlayerMovingMe() == null)
type = creature.GetDefaultMovementType(); type = creature.GetDefaultMovementType();
return type switch return type switch
+1 -1
View File
@@ -3189,7 +3189,7 @@ namespace Game.Entities
public void SetNoSearchAssistance(bool val) { m_AlreadySearchedAssistance = val; } public void SetNoSearchAssistance(bool val) { m_AlreadySearchedAssistance = val; }
public bool HasSearchedAssistance() { return m_AlreadySearchedAssistance; } public bool HasSearchedAssistance() { return m_AlreadySearchedAssistance; }
public MovementGeneratorType GetDefaultMovementType() { return DefaultMovementType; } public override MovementGeneratorType GetDefaultMovementType() { return DefaultMovementType; }
public void SetDefaultMovementType(MovementGeneratorType mgt) { DefaultMovementType = mgt; } public void SetDefaultMovementType(MovementGeneratorType mgt) { DefaultMovementType = mgt; }
public long GetRespawnTime() { return m_respawnTime; } public long GetRespawnTime() { return m_respawnTime; }
+7 -3
View File
@@ -150,6 +150,11 @@ namespace Game.Entities
public float GetSpeedRate(UnitMoveType mtype) { return m_speed_rate[(int)mtype]; } public float GetSpeedRate(UnitMoveType mtype) { return m_speed_rate[(int)mtype]; }
public virtual MovementGeneratorType GetDefaultMovementType()
{
return MovementGeneratorType.Idle;
}
public void StopMoving() public void StopMoving()
{ {
ClearUnitState(UnitState.Moving); ClearUnitState(UnitState.Moving);
@@ -523,10 +528,9 @@ namespace Game.Entities
if (creature.HasUnitTypeMask(UnitTypeMask.Minion) && !creature.IsInCombat()) if (creature.HasUnitTypeMask(UnitTypeMask.Minion) && !creature.IsInCombat())
{ {
var top = creature.GetMotionMaster().TopOrNull(); if (GetMotionMaster().GetCurrentMovementGeneratorType() == MovementGeneratorType.Follow)
if (top != null && top.GetMovementGeneratorType() == MovementGeneratorType.Follow)
{ {
Unit followed = ((AbstractFollower)top).GetTarget(); Unit followed = ((AbstractFollower)GetMotionMaster().Top()).GetTarget();
if (followed != null && followed.GetGUID() == GetOwnerGUID() && !followed.IsInCombat()) if (followed != null && followed.GetGUID() == GetOwnerGUID() && !followed.IsInCombat())
{ {
float ownerSpeed = followed.GetSpeedRate(mtype); float ownerSpeed = followed.GetSpeedRate(mtype);
+2 -2
View File
@@ -3319,7 +3319,7 @@ namespace Game
data.phaseGroup = result.Read<uint>(25); data.phaseGroup = result.Read<uint>(25);
data.terrainSwapMap = result.Read<int>(26); data.terrainSwapMap = result.Read<int>(26);
data.ScriptId = GetScriptId(result.Read<string>(27)); data.ScriptId = GetScriptId(result.Read<string>(27));
data.spawnGroupData = _spawnGroupDataStorage[IsTransportMap(data.spawnPoint.GetMapId()) ? 1 : 0]; // transport spawns default to compatibility group data.spawnGroupData = _spawnGroupDataStorage[IsTransportMap(data.spawnPoint.GetMapId()) ? 1 : 0u]; // transport spawns default to compatibility group
var mapEntry = CliDB.MapStorage.LookupByKey(data.spawnPoint.GetMapId()); var mapEntry = CliDB.MapStorage.LookupByKey(data.spawnPoint.GetMapId());
if (mapEntry == null) if (mapEntry == null)
@@ -4063,7 +4063,7 @@ namespace Game
data.rotation.Z = result.Read<float>(9); data.rotation.Z = result.Read<float>(9);
data.rotation.W = result.Read<float>(10); data.rotation.W = result.Read<float>(10);
data.spawntimesecs = result.Read<int>(11); data.spawntimesecs = result.Read<int>(11);
data.spawnGroupData = _spawnGroupDataStorage[IsTransportMap(data.spawnPoint.GetMapId()) ? 1 : 0]; // transport spawns default to compatibility group data.spawnGroupData = _spawnGroupDataStorage[IsTransportMap(data.spawnPoint.GetMapId()) ? 1 : 0u]; // transport spawns default to compatibility group
var mapEntry = CliDB.MapStorage.LookupByKey(data.spawnPoint.GetMapId()); var mapEntry = CliDB.MapStorage.LookupByKey(data.spawnPoint.GetMapId());
if (mapEntry == null) if (mapEntry == null)
@@ -49,6 +49,7 @@ namespace Game.Movement
{ {
owner.AddUnitState(UnitState.Chase); owner.AddUnitState(UnitState.Chase);
owner.SetWalk(false); owner.SetWalk(false);
_path = null;
} }
public bool Update(Unit owner, uint diff) public bool Update(Unit owner, uint diff)
@@ -187,18 +188,18 @@ namespace Game.Movement
cOwner.SetCannotReachTarget(false); cOwner.SetCannotReachTarget(false);
} }
public MovementGeneratorType GetMovementGeneratorType() { return MovementGeneratorType.Chase; }
public void Reset(Unit owner) { Initialize(owner); } public void Reset(Unit owner) { Initialize(owner); }
public MovementGeneratorType GetMovementGeneratorType() { return MovementGeneratorType.Chase; }
public void UnitSpeedChanged() { _lastTargetPosition.Relocate(0.0f, 0.0f, 0.0f); } public void UnitSpeedChanged() { _lastTargetPosition.Relocate(0.0f, 0.0f, 0.0f); }
static bool IsMutualChase(Unit owner, Unit target) static bool IsMutualChase(Unit owner, Unit target)
{ {
IMovementGenerator gen = target.GetMotionMaster().TopOrNull(); if (target.GetMotionMaster().GetCurrentMovementGeneratorType() != MovementGeneratorType.Chase)
if (gen == null || gen.GetMovementGeneratorType() != MovementGeneratorType.Chase)
return false; return false;
return ((ChaseMovementGenerator)gen).GetTarget() == owner;
return ((ChaseMovementGenerator)target.GetMotionMaster().Top()).GetTarget() == owner;
} }
static bool PositionOkay(Unit owner, Unit target, float? minDistance, float? maxDistance, ChaseAngle? angle) static bool PositionOkay(Unit owner, Unit target, float? minDistance, float? maxDistance, ChaseAngle? angle)
@@ -39,6 +39,7 @@ namespace Game.Movement
_timer.Reset(0); _timer.Reset(0);
_reference = owner.GetPosition(); _reference = owner.GetPosition();
_path = null;
} }
public override void DoReset(T owner) public override void DoReset(T owner)
@@ -55,6 +56,7 @@ namespace Game.Movement
{ {
_interrupt = true; _interrupt = true;
owner.StopMoving(); owner.StopMoving();
_path = null;
return true; return true;
} }
else else
@@ -73,9 +75,11 @@ namespace Game.Movement
owner.MovePositionToFirstCollision(destination, distance, angle); owner.MovePositionToFirstCollision(destination, distance, angle);
if (_path == null) if (_path == null)
{
_path = new PathGenerator(owner); _path = new PathGenerator(owner);
_path.SetPathLengthLimit(30.0f);
}
_path.SetPathLengthLimit(30.0f);
bool result = _path.CalculatePath(destination.GetPositionX(), destination.GetPositionY(), destination.GetPositionZ()); bool result = _path.CalculatePath(destination.GetPositionX(), destination.GetPositionY(), destination.GetPositionZ());
if (!result || _path.GetPathType().HasAnyFlag(PathType.NoPath)) if (!result || _path.GetPathType().HasAnyFlag(PathType.NoPath))
{ {
@@ -40,6 +40,7 @@ namespace Game.Movement
owner.AddUnitFlag(UnitFlags.Fleeing); owner.AddUnitFlag(UnitFlags.Fleeing);
owner.AddUnitState(UnitState.Fleeing); owner.AddUnitState(UnitState.Fleeing);
SetTargetLocation(owner); SetTargetLocation(owner);
_path = null;
} }
public override void DoReset(T owner) public override void DoReset(T owner)
@@ -56,6 +57,7 @@ namespace Game.Movement
{ {
_interrupt = true; _interrupt = true;
owner.StopMoving(); owner.StopMoving();
_path = null;
return true; return true;
} }
else else
@@ -94,6 +96,7 @@ namespace Game.Movement
{ {
_interrupt = true; _interrupt = true;
owner.StopMoving(); owner.StopMoving();
_path = null;
return; return;
} }
@@ -110,9 +113,11 @@ namespace Game.Movement
} }
if (_path == null) if (_path == null)
{
_path = new PathGenerator(owner); _path = new PathGenerator(owner);
_path.SetPathLengthLimit(30.0f);
}
_path.SetPathLengthLimit(30.0f);
bool result = _path.CalculatePath(destination.GetPositionX(), destination.GetPositionY(), destination.GetPositionZ()); bool result = _path.CalculatePath(destination.GetPositionX(), destination.GetPositionY(), destination.GetPositionZ());
if (!result || _path.GetPathType().HasAnyFlag(PathType.NoPath)) if (!result || _path.GetPathType().HasAnyFlag(PathType.NoPath))
{ {
@@ -218,6 +223,11 @@ namespace Game.Movement
return base.Update(owner, diff); return base.Update(owner, diff);
} }
public override MovementGeneratorType GetMovementGeneratorType()
{
return MovementGeneratorType.TimedFleeing;
}
TimeTracker _totalFleeTime; TimeTracker _totalFleeTime;
} }
} }
@@ -44,6 +44,7 @@ namespace Game.Movement
{ {
owner.AddUnitState(UnitState.Follow); owner.AddUnitState(UnitState.Follow);
UpdatePetSpeed(owner); UpdatePetSpeed(owner);
_path = null;
} }
public bool Update(Unit owner, uint diff) public bool Update(Unit owner, uint diff)
@@ -55,14 +55,17 @@ namespace Game.Movement
DoInitialize((T)owner); DoInitialize((T)owner);
IsActive = true; IsActive = true;
} }
public virtual void Finalize(Unit owner) public virtual void Finalize(Unit owner)
{ {
DoFinalize((T)owner); DoFinalize((T)owner);
} }
public virtual void Reset(Unit owner) public virtual void Reset(Unit owner)
{ {
DoReset((T)owner); DoReset((T)owner);
} }
public virtual bool Update(Unit owner, uint diff) public virtual bool Update(Unit owner, uint diff)
{ {
return DoUpdate((T)owner, diff); return DoUpdate((T)owner, diff);
@@ -43,6 +43,7 @@ namespace Game.Movement
_wanderDistance = owner.GetRespawnRadius(); _wanderDistance = owner.GetRespawnRadius();
_timer.Reset(0); _timer.Reset(0);
_path = null;
} }
public override void DoReset(Creature owner) public override void DoReset(Creature owner)
@@ -59,6 +60,7 @@ namespace Game.Movement
{ {
_interrupt = true; _interrupt = true;
owner.StopMoving(); owner.StopMoving();
_path = null;
return true; return true;
} }
else else
@@ -87,6 +89,7 @@ namespace Game.Movement
{ {
_interrupt = true; _interrupt = true;
owner.StopMoving(); owner.StopMoving();
_path = null;
return; return;
} }
@@ -100,9 +103,11 @@ namespace Game.Movement
uint resetTimer = RandomHelper.randChance(50) ? RandomHelper.URand(5000, 10000) : RandomHelper.URand(1000, 2000); uint resetTimer = RandomHelper.randChance(50) ? RandomHelper.URand(5000, 10000) : RandomHelper.URand(1000, 2000);
if (_path == null) if (_path == null)
{
_path = new PathGenerator(owner); _path = new PathGenerator(owner);
_path.SetPathLengthLimit(30.0f);
}
_path.SetPathLengthLimit(30.0f);
bool result = _path.CalculatePath(position.GetPositionX(), position.GetPositionY(), position.GetPositionZ()); bool result = _path.CalculatePath(position.GetPositionX(), position.GetPositionY(), position.GetPositionZ());
if (!result || _path.GetPathType().HasAnyFlag(PathType.NoPath)) if (!result || _path.GetPathType().HasAnyFlag(PathType.NoPath))
{ {
@@ -257,7 +257,7 @@ namespace Game.Movement
// check if there is a wait time for the next movement // check if there is a wait time for the next movement
if (!_nextMoveTime.Passed()) if (!_nextMoveTime.Passed())
{ {
// dont update wait timer while moving // update timer since it's not moving
_nextMoveTime.Update((int)diff); _nextMoveTime.Update((int)diff);
if (_nextMoveTime.Passed()) if (_nextMoveTime.Passed())
{ {
@@ -268,7 +268,7 @@ namespace Game.Movement
else // if it's not moving and there is no timer, assume node is reached else // if it's not moving and there is no timer, assume node is reached
{ {
OnArrived(creature); // hooks and wait timer reset (if necessary) OnArrived(creature); // hooks and wait timer reset (if necessary)
_isArrivalDone = true; // signals that the next move will happen after reaching a node _isArrivalDone = true; // signals to future StartMove that it reached a node
if (_nextMoveTime.Passed()) if (_nextMoveTime.Passed())
StartMove(creature); // check path status, get next point and move if necessary & can StartMove(creature); // check path status, get next point and move if necessary & can
+28 -29
View File
@@ -35,7 +35,7 @@ namespace Game.Movement
{ {
_owner = me; _owner = me;
_top = -1; _top = -1;
_cleanFlag = MMCleanFlag.None; _cleanFlag = MotionMasterCleanFlag.None;
for (byte i = 0; i < (int)MovementSlot.Max; ++i) for (byte i = 0; i < (int)MovementSlot.Max; ++i)
{ {
@@ -44,6 +44,12 @@ namespace Game.Movement
} }
} }
public IMovementGenerator Top()
{
Cypher.Assert(!Empty());
return _slot[_top];
}
public void Initialize() public void Initialize()
{ {
while (!Empty()) while (!Empty())
@@ -61,7 +67,7 @@ namespace Game.Movement
{ {
if (_owner.IsTypeId(TypeId.Unit)) if (_owner.IsTypeId(TypeId.Unit))
{ {
IMovementGenerator movement = AISelector.SelectMovementAI(_owner.ToCreature()); IMovementGenerator movement = AISelector.SelectMovementAI(_owner);
StartMovement(movement ?? staticIdleMovement, MovementSlot.Idle); StartMovement(movement ?? staticIdleMovement, MovementSlot.Idle);
} }
else else
@@ -75,14 +81,14 @@ namespace Game.Movement
Cypher.Assert(!Empty()); Cypher.Assert(!Empty());
_cleanFlag |= MMCleanFlag.Update; _cleanFlag |= MotionMasterCleanFlag.Update;
if (!Top().Update(_owner, diff)) if (!Top().Update(_owner, diff))
{ {
_cleanFlag &= ~MMCleanFlag.Update; _cleanFlag &= ~MotionMasterCleanFlag.Update;
MovementExpired(); MovementExpired();
} }
else else
_cleanFlag &= ~MMCleanFlag.Update; _cleanFlag &= ~MotionMasterCleanFlag.Update;
if (!_expireList.Empty()) if (!_expireList.Empty())
ClearExpireList(); ClearExpireList();
@@ -90,12 +96,12 @@ namespace Game.Movement
public void Clear(bool reset = true) public void Clear(bool reset = true)
{ {
if (Convert.ToBoolean(_cleanFlag & MMCleanFlag.Update)) if (Convert.ToBoolean(_cleanFlag & MotionMasterCleanFlag.Update))
{ {
if (reset) if (reset)
_cleanFlag |= MMCleanFlag.Reset; _cleanFlag |= MotionMasterCleanFlag.Reset;
else else
_cleanFlag &= ~MMCleanFlag.Reset; _cleanFlag &= ~MotionMasterCleanFlag.Reset;
DelayedClean(); DelayedClean();
} }
else else
@@ -107,7 +113,7 @@ namespace Game.Movement
if (Empty() || slot >= MovementSlot.Max) if (Empty() || slot >= MovementSlot.Max)
return; return;
if (_cleanFlag.HasAnyFlag(MMCleanFlag.Update)) if (_cleanFlag.HasAnyFlag(MotionMasterCleanFlag.Update))
DelayedClean(slot); DelayedClean(slot);
else else
DirectClean(slot); DirectClean(slot);
@@ -115,12 +121,12 @@ namespace Game.Movement
public void MovementExpired(bool reset = true) public void MovementExpired(bool reset = true)
{ {
if (Convert.ToBoolean(_cleanFlag & MMCleanFlag.Update)) if (Convert.ToBoolean(_cleanFlag & MotionMasterCleanFlag.Update))
{ {
if (reset) if (reset)
_cleanFlag |= MMCleanFlag.Reset; _cleanFlag |= MotionMasterCleanFlag.Reset;
else else
_cleanFlag &= ~MMCleanFlag.Reset; _cleanFlag &= ~MotionMasterCleanFlag.Reset;
DelayedExpire(); DelayedExpire();
} }
else else
@@ -130,7 +136,11 @@ namespace Game.Movement
public MovementGeneratorType GetCurrentMovementGeneratorType() public MovementGeneratorType GetCurrentMovementGeneratorType()
{ {
if (Empty()) if (Empty())
return MovementGeneratorType.Idle; return MovementGeneratorType.Max;
IMovementGenerator movement = Top();
if (movement == null)
return MovementGeneratorType.Max;
return Top().GetMovementGeneratorType(); return Top().GetMovementGeneratorType();
} }
@@ -654,7 +664,7 @@ namespace Game.Movement
if (curr != null) if (curr != null)
{ {
_slot[(int)slot] = null; // in case a new one is generated in this slot during directdelete _slot[(int)slot] = null; // in case a new one is generated in this slot during directdelete
if (_top == (int)slot && Convert.ToBoolean(_cleanFlag & MMCleanFlag.Update)) if (_top == (int)slot && Convert.ToBoolean(_cleanFlag & MotionMasterCleanFlag.Update))
DelayedDelete(curr); DelayedDelete(curr);
else else
DirectDelete(curr); DirectDelete(curr);
@@ -794,27 +804,16 @@ namespace Game.Movement
Initialize(); Initialize();
else if (NeedInitTop()) else if (NeedInitTop())
InitTop(); InitTop();
else if (_cleanFlag.HasAnyFlag(MMCleanFlag.Reset)) else if (_cleanFlag.HasAnyFlag(MotionMasterCleanFlag.Reset))
Top().Reset(_owner); Top().Reset(_owner);
_cleanFlag &= ~MMCleanFlag.Reset; _cleanFlag &= ~MotionMasterCleanFlag.Reset;
} }
public bool Empty() { return (_top < 0); } public bool Empty() { return (_top < 0); }
int Size() { return _top + 1; } int Size() { return _top + 1; }
public IMovementGenerator TopOrNull()
{
return Empty() ? null : Top();
}
public IMovementGenerator Top()
{
Cypher.Assert(!Empty());
return _slot[_top];
}
public static uint SplineId public static uint SplineId
{ {
get { return splineId++; } get { return splineId++; }
@@ -829,7 +828,7 @@ namespace Game.Movement
Unit _owner { get; } Unit _owner { get; }
IMovementGenerator[] _slot = new IMovementGenerator[(int)MovementSlot.Max]; IMovementGenerator[] _slot = new IMovementGenerator[(int)MovementSlot.Max];
MMCleanFlag _cleanFlag; MotionMasterCleanFlag _cleanFlag;
bool[] _initialize = new bool[(int)MovementSlot.Max]; bool[] _initialize = new bool[(int)MovementSlot.Max];
int _top; int _top;
List<IMovementGenerator> _expireList = new(); List<IMovementGenerator> _expireList = new();
@@ -841,7 +840,7 @@ namespace Game.Movement
public ObjectGuid Target; public ObjectGuid Target;
} }
enum MMCleanFlag enum MotionMasterCleanFlag
{ {
None = 0, None = 0,
Update = 1, // Clear or Expire called from update Update = 1, // Clear or Expire called from update