Public feed #889664

Feared Movement Generator

public text v1 · immutable
Raw Edit
·published 2008-02-03 02:04 UTC
rendered paste body
Index: src/game/ConfusedMovementGenerator.h
===================================================================
--- src/game/ConfusedMovementGenerator.h	(revision 5129)
+++ src/game/ConfusedMovementGenerator.h	(working copy)
@@ -16,8 +16,8 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-#ifndef MANGOS_RANDOMMOTIONGENERATOR_H
-#define MANGOS_RANDOMMOTIONGENERATOR_H
+#ifndef MANGOS_CONFUSEDMOVEMENTGENERATOR_H
+#define MANGOS_CONFUSEDMOVEMENTGENERATOR_H
 
 #include "MovementGenerator.h"
 #include "DestinationHolder.h"
Index: src/game/FearedMovementGenerator.cpp
===================================================================
--- src/game/FearedMovementGenerator.cpp	(revision 0)
+++ src/game/FearedMovementGenerator.cpp	(revision 0)
@@ -0,0 +1,315 @@
+/* 
+ * Copyright (C) 2005,2006,2007 MaNGOS <http://www.mangosproject.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "FearedMovementGenerator.h"
+#include "Creature.h"
+
+#define FEAR_MAX_TRIES 6
+#define FEAR_MAX_STEPS 12
+#define FEAR_MAX_FEAR_ANGLE 45
+#define FEAR_STEP_DIST 3
+#define FEAR_MIN_STEP_DIST 15
+#define FEAR_MAX_STEP_DIST 25
+#define FEAR_GOOD_DIST 26
+#define FEAR_MAX_DIST 40
+
+template<class T>
+void FearedMovementGenerator<T>::Initialize(T &unit)
+{
+    unit.StopMoving();
+    unit.setMoveRunFlag(true);
+    _InitSpecific(unit, is_water_ok, is_land_ok);
+	ReinitDestination(unit);
+}
+
+template<class T>
+void FearedMovementGenerator<T>::Finalize(T &)
+{
+}
+
+template<class T>
+void FearedMovementGenerator<T>::Reset(T &unit)
+{
+    timeTracker.Reset(0);
+    i_destinationHolder.ResetUpdate();
+    unit.StopMoving();
+	unit.setMoveRunFlag(true);
+	_InitSpecific(unit, is_water_ok, is_land_ok);
+	ReinitDestination(unit);
+}
+
+template<class T>
+bool FearedMovementGenerator<T>::Update(T &unit, const uint32 &diff)
+{
+    if(!&unit)
+        return true;
+
+    if(unit.hasUnitState(UNIT_STAT_ROOT) || unit.hasUnitState(UNIT_STAT_STUNDED))
+        return true;
+    timeTracker.Update(diff);    
+    Traveller<T> traveller(unit);
+    i_destinationHolder.UpdateTraveller(traveller, diff, false);
+    if( timeTracker.Passed() )
+    {
+        if( i_destinationHolder.HasArrived() )
+        {
+            unit.StopMoving();
+            unit.setMoveRunFlag(true);
+            if (destSteps)
+            {
+                GenerateMovement(unit);
+                timeTracker.Reset( i_destinationHolder.GetTotalTravelTime() );
+            }
+            else
+                timeTracker.Reset(urand(700,1000));
+        }
+    }
+    return true;
+}
+
+template<class T>
+void FearedMovementGenerator<T>::ReinitDestination(T &unit)
+{
+	destSteps = FEAR_MAX_STEPS;
+	if (caster)
+	{
+		baseX = caster->GetPositionX();
+		baseY = caster->GetPositionY();
+		baseZ = caster->GetPositionZ();
+	}
+	else
+	{
+		baseX = unit.GetPositionX();
+		baseY = unit.GetPositionX();
+		baseZ = unit.GetPositionX();
+	}
+}
+
+template<class T>
+void FearedMovementGenerator<T>::SetNoMovement(float &dX, float &dY, float &dZ, T &unit)
+{
+	dX = unit.GetPositionX();
+	dY = unit.GetPositionY();
+	dZ = unit.GetPositionZ();
+}
+
+template<class T>
+void FearedMovementGenerator<T>::SetMovement(float &dX, float &dY, float &dZ, T &unit, float angle, float distance)
+{
+	uint32 mapid = unit.GetMapId();
+
+	dX = unit.GetPositionX() + cosf(angle) * distance;
+	dY = unit.GetPositionY() + sinf(angle) * distance;
+	dZ = unit.GetPositionZ();
+
+	dZ = MapManager::Instance().GetBaseMap(mapid)->GetHeight(dX,dY,dZ,true);
+    if(dZ > INVALID_HEIGHT)
+        dZ = dZ + 0.05f; //just to be sure that we are not a few pixel under the surface
+}
+
+template<class T>
+float FearedMovementGenerator<T>::ComputeAngle(float x, float y)
+{
+    float angle = x*x + y*y;
+    if (angle != 0)
+        angle = sqrt(angle);
+    if (angle != 0)
+        angle = atan2(x/angle, y/angle);
+    return angle;
+}
+
+template<class T>
+float FearedMovementGenerator<T>::ComputeUnitAngle(T &unit)
+{
+	return ComputeAngle(unit.GetPositionX() - baseX, unit.GetPositionY() - baseY);
+}
+
+template<class T>
+float FearedMovementGenerator<T>::GetRandAngle(int start, int end)
+{
+	return (urand(start, end)*M_PI)/180;
+}
+
+template<class T>
+float FearedMovementGenerator<T>::GetFearedDist(float dX, float dY)
+{
+	return sqrt((dX-baseX)*(dX-baseX)+(dY-baseY)*(dY-baseY));
+}
+
+template<class T>
+float FearedMovementGenerator<T>::GetFearedDist(float dX, float dY, float dZ)
+{
+	return sqrt((dX-baseX)*(dX-baseX)+(dY-baseY)*(dY-baseY)+(dZ-baseZ)*(dZ-baseZ));
+}
+
+template<class T>
+bool FearedMovementGenerator<T>::IsFearedAngleOk(float angle)
+{
+	bool angleOk = false;
+	if (angle >= 0 && angle < 90)
+	{
+		if (angle <= FEAR_MAX_FEAR_ANGLE)
+			angleOk=true;
+	}
+	else if (angle >= 90 && angle < 180)
+	{
+		angle -=90;
+		if (angle >= FEAR_MAX_FEAR_ANGLE)
+			angleOk=true;
+	}
+	else if (angle >= -90 && angle < 0)
+	{
+		angle +=90;
+		if (angle >= FEAR_MAX_FEAR_ANGLE)
+			angleOk=true;
+	}
+	else if (angle >= -180 && angle < 90)
+	{
+		angle +=180;
+		if (angle <= FEAR_MAX_FEAR_ANGLE)
+			angleOk=true;
+	}
+	return angleOk;
+}
+
+template<class T>
+bool FearedMovementGenerator<T>::IsDestOk(float dX, float dY, float dZ, T &unit)
+{
+	uint32 mapid = unit.GetMapId();
+	bool is_water = false;
+	float heightAngle = 0;
+	float fearedDist = GetFearedDist(dX, dY);
+	float realFearedDist = GetFearedDist(dX, dY, dZ);
+	//make sure the distances are big enoughf and not waste useless divisions
+	if (
+		(dZ-unit.GetPositionZ() <= -1 || dZ-unit.GetPositionZ() >= 1) &&
+		(fearedDist <= -1 || fearedDist >= 1)
+		)
+	{
+		heightAngle = ComputeAngle(fearedDist, dZ-unit.GetPositionZ());
+		heightAngle = (heightAngle*180)/M_PI;
+	}
+	is_water = MapManager::Instance().GetBaseMap(mapid)->IsInWater(dX, dY, dZ);
+	return (unit.IsWithinLOS(dX, dY, dZ) &&
+			(realFearedDist <= FEAR_MAX_DIST) &&
+			IsFearedAngleOk(heightAngle) &&
+			!((is_water && !is_water_ok) || (!is_water && !is_land_ok)));
+}
+
+template<class T>
+void FearedMovementGenerator<T>::RandomizeDestination(T &unit)
+{
+	if (!destSteps)
+		return;
+	else
+		--destSteps;
+	
+	bool destOK = false;
+	float unitAngle = ComputeUnitAngle(unit);
+	float randMultiplier = 0.0f;
+	float randAngle = 0.0f;
+	float tmpDist = 0.0f;
+
+	float lastdX = 0.0f, lastdY = 0.0f, lastdZ = 0.0f;
+
+	int tries = FEAR_MAX_TRIES;
+	
+	do
+	{
+		if (tries-- == 0)
+		{
+			SetNoMovement(destX, destY, destZ, unit);
+			destSteps = 0;
+			break;
+		}
+		
+		randAngle = (urand(0, 1)?(-1):(1));
+           
+        if(destSteps % 2)
+        {
+			randAngle *= GetRandAngle(45, 90);
+			randMultiplier = urand(FEAR_STEP_DIST, FEAR_MIN_STEP_DIST) + FEAR_STEP_DIST;
+		}
+		else
+        {
+			if (tries >= FEAR_MAX_TRIES/2)
+				randAngle *= GetRandAngle(0, 60);
+			else if (tries >= FEAR_MAX_TRIES/4)
+				randAngle *= GetRandAngle(45, 90);
+			else
+				randAngle *= GetRandAngle(90, 180);
+			if (tries >= FEAR_MAX_TRIES/2)
+				randMultiplier = urand(FEAR_MIN_STEP_DIST, FEAR_MAX_STEP_DIST);
+			else
+				randMultiplier = urand(FEAR_STEP_DIST, FEAR_MIN_STEP_DIST);
+		}
+        randAngle += unitAngle;
+		
+		destOK = false;
+		for (tmpDist = FEAR_STEP_DIST; tmpDist <= randMultiplier; tmpDist += FEAR_STEP_DIST)
+		{
+			SetMovement(lastdX, lastdY, lastdZ, unit, randAngle, tmpDist);
+			destOK = IsDestOk(lastdX, lastdY, lastdZ, unit);
+			if (!destOK)
+			{
+				if (tmpDist > FEAR_STEP_DIST)
+					destOK = true;
+				break;
+			}
+			else
+			{
+				destX = lastdX;
+				destY = lastdY;
+				destZ = lastdZ;
+			}
+		}
+	}while(!destOK);
+}
+
+template<class T>
+void FearedMovementGenerator<T>::GenerateMovement(T &unit)
+{
+	RandomizeDestination(unit);
+    Traveller<T> traveller(unit);
+    i_destinationHolder.SetDestination(traveller, destX, destY, destZ);
+}
+
+template<>
+void
+FearedMovementGenerator<Creature>::_InitSpecific(Creature &creature, bool &is_water_ok, bool &is_land_ok)
+{
+    is_water_ok = creature.isCanSwimOrFly();
+    is_land_ok  = creature.isCanWalkOrFly();
+}
+
+template<>
+void
+FearedMovementGenerator<Player>::_InitSpecific(Player &, bool &is_water_ok, bool &is_land_ok)
+{
+    is_water_ok = true;
+    is_land_ok  = true;
+}
+
+template void FearedMovementGenerator<Player>::Initialize(Player &player);
+template void FearedMovementGenerator<Creature>::Initialize(Creature &creature);
+template void FearedMovementGenerator<Player>::Finalize(Player &player);
+template void FearedMovementGenerator<Creature>::Finalize(Creature &player);
+template void FearedMovementGenerator<Player>::Reset(Player &player);
+template void FearedMovementGenerator<Creature>::Reset(Creature &creature);
+template bool FearedMovementGenerator<Player>::Update(Player &player, const uint32 &diff);
+template bool FearedMovementGenerator<Creature>::Update(Creature &creature, const uint32 &diff);
Index: src/game/FearedMovementGenerator.h
===================================================================
--- src/game/FearedMovementGenerator.h	(revision 0)
+++ src/game/FearedMovementGenerator.h	(revision 0)
@@ -0,0 +1,67 @@
+/* 
+ * Copyright (C) 2005,2006,2007 MaNGOS <http://www.mangosproject.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef MANGOS_FEAREDMOVEMENTGENERATOR_H
+#define MANGOS_FEAREDMOVEMENTGENERATOR_H
+
+#include "MovementGenerator.h"
+#include "DestinationHolder.h"
+#include "Traveller.h"
+
+template<class T>
+class MANGOS_DLL_SPEC FearedMovementGenerator : public MovementGeneratorMedium< T, FearedMovementGenerator<T> >
+{
+	public:
+        FearedMovementGenerator(const Unit &, Unit *_caster) : caster(_caster), timeTracker(0),
+				baseX(0.0f), baseY(0.0f), baseZ(0.0f),
+				destSteps(0), destX(0.0f), destY(0.0f), destZ(0.0f) {}
+        void Initialize(T &);
+        void Finalize(T &);
+        void Reset(T &unit);
+        bool Update(T &, const uint32 &diff);
+        MovementGeneratorType GetMovementGeneratorType() { return FEARED_MOTION_TYPE; }
+        
+	private:
+        DestinationHolder< Traveller<T> > i_destinationHolder;
+        Unit *caster;
+		TimeTracker timeTracker;
+
+		bool is_water_ok;
+		bool is_land_ok;
+		void _InitSpecific(T &, bool &, bool &);
+
+		uint32 destSteps;
+		float baseX, baseY, baseZ;
+		void ReinitDestination(T &unit);
+		
+		float destX, destY, destZ;
+		void SetNoMovement(float &dX, float &dY, float &dZ, T &unit);
+		void SetMovement(float &dX, float &dY, float &dZ, T &unit, float angle, float distance);
+		float ComputeAngle(float x, float y);
+		float ComputeUnitAngle(T &unit);
+		float GetRandAngle(int start, int end);
+		float GetFearedDist(float dX, float dY);
+		float GetFearedDist(float dX, float dY, float dZ);
+		bool IsFearedAngleOk(float angle);
+		bool IsDestOk(float dX, float dY, float dZ, T &unit);
+		void RandomizeDestination(T &unit);
+        
+        void GenerateMovement(T &unit);
+};
+
+#endif
Index: src/game/FleeMovementGenerator.cpp
===================================================================
--- src/game/FleeMovementGenerator.cpp	(revision 0)
+++ src/game/FleeMovementGenerator.cpp	(revision 0)
@@ -0,0 +1,133 @@
+/* 
+ * Copyright (C) 2005,2006,2007 MaNGOS <http://www.mangosproject.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "FleeMovementGenerator.h"
+#include "Creature.h"
+
+template<class T>
+bool FleeMovementGenerator<T>::Update(T &unit, const uint32 &diff)
+{
+    if(!&unit)
+        return true;
+
+    if(unit.hasUnitState(UNIT_STAT_ROOT) || unit.hasUnitState(UNIT_STAT_STUNDED))
+        return true;
+    timeTracker.Update(diff);    
+    Traveller<T> traveller(unit);
+    i_destinationHolder.UpdateTraveller(traveller, diff, false);
+    if( timeTracker.Passed() )
+    {
+        if( i_destinationHolder.HasArrived() )
+        {
+            unit.StopMoving();
+            unit.setMoveRunFlag(true);
+            if (FindNextPosition(unit))
+                timeTracker.Reset( i_destinationHolder.GetTotalTravelTime() );
+            else
+				return false;
+        }
+    }
+    return true;
+}
+
+template<class T>
+void FleeMovementGenerator<T>::Initialize(T &unit)
+{
+    unit.StopMoving();
+	FindSafePosition(unit);
+}
+
+template<class T>
+void FleeMovementGenerator<T>::Finalize(T &)
+{
+}
+
+template<class T>
+void FleeMovementGenerator<T>::Reset(T &unit)
+{
+	unit.StopMoving();
+	FindSafePosition(unit);
+}
+
+template<class T>
+bool FleeMovementGenerator<T>::IsSafePosition(T&unit)
+{
+	bool bIsSafe = true;
+	float fPx,fPy,fPz;
+	fPx = destX;
+	fPx = destY;
+	fPx = destZ;
+	if (fPx != unit.GetPositionX() ||
+		fPy != unit.GetPositionY() ||
+		fPz != unit.GetPositionZ()
+		)
+		bIsSafe = false;
+	return bIsSafe;
+}
+
+template<class T>
+bool FleeMovementGenerator<T>::FindSafePosition(T&unit)
+{
+	bool bFoundSafePlace = false;
+	destX = unit.GetPositionX();
+	destY = unit.GetPositionY();
+	destZ = unit.GetPositionZ();
+
+	uint32 mapid = unit.GetMapId();
+	const Map*currentMap = MapManager::Instance().GetBaseMap(mapid);
+	if (currentMap != NULL)
+	{
+		//currentMap->
+	}
+	return bFoundSafePlace;
+}
+
+template<class T>
+bool FleeMovementGenerator<T>::FindNextPosition(T&unit)
+{
+	if (IsSafePosition(unit))
+		return false;
+	else
+	{
+		nextPX = unit.GetPositionX();
+		nextPY = unit.GetPositionY();
+		nextPZ = unit.GetPositionZ();
+		if (nextPX == destX &&
+			nextPY == destY &&
+			nextPZ == destZ)
+		{
+			if (!FindSafePosition(unit))
+				return false;
+		}
+		//find path
+		nextPX = destX;
+		nextPY = destY;
+		nextPZ = destZ;
+
+		Traveller<T> traveller(unit);
+		i_destinationHolder.SetDestination(traveller, nextPX, nextPY, nextPZ);
+	}
+	return true;
+}
+
+template void FleeMovementGenerator<Player>::Initialize(Player &);
+template void FleeMovementGenerator<Player>::Finalize(Player &);
+template bool FleeMovementGenerator<Player>::Update(Player &, const uint32 &);
+template void FleeMovementGenerator<Creature>::Initialize(Creature &);
+template void FleeMovementGenerator<Creature>::Finalize(Creature &);
+template bool FleeMovementGenerator<Creature>::Update(Creature &, const uint32 &);
Index: src/game/FleeMovementGenerator.h
===================================================================
--- src/game/FleeMovementGenerator.h	(revision 0)
+++ src/game/FleeMovementGenerator.h	(revision 0)
@@ -0,0 +1,51 @@
+/* 
+ * Copyright (C) 2005,2006,2007 MaNGOS <http://www.mangosproject.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef MANGOS_FLEEMOVEMENTGENERATOR_H
+#define MANGOS_FLEEMOVEMENTGENERATOR_H
+
+#include "MovementGenerator.h"
+#include "DestinationHolder.h"
+#include "Traveller.h"
+
+class Creature;
+
+template<class T>
+class MANGOS_DLL_SPEC FleeMovementGenerator : public MovementGeneratorMedium< T, FleeMovementGenerator<T> >
+{
+	public:
+			FleeMovementGenerator() :
+				destX(0), destY(0), destZ(0),
+				nextPX(0), nextPY(0), nextPZ(0),
+				timeTracker(0) {}
+			void Initialize(T &);
+			void Finalize(T &);
+			void Reset(T &unit);
+			bool Update(T &, const uint32 &diff);
+			MovementGeneratorType GetMovementGeneratorType() { return FLEE_MOTION_TYPE; }
+	private:
+			TimeTracker timeTracker;
+			float destX,destY,destZ;
+			float nextPX,nextPY,nextPZ;
+			bool IsSafePosition(T&unit);
+			bool FindSafePosition(T&unit);
+			bool FindNextPosition(T&unit);
+			DestinationHolder< Traveller<T> > i_destinationHolder;
+};
+
+#endif
Index: src/game/Makefile.am
===================================================================
--- src/game/Makefile.am	(revision 5129)
+++ src/game/Makefile.am	(working copy)
@@ -96,6 +96,8 @@
 	DuelHandler.cpp \
 	DynamicObject.cpp \
 	DynamicObject.h \
+	FearedMovementGenerator.cpp \
+	FearedMovementGenerator.h \
 	Formulas.h \
 	GameEvent.cpp \
 	GameEvent.h \
Index: src/game/MotionMaster.h
===================================================================
--- src/game/MotionMaster.h	(revision 5129)
+++ src/game/MotionMaster.h	(working copy)
@@ -38,7 +38,10 @@
     CONFUSED_MOTION_TYPE  = 4,                              // ConfusedMovementGenerator.h
     TARGETED_MOTION_TYPE  = 5,                              // TargetedMovementGenerator.h
     HOME_MOTION_TYPE      = 6,                              // HomeMovementGenerator.h
-    FLIGHT_MOTION_TYPE    = 7                               // WaypointMovementGenerator.h
+    FLIGHT_MOTION_TYPE    = 7,                              // WaypointMovementGenerator.h
+    POINT_MOTION_TYPE     = 8,                              // PointMovementGenerator.h
+    FEARED_MOTION_TYPE    = 9,                              // FearedMovementGenerator.h
+    FLEE_MOTION_TYPE      = 10,                             // FleeMovementGenerator.h
 };
 
 class MANGOS_DLL_SPEC MotionMaster : private std::stack<MovementGenerator *>
Index: src/game/PointMovementGenerator.cpp
===================================================================
--- src/game/PointMovementGenerator.cpp	(revision 0)
+++ src/game/PointMovementGenerator.cpp	(revision 0)
@@ -0,0 +1,62 @@
+/* 
+ * Copyright (C) 2005,2006,2007 MaNGOS <http://www.mangosproject.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "PointMovementGenerator.h"
+#include "Creature.h"
+
+template<class T>
+bool PointMovementGenerator<T>::Update(T &unit, const uint32 &diff)
+{
+    if(!&unit)
+        return false;
+
+    if(unit.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNDED))
+        return true;
+
+    Traveller<T> traveller(unit);
+
+    i_destinationHolder.UpdateTraveller(traveller, diff, false);
+
+    if(i_destinationHolder.HasArrived())
+    {
+        unit.StopMoving();
+        return false;    
+    }
+
+    return true;
+}
+
+template<class T>
+void PointMovementGenerator<T>::Initialize(T &unit)
+{
+    unit.StopMoving();
+    Traveller<T> traveller(unit);
+    i_destinationHolder.SetDestination(traveller,x,y,z);
+}
+
+template<class T>
+void PointMovementGenerator<T>::Finalize(T &)
+{
+}
+
+template void PointMovementGenerator<Player>::Initialize(Player &);
+template void PointMovementGenerator<Player>::Finalize(Player &);
+template bool PointMovementGenerator<Player>::Update(Player &, const uint32 &);
+template void PointMovementGenerator<Creature>::Initialize(Creature &);
+template void PointMovementGenerator<Creature>::Finalize(Creature &);
+template bool PointMovementGenerator<Creature>::Update(Creature &, const uint32 &);
Index: src/game/PointMovementGenerator.h
===================================================================
--- src/game/PointMovementGenerator.h	(revision 0)
+++ src/game/PointMovementGenerator.h	(revision 0)
@@ -0,0 +1,45 @@
+/* 
+ * Copyright (C) 2005,2006,2007 MaNGOS <http://www.mangosproject.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef MANGOS_POINTMOVEMENTGENERATOR_H
+#define MANGOS_POINTMOVEMENTGENERATOR_H
+
+#include "MovementGenerator.h"
+#include "DestinationHolder.h"
+#include "Traveller.h"
+
+class Creature;
+
+template<class T>
+class MANGOS_DLL_SPEC PointMovementGenerator : public MovementGeneratorMedium< T, PointMovementGenerator<T> >
+{
+	public:
+			PointMovementGenerator(float _x, float _y, float _z) :
+					x(_x), y(_y), z(_z), i_nextMoveTime(0) {}
+			void Initialize(T &);
+			void Finalize(T &);
+			void Reset(T &unit) { unit.StopMoving(); }
+			bool Update(T &, const uint32 &diff);
+			MovementGeneratorType GetMovementGeneratorType() { return POINT_MOTION_TYPE; }
+	private:
+			TimeTracker i_nextMoveTime;
+			float x,y,z;
+			DestinationHolder< Traveller<T> > i_destinationHolder;
+};
+
+#endif
Index: src/game/SpellAuras.cpp
===================================================================
--- src/game/SpellAuras.cpp	(revision 5129)
+++ src/game/SpellAuras.cpp	(working copy)
@@ -39,6 +39,7 @@
 #include "Totem.h"
 #include "Creature.h"
 #include "ConfusedMovementGenerator.h"
+#include "FearedMovementGenerator.h"
 #include "TargetedMovementGenerator.h"
 #include "Formulas.h"
 #include "BattleGround.h"
@@ -464,7 +465,7 @@
             caster->ModifyPower(powertype,-manaPerSecond);
             caster->ModifyPower(powertype,-manaPerSecondPerLevel);
         }
-        if(caster && m_target->isAlive() && m_target->HasFlag(UNIT_FIELD_FLAGS,(UNIT_STAT_FLEEING<<16)))
+        if(caster && m_target->isAlive() && m_target->HasFlag(UNIT_FIELD_FLAGS,(UNIT_STAT_FLEEING<<16)) && !m_target->HasAuraType(SPELL_AURA_MOD_FEAR))
         {
             int q = rand() % 80;
             if(q == 8) m_fearMoveAngle += (float)(urand(45, 90));
@@ -2096,22 +2097,27 @@
 {
     if( Apply )
     {
+        if(Real)
+			    m_target->StopMoving();
         m_target->addUnitState(UNIT_STAT_FLEEING);
         m_target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_FLEEING);
 
         // only at real add aura
         if(Real)
         {
-            //FIX ME: we need Mutate to now not existed FleeMovementGenerator (see Aura::Update hack code)
-            // at this moment Idle instead
-            m_target->GetMotionMaster()->MovementExpired(false);
-            m_target->GetMotionMaster()->Idle();
-
-            // what is this for ? (doesn't work anyway)
-            /*WorldPacket data(SMSG_DEATH_NOTIFY_OBSOLETE, 9);
-            data.append(m_target->GetPackGUID());
-            data << uint8(0x00);
-            m_target->SendMessageToSet(&data,true);*/
+			m_target->GetMotionMaster()->MovementExpired(false);
+			if (m_target->GetTypeId() == TYPEID_UNIT)
+				m_target->GetMotionMaster()->Mutate(new FearedMovementGenerator<Creature>(*((Creature*)m_target), GetCaster()));
+			else
+			{
+				m_target->GetMotionMaster()->Mutate(new FearedMovementGenerator<Player>(*((Player*)m_target), GetCaster()));
+				Player *player = (Player*)m_target;
+				
+				WorldPacket data(SMSG_DEATH_NOTIFY_OBSOLETE, 10);
+				data.append(player->GetPackGUID());             // target's viewpoint
+				data << uint8(0x00);                            // movement disabled
+				player->GetSession()->SendPacket(&data);
+			}
         }
     }
     else
@@ -2122,28 +2128,34 @@
         // only at real remove aura
         if(Real)
         {
+            m_target->StopMoving();
             m_target->GetMotionMaster()->MovementExpired(false);
 
             if( m_target->GetTypeId() != TYPEID_PLAYER && m_target->isAlive() )
             {
-                // restore appropriate movement generator
-                if(m_target->getVictim())
-                    m_target->GetMotionMaster()->Mutate(new TargetedMovementGenerator<Creature>(*m_target->getVictim()));
-                else
-                    m_target->GetMotionMaster()->Initialize();
-
-                // attack caster if can
-                Unit* caster = GetCaster();
-                if(caster && caster != m_target->getVictim())
-                    if (((Creature*)m_target)->AI())
-                        ((Creature*)m_target)->AI()->AttackStart(caster);
+                if (!m_target->willBeDead())
+                {
+                    // restore appropriate movement generator
+                    if(m_target->getVictim())
+                        m_target->GetMotionMaster()->Mutate(new TargetedMovementGenerator<Creature>(*m_target->getVictim()));
+                    else
+                        m_target->GetMotionMaster()->Initialize();
+                    // attack caster if can
+                    Unit* caster = GetCaster();
+                    if(caster && caster != m_target->getVictim())
+                        if (((Creature*)m_target)->AI())
+                            ((Creature*)m_target)->AI()->AttackStart(caster);
+                }
             }
-
-            // what is this for ? (doesn't work anyway)
-            /*WorldPacket data(SMSG_DEATH_NOTIFY_OBSOLETE, 9);
-            data.append(m_target->GetPackGUID());
-            data << uint8(0x01);
-            m_target->SendMessageToSet(&data,true);*/
+			else
+			{
+				Player *player = (Player*)m_target;
+			
+				WorldPacket data(SMSG_DEATH_NOTIFY_OBSOLETE, 10);
+				data.append(player->GetPackGUID());             // target's viewpoint
+				data << uint8(0x01);                            // movement enabled
+				player->GetSession()->SendPacket(&data);
+			}
         }
     }
 }
Index: src/game/Traveller.h
===================================================================
--- src/game/Traveller.h	(revision 5129)
+++ src/game/Traveller.h	(working copy)
@@ -78,7 +78,10 @@
 template<>
 inline float Traveller<Player>::Speed()
 {
-    return PLAYER_FLIGHT_SPEED;
+    if (i_traveller.isInFlight())
+        return PLAYER_FLIGHT_SPEED;
+    else
+        return i_traveller.GetSpeed(i_traveller.getMoveRunFlag() ? MOVE_RUN : MOVE_WALK);
 }
 
 template<>
Index: src/game/Unit.cpp
===================================================================
--- src/game/Unit.cpp	(revision 5129)
+++ src/game/Unit.cpp	(working copy)
@@ -153,6 +153,7 @@
     m_state = 0;
     m_form = 0;
     m_deathState = ALIVE;
+    m_nextDeathState = ALIVE;
 
     for (uint32 i = 0; i < CURRENT_MAX_SPELL; i++)
         m_currentSpells[i] = NULL;
@@ -6713,6 +6714,7 @@
 
 void Unit::setDeathState(DeathState s)
 {
+    m_nextDeathState = s;
     if (s != ALIVE)
     {
         CombatStop();
@@ -7946,7 +7948,10 @@
 
 void Unit::StopMoving()
 {
-    clearUnitState(UNIT_STAT_MOVING);
+    uint32 unitState = UNIT_STAT_MOVING;
+    if (HasFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_FLEEING))
+        unitState &= (~UNIT_STAT_FLEEING);
+    clearUnitState(unitState);
     // send explicit stop packet
     SendMonsterMove(GetPositionX(), GetPositionY(), GetPositionZ(),0,true,0);
 
Index: src/game/Unit.h
===================================================================
--- src/game/Unit.h	(revision 5129)
+++ src/game/Unit.h	(working copy)
@@ -779,8 +779,11 @@
 
         bool isAlive() const { return (m_deathState == ALIVE); };
         bool isDead() const { return ( m_deathState == DEAD || m_deathState == CORPSE ); };
+        bool willBeAlive() const { return (m_nextDeathState == ALIVE); };
+        bool willBeDead() const { return ( m_nextDeathState == DEAD || m_nextDeathState == CORPSE ); };
         DeathState getDeathState() { return m_deathState; };
         virtual void setDeathState(DeathState s);           // overwrited in Creature/Player/Pet
+        DeathState getNextDeathState() { return m_nextDeathState; };
 
         uint64 const& GetOwnerGUID() const { return  GetUInt64Value(UNIT_FIELD_SUMMONEDBY); }
         uint64 GetPetGUID() const { return  GetUInt64Value(UNIT_FIELD_SUMMON); }
@@ -1029,6 +1032,7 @@
         Unit* m_attacking;
 
         DeathState m_deathState;
+        DeathState m_nextDeathState;
 
         AuraMap m_Auras;