diff --git a/src/game/ConfusedMovementGenerator.cpp b/src/game/ConfusedMovementGenerator.cpp index 656cf2035..b44740640 100644 --- a/src/game/ConfusedMovementGenerator.cpp +++ b/src/game/ConfusedMovementGenerator.cpp @@ -117,9 +117,12 @@ bool ConfusedMovementGenerator::Update(T &unit, const uint32 &diff) // currently moving, update location unit.addUnitState(UNIT_STAT_CONFUSED_MOVE); Traveller traveller(unit); - if( i_destinationHolder.UpdateTraveller(traveller, diff, false)) + if (i_destinationHolder.UpdateTraveller(traveller, diff, false)) { - if( i_destinationHolder.HasArrived()) + if (!IsActive(unit)) // force stop processing (movement can move out active zone with cleanup movegens list) + return true; // not expire now, but already lost + + if (i_destinationHolder.HasArrived()) { // arrived, stop and wait a bit unit.StopMoving(); diff --git a/src/game/HomeMovementGenerator.cpp b/src/game/HomeMovementGenerator.cpp index 75ec2467c..055951e19 100644 --- a/src/game/HomeMovementGenerator.cpp +++ b/src/game/HomeMovementGenerator.cpp @@ -59,7 +59,11 @@ bool HomeMovementGenerator::Update(Creature &owner, const uint32& time_diff) { CreatureTraveller traveller( owner); - i_destinationHolder.UpdateTraveller(traveller, time_diff, false); + if (i_destinationHolder.UpdateTraveller(traveller, time_diff, false)) + { + if (!IsActive(owner)) // force stop processing (movement can move out active zone with cleanup movegens list) + return true; // not expire now, but already lost + } if (time_diff > i_travel_timer) { diff --git a/src/game/MovementGenerator.cpp b/src/game/MovementGenerator.cpp index 1e663922f..842a2c5b8 100644 --- a/src/game/MovementGenerator.cpp +++ b/src/game/MovementGenerator.cpp @@ -21,3 +21,10 @@ MovementGenerator::~MovementGenerator() { } + +bool MovementGenerator::IsActive( Unit& u ) +{ + // When movement generator list modified from Update movegen object erase delayed, + // so pointer still valid and be used for check + return !u.GetMotionMaster()->empty() && u.GetMotionMaster()->top() == this; +} \ No newline at end of file diff --git a/src/game/MovementGenerator.h b/src/game/MovementGenerator.h index 37b481a64..e8d9c40ad 100644 --- a/src/game/MovementGenerator.h +++ b/src/game/MovementGenerator.h @@ -55,6 +55,10 @@ class MANGOS_DLL_SPEC MovementGenerator // used by Evade code for select point to evade with expected restart default movement virtual bool GetResetPosition(Unit &, float& /*x*/, float& /*y*/, float& /*z*/) { return false; } + + // used for check from Update call is movegen still be active (top movement generator) + // after some not safe for this calls + bool IsActive(Unit& u); }; template diff --git a/src/game/RandomMovementGenerator.cpp b/src/game/RandomMovementGenerator.cpp index dacd112d2..27ae9a4bf 100644 --- a/src/game/RandomMovementGenerator.cpp +++ b/src/game/RandomMovementGenerator.cpp @@ -164,6 +164,9 @@ bool RandomMovementGenerator::Update(Creature &creature, const uint32 if (i_destinationHolder.UpdateTraveller(traveller, diff, false, true)) { + if (!IsActive(creature)) // force stop processing (movement can move out active zone with cleanup movegens list) + return true; // not expire now, but already lost + if (i_nextMoveTime.Passed()) { if (creature.canFly()) diff --git a/src/game/TargetedMovementGenerator.cpp b/src/game/TargetedMovementGenerator.cpp index 0336187d2..b59e6c8f1 100644 --- a/src/game/TargetedMovementGenerator.cpp +++ b/src/game/TargetedMovementGenerator.cpp @@ -149,6 +149,9 @@ bool TargetedMovementGeneratorMedium::Update(T &owner, const uint32 & time_ if (i_destinationHolder.UpdateTraveller(traveller, time_diff, false)) { + if (!IsActive(owner)) // force stop processing (movement can move out active zone with cleanup movegens list) + return true; // not expire now, but already lost + // put targeted movement generators on a higher priority if (owner.GetObjectSize()) i_destinationHolder.ResetUpdate(50); diff --git a/src/game/WaypointMovementGenerator.cpp b/src/game/WaypointMovementGenerator.cpp index 4abfe45cd..755fb1e46 100644 --- a/src/game/WaypointMovementGenerator.cpp +++ b/src/game/WaypointMovementGenerator.cpp @@ -129,7 +129,11 @@ bool WaypointMovementGenerator::Update(Creature &creature, const uint3 CreatureTraveller traveller(creature); i_nextMoveTime.Update(diff); - i_destinationHolder.UpdateTraveller(traveller, diff, false, true); + if (i_destinationHolder.UpdateTraveller(traveller, diff, false, true)) + { + if (!IsActive(creature)) // force stop processing (movement can move out active zone with cleanup movegens list) + return true; // not expire now, but already lost + } // creature has been stopped in middle of the waypoint segment if (!i_destinationHolder.HasArrived() && creature.IsStopped()) @@ -206,12 +210,11 @@ bool WaypointMovementGenerator::Update(Creature &creature, const uint3 i_hasDone[idx] = true; MovementInform(creature); - // force stop processing (script change movegen list) - if (creature.GetMotionMaster()->empty() || creature.GetMotionMaster()->top() != this) + if (!IsActive(creature)) // force stop processing (movement can move out active zone with cleanup movegens list) return true; // not expire now, but already lost // prevent a crash at empty waypoint path. - if (!i_path || i_path->empty()) + if (!i_path || i_path->empty() || i_currentNode >= i_path->size()) { creature.clearUnitState(UNIT_STAT_ROAMING_MOVE); return true; diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 2d8ba8a72..2e2fbeee9 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "9444" + #define REVISION_NR "9445" #endif // __REVISION_NR_H__