Public feed
#890302
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;