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
+ *
+ * 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
+void FearedMovementGenerator::Initialize(T &unit)
+{
+ unit.StopMoving();
+ unit.setMoveRunFlag(true);
+ _InitSpecific(unit, is_water_ok, is_land_ok);
+ ReinitDestination(unit);
+}
+
+template
+void FearedMovementGenerator::Finalize(T &)
+{
+}
+
+template
+void FearedMovementGenerator::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
+bool FearedMovementGenerator::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 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
+void FearedMovementGenerator::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
+void FearedMovementGenerator::SetNoMovement(float &dX, float &dY, float &dZ, T &unit)
+{
+ dX = unit.GetPositionX();
+ dY = unit.GetPositionY();
+ dZ = unit.GetPositionZ();
+}
+
+template
+void FearedMovementGenerator::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
+float FearedMovementGenerator::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
+float FearedMovementGenerator::ComputeUnitAngle(T &unit)
+{
+ return ComputeAngle(unit.GetPositionX() - baseX, unit.GetPositionY() - baseY);
+}
+
+template
+float FearedMovementGenerator::GetRandAngle(int start, int end)
+{
+ return (urand(start, end)*M_PI)/180;
+}
+
+template
+float FearedMovementGenerator::GetFearedDist(float dX, float dY)
+{
+ return sqrt((dX-baseX)*(dX-baseX)+(dY-baseY)*(dY-baseY));
+}
+
+template
+float FearedMovementGenerator::GetFearedDist(float dX, float dY, float dZ)
+{
+ return sqrt((dX-baseX)*(dX-baseX)+(dY-baseY)*(dY-baseY)+(dZ-baseZ)*(dZ-baseZ));
+}
+
+template
+bool FearedMovementGenerator::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
+bool FearedMovementGenerator::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
+void FearedMovementGenerator::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
+void FearedMovementGenerator::GenerateMovement(T &unit)
+{
+ RandomizeDestination(unit);
+ Traveller traveller(unit);
+ i_destinationHolder.SetDestination(traveller, destX, destY, destZ);
+}
+
+template<>
+void
+FearedMovementGenerator::_InitSpecific(Creature &creature, bool &is_water_ok, bool &is_land_ok)
+{
+ is_water_ok = creature.isCanSwimOrFly();
+ is_land_ok = creature.isCanWalkOrFly();
+}
+
+template<>
+void
+FearedMovementGenerator::_InitSpecific(Player &, bool &is_water_ok, bool &is_land_ok)
+{
+ is_water_ok = true;
+ is_land_ok = true;
+}
+
+template void FearedMovementGenerator::Initialize(Player &player);
+template void FearedMovementGenerator::Initialize(Creature &creature);
+template void FearedMovementGenerator::Finalize(Player &player);
+template void FearedMovementGenerator::Finalize(Creature &player);
+template void FearedMovementGenerator::Reset(Player &player);
+template void FearedMovementGenerator::Reset(Creature &creature);
+template bool FearedMovementGenerator::Update(Player &player, const uint32 &diff);
+template bool FearedMovementGenerator::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
+ *
+ * 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 MANGOS_DLL_SPEC FearedMovementGenerator : public MovementGeneratorMedium< T, FearedMovementGenerator >
+{
+ 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 > 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,234 @@
+/*
+ * Copyright (C) 2005,2006,2007 MaNGOS
+ *
+ * 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
+bool FleeMovementGenerator::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 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
+void FleeMovementGenerator::Initialize(T &unit)
+{
+ unit.StopMoving();
+ FindSafePosition(unit);
+}
+
+template
+void FleeMovementGenerator::Finalize(T &)
+{
+}
+
+template
+void FleeMovementGenerator::Reset(T &unit)
+{
+ unit.StopMoving();
+ FindSafePosition(unit);
+}
+
+template
+void FleeMovementGenerator::GetTargets(Creature*unit, float range, std::list&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 searcher(targets, u_check);
+
+ TypeContainerVisitor, WorldTypeMapContainer > world_unit_searcher(searcher);
+ TypeContainerVisitor, GridTypeMapContainer > grid_unit_searcher(searcher);
+
+ CellLock 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::iterator tIter = targets.begin(); tIter != targets.end();)
+ {
+ if(!unit->IsWithinLOSInMap(*tIter))
+ {
+ std::list::iterator tIter2 = tIter;
+ ++tIter;
+ targets.erase(tIter2);
+ }
+ else
+ ++tIter;
+ }
+}
+
+template
+void FleeMovementGenerator::GetTargets(Player*unit, float range, std::list&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 searcher(targets, u_check);
+
+ TypeContainerVisitor, WorldTypeMapContainer > world_unit_searcher(searcher);
+ TypeContainerVisitor, GridTypeMapContainer > grid_unit_searcher(searcher);
+
+ CellLock 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::iterator tIter = targets.begin(); tIter != targets.end();)
+ {
+ if(!unit->IsWithinLOSInMap(*tIter))
+ {
+ std::list::iterator tIter2 = tIter;
+ ++tIter;
+ targets.erase(tIter2);
+ }
+ else
+ ++tIter;
+ }
+}
+
+template
+Unit*FleeMovementGenerator::IsSafePosition(T&unit)
+{
+ std::list 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::const_iterator tIter = targets.begin();
+ for(uint32 i = 0; i < rIdx; ++i)
+ ++tIter;
+
+ // Set our target
+ (*tIter)->GetPosition(destX, destY, destZ);
+
+ return (*tIter);
+}
+
+template
+bool FleeMovementGenerator::FindSafePosition(T&unit)
+{
+ destX = unit.GetPositionX();
+ destY = unit.GetPositionY();
+ destZ = unit.GetPositionZ();
+
+ std::list 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::const_iterator tIter = targets.begin();
+ for(uint32 i = 0; i < rIdx; ++i)
+ ++tIter;
+
+ // Set our target
+ (*tIter)->GetPosition(destX, destY, destZ);
+
+ return true;
+}
+
+template
+bool FleeMovementGenerator::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 traveller(unit);
+ i_destinationHolder.SetDestination(traveller, nextPX, nextPY, nextPZ);
+ return true;
+}
+
+template void FleeMovementGenerator::Initialize(Player &);
+template void FleeMovementGenerator::Finalize(Player &);
+template bool FleeMovementGenerator::Update(Player &, const uint32 &);
+template void FleeMovementGenerator::Initialize(Creature &);
+template void FleeMovementGenerator::Finalize(Creature &);
+template bool FleeMovementGenerator::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
+ *
+ * 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 MANGOS_DLL_SPEC FleeMovementGenerator : public MovementGeneratorMedium< T, FleeMovementGenerator >
+{
+ 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&targets);
+ void GetTargets(Player*unit, float range, std::list&targets);
+ Unit*IsSafePosition(T&unit);
+ bool FindSafePosition(T&unit);
+ bool FindNextPosition(T&unit);
+ DestinationHolder< Traveller > i_destinationHolder;
+};
+
+#endif
Index: 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
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
+ *
+ * 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
+bool PointMovementGenerator::Update(T &unit, const uint32 &diff)
+{
+ if(!&unit)
+ return false;
+
+ if(unit.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNDED))
+ return true;
+
+ Traveller traveller(unit);
+
+ i_destinationHolder.UpdateTraveller(traveller, diff, false);
+
+ if(i_destinationHolder.HasArrived())
+ {
+ unit.StopMoving();
+ return false;
+ }
+
+ return true;
+}
+
+template
+void PointMovementGenerator::Initialize(T &unit)
+{
+ unit.StopMoving();
+ Traveller traveller(unit);
+ i_destinationHolder.SetDestination(traveller,x,y,z);
+}
+
+template
+void PointMovementGenerator::Finalize(T &)
+{
+}
+
+template void PointMovementGenerator::Initialize(Player &);
+template void PointMovementGenerator::Finalize(Player &);
+template bool PointMovementGenerator::Update(Player &, const uint32 &);
+template void PointMovementGenerator::Initialize(Creature &);
+template void PointMovementGenerator::Finalize(Creature &);
+template bool PointMovementGenerator::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
+ *
+ * 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 MANGOS_DLL_SPEC PointMovementGenerator : public MovementGeneratorMedium< T, PointMovementGenerator >
+{
+ 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 > i_destinationHolder;
+};
+
+#endif
Index: 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*)m_target), GetCaster()));
+ else
+ {
+ m_target->GetMotionMaster()->Mutate(new FearedMovementGenerator(*((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(*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(*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::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;