Public feed #890302

Feared Movement Generator

public diff v1 · immutable
Raw Edit
·published 2008-02-03 17:06 UTC
rendered paste body
Index: src/game/ConfusedMovementGenerator.h===================================================================--- src/game/ConfusedMovementGenerator.h	(revision 5137)+++ 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);+};++#endifIndex: src/game/FleeMovementGenerator.cpp===================================================================--- src/game/FleeMovementGenerator.cpp	(revision 0)+++ src/game/FleeMovementGenerator.cpp	(revision 0)@@ -0,0 +1,234 @@+/* + * 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"+#include "GridNotifiersImpl.h"+#include "CellImpl.h"++#define FLEE_MAX_CALL_DISTANCE 3+#define FLEE_MAX_DISTANCE 20++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>+void FleeMovementGenerator<T>::GetTargets(Creature*unit, float range, std::list<Unit *>&targets)+{+    CellPair p(MaNGOS::ComputeCellPair(unit->GetPositionX(), unit->GetPositionY()));+    Cell cell(p);+    cell.data.Part.reserved = ALL_DISTRICT;+    cell.SetNoCreate();++    {+        MaNGOS::AnyAssistCreatureInRangeCheck u_check(unit, unit, range);+        MaNGOS::UnitListSearcher<MaNGOS::AnyAssistCreatureInRangeCheck> searcher(targets, u_check);++		TypeContainerVisitor<MaNGOS::UnitListSearcher<MaNGOS::AnyAssistCreatureInRangeCheck>, WorldTypeMapContainer > world_unit_searcher(searcher);+		TypeContainerVisitor<MaNGOS::UnitListSearcher<MaNGOS::AnyAssistCreatureInRangeCheck>, GridTypeMapContainer >  grid_unit_searcher(searcher);++        CellLock<GridReadGuard> cell_lock(cell, p);+        cell_lock->Visit(cell_lock, world_unit_searcher, *MapManager::Instance().GetMap(unit->GetMapId(), unit));+        cell_lock->Visit(cell_lock, grid_unit_searcher, *MapManager::Instance().GetMap(unit->GetMapId(), unit));+    }++    for(std::list<Unit *>::iterator tIter = targets.begin(); tIter != targets.end();)+    {+        if(!unit->IsWithinLOSInMap(*tIter))+        {+            std::list<Unit *>::iterator tIter2 = tIter;+            ++tIter;+            targets.erase(tIter2);+        }+        else+            ++tIter;+    }+}++template<class T>+void FleeMovementGenerator<T>::GetTargets(Player*unit, float range, std::list<Unit *>&targets)+{+    CellPair p(MaNGOS::ComputeCellPair(unit->GetPositionX(), unit->GetPositionY()));+    Cell cell(p);+    cell.data.Part.reserved = ALL_DISTRICT;+    cell.SetNoCreate();++    {+        MaNGOS::AnyAssistCreatureInRangeCheck u_check(unit, unit, range);+        MaNGOS::UnitListSearcher<MaNGOS::AnyAssistCreatureInRangeCheck> searcher(targets, u_check);++		TypeContainerVisitor<MaNGOS::UnitListSearcher<MaNGOS::AnyAssistCreatureInRangeCheck>, WorldTypeMapContainer > world_unit_searcher(searcher);+		TypeContainerVisitor<MaNGOS::UnitListSearcher<MaNGOS::AnyAssistCreatureInRangeCheck>, GridTypeMapContainer >  grid_unit_searcher(searcher);++        CellLock<GridReadGuard> cell_lock(cell, p);+        cell_lock->Visit(cell_lock, world_unit_searcher, *MapManager::Instance().GetMap(unit->GetMapId(), unit));+        cell_lock->Visit(cell_lock, grid_unit_searcher, *MapManager::Instance().GetMap(unit->GetMapId(), unit));+    }++    for(std::list<Unit *>::iterator tIter = targets.begin(); tIter != targets.end();)+    {+        if(!unit->IsWithinLOSInMap(*tIter))+        {+            std::list<Unit *>::iterator tIter2 = tIter;+            ++tIter;+            targets.erase(tIter2);+        }+        else+            ++tIter;+    }+}++template<class T>+Unit*FleeMovementGenerator<T>::IsSafePosition(T&unit)+{+	std::list<Unit *> targets;+	if (unit.GetTypeId() == TYPEID_UNIT)+		GetTargets((Creature*)&unit, FLEE_MAX_CALL_DISTANCE, targets);+	else+		GetTargets((Player*)&unit, FLEE_MAX_CALL_DISTANCE, targets);++    // no appropriate targets+    if(targets.empty())+        return NULL;++    // select random+    uint32 rIdx = rand32(0,targets.size()-1);+    std::list<Unit *>::const_iterator tIter = targets.begin();+    for(uint32 i = 0; i < rIdx; ++i)+        ++tIter;++	// Set our target+	(*tIter)->GetPosition(destX, destY, destZ);++	return (*tIter);+}++template<class T>+bool FleeMovementGenerator<T>::FindSafePosition(T&unit)+{+	destX = unit.GetPositionX();+	destY = unit.GetPositionY();+	destZ = unit.GetPositionZ();++    std::list<Unit *> targets;+	if (unit.GetTypeId() == TYPEID_UNIT)+		GetTargets((Creature*)&unit, FLEE_MAX_DISTANCE, targets);+	else+		GetTargets((Player*)&unit, FLEE_MAX_DISTANCE, targets);++    // no appropriate targets+    if(targets.empty())+        return false;++    // select random+    uint32 rIdx = rand32(0,targets.size()-1);+    std::list<Unit *>::const_iterator tIter = targets.begin();+    for(uint32 i = 0; i < rIdx; ++i)+        ++tIter;++	// Set our target+	(*tIter)->GetPosition(destX, destY, destZ);++	return true;+}++template<class T>+bool FleeMovementGenerator<T>::FindNextPosition(T&unit)+{+	nextPX = unit.GetPositionX();+	nextPY = unit.GetPositionY();+	nextPZ = unit.GetPositionZ();++	if (nextPX == destX &&+		nextPY == destY &&+		nextPZ == destZ)+	{+		Creature*friendlyUnit = (Creature*)IsSafePosition(unit);+		if (friendlyUnit)+		{+			/*+			We reached to one of our friendly units.+			Here we should call for asistance.+			*/+			if (unit.getVictim() && friendlyUnit->AI())+				friendlyUnit->AI()->AttackStart(unit.getVictim());+			return false;+		}+		else+		{+			if (!FindSafePosition(unit))+				return false;+		}+	}+	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,53 @@+/* + * 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;+			void GetTargets(Creature*unit, float range, std::list<Unit *>&targets);+			void GetTargets(Player*unit, float range, std::list<Unit *>&targets);+			Unit*IsSafePosition(T&unit);+			bool FindSafePosition(T&unit);+			bool FindNextPosition(T&unit);+			DestinationHolder< Traveller<T> > i_destinationHolder;+};++#endifIndex: src/game/GridNotifiers.h===================================================================--- src/game/GridNotifiers.h	(revision 5137)+++ src/game/GridNotifiers.h	(working copy)@@ -652,6 +652,40 @@                  return true;             }+            bool operator()(Player* u)+            {+                if(u == i_funit)+                    return false;++                // we don't need help from zombies :)+                if( !u->isAlive() )+                    return false;++                // only free creature+                if( u->GetCharmerOrOwnerGUID() )+                    return false;++                // skip fighting creature+                if( u->isInCombat() )+                    return false;++                // too far+                if( !i_funit->IsWithinDistInMap(u, i_range) )+                    return false;++                // skip non hostile to caster enemy creatures+                if( !u->IsHostileTo(i_enemy) )+                    return false;++                // only from same creature faction+                if(u->getFaction() != i_funit->getFaction() )+                    return false;++                if(!u->IsWithinLOSInMap(i_enemy) )+                    return false;++                return true;+            }         private:             Unit* const i_funit;             Unit* const i_enemy;Index: src/game/Makefile.am===================================================================--- src/game/Makefile.am	(revision 5137)+++ 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 5137)+++ 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;+};++#endifIndex: src/game/SpellAuras.cpp===================================================================--- src/game/SpellAuras.cpp	(revision 5137)+++ 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 5137)+++ 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 5137)+++ 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;@@ -7040,6 +7041,7 @@  void Unit::setDeathState(DeathState s) {+    m_nextDeathState = s;     if (s != ALIVE)     {         CombatStop();@@ -8271,7 +8273,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 5137)+++ src/game/Unit.h	(working copy)@@ -780,8 +780,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); }@@ -1030,6 +1033,7 @@         Unit* m_attacking;          DeathState m_deathState;+        DeathState m_nextDeathState;          AuraMap m_Auras;