[9445] Possible fix often crashes in waypoint movegen.

Thanks to DrKLO for research source of problem!
This commit is contained in:
VladimirMangos 2010-02-24 22:37:26 +03:00
parent 24f2d4658f
commit 87b08b4fa1
8 changed files with 35 additions and 8 deletions

View file

@ -119,6 +119,9 @@ bool ConfusedMovementGenerator<T>::Update(T &unit, const uint32 &diff)
Traveller<T> traveller(unit);
if (i_destinationHolder.UpdateTraveller(traveller, diff, false))
{
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

View file

@ -59,7 +59,11 @@ bool
HomeMovementGenerator<Creature>::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)
{

View file

@ -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;
}

View file

@ -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<class T, class D>

View file

@ -164,6 +164,9 @@ bool RandomMovementGenerator<Creature>::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())

View file

@ -149,6 +149,9 @@ bool TargetedMovementGeneratorMedium<T,D>::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);

View file

@ -129,7 +129,11 @@ bool WaypointMovementGenerator<Creature>::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<Creature>::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;

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__
#define __REVISION_NR_H__
#define REVISION_NR "9444"
#define REVISION_NR "9445"
#endif // __REVISION_NR_H__