aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsilver1ce <none@none>2010-03-06 18:18:32 +0200
committersilver1ce <none@none>2010-03-06 18:18:32 +0200
commitefb123f4f7b0642330d2ae7af6a6fb859cbbfa30 (patch)
tree66db789734c8d6c751e3612462a89019bb002fa1
parenta135d9e6c704528675e8255b4c7a7fd803c2f69e (diff)
prevent stack overflow caused by MoveInLineOfSight calls
should close #995 issue --HG-- branch : trunk
-rw-r--r--src/game/CreatureAI.cpp11
-rw-r--r--src/game/CreatureAI.h9
-rw-r--r--src/game/GridNotifiers.cpp2
3 files changed, 19 insertions, 3 deletions
diff --git a/src/game/CreatureAI.cpp b/src/game/CreatureAI.cpp
index e9f01098b03..9753008e3de 100644
--- a/src/game/CreatureAI.cpp
+++ b/src/game/CreatureAI.cpp
@@ -104,6 +104,17 @@ void CreatureAI::DoZoneInCombat(Creature* creature)
}
}
+// scripts does not take care about MoveInLineOfSight loops
+// MoveInLineOfSight can be called inside another MoveInLineOfSight and cause stack overflow
+void CreatureAI::MoveInLineOfSight_Safe(Unit *who)
+{
+ if(m_MoveInLineOfSight_locked == true)
+ return;
+ m_MoveInLineOfSight_locked = true;
+ MoveInLineOfSight(who);
+ m_MoveInLineOfSight_locked = false;
+}
+
void CreatureAI::MoveInLineOfSight(Unit *who)
{
if(me->getVictim())
diff --git a/src/game/CreatureAI.h b/src/game/CreatureAI.h
index 57480107e66..66aa2f2785f 100644
--- a/src/game/CreatureAI.h
+++ b/src/game/CreatureAI.h
@@ -83,14 +83,14 @@ class CreatureAI : public UnitAI
Creature *DoSummonFlyer(uint32 uiEntry, WorldObject *obj, float fZ, float fRadius = 5.0f, uint32 uiDespawntime = 30000, TempSummonType uiType = TEMPSUMMON_CORPSE_TIMED_DESPAWN);
public:
- explicit CreatureAI(Creature *c) : UnitAI((Unit*)c), me(c), m_creature(c) {}
+ explicit CreatureAI(Creature *c) : UnitAI((Unit*)c), me(c), m_creature(c), m_MoveInLineOfSight_locked(false) {}
virtual ~CreatureAI() {}
///== Reactions At =================================
// Called if IsVisible(Unit *who) is true at each *who move, reaction at visibility zone enter
- virtual void MoveInLineOfSight(Unit *);
+ void MoveInLineOfSight_Safe(Unit *who);
// Called for reaction at stopping attack at no attackers or targets
virtual void EnterEvadeMode();
@@ -174,7 +174,12 @@ class CreatureAI : public UnitAI
virtual void PassengerBoarded(Unit *who, int8 seatId, bool apply) {}
protected:
+ virtual void MoveInLineOfSight(Unit *);
+
bool _EnterEvadeMode();
+
+ private:
+ bool m_MoveInLineOfSight_locked;
};
enum Permitions
diff --git a/src/game/GridNotifiers.cpp b/src/game/GridNotifiers.cpp
index 5617fe19358..0e7b60fa607 100644
--- a/src/game/GridNotifiers.cpp
+++ b/src/game/GridNotifiers.cpp
@@ -120,7 +120,7 @@ inline void CreatureUnitRelocationWorker(Creature* c, Unit* u)
if(c->HasReactState(REACT_AGGRESSIVE) && !c->hasUnitState(UNIT_STAT_SIGHTLESS))
if(c->_IsWithinDist(u, c->m_SightDistance, true) && c->IsAIEnabled)
- c->AI()->MoveInLineOfSight(u);
+ c->AI()->MoveInLineOfSight_Safe(u);
}
void PlayerRelocationNotifier::Visit(PlayerMapType &m)