aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorccrs <ccrs@users.noreply.github.com>2017-04-07 21:35:23 +0200
committerGitHub <noreply@github.com>2017-04-07 21:35:23 +0200
commit21b8c4997a260b5e2dc24ab07df17d3daa6b8b5d (patch)
treef702e10246c1385acf7928fec24e192778d111f6 /src
parent5cb1555de6db43db03d6202b7edaa9c6835ecfab (diff)
[3.3.5] Core/Movement: MotionMaster & MovementGenerators cleaning (#19361)
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp2
-rw-r--r--src/server/game/Entities/Unit/Unit.h2
-rw-r--r--src/server/game/Movement/MotionMaster.cpp9
-rw-r--r--src/server/game/Movement/MotionMaster.h2
-rwxr-xr-xsrc/server/game/Movement/MovementGenerator.h17
-rw-r--r--src/server/game/Movement/MovementGeneratorImpl.h8
-rwxr-xr-xsrc/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp109
-rwxr-xr-xsrc/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.h13
-rw-r--r--src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp256
-rwxr-xr-xsrc/server/game/Movement/MovementGenerators/FleeingMovementGenerator.h24
-rw-r--r--src/server/game/Movement/MovementGenerators/HomeMovementGenerator.cpp79
-rw-r--r--src/server/game/Movement/MovementGenerators/HomeMovementGenerator.h32
-rwxr-xr-xsrc/server/game/Movement/MovementGenerators/IdleMovementGenerator.cpp42
-rwxr-xr-xsrc/server/game/Movement/MovementGenerators/IdleMovementGenerator.h15
-rwxr-xr-xsrc/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp145
-rw-r--r--src/server/game/Movement/MovementGenerators/PointMovementGenerator.h38
-rw-r--r--src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp207
-rw-r--r--src/server/game/Movement/MovementGenerators/RandomMovementGenerator.h21
-rw-r--r--src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp424
-rwxr-xr-xsrc/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h104
20 files changed, 813 insertions, 736 deletions
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index a5f8c98c290..87d7bd7e9c2 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -9339,7 +9339,7 @@ void Unit::SetSpeedRate(UnitMoveType mtype, float rate)
m_speed_rate[mtype] = rate;
- propagateSpeedChange();
+ PropagateSpeedChange();
// Spline packets are for units controlled by AI. "Force speed change" (wrongly named opcodes) and "move set speed" packets are for units controlled by a player.
static Opcodes const moveTypeToOpcode[MAX_MOVE_TYPE][3] =
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index 3a5414c4db9..c6f78865dc2 100644
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -2134,7 +2134,7 @@ class TC_GAME_API Unit : public WorldObject
void SendPetAIReaction(ObjectGuid guid);
///----------End of Pet responses methods----------
- void propagateSpeedChange() { GetMotionMaster()->propagateSpeedChange(); }
+ void PropagateSpeedChange() { GetMotionMaster()->PropagateSpeedChange(); }
// reactive attacks
void ClearAllReactives();
diff --git a/src/server/game/Movement/MotionMaster.cpp b/src/server/game/Movement/MotionMaster.cpp
index c91fb0692df..4d5e2f9036b 100644
--- a/src/server/game/Movement/MotionMaster.cpp
+++ b/src/server/game/Movement/MotionMaster.cpp
@@ -75,7 +75,7 @@ void MotionMaster::InitDefault()
if (_owner->GetTypeId() == TYPEID_UNIT)
{
MovementGenerator* movement = FactorySelector::selectMovementGenerator(_owner->ToCreature());
- Mutate(movement == NULL ? &si_idleMovement : movement, MOTION_SLOT_IDLE);
+ Mutate(movement == nullptr ? &si_idleMovement : movement, MOTION_SLOT_IDLE);
}
else
{
@@ -88,9 +88,6 @@ void MotionMaster::UpdateMotion(uint32 diff)
if (!_owner)
return;
- if (_owner->HasUnitState(UNIT_STATE_ROOT | UNIT_STATE_STUNNED)) // what about UNIT_STATE_DISTRACTED? Why is this not included?
- return;
-
ASSERT(!empty());
_cleanFlag |= MMCF_UPDATE;
@@ -173,12 +170,12 @@ MovementGenerator* MotionMaster::GetMotionSlot(int slot) const
return _slot[slot];
}
-void MotionMaster::propagateSpeedChange()
+void MotionMaster::PropagateSpeedChange()
{
for (int i = 0; i <= _top; ++i)
{
if (_slot[i])
- _slot[i]->unitSpeedChanged();
+ _slot[i]->UnitSpeedChanged();
}
}
diff --git a/src/server/game/Movement/MotionMaster.h b/src/server/game/Movement/MotionMaster.h
index 0976076f0af..b2ea200b0b1 100644
--- a/src/server/game/Movement/MotionMaster.h
+++ b/src/server/game/Movement/MotionMaster.h
@@ -108,7 +108,7 @@ class TC_GAME_API MotionMaster
MovementGeneratorType GetMotionSlotType(int slot) const;
MovementGenerator* GetMotionSlot(int slot) const;
- void propagateSpeedChange();
+ void PropagateSpeedChange();
bool GetDestination(float &x, float &y, float &z);
diff --git a/src/server/game/Movement/MovementGenerator.h b/src/server/game/Movement/MovementGenerator.h
index ed8726b2ff6..8119c2d2599 100755
--- a/src/server/game/Movement/MovementGenerator.h
+++ b/src/server/game/Movement/MovementGenerator.h
@@ -34,14 +34,12 @@ class TC_GAME_API MovementGenerator
virtual void Initialize(Unit*) = 0;
virtual void Finalize(Unit*) = 0;
-
virtual void Reset(Unit*) = 0;
-
- virtual bool Update(Unit*, uint32 time_diff) = 0;
+ virtual bool Update(Unit*, uint32 diff) = 0;
virtual MovementGeneratorType GetMovementGeneratorType() const = 0;
- virtual void unitSpeedChanged() { }
+ virtual void UnitSpeedChanged() { }
// used by Evade code for select point to evade with expected restart default movement
virtual bool GetResetPosition(Unit*, float& /*x*/, float& /*y*/, float& /*z*/) { return false; }
@@ -53,42 +51,39 @@ class MovementGeneratorMedium : public MovementGenerator
public:
void Initialize(Unit* u) override
{
- //u->AssertIsType<T>();
(static_cast<D*>(this))->DoInitialize(static_cast<T*>(u));
}
void Finalize(Unit* u) override
{
- //u->AssertIsType<T>();
(static_cast<D*>(this))->DoFinalize(static_cast<T*>(u));
}
void Reset(Unit* u) override
{
- //u->AssertIsType<T>();
(static_cast<D*>(this))->DoReset(static_cast<T*>(u));
}
bool Update(Unit* u, uint32 time_diff) override
{
- //u->AssertIsType<T>();
return (static_cast<D*>(this))->DoUpdate(static_cast<T*>(u), time_diff);
}
};
struct SelectableMovement : public FactoryHolder<MovementGenerator, MovementGeneratorType>
{
- SelectableMovement(MovementGeneratorType mgt) : FactoryHolder<MovementGenerator, MovementGeneratorType>(mgt) { }
+ SelectableMovement(MovementGeneratorType movementGeneratorType) : FactoryHolder<MovementGenerator, MovementGeneratorType>(movementGeneratorType) { }
};
-template<class REAL_MOVEMENT>
+template<class Movement>
struct MovementGeneratorFactory : public SelectableMovement
{
- MovementGeneratorFactory(MovementGeneratorType mgt) : SelectableMovement(mgt) { }
+ MovementGeneratorFactory(MovementGeneratorType movementGeneratorType) : SelectableMovement(movementGeneratorType) { }
MovementGenerator* Create(void *) const override;
};
typedef FactoryHolder<MovementGenerator, MovementGeneratorType> MovementGeneratorCreator;
typedef FactoryHolder<MovementGenerator, MovementGeneratorType>::FactoryHolderRegistry MovementGeneratorRegistry;
+
#endif
diff --git a/src/server/game/Movement/MovementGeneratorImpl.h b/src/server/game/Movement/MovementGeneratorImpl.h
index dd73055710c..3488de8534a 100644
--- a/src/server/game/Movement/MovementGeneratorImpl.h
+++ b/src/server/game/Movement/MovementGeneratorImpl.h
@@ -21,10 +21,10 @@
#include "MovementGenerator.h"
-template<class MOVEMENT_GEN>
-inline MovementGenerator*
-MovementGeneratorFactory<MOVEMENT_GEN>::Create(void * /*data*/) const
+template<class Movement>
+inline MovementGenerator* MovementGeneratorFactory<Movement>::Create(void * /*data*/) const
{
- return (new MOVEMENT_GEN());
+ return (new Movement());
}
+
#endif
diff --git a/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp
index b54aef633ef..48524d9c663 100755
--- a/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp
+++ b/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp
@@ -17,91 +17,94 @@
*/
#include "Creature.h"
-#include "ConfusedMovementGenerator.h"
+#include "Player.h"
#include "PathGenerator.h"
#include "MoveSplineInit.h"
#include "MoveSpline.h"
-#include "Player.h"
+#include "ConfusedMovementGenerator.h"
template<class T>
-void ConfusedMovementGenerator<T>::DoInitialize(T* unit)
+ConfusedMovementGenerator<T>::~ConfusedMovementGenerator()
{
- unit->AddUnitState(UNIT_STATE_CONFUSED);
- unit->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_CONFUSED);
- unit->GetPosition(i_x, i_y, i_z);
+ delete _path;
+}
- if (!unit->IsAlive() || unit->IsStopped())
+template<class T>
+void ConfusedMovementGenerator<T>::DoInitialize(T* owner)
+{
+ if (!owner || !owner->IsAlive())
return;
- unit->StopMoving();
- unit->AddUnitState(UNIT_STATE_CONFUSED_MOVE);
+ owner->AddUnitState(UNIT_STATE_CONFUSED);
+ owner->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_CONFUSED);
+ owner->StopMoving();
+
+ _timer.Reset(0);
+ owner->GetPosition(_reference.x, _reference.y, _reference.z);
}
template<class T>
-void ConfusedMovementGenerator<T>::DoReset(T* unit)
+void ConfusedMovementGenerator<T>::DoReset(T* owner)
{
- i_nextMoveTime.Reset(0);
-
- if (!unit->IsAlive() || unit->IsStopped())
- return;
-
- unit->StopMoving();
- unit->AddUnitState(UNIT_STATE_CONFUSED | UNIT_STATE_CONFUSED_MOVE);
+ DoInitialize(owner);
}
template<class T>
-bool ConfusedMovementGenerator<T>::DoUpdate(T* unit, uint32 diff)
+bool ConfusedMovementGenerator<T>::DoUpdate(T* owner, uint32 diff)
{
- if (unit->HasUnitState(UNIT_STATE_ROOT | UNIT_STATE_STUNNED | UNIT_STATE_DISTRACTED))
- return true;
+ if (!owner || !owner->IsAlive())
+ return false;
- if (i_nextMoveTime.Passed())
+ if (owner->HasUnitState(UNIT_STATE_NOT_MOVE) || owner->IsMovementPreventedByCasting())
{
- // currently moving, update location
- unit->AddUnitState(UNIT_STATE_CONFUSED_MOVE);
-
- if (unit->movespline->Finalized())
- i_nextMoveTime.Reset(urand(800, 1500));
+ _interrupt = true;
+ owner->StopMoving();
+ return true;
}
else
+ _interrupt = false;
+
+ // waiting for next move
+ _timer.Update(diff);
+ if (!_interrupt && _timer.Passed() && owner->movespline->Finalized())
{
- // waiting for next move
- i_nextMoveTime.Update(diff);
- if (i_nextMoveTime.Passed())
+ // start moving
+ owner->AddUnitState(UNIT_STATE_CONFUSED_MOVE);
+
+ Position destination(_reference);
+ float distance = 4.0f * frand(0.0f, 1.0f) - 2.0f;
+ float angle = frand(0.0f, 1.0f) * float(M_PI) * 2.0f;
+ owner->MovePositionToFirstCollision(destination, distance, angle);
+
+ if (!_path)
+ _path = new PathGenerator(owner);
+
+ _path->SetPathLengthLimit(30.0f);
+ bool result = _path->CalculatePath(destination.GetPositionX(), destination.GetPositionY(), destination.GetPositionZ());
+ if (!result || (_path->GetPathType() & PATHFIND_NOPATH))
{
- // start moving
- unit->AddUnitState(UNIT_STATE_CONFUSED_MOVE);
-
- float dest = 4.0f * (float)rand_norm() - 2.0f;
-
- Position pos;
- pos.Relocate(i_x, i_y, i_z);
- unit->MovePositionToFirstCollision(pos, dest, 0.0f);
-
- PathGenerator path(unit);
- path.SetPathLengthLimit(30.0f);
- bool result = path.CalculatePath(pos.m_positionX, pos.m_positionY, pos.m_positionZ);
- if (!result || (path.GetPathType() & PATHFIND_NOPATH))
- {
- i_nextMoveTime.Reset(100);
- return true;
- }
-
- Movement::MoveSplineInit init(unit);
- init.MovebyPath(path.GetPath());
- init.SetWalk(true);
- init.Launch();
+ _timer.Reset(100);
+ return true;
}
+
+ Movement::MoveSplineInit init(owner);
+ init.MovebyPath(_path->GetPath());
+ init.SetWalk(true);
+ int32 traveltime = init.Launch();
+ _timer.Reset(traveltime + urand(800, 1500));
}
return true;
}
+template<class T>
+void ConfusedMovementGenerator<T>::DoFinalize(T*) { }
+
template<>
void ConfusedMovementGenerator<Player>::DoFinalize(Player* unit)
{
unit->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_CONFUSED);
- unit->ClearUnitState(UNIT_STATE_CONFUSED | UNIT_STATE_CONFUSED_MOVE);
+ unit->ClearUnitState(UNIT_STATE_CONFUSED);
unit->StopMoving();
}
@@ -114,6 +117,8 @@ void ConfusedMovementGenerator<Creature>::DoFinalize(Creature* unit)
unit->SetTarget(unit->EnsureVictim()->GetGUID());
}
+template ConfusedMovementGenerator<Player>::~ConfusedMovementGenerator();
+template ConfusedMovementGenerator<Creature>::~ConfusedMovementGenerator();
template void ConfusedMovementGenerator<Player>::DoInitialize(Player*);
template void ConfusedMovementGenerator<Creature>::DoInitialize(Creature*);
template void ConfusedMovementGenerator<Player>::DoReset(Player*);
diff --git a/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.h b/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.h
index a23a18cbcfe..95ba375de27 100755
--- a/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.h
+++ b/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.h
@@ -26,16 +26,21 @@ template<class T>
class ConfusedMovementGenerator : public MovementGeneratorMedium< T, ConfusedMovementGenerator<T> >
{
public:
- explicit ConfusedMovementGenerator() : i_nextMoveTime(0), i_x(0), i_y(0), i_z(0) { }
+ explicit ConfusedMovementGenerator() : _path(nullptr), _timer(0), _reference(0.f, 0.f, 0.f), _interrupt(false) { }
+ ~ConfusedMovementGenerator();
+
+ MovementGeneratorType GetMovementGeneratorType() const override { return CONFUSED_MOTION_TYPE; }
void DoInitialize(T*);
void DoFinalize(T*);
void DoReset(T*);
bool DoUpdate(T*, uint32);
- MovementGeneratorType GetMovementGeneratorType() const override { return CONFUSED_MOTION_TYPE; }
private:
- TimeTracker i_nextMoveTime;
- float i_x, i_y, i_z;
+ PathGenerator* _path;
+ TimeTracker _timer;
+ G3D::Vector3 _reference;
+ bool _interrupt;
};
+
#endif
diff --git a/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp
index 6bf8d0affdd..600aae8f8b3 100644
--- a/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp
+++ b/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp
@@ -16,178 +16,202 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "Creature.h"
+#include "VMapFactory.h"
#include "CreatureAI.h"
-#include "FleeingMovementGenerator.h"
-#include "PathGenerator.h"
#include "ObjectAccessor.h"
+#include "Creature.h"
+#include "Player.h"
+#include "PathGenerator.h"
#include "MoveSplineInit.h"
#include "MoveSpline.h"
-#include "Player.h"
-#include "VMapFactory.h"
+#include "FleeingMovementGenerator.h"
#define MIN_QUIET_DISTANCE 28.0f
#define MAX_QUIET_DISTANCE 43.0f
template<class T>
-void FleeingMovementGenerator<T>::_setTargetLocation(T* owner)
+FleeingMovementGenerator<T>::~FleeingMovementGenerator()
+{
+ delete _path;
+}
+
+template<class T>
+void FleeingMovementGenerator<T>::DoInitialize(T* owner)
{
if (!owner)
return;
- if (owner->HasUnitState(UNIT_STATE_ROOT | UNIT_STATE_STUNNED))
+ owner->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_FLEEING);
+ owner->AddUnitState(UNIT_STATE_FLEEING);
+ SetTargetLocation(owner);
+}
+
+template<class T>
+void FleeingMovementGenerator<T>::DoFinalize(T *)
+{
+}
+
+template<>
+void FleeingMovementGenerator<Player>::DoFinalize(Player* owner)
+{
+ owner->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_FLEEING);
+ owner->ClearUnitState(UNIT_STATE_FLEEING);
+ owner->StopMoving();
+}
+
+template<>
+void FleeingMovementGenerator<Creature>::DoFinalize(Creature* owner)
+{
+ owner->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_FLEEING);
+ owner->ClearUnitState(UNIT_STATE_FLEEING | UNIT_STATE_FLEEING_MOVE);
+ if (owner->GetVictim())
+ owner->SetTarget(owner->EnsureVictim()->GetGUID());
+}
+
+template<class T>
+void FleeingMovementGenerator<T>::DoReset(T* owner)
+{
+ DoInitialize(owner);
+}
+
+template<class T>
+bool FleeingMovementGenerator<T>::DoUpdate(T* owner, uint32 diff)
+{
+ if (!owner || !owner->IsAlive())
+ return false;
+
+ if (owner->HasUnitState(UNIT_STATE_NOT_MOVE) || owner->IsMovementPreventedByCasting())
+ {
+ _interrupt = true;
+ owner->StopMoving();
+ return true;
+ }
+ else
+ _interrupt = false;
+
+ _timer.Update(diff);
+ if (!_interrupt && _timer.Passed() && owner->movespline->Finalized())
+ SetTargetLocation(owner);
+
+ return true;
+}
+
+template<class T>
+void FleeingMovementGenerator<T>::SetTargetLocation(T* owner)
+{
+ if (!owner)
return;
- if (owner->IsMovementPreventedByCasting())
+ if (owner->HasUnitState(UNIT_STATE_NOT_MOVE) || owner->IsMovementPreventedByCasting())
{
- owner->CastStop();
+ _interrupt = true;
+ owner->StopMoving();
return;
}
owner->AddUnitState(UNIT_STATE_FLEEING_MOVE);
- float x, y, z;
- _getPoint(owner, x, y, z);
+ Position destination = owner->GetPosition();
+ GetPoint(owner, destination);
// Add LOS check for target point
- Position mypos = owner->GetPosition();
- bool isInLOS = VMAP::VMapFactory::createOrGetVMapManager()->isInLineOfSight(owner->GetMapId(),
- mypos.m_positionX,
- mypos.m_positionY,
- mypos.m_positionZ + 2.0f,
- x, y, z + 2.0f,
- VMAP::ModelIgnoreFlags::Nothing);
- if (!isInLOS)
+ Position currentPosition = owner->GetPosition();
+ if (!VMAP::VMapFactory::createOrGetVMapManager()->isInLineOfSight(owner->GetMapId(), currentPosition.m_positionX, currentPosition.m_positionY, currentPosition.m_positionZ + 1.0f, destination.GetPositionX(), destination.GetPositionY(), destination.GetPositionZ() + 1.0f, VMAP::ModelIgnoreFlags::Nothing))
{
- i_nextCheckTime.Reset(200);
+ _timer.Reset(200);
return;
}
- PathGenerator path(owner);
- path.SetPathLengthLimit(30.0f);
- bool result = path.CalculatePath(x, y, z);
- if (!result || (path.GetPathType() & PATHFIND_NOPATH))
+ if (!_path)
+ _path = new PathGenerator(owner);
+
+ _path->SetPathLengthLimit(30.0f);
+ bool result = _path->CalculatePath(destination.GetPositionX(), destination.GetPositionY(), destination.GetPositionZ());
+ if (!result || (_path->GetPathType() & PATHFIND_NOPATH))
{
- i_nextCheckTime.Reset(100);
+ _timer.Reset(100);
return;
}
Movement::MoveSplineInit init(owner);
- init.MovebyPath(path.GetPath());
+ init.MovebyPath(_path->GetPath());
init.SetWalk(false);
int32 traveltime = init.Launch();
- i_nextCheckTime.Reset(traveltime + urand(800, 1500));
+ _timer.Reset(traveltime + urand(800, 1500));
}
template<class T>
-void FleeingMovementGenerator<T>::_getPoint(T* owner, float &x, float &y, float &z)
+void FleeingMovementGenerator<T>::GetPoint(T* owner, Position &position)
{
- float dist_from_caster, angle_to_caster;
- if (Unit* fright = ObjectAccessor::GetUnit(*owner, i_frightGUID))
+ float casterDistance, casterAngle;
+ if (Unit* fleeTarget = ObjectAccessor::GetUnit(*owner, _fleeTargetGUID))
{
- dist_from_caster = fright->GetDistance(owner);
- if (dist_from_caster > 0.2f)
- angle_to_caster = fright->GetAngle(owner);
+ casterDistance = fleeTarget->GetDistance(owner);
+ if (casterDistance > 0.2f)
+ casterAngle = fleeTarget->GetAngle(owner);
else
- angle_to_caster = frand(0, 2 * static_cast<float>(M_PI));
+ casterAngle = frand(0.0f, 2.0f * float(M_PI));
}
else
{
- dist_from_caster = 0.0f;
- angle_to_caster = frand(0, 2 * static_cast<float>(M_PI));
+ casterDistance = 0.0f;
+ casterAngle = frand(0.0f, 2.0f * float(M_PI));
}
- float dist, angle;
- if (dist_from_caster < MIN_QUIET_DISTANCE)
+ float distance, angle;
+ if (casterDistance < MIN_QUIET_DISTANCE)
{
- dist = frand(0.4f, 1.3f)*(MIN_QUIET_DISTANCE - dist_from_caster);
- angle = angle_to_caster + frand(-static_cast<float>(M_PI)/8, static_cast<float>(M_PI)/8);
+ distance = frand(0.4f, 1.3f) * (MIN_QUIET_DISTANCE - casterDistance);
+ angle = casterAngle + frand(-float(M_PI) / 8.0f, float(M_PI) / 8.0f);
}
- else if (dist_from_caster > MAX_QUIET_DISTANCE)
+ else if (casterDistance > MAX_QUIET_DISTANCE)
{
- dist = frand(0.4f, 1.0f)*(MAX_QUIET_DISTANCE - MIN_QUIET_DISTANCE);
- angle = -angle_to_caster + frand(-static_cast<float>(M_PI)/4, static_cast<float>(M_PI)/4);
+ distance = frand(0.4f, 1.0f) * (MAX_QUIET_DISTANCE - MIN_QUIET_DISTANCE);
+ angle = -casterAngle + frand(-float(M_PI) / 4.0f, float(M_PI) / 4.0f);
}
else // we are inside quiet range
{
- dist = frand(0.6f, 1.2f)*(MAX_QUIET_DISTANCE - MIN_QUIET_DISTANCE);
- angle = frand(0, 2*static_cast<float>(M_PI));
+ distance = frand(0.6f, 1.2f) * (MAX_QUIET_DISTANCE - MIN_QUIET_DISTANCE);
+ angle = frand(0.0f, 2.0f * float(M_PI));
}
- Position pos = owner->GetFirstCollisionPosition(dist, angle);
- x = pos.m_positionX;
- y = pos.m_positionY;
- z = pos.m_positionZ;
-}
-
-template<class T>
-void FleeingMovementGenerator<T>::DoInitialize(T* owner)
-{
- if (!owner)
- return;
-
- owner->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_FLEEING);
- owner->AddUnitState(UNIT_STATE_FLEEING | UNIT_STATE_FLEEING_MOVE);
- _setTargetLocation(owner);
+ owner->MovePositionToFirstCollision(position, distance, angle);
}
-template<>
-void FleeingMovementGenerator<Player>::DoFinalize(Player* owner)
-{
- owner->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_FLEEING);
- owner->ClearUnitState(UNIT_STATE_FLEEING | UNIT_STATE_FLEEING_MOVE);
- owner->StopMoving();
-}
-
-template<>
-void FleeingMovementGenerator<Creature>::DoFinalize(Creature* owner)
-{
- owner->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_FLEEING);
- owner->ClearUnitState(UNIT_STATE_FLEEING|UNIT_STATE_FLEEING_MOVE);
- if (owner->GetVictim())
- owner->SetTarget(owner->EnsureVictim()->GetGUID());
-}
+template FleeingMovementGenerator<Player>::~FleeingMovementGenerator();
+template FleeingMovementGenerator<Creature>::~FleeingMovementGenerator();
+template void FleeingMovementGenerator<Player>::DoInitialize(Player*);
+template void FleeingMovementGenerator<Creature>::DoInitialize(Creature*);
+template void FleeingMovementGenerator<Player>::DoReset(Player*);
+template void FleeingMovementGenerator<Creature>::DoReset(Creature*);
+template bool FleeingMovementGenerator<Player>::DoUpdate(Player*, uint32);
+template bool FleeingMovementGenerator<Creature>::DoUpdate(Creature*, uint32);
+template void FleeingMovementGenerator<Player>::SetTargetLocation(Player*);
+template void FleeingMovementGenerator<Creature>::SetTargetLocation(Creature*);
+template void FleeingMovementGenerator<Player>::GetPoint(Player*, Position &);
+template void FleeingMovementGenerator<Creature>::GetPoint(Creature*, Position &);
-template<class T>
-void FleeingMovementGenerator<T>::DoReset(T* owner)
-{
- DoInitialize(owner);
-}
+//---- TimedFleeingMovementGenerator
-template<class T>
-bool FleeingMovementGenerator<T>::DoUpdate(T* owner, uint32 time_diff)
+bool TimedFleeingMovementGenerator::Update(Unit* owner, uint32 time_diff)
{
- if (!owner || !owner->IsAlive())
+ if (!owner->IsAlive())
return false;
- if (owner->HasUnitState(UNIT_STATE_ROOT | UNIT_STATE_STUNNED))
- {
- owner->ClearUnitState(UNIT_STATE_FLEEING_MOVE);
- return true;
- }
-
- i_nextCheckTime.Update(time_diff);
- if (i_nextCheckTime.Passed() && owner->movespline->Finalized())
- _setTargetLocation(owner);
+ _totalFleeTime.Update(time_diff);
+ if (_totalFleeTime.Passed())
+ return false;
- return true;
+ // This calls grant-parent Update method hiden by FleeingMovementGenerator::Update(Creature &, uint32) version
+ // This is done instead of casting Unit& to Creature& and call parent method, then we can use Unit directly
+ return MovementGeneratorMedium< Creature, FleeingMovementGenerator<Creature> >::Update(owner, time_diff);
}
-template void FleeingMovementGenerator<Player>::DoInitialize(Player*);
-template void FleeingMovementGenerator<Creature>::DoInitialize(Creature*);
-template void FleeingMovementGenerator<Player>::_getPoint(Player*, float&, float&, float&);
-template void FleeingMovementGenerator<Creature>::_getPoint(Creature*, float&, float&, float&);
-template void FleeingMovementGenerator<Player>::_setTargetLocation(Player*);
-template void FleeingMovementGenerator<Creature>::_setTargetLocation(Creature*);
-template void FleeingMovementGenerator<Player>::DoReset(Player*);
-template void FleeingMovementGenerator<Creature>::DoReset(Creature*);
-template bool FleeingMovementGenerator<Player>::DoUpdate(Player*, uint32);
-template bool FleeingMovementGenerator<Creature>::DoUpdate(Creature*, uint32);
-
void TimedFleeingMovementGenerator::Finalize(Unit* owner)
{
owner->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_FLEEING);
- owner->ClearUnitState(UNIT_STATE_FLEEING|UNIT_STATE_FLEEING_MOVE);
+ owner->ClearUnitState(UNIT_STATE_FLEEING);
+ owner->StopMoving();
if (Unit* victim = owner->GetVictim())
{
if (owner->IsAlive())
@@ -197,23 +221,3 @@ void TimedFleeingMovementGenerator::Finalize(Unit* owner)
}
}
}
-
-bool TimedFleeingMovementGenerator::Update(Unit* owner, uint32 time_diff)
-{
- if (!owner->IsAlive())
- return false;
-
- if (owner->HasUnitState(UNIT_STATE_ROOT | UNIT_STATE_STUNNED))
- {
- owner->ClearUnitState(UNIT_STATE_FLEEING_MOVE);
- return true;
- }
-
- i_totalFleeTime.Update(time_diff);
- if (i_totalFleeTime.Passed())
- return false;
-
- // This calls grant-parent Update method hiden by FleeingMovementGenerator::Update(Creature &, uint32) version
- // This is done instead of casting Unit& to Creature& and call parent method, then we can use Unit directly
- return MovementGeneratorMedium< Creature, FleeingMovementGenerator<Creature> >::Update(owner, time_diff);
-}
diff --git a/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.h b/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.h
index 5739107b41f..e75240929db 100755
--- a/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.h
+++ b/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.h
@@ -20,41 +20,43 @@
#define TRINITY_FLEEINGMOVEMENTGENERATOR_H
#include "MovementGenerator.h"
+#include "Timer.h"
template<class T>
class FleeingMovementGenerator : public MovementGeneratorMedium< T, FleeingMovementGenerator<T> >
{
public:
- FleeingMovementGenerator(ObjectGuid fright) : i_frightGUID(fright), i_nextCheckTime(0) { }
+ explicit FleeingMovementGenerator(ObjectGuid fleeTargetGUID) : _path(nullptr), _fleeTargetGUID(fleeTargetGUID), _timer(0), _interrupt(false) { }
+ ~FleeingMovementGenerator();
+
+ MovementGeneratorType GetMovementGeneratorType() const override { return FLEEING_MOTION_TYPE; }
void DoInitialize(T*);
void DoFinalize(T*);
void DoReset(T*);
bool DoUpdate(T*, uint32);
- MovementGeneratorType GetMovementGeneratorType() const override { return FLEEING_MOTION_TYPE; }
-
private:
- void _setTargetLocation(T*);
- void _getPoint(T*, float &x, float &y, float &z);
+ void SetTargetLocation(T*);
+ void GetPoint(T*, Position &position);
- ObjectGuid i_frightGUID;
- TimeTracker i_nextCheckTime;
+ PathGenerator* _path;
+ ObjectGuid _fleeTargetGUID;
+ TimeTracker _timer;
+ bool _interrupt;
};
class TimedFleeingMovementGenerator : public FleeingMovementGenerator<Creature>
{
public:
- TimedFleeingMovementGenerator(ObjectGuid fright, uint32 time) :
- FleeingMovementGenerator<Creature>(fright),
- i_totalFleeTime(time) { }
+ explicit TimedFleeingMovementGenerator(ObjectGuid fleeTargetGUID, uint32 time) : FleeingMovementGenerator<Creature>(fleeTargetGUID), _totalFleeTime(time) { }
MovementGeneratorType GetMovementGeneratorType() const override { return TIMED_FLEEING_MOTION_TYPE; }
bool Update(Unit*, uint32) override;
void Finalize(Unit*) override;
private:
- TimeTracker i_totalFleeTime;
+ TimeTracker _totalFleeTime;
};
#endif
diff --git a/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.cpp
index 21fc465d0b2..6bd2ba9377b 100644
--- a/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.cpp
+++ b/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.cpp
@@ -16,36 +16,30 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "HomeMovementGenerator.h"
#include "Creature.h"
#include "CreatureAI.h"
#include "MoveSplineInit.h"
#include "MoveSpline.h"
+#include "HomeMovementGenerator.h"
-void HomeMovementGenerator<Creature>::DoInitialize(Creature* owner)
-{
- _setTargetLocation(owner);
-}
+template<class T>
+HomeMovementGenerator<T>::~HomeMovementGenerator() { }
-void HomeMovementGenerator<Creature>::DoFinalize(Creature* owner)
+template<>
+HomeMovementGenerator<Creature>::~HomeMovementGenerator()
{
- if (arrived)
- {
- owner->ClearUnitState(UNIT_STATE_EVADE);
- owner->SetWalk(true);
- owner->LoadCreaturesAddon();
- owner->AI()->JustReachedHome();
- owner->SetSpawnHealth();
- }
+ delete _path;
}
-void HomeMovementGenerator<Creature>::DoReset(Creature*) { }
+template<class T>
+void HomeMovementGenerator<T>::SetTargetLocation(T*) { }
-void HomeMovementGenerator<Creature>::_setTargetLocation(Creature* owner)
+template<>
+void HomeMovementGenerator<Creature>::SetTargetLocation(Creature* owner)
{
if (owner->HasUnitState(UNIT_STATE_ROOT | UNIT_STATE_STUNNED | UNIT_STATE_DISTRACTED))
{ // if we are ROOT/STUNNED/DISTRACTED even after aura clear, finalize on next update - otherwise we would get stuck in evade
- skipToHome = true;
+ _skipToHome = true;
return;
}
@@ -61,14 +55,55 @@ void HomeMovementGenerator<Creature>::_setTargetLocation(Creature* owner)
init.SetWalk(false);
init.Launch();
- skipToHome = false;
- arrived = false;
+ _skipToHome = false;
+ _arrived = false;
owner->ClearUnitState(UNIT_STATE_ALL_ERASABLE & ~UNIT_STATE_EVADE);
}
-bool HomeMovementGenerator<Creature>::DoUpdate(Creature* owner, const uint32 /*time_diff*/)
+template<class T>
+void HomeMovementGenerator<T>::DoInitialize(T*) { }
+
+template<>
+void HomeMovementGenerator<Creature>::DoInitialize(Creature* owner)
+{
+ SetTargetLocation(owner);
+}
+
+template<class T>
+void HomeMovementGenerator<T>::DoFinalize(T*) { }
+
+template<>
+void HomeMovementGenerator<Creature>::DoFinalize(Creature* owner)
+{
+ if (_arrived)
+ {
+ owner->ClearUnitState(UNIT_STATE_EVADE);
+ owner->SetWalk(true);
+ owner->LoadCreaturesAddon();
+ owner->AI()->JustReachedHome();
+ owner->SetSpawnHealth();
+ }
+}
+
+template<class T>
+void HomeMovementGenerator<T>::DoReset(T*) { }
+
+template<>
+void HomeMovementGenerator<Creature>::DoReset(Creature* owner)
+{
+ DoInitialize(owner);
+}
+
+template<class T>
+bool HomeMovementGenerator<T>::DoUpdate(T*, uint32)
+{
+ return false;
+}
+
+template<>
+bool HomeMovementGenerator<Creature>::DoUpdate(Creature* owner, uint32 /*diff*/)
{
- arrived = skipToHome || owner->movespline->Finalized();
- return !arrived;
+ _arrived = _skipToHome || owner->movespline->Finalized();
+ return !_arrived;
}
diff --git a/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.h b/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.h
index e332c06df97..4674f99b3de 100644
--- a/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.h
+++ b/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.h
@@ -21,28 +21,26 @@
#include "MovementGenerator.h"
-class Creature;
-
-template < class T >
-class HomeMovementGenerator;
-
-template <>
-class HomeMovementGenerator<Creature> : public MovementGeneratorMedium< Creature, HomeMovementGenerator<Creature> >
+template <class T>
+class HomeMovementGenerator : public MovementGeneratorMedium< T, HomeMovementGenerator<T> >
{
public:
+ explicit HomeMovementGenerator() : _path(nullptr), _arrived(false), _skipToHome(false) { }
+ ~HomeMovementGenerator();
- HomeMovementGenerator() : arrived(false), skipToHome(false) { }
- ~HomeMovementGenerator() { }
-
- void DoInitialize(Creature*);
- void DoFinalize(Creature*);
- void DoReset(Creature*);
- bool DoUpdate(Creature*, const uint32);
MovementGeneratorType GetMovementGeneratorType() const override { return HOME_MOTION_TYPE; }
+ void DoInitialize(T*);
+ void DoFinalize(T*);
+ void DoReset(T*);
+ bool DoUpdate(T*, uint32);
+
private:
- void _setTargetLocation(Creature*);
- bool arrived;
- bool skipToHome;
+ void SetTargetLocation(T*);
+
+ PathGenerator* _path;
+ bool _arrived;
+ bool _skipToHome;
};
+
#endif
diff --git a/src/server/game/Movement/MovementGenerators/IdleMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/IdleMovementGenerator.cpp
index 78bacc161af..97d526a47c5 100755
--- a/src/server/game/Movement/MovementGenerators/IdleMovementGenerator.cpp
+++ b/src/server/game/Movement/MovementGenerators/IdleMovementGenerator.cpp
@@ -35,6 +35,8 @@ void IdleMovementGenerator::Reset(Unit* owner)
owner->StopMoving();
}
+//----------------------------------------------------//
+
void RotateMovementGenerator::Initialize(Unit* owner)
{
if (!owner->IsStopped())
@@ -51,34 +53,38 @@ void RotateMovementGenerator::Initialize(Unit* owner)
bool RotateMovementGenerator::Update(Unit* owner, uint32 diff)
{
float angle = owner->GetOrientation();
- if (m_direction == ROTATE_DIRECTION_LEFT)
+ if (_direction == ROTATE_DIRECTION_LEFT)
{
- angle += (float)diff * static_cast<float>(M_PI * 2) / m_maxDuration;
- while (angle >= static_cast<float>(M_PI * 2)) angle -= static_cast<float>(M_PI * 2);
+ angle += float(diff) * float(M_PI) * 2.f / float(_maxDuration);
+ while (angle >= float(M_PI) * 2.f)
+ angle -= float(M_PI) * 2.f;
}
else
{
- angle -= (float)diff * static_cast<float>(M_PI * 2) / m_maxDuration;
- while (angle < 0) angle += static_cast<float>(M_PI * 2);
+ angle -= float(diff) * float(M_PI) * 2.f / float(_maxDuration);
+ while (angle < 0.f)
+ angle += float(M_PI) * 2.f;
}
owner->SetFacingTo(angle);
- if (m_duration > diff)
- m_duration -= diff;
+ if (_duration > diff)
+ _duration -= diff;
else
return false;
return true;
}
-void RotateMovementGenerator::Finalize(Unit* unit)
+void RotateMovementGenerator::Finalize(Unit* owner)
{
- unit->ClearUnitState(UNIT_STATE_ROTATING);
- if (unit->GetTypeId() == TYPEID_UNIT)
- unit->ToCreature()->AI()->MovementInform(ROTATE_MOTION_TYPE, 0);
+ owner->ClearUnitState(UNIT_STATE_ROTATING);
+ if (owner->GetTypeId() == TYPEID_UNIT)
+ owner->ToCreature()->AI()->MovementInform(ROTATE_MOTION_TYPE, 0);
}
+//----------------------------------------------------//
+
void DistractMovementGenerator::Initialize(Unit* owner)
{
// Distracted creatures stand up if not standing
@@ -100,17 +106,19 @@ void DistractMovementGenerator::Finalize(Unit* owner)
}
}
-bool DistractMovementGenerator::Update(Unit* /*owner*/, uint32 time_diff)
+bool DistractMovementGenerator::Update(Unit* /*owner*/, uint32 diff)
{
- if (time_diff > m_timer)
+ if (diff > _timer)
return false;
- m_timer -= time_diff;
+ _timer -= diff;
return true;
}
-void AssistanceDistractMovementGenerator::Finalize(Unit* unit)
+//----------------------------------------------------//
+
+void AssistanceDistractMovementGenerator::Finalize(Unit* owner)
{
- unit->ClearUnitState(UNIT_STATE_DISTRACTED);
- unit->ToCreature()->SetReactState(REACT_AGGRESSIVE);
+ owner->ClearUnitState(UNIT_STATE_DISTRACTED);
+ owner->ToCreature()->SetReactState(REACT_AGGRESSIVE);
}
diff --git a/src/server/game/Movement/MovementGenerators/IdleMovementGenerator.h b/src/server/game/Movement/MovementGenerators/IdleMovementGenerator.h
index 29846f42614..68ad0d775e9 100755
--- a/src/server/game/Movement/MovementGenerators/IdleMovementGenerator.h
+++ b/src/server/game/Movement/MovementGenerators/IdleMovementGenerator.h
@@ -20,11 +20,11 @@
#define TRINITY_IDLEMOVEMENTGENERATOR_H
#include "MovementGenerator.h"
+#include "Timer.h"
class IdleMovementGenerator : public MovementGenerator
{
public:
-
void Initialize(Unit*) override;
void Finalize(Unit*) override { }
void Reset(Unit*) override;
@@ -37,7 +37,7 @@ TC_GAME_API extern IdleMovementGenerator si_idleMovement;
class RotateMovementGenerator : public MovementGenerator
{
public:
- explicit RotateMovementGenerator(uint32 time, RotateDirection direction) : m_duration(time), m_maxDuration(time), m_direction(direction) { }
+ explicit RotateMovementGenerator(uint32 time, RotateDirection direction) : _duration(time), _maxDuration(time), _direction(direction) { }
void Initialize(Unit*) override;
void Finalize(Unit*) override;
@@ -46,14 +46,14 @@ class RotateMovementGenerator : public MovementGenerator
MovementGeneratorType GetMovementGeneratorType() const override { return ROTATE_MOTION_TYPE; }
private:
- uint32 m_duration, m_maxDuration;
- RotateDirection m_direction;
+ uint32 _duration, _maxDuration;
+ RotateDirection _direction;
};
class DistractMovementGenerator : public MovementGenerator
{
public:
- explicit DistractMovementGenerator(uint32 timer) : m_timer(timer) { }
+ explicit DistractMovementGenerator(uint32 timer) : _timer(timer) { }
void Initialize(Unit*) override;
void Finalize(Unit*) override;
@@ -62,14 +62,13 @@ class DistractMovementGenerator : public MovementGenerator
MovementGeneratorType GetMovementGeneratorType() const override { return DISTRACT_MOTION_TYPE; }
private:
- uint32 m_timer;
+ uint32 _timer;
};
class AssistanceDistractMovementGenerator : public DistractMovementGenerator
{
public:
- AssistanceDistractMovementGenerator(uint32 timer) :
- DistractMovementGenerator(timer) { }
+ explicit AssistanceDistractMovementGenerator(uint32 timer) : DistractMovementGenerator(timer) { }
MovementGeneratorType GetMovementGeneratorType() const override { return ASSISTANCE_DISTRACT_MOTION_TYPE; }
void Finalize(Unit*) override;
diff --git a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp
index bdde0222027..b3fa1c68e99 100755
--- a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp
+++ b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp
@@ -16,98 +16,111 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "PointMovementGenerator.h"
-#include "Errors.h"
-#include "Creature.h"
#include "CreatureAI.h"
-#include "World.h"
+#include "Creature.h"
+#include "CreatureGroups.h"
+#include "Player.h"
#include "MoveSplineInit.h"
#include "MoveSpline.h"
-#include "Player.h"
-#include "CreatureGroups.h"
+#include "World.h"
+#include "PointMovementGenerator.h"
//----- Point Movement Generator
+
template<class T>
-void PointMovementGenerator<T>::DoInitialize(T* unit)
+void PointMovementGenerator<T>::DoInitialize(T* owner)
{
- if (!unit->IsStopped())
- unit->StopMoving();
+ if (_movementId == EVENT_CHARGE_PREPATH)
+ {
+ owner->AddUnitState(UNIT_STATE_ROAMING | UNIT_STATE_ROAMING_MOVE);
+ return;
+ }
- unit->AddUnitState(UNIT_STATE_ROAMING|UNIT_STATE_ROAMING_MOVE);
+ owner->AddUnitState(UNIT_STATE_ROAMING);
- if (id == EVENT_CHARGE_PREPATH)
+ if (owner->HasUnitState(UNIT_STATE_NOT_MOVE) || owner->IsMovementPreventedByCasting())
+ {
+ _interrupt = true;
+ owner->StopMoving();
return;
+ }
+
+ owner->AddUnitState(UNIT_STATE_ROAMING_MOVE);
- Movement::MoveSplineInit init(unit);
- init.MoveTo(i_x, i_y, i_z, m_generatePath);
- if (speed > 0.0f)
- init.SetVelocity(speed);
+ Movement::MoveSplineInit init(owner);
+ init.MoveTo(_destination, _generatePath);
+ if (_speed > 0.0f)
+ init.SetVelocity(_speed);
init.Launch();
// Call for creature group update
- if (Creature* creature = unit->ToCreature())
+ if (Creature* creature = owner->ToCreature())
if (creature->GetFormation() && creature->GetFormation()->getLeader() == creature)
- creature->GetFormation()->LeaderMoveTo(i_x, i_y, i_z);
+ creature->GetFormation()->LeaderMoveTo(_destination.x, _destination.y, _destination.z);
}
template<class T>
-bool PointMovementGenerator<T>::DoUpdate(T* unit, uint32 /*diff*/)
+bool PointMovementGenerator<T>::DoUpdate(T* owner, uint32 /*diff*/)
{
- if (!unit)
+ if (!owner)
return false;
- if (unit->HasUnitState(UNIT_STATE_ROOT | UNIT_STATE_STUNNED))
+ if (_movementId == EVENT_CHARGE_PREPATH)
+ return !owner->movespline->Finalized();
+
+ if (owner->HasUnitState(UNIT_STATE_NOT_MOVE) || owner->IsMovementPreventedByCasting())
{
- unit->ClearUnitState(UNIT_STATE_ROAMING_MOVE);
+ _interrupt = true;
+ owner->StopMoving();
return true;
}
- unit->AddUnitState(UNIT_STATE_ROAMING_MOVE);
-
- if (id != EVENT_CHARGE_PREPATH && i_recalculateSpeed && !unit->movespline->Finalized())
+ if ((_interrupt && owner->movespline->Finalized()) || (_recalculateSpeed && !owner->movespline->Finalized()))
{
- i_recalculateSpeed = false;
- Movement::MoveSplineInit init(unit);
- init.MoveTo(i_x, i_y, i_z, m_generatePath);
- if (speed > 0.0f) // Default value for point motion type is 0.0, if 0.0 spline will use GetSpeed on unit
- init.SetVelocity(speed);
+ _recalculateSpeed = false;
+ _interrupt = false;
+
+ owner->AddUnitState(UNIT_STATE_ROAMING_MOVE);
+
+ Movement::MoveSplineInit init(owner);
+ init.MoveTo(_destination, _generatePath);
+ if (_speed > 0.0f) // Default value for point motion type is 0.0, if 0.0 spline will use GetSpeed on unit
+ init.SetVelocity(_speed);
init.Launch();
// Call for creature group update
- if (Creature* creature = unit->ToCreature())
+ if (Creature* creature = owner->ToCreature())
if (creature->GetFormation() && creature->GetFormation()->getLeader() == creature)
- creature->GetFormation()->LeaderMoveTo(i_x, i_y, i_z);
+ creature->GetFormation()->LeaderMoveTo(_destination.x, _destination.y, _destination.z);
}
- return !unit->movespline->Finalized();
+ return !owner->movespline->Finalized();
}
template<class T>
-void PointMovementGenerator<T>::DoFinalize(T* unit)
+void PointMovementGenerator<T>::DoFinalize(T* owner)
{
- if (unit->HasUnitState(UNIT_STATE_CHARGING))
- unit->ClearUnitState(UNIT_STATE_ROAMING | UNIT_STATE_ROAMING_MOVE);
+ owner->ClearUnitState(UNIT_STATE_ROAMING | UNIT_STATE_ROAMING_MOVE);
- if (unit->movespline->Finalized())
- MovementInform(unit);
+ if (owner->movespline->Finalized())
+ MovementInform(owner);
}
template<class T>
-void PointMovementGenerator<T>::DoReset(T* unit)
+void PointMovementGenerator<T>::DoReset(T* owner)
{
- if (!unit->IsStopped())
- unit->StopMoving();
-
- unit->AddUnitState(UNIT_STATE_ROAMING|UNIT_STATE_ROAMING_MOVE);
+ owner->StopMoving();
+ DoInitialize(owner);
}
template<class T>
-void PointMovementGenerator<T>::MovementInform(T* /*unit*/) { }
+void PointMovementGenerator<T>::MovementInform(T*) { }
-template <> void PointMovementGenerator<Creature>::MovementInform(Creature* unit)
+template <>
+void PointMovementGenerator<Creature>::MovementInform(Creature* owner)
{
- if (unit->AI())
- unit->AI()->MovementInform(POINT_MOTION_TYPE, id);
+ if (owner->AI())
+ owner->AI()->MovementInform(POINT_MOTION_TYPE, _movementId);
}
template void PointMovementGenerator<Player>::DoInitialize(Player*);
@@ -119,31 +132,33 @@ template void PointMovementGenerator<Creature>::DoReset(Creature*);
template bool PointMovementGenerator<Player>::DoUpdate(Player*, uint32);
template bool PointMovementGenerator<Creature>::DoUpdate(Creature*, uint32);
-void AssistanceMovementGenerator::Finalize(Unit* unit)
+//---- AssistanceMovementGenerator
+
+void AssistanceMovementGenerator::Finalize(Unit* owner)
{
- unit->ToCreature()->SetNoCallAssistance(false);
- unit->ToCreature()->CallAssistance();
- if (unit->IsAlive())
- unit->GetMotionMaster()->MoveSeekAssistanceDistract(sWorld->getIntConfig(CONFIG_CREATURE_FAMILY_ASSISTANCE_DELAY));
+ owner->ClearUnitState(UNIT_STATE_ROAMING);
+ owner->StopMoving();
+ owner->ToCreature()->SetNoCallAssistance(false);
+ owner->ToCreature()->CallAssistance();
+ if (owner->IsAlive())
+ owner->GetMotionMaster()->MoveSeekAssistanceDistract(sWorld->getIntConfig(CONFIG_CREATURE_FAMILY_ASSISTANCE_DELAY));
}
-bool EffectMovementGenerator::Update(Unit* unit, uint32)
+//---- EffectMovementGenerator
+
+bool EffectMovementGenerator::Update(Unit* owner, uint32 /*diff*/)
{
- return !unit->movespline->Finalized();
+ return !owner->movespline->Finalized();
}
-void EffectMovementGenerator::Finalize(Unit* unit)
+void EffectMovementGenerator::Finalize(Unit* owner)
{
- if (unit->GetTypeId() != TYPEID_UNIT)
- return;
-
- // Need restore previous movement since we have no proper states system
- if (unit->IsAlive() && !unit->HasUnitState(UNIT_STATE_CONFUSED | UNIT_STATE_FLEEING))
- {
- if (Unit* victim = unit->GetVictim())
- unit->GetMotionMaster()->MoveChase(victim);
- }
+ MovementInform(owner);
+}
- if (unit->ToCreature()->AI())
- unit->ToCreature()->AI()->MovementInform(EFFECT_MOTION_TYPE, m_Id);
+void EffectMovementGenerator::MovementInform(Unit* owner)
+{
+ if (Creature* creature = owner->ToCreature())
+ if (creature->AI())
+ creature->AI()->MovementInform(EFFECT_MOTION_TYPE, _pointId);
}
diff --git a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.h b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.h
index 2e5eda776ed..f68021c51c4 100644
--- a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.h
+++ b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.h
@@ -20,57 +20,57 @@
#define TRINITY_POINTMOVEMENTGENERATOR_H
#include "MovementGenerator.h"
-#include "FollowerReference.h"
template<class T>
class PointMovementGenerator : public MovementGeneratorMedium< T, PointMovementGenerator<T> >
{
public:
- PointMovementGenerator(uint32 _id, float _x, float _y, float _z, bool _generatePath, float _speed = 0.0f) : id(_id),
- i_x(_x), i_y(_y), i_z(_z), speed(_speed), m_generatePath(_generatePath), i_recalculateSpeed(false) { }
+ explicit PointMovementGenerator(uint32 id, float x, float y, float z, bool generatePath, float speed = 0.0f) : _movementId(id), _destination(x, y, z), _speed(speed), _generatePath(generatePath), _recalculateSpeed(false), _interrupt(false) { }
+
+ MovementGeneratorType GetMovementGeneratorType() const override { return POINT_MOTION_TYPE; }
void DoInitialize(T*);
void DoFinalize(T*);
void DoReset(T*);
bool DoUpdate(T*, uint32);
- void MovementInform(T*);
-
- void unitSpeedChanged() override { i_recalculateSpeed = true; }
-
- MovementGeneratorType GetMovementGeneratorType() const override { return POINT_MOTION_TYPE; }
+ void UnitSpeedChanged() override { _recalculateSpeed = true; }
- void GetDestination(float& x, float& y, float& z) const { x = i_x; y = i_y; z = i_z; }
private:
- uint32 id;
- float i_x, i_y, i_z;
- float speed;
- bool m_generatePath;
- bool i_recalculateSpeed;
+ void MovementInform(T*);
+
+ uint32 _movementId;
+ G3D::Vector3 _destination;
+ float _speed;
+ bool _generatePath;
+ bool _recalculateSpeed;
+ bool _interrupt;
};
class AssistanceMovementGenerator : public PointMovementGenerator<Creature>
{
public:
- AssistanceMovementGenerator(float _x, float _y, float _z) :
- PointMovementGenerator<Creature>(0, _x, _y, _z, true) { }
+ explicit AssistanceMovementGenerator(float _x, float _y, float _z) : PointMovementGenerator<Creature>(0, _x, _y, _z, true) { }
MovementGeneratorType GetMovementGeneratorType() const override { return ASSISTANCE_MOTION_TYPE; }
void Finalize(Unit*) override;
};
-// Does almost nothing - just doesn't allows previous movegen interrupt current effect.
class EffectMovementGenerator : public MovementGenerator
{
public:
- explicit EffectMovementGenerator(uint32 Id) : m_Id(Id) { }
+ explicit EffectMovementGenerator(uint32 id) : _pointId(id) { }
+
void Initialize(Unit*) override { }
void Finalize(Unit*) override;
void Reset(Unit*) override { }
bool Update(Unit*, uint32) override;
MovementGeneratorType GetMovementGeneratorType() const override { return EFFECT_MOTION_TYPE; }
+
private:
- uint32 m_Id;
+ void MovementInform(Unit*);
+
+ uint32 _pointId;
};
#endif
diff --git a/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp
index 9b3f4c0060d..6f9738976a8 100644
--- a/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp
+++ b/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp
@@ -17,164 +17,131 @@
*/
#include "Creature.h"
-#include "RandomMovementGenerator.h"
-#include "Map.h"
-#include "Util.h"
#include "CreatureGroups.h"
+#include "Map.h"
#include "MoveSplineInit.h"
#include "MoveSpline.h"
+#include "RandomMovementGenerator.h"
-#define RUNNING_CHANCE_RANDOMMV 20 //will be "1 / RUNNING_CHANCE_RANDOMMV"
+template<class T>
+RandomMovementGenerator<T>::~RandomMovementGenerator() { }
template<>
-void RandomMovementGenerator<Creature>::_setRandomLocation(Creature* creature)
+RandomMovementGenerator<Creature>::~RandomMovementGenerator()
{
- if (creature->IsMovementPreventedByCasting())
- {
- creature->CastStop();
+ delete _path;
+}
+
+template<class T>
+void RandomMovementGenerator<T>::DoInitialize(T*) { }
+
+template<>
+void RandomMovementGenerator<Creature>::DoInitialize(Creature* owner)
+{
+ if (!owner || !owner->IsAlive())
return;
- }
- float respX, respY, respZ, respO, destX, destY, destZ, travelDistZ;
- creature->GetHomePosition(respX, respY, respZ, respO);
- Map const* map = creature->GetBaseMap();
+ owner->AddUnitState(UNIT_STATE_ROAMING);
+ owner->GetPosition(_reference.x, _reference.y, _reference.z);
+ owner->StopMoving();
+
+ if (!_wanderDistance)
+ _wanderDistance = owner->GetRespawnRadius();
- // For 2D/3D system selection
- //bool is_land_ok = creature.CanWalk(); // not used?
- //bool is_water_ok = creature.CanSwim(); // not used?
- bool is_air_ok = creature->CanFly();
+ _timer.Reset(0);
+}
- const float angle = float(rand_norm()) * static_cast<float>(M_PI*2.0f);
- const float range = float(rand_norm()) * wander_distance;
- const float distanceX = range * std::cos(angle);
- const float distanceY = range * std::sin(angle);
+template<class T>
+void RandomMovementGenerator<T>::DoFinalize(T*) { }
- destX = respX + distanceX;
- destY = respY + distanceY;
+template<>
+void RandomMovementGenerator<Creature>::DoFinalize(Creature* owner)
+{
+ owner->ClearUnitState(UNIT_STATE_ROAMING);
+ owner->StopMoving();
+ owner->SetWalk(false);
+}
- // prevent invalid coordinates generation
- Trinity::NormalizeMapCoord(destX);
- Trinity::NormalizeMapCoord(destY);
+template<class T>
+void RandomMovementGenerator<T>::DoReset(T*) { }
- travelDistZ = range; // sin^2+cos^2=1, so travelDistZ=range^2; no need for sqrt below
+template<>
+void RandomMovementGenerator<Creature>::DoReset(Creature* owner)
+{
+ DoInitialize(owner);
+}
- if (is_air_ok) // 3D system above ground and above water (flying mode)
- {
- // Limit height change
- const float distanceZ = float(rand_norm()) * travelDistZ/2.0f;
- destZ = respZ + distanceZ;
- float levelZ = map->GetWaterOrGroundLevel(creature->GetPhaseMask(), destX, destY, destZ-2.5f);
-
- // Problem here, we must fly above the ground and water, not under. Let's try on next tick
- if (levelZ >= destZ)
- return;
- }
- //else if (is_water_ok) // 3D system under water and above ground (swimming mode)
- else // 2D only
- {
- // 10.0 is the max that vmap high can check (MAX_CAN_FALL_DISTANCE)
- travelDistZ = travelDistZ >= 10.0f ? 10.0f : travelDistZ;
-
- // The fastest way to get an accurate result 90% of the time.
- // Better result can be obtained like 99% accuracy with a ray light, but the cost is too high and the code is too long.
- destZ = map->GetHeight(creature->GetPhaseMask(), destX, destY, respZ+travelDistZ-2.0f, false);
-
- if (std::fabs(destZ - respZ) > travelDistZ) // Map check
- {
- // Vmap Horizontal or above
- destZ = map->GetHeight(creature->GetPhaseMask(), destX, destY, respZ - 2.0f, true);
-
- if (std::fabs(destZ - respZ) > travelDistZ)
- {
- // Vmap Higher
- destZ = map->GetHeight(creature->GetPhaseMask(), destX, destY, respZ+travelDistZ-2.0f, true);
-
- // let's forget this bad coords where a z cannot be find and retry at next tick
- if (std::fabs(destZ - respZ) > travelDistZ)
- return;
- }
- }
- }
+template<class T>
+void RandomMovementGenerator<T>::SetRandomLocation(T*) { }
- if (is_air_ok)
- i_nextMoveTime.Reset(0);
- else
+template<>
+void RandomMovementGenerator<Creature>::SetRandomLocation(Creature* owner)
+{
+ if (!owner)
+ return;
+
+ if (owner->HasUnitState(UNIT_STATE_NOT_MOVE) || owner->IsMovementPreventedByCasting())
{
- if (roll_chance_i(50))
- i_nextMoveTime.Reset(urand(5000, 10000));
- else
- i_nextMoveTime.Reset(urand(50, 400));
+ _interrupt = true;
+ owner->StopMoving();
+ return;
}
- creature->AddUnitState(UNIT_STATE_ROAMING_MOVE);
+ owner->AddUnitState(UNIT_STATE_ROAMING_MOVE);
- Movement::MoveSplineInit init(creature);
- init.MoveTo(destX, destY, destZ);
- init.SetWalk(true);
- init.Launch();
+ Position position(_reference);
+ float distance = frand(0.f, 1.f) * _wanderDistance;
+ float angle = frand(0.f, 1.f) * float(M_PI) * 2.f;
+ owner->MovePositionToFirstCollision(position, distance, angle);
- //Call for creature group update
- if (creature->GetFormation() && creature->GetFormation()->getLeader() == creature)
- creature->GetFormation()->LeaderMoveTo(destX, destY, destZ);
-}
+ uint32 resetTimer = roll_chance_i(50) ? urand(5000, 10000) : urand(1000, 2000);
-template<>
-void RandomMovementGenerator<Creature>::DoInitialize(Creature* creature)
-{
- if (!creature->IsAlive())
+ if (!_path)
+ _path = new PathGenerator(owner);
+
+ _path->SetPathLengthLimit(30.0f);
+ bool result = _path->CalculatePath(position.GetPositionX(), position.GetPositionY(), position.GetPositionZ());
+ if (!result || (_path->GetPathType() & PATHFIND_NOPATH))
+ {
+ _timer.Reset(100);
return;
+ }
- if (!wander_distance)
- wander_distance = creature->GetRespawnRadius();
+ Movement::MoveSplineInit init(owner);
+ init.MovebyPath(_path->GetPath());
+ init.SetWalk(true);
+ int32 traveltime = init.Launch();
+ _timer.Reset(traveltime + resetTimer);
- creature->AddUnitState(UNIT_STATE_ROAMING | UNIT_STATE_ROAMING_MOVE);
- _setRandomLocation(creature);
+ // Call for creature group update
+ if (owner->GetFormation() && owner->GetFormation()->getLeader() == owner)
+ owner->GetFormation()->LeaderMoveTo(position.m_positionX, position.m_positionY, position.m_positionZ);
}
-template<>
-void RandomMovementGenerator<Creature>::DoReset(Creature* creature)
+template<class T>
+bool RandomMovementGenerator<T>::DoUpdate(T*, uint32)
{
- DoInitialize(creature);
+ return false;
}
template<>
-void RandomMovementGenerator<Creature>::DoFinalize(Creature* creature)
+bool RandomMovementGenerator<Creature>::DoUpdate(Creature* owner, uint32 diff)
{
- creature->ClearUnitState(UNIT_STATE_ROAMING|UNIT_STATE_ROAMING_MOVE);
- creature->SetWalk(false);
-}
-
-template<>
-bool RandomMovementGenerator<Creature>::DoUpdate(Creature* creature, const uint32 diff)
-{
- if (!creature || !creature->IsAlive())
+ if (!owner || !owner->IsAlive())
return false;
- if (creature->HasUnitState(UNIT_STATE_ROOT | UNIT_STATE_STUNNED | UNIT_STATE_DISTRACTED))
+ if (owner->HasUnitState(UNIT_STATE_NOT_MOVE) || owner->IsMovementPreventedByCasting())
{
- i_nextMoveTime.Reset(0); // Expire the timer
- creature->ClearUnitState(UNIT_STATE_ROAMING_MOVE);
+ _interrupt = true;
+ owner->StopMoving();
return true;
}
+ else
+ _interrupt = false;
- if (creature->movespline->Finalized())
- {
- i_nextMoveTime.Update(diff);
- if (i_nextMoveTime.Passed())
- _setRandomLocation(creature);
- }
- return true;
-}
-
-template<>
-bool RandomMovementGenerator<Creature>::GetResetPos(Creature* creature, float& x, float& y, float& z)
-{
- float radius;
- creature->GetRespawnPosition(x, y, z, NULL, &radius);
-
- // use current if in range
- if (creature->IsWithinDist2d(x, y, radius))
- creature->GetPosition(x, y, z);
+ _timer.Update(diff);
+ if (!_interrupt && _timer.Passed() && owner->movespline->Finalized())
+ SetRandomLocation(owner);
return true;
}
diff --git a/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.h b/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.h
index 9a4f22f60e8..5bf0eb03f32 100644
--- a/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.h
+++ b/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.h
@@ -20,23 +20,30 @@
#define TRINITY_RANDOMMOTIONGENERATOR_H
#include "MovementGenerator.h"
+#include "Timer.h"
template<class T>
class RandomMovementGenerator : public MovementGeneratorMedium< T, RandomMovementGenerator<T> >
{
public:
- RandomMovementGenerator(float spawn_dist = 0.0f) : i_nextMoveTime(0), wander_distance(spawn_dist) { }
+ explicit RandomMovementGenerator(float distance = 0.0f) : _path(nullptr), _timer(0), _reference(0.f, 0.f, 0.f), _wanderDistance(distance), _interrupt(false) { }
+ ~RandomMovementGenerator();
+
+ MovementGeneratorType GetMovementGeneratorType() const override { return RANDOM_MOTION_TYPE; }
- void _setRandomLocation(T*);
void DoInitialize(T*);
void DoFinalize(T*);
void DoReset(T*);
- bool DoUpdate(T*, const uint32);
- bool GetResetPos(T*, float& x, float& y, float& z);
- MovementGeneratorType GetMovementGeneratorType() const override { return RANDOM_MOTION_TYPE; }
+ bool DoUpdate(T*, uint32);
+
private:
- TimeTrackerSmall i_nextMoveTime;
+ void SetRandomLocation(T*);
- float wander_distance;
+ PathGenerator* _path;
+ TimeTracker _timer;
+ G3D::Vector3 _reference;
+ float _wanderDistance;
+ bool _interrupt;
};
+
#endif
diff --git a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp
index 48e55c9960f..1e6a01a08f4 100644
--- a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp
+++ b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp
@@ -16,226 +16,208 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "ByteBuffer.h"
-#include "TargetedMovementGenerator.h"
-#include "Errors.h"
-#include "Creature.h"
#include "CreatureAI.h"
-#include "World.h"
-#include "MoveSplineInit.h"
-#include "MoveSpline.h"
+#include "Creature.h"
#include "Player.h"
#include "VehicleDefines.h"
+#include "MoveSplineInit.h"
+#include "MoveSpline.h"
+#include "World.h"
+#include "TargetedMovementGenerator.h"
template<class T, typename D>
-void TargetedMovementGeneratorMedium<T, D>::_setTargetLocation(T* owner, bool updateDestination)
+TargetedMovementGenerator<T, D>::~TargetedMovementGenerator()
{
- if (!i_target.isValid() || !i_target->IsInWorld())
- return;
+ delete _path;
+}
+
+template<class T, typename D>
+bool TargetedMovementGenerator<T, D>::DoUpdate(T* owner, uint32 diff)
+{
+ if (!IsTargetValid() || !GetTarget()->IsInWorld())
+ return false;
+
+ if (!owner || !owner->IsAlive())
+ return false;
+
+ if (owner->HasUnitState(UNIT_STATE_NOT_MOVE) || owner->IsMovementPreventedByCasting() || HasLostTarget(owner)
+ || (owner->GetTypeId() == TYPEID_UNIT && owner->ToCreature()->IsFocusing(nullptr, true)))
+ {
+ _interrupt = true;
+ owner->StopMoving();
+ return true;
+ }
+
+ if (_interrupt || _recalculateTravel)
+ {
+ _interrupt = false;
+ SetTargetLocation(owner, true);
+ return true;
+ }
+
+ bool targetMoved = false;
+ _timer.Update(diff);
+ if (!_interrupt && _timer.Passed())
+ {
+ _timer.Reset(100);
+
+ float distance = owner->GetCombatReach() + sWorld->getRate(RATE_TARGET_POS_RECALCULATION_RANGE);
+ if (owner->IsPet() && (owner->GetCharmerOrOwnerGUID() == GetTarget()->GetGUID()))
+ distance = 1.f; // pet following owner
+
+ G3D::Vector3 destination = owner->movespline->FinalDestination();
+ if (owner->movespline->onTransport)
+ if (TransportBase* transport = owner->GetDirectTransport())
+ transport->CalculatePassengerPosition(destination.x, destination.y, destination.z);
+
+ // First check distance
+ if (owner->GetTypeId() == TYPEID_UNIT && owner->ToCreature()->CanFly())
+ targetMoved = !GetTarget()->IsWithinDist3d(destination.x, destination.y, destination.z, distance);
+ else
+ targetMoved = !GetTarget()->IsWithinDist2d(destination.x, destination.y, distance);
- if (owner->HasUnitState(UNIT_STATE_NOT_MOVE))
+ // then, if the target is in range, check also Line of Sight.
+ if (!targetMoved)
+ targetMoved = !GetTarget()->IsWithinLOSInMap(owner);
+ }
+
+ if (targetMoved)
+ SetTargetLocation(owner, targetMoved);
+
+ if (!_targetReached && owner->movespline->Finalized())
+ {
+ MovementInform(owner);
+ if (_angle == 0.f && !owner->HasInArc(0.01f, GetTarget()))
+ owner->SetInFront(GetTarget());
+
+ if (!_targetReached)
+ {
+ _targetReached = true;
+ ReachTarget(owner);
+ }
+ }
+
+ return true;
+}
+
+template<class T, typename D>
+void TargetedMovementGenerator<T, D>::SetTargetLocation(T* owner, bool updateDestination)
+{
+ if (!IsTargetValid() || !GetTarget()->IsInWorld())
return;
- if (owner->IsMovementPreventedByCasting())
+ if (!owner || !owner->IsAlive())
return;
- if (owner->GetTypeId() == TYPEID_UNIT && !i_target->isInAccessiblePlaceFor(owner->ToCreature()))
+ if (owner->HasUnitState(UNIT_STATE_NOT_MOVE) || owner->IsMovementPreventedByCasting() || HasLostTarget(owner)
+ || (owner->GetTypeId() == TYPEID_UNIT && owner->ToCreature()->IsFocusing(nullptr, true)))
{
- owner->ToCreature()->SetCannotReachTarget(true);
+ _interrupt = true;
+ owner->StopMoving();
return;
}
- if (owner->GetTypeId() == TYPEID_UNIT && owner->ToCreature()->IsFocusing(nullptr, true))
+ if (owner->GetTypeId() == TYPEID_UNIT && !GetTarget()->isInAccessiblePlaceFor(owner->ToCreature()))
+ {
+ owner->ToCreature()->SetCannotReachTarget(true);
return;
+ }
float x, y, z;
-
- if (updateDestination || !i_path)
+ if (updateDestination || !_path)
{
- if (!i_offset)
+ if (!_offset)
{
- if (i_target->IsWithinDistInMap(owner, CONTACT_DISTANCE))
+ if (GetTarget()->IsWithinDistInMap(owner, CONTACT_DISTANCE))
return;
- // to nearest contact position
- i_target->GetContactPoint(owner, x, y, z);
+ GetTarget()->GetContactPoint(owner, x, y, z);
}
else
{
- float dist;
- float size;
-
- // Pets need special handling.
- // We need to subtract GetCombatReach() because it gets added back further down the chain
- // and that makes pets too far away. Subtracting it allows pets to properly
- // be (GetCombatReach() + i_offset) away.
- // Only applies when i_target is pet's owner otherwise pets and mobs end up
- // doing a "dance" while fighting
- if (owner->IsPet() && i_target->GetTypeId() == TYPEID_PLAYER)
- {
- dist = 1.0f; //i_target->GetCombatReach();
- size = 1.0f; //i_target->GetCombatReach() - i_target->GetCombatReach();
- }
- else
+ float distance = _offset + 1.0f;
+ float size = owner->GetCombatReach();
+
+ if (owner->IsPet() && GetTarget()->GetTypeId() == TYPEID_PLAYER)
{
- dist = i_offset + 1.0f;
- size = owner->GetCombatReach();
+ distance = 1.0f;
+ size = 1.0f;
}
- if (i_target->IsWithinDistInMap(owner, dist))
+ if (GetTarget()->IsWithinDistInMap(owner, distance))
return;
- // to at i_offset distance from target and i_angle from target facing
- i_target->GetClosePoint(x, y, z, size, i_offset, i_angle);
+ GetTarget()->GetClosePoint(x, y, z, size, _offset, _angle);
}
}
else
{
// the destination has not changed, we just need to refresh the path (usually speed change)
- G3D::Vector3 end = i_path->GetEndPosition();
+ G3D::Vector3 end = _path->GetEndPosition();
x = end.x;
y = end.y;
z = end.z;
}
- if (!i_path)
- i_path = new PathGenerator(owner);
+ if (!_path)
+ _path = new PathGenerator(owner);
// allow pets to use shortcut if no path found when following their master
- bool forceDest = (owner->GetTypeId() == TYPEID_UNIT && owner->ToCreature()->IsPet()
- && owner->HasUnitState(UNIT_STATE_FOLLOW));
+ bool forceDest = (owner->GetTypeId() == TYPEID_UNIT && owner->ToCreature()->IsPet() && owner->HasUnitState(UNIT_STATE_FOLLOW));
- bool result = i_path->CalculatePath(x, y, z, forceDest);
- if (!result || (i_path->GetPathType() & PATHFIND_NOPATH))
+ bool result = _path->CalculatePath(x, y, z, forceDest);
+ if (!result || (_path->GetPathType() & PATHFIND_NOPATH))
{
// can't reach target
- i_recalculateTravel = true;
+ _recalculateTravel = true;
if (owner->GetTypeId() == TYPEID_UNIT)
owner->ToCreature()->SetCannotReachTarget(true);
return;
}
- D::_addUnitStateMove(owner);
- i_targetReached = false;
- i_recalculateTravel = false;
- owner->AddUnitState(UNIT_STATE_CHASE);
+ _targetReached = false;
+ _recalculateTravel = false;
+
+ AddUnitStateMove(owner);
+
if (owner->GetTypeId() == TYPEID_UNIT)
owner->ToCreature()->SetCannotReachTarget(false);
Movement::MoveSplineInit init(owner);
- init.MovebyPath(i_path->GetPath());
- init.SetWalk(((D*)this)->EnableWalking());
+ init.MovebyPath(_path->GetPath());
+ init.SetWalk(EnableWalking());
// Using the same condition for facing target as the one that is used for SetInFront on movement end
// - applies to ChaseMovementGenerator mostly
- if (i_angle == 0.f)
- init.SetFacing(i_target.getTarget());
+ if (_angle == 0.f)
+ init.SetFacing(GetTarget());
init.Launch();
}
template<class T, typename D>
-bool TargetedMovementGeneratorMedium<T, D>::DoUpdate(T* owner, uint32 time_diff)
+bool TargetedMovementGenerator<T, D>::IsReachable() const
{
- if (!i_target.isValid() || !i_target->IsInWorld())
- return false;
-
- if (!owner || !owner->IsAlive())
- return false;
-
- if (owner->HasUnitState(UNIT_STATE_NOT_MOVE))
- {
- D::_clearUnitStateMove(owner);
- return true;
- }
-
- // prevent movement while casting spells with cast time or channel time
- if (owner->IsMovementPreventedByCasting())
- {
- if (!owner->IsStopped())
- owner->StopMoving();
- return true;
- }
-
- // prevent crash after creature killed pet
- if (static_cast<D*>(this)->_lostTarget(owner))
- {
- D::_clearUnitStateMove(owner);
- return true;
- }
-
- bool targetMoved = false;
- i_recheckDistance.Update(time_diff);
- if (i_recheckDistance.Passed())
- {
- i_recheckDistance.Reset(100);
-
- //More distance let have better performance, less distance let have more sensitive reaction at target move.
- float allowed_dist = 0.0f;
-
- if (owner->IsPet() && (owner->GetCharmerOrOwnerGUID() == i_target->GetGUID()))
- allowed_dist = 1.0f; // pet following owner
- else
- allowed_dist = owner->GetCombatReach() + sWorld->getRate(RATE_TARGET_POS_RECALCULATION_RANGE);
-
- G3D::Vector3 dest = owner->movespline->FinalDestination();
- if (owner->movespline->onTransport)
- if (TransportBase* transport = owner->GetDirectTransport())
- transport->CalculatePassengerPosition(dest.x, dest.y, dest.z);
-
- // First check distance
- if (owner->GetTypeId() == TYPEID_UNIT && owner->ToCreature()->CanFly())
- targetMoved = !i_target->IsWithinDist3d(dest.x, dest.y, dest.z, allowed_dist);
- else
- targetMoved = !i_target->IsWithinDist2d(dest.x, dest.y, allowed_dist);
-
- // then, if the target is in range, check also Line of Sight.
- if (!targetMoved)
- targetMoved = !i_target->IsWithinLOSInMap(owner);
- }
-
- if (i_recalculateTravel || targetMoved)
- _setTargetLocation(owner, targetMoved);
-
- if (owner->movespline->Finalized())
- {
- static_cast<D*>(this)->MovementInform(owner);
- if (i_angle == 0.f && !owner->HasInArc(0.01f, i_target.getTarget()))
- owner->SetInFront(i_target.getTarget());
-
- if (!i_targetReached)
- {
- i_targetReached = true;
- static_cast<D*>(this)->_reachTarget(owner);
- }
- }
-
- return true;
+ return (_path) ? (_path->GetPathType() & PATHFIND_NORMAL) : true;
}
-//-----------------------------------------------//
+//---- ChaseMovementGenerator
+
template<class T>
-void ChaseMovementGenerator<T>::_reachTarget(T* owner)
-{
- _clearUnitStateMove(owner);
- if (owner->IsWithinMeleeRange(this->i_target.getTarget()))
- owner->Attack(this->i_target.getTarget(), true);
- if (owner->GetTypeId() == TYPEID_UNIT)
- owner->ToCreature()->SetCannotReachTarget(false);
-}
+void ChaseMovementGenerator<T>::DoInitialize(T*) { }
template<>
void ChaseMovementGenerator<Player>::DoInitialize(Player* owner)
{
- owner->AddUnitState(UNIT_STATE_CHASE | UNIT_STATE_CHASE_MOVE);
- _setTargetLocation(owner, true);
+ owner->AddUnitState(UNIT_STATE_CHASE);
+ SetTargetLocation(owner, true);
}
template<>
void ChaseMovementGenerator<Creature>::DoInitialize(Creature* owner)
{
owner->SetWalk(false);
- owner->AddUnitState(UNIT_STATE_CHASE | UNIT_STATE_CHASE_MOVE);
- _setTargetLocation(owner, true);
+ owner->AddUnitState(UNIT_STATE_CHASE);
+ SetTargetLocation(owner, true);
}
template<class T>
@@ -251,41 +233,60 @@ void ChaseMovementGenerator<T>::DoReset(T* owner)
}
template<class T>
-void ChaseMovementGenerator<T>::MovementInform(T* /*unit*/) { }
+void ChaseMovementGenerator<T>::ClearUnitStateMove(T* owner)
+{
+ owner->ClearUnitState(UNIT_STATE_CHASE_MOVE);
+}
-template<>
-void ChaseMovementGenerator<Creature>::MovementInform(Creature* unit)
+template<class T>
+void ChaseMovementGenerator<T>::AddUnitStateMove(T* owner)
{
- // Pass back the GUIDLow of the target. If it is pet's owner then PetAI will handle
- if (unit->AI())
- unit->AI()->MovementInform(CHASE_MOTION_TYPE, i_target.getTarget()->GetGUID().GetCounter());
+ owner->AddUnitState(UNIT_STATE_CHASE_MOVE);
}
-//-----------------------------------------------//
-template<>
-bool FollowMovementGenerator<Creature>::EnableWalking() const
+template<class T>
+bool ChaseMovementGenerator<T>::HasLostTarget(T* owner) const
{
- return i_target.isValid() && i_target->IsWalking();
+ return owner->GetVictim() != TargetedMovementGeneratorBase::GetTarget();
}
-template<>
-bool FollowMovementGenerator<Player>::EnableWalking() const
+template<class T>
+void ChaseMovementGenerator<T>::ReachTarget(T* owner)
{
- return false;
+ ClearUnitStateMove(owner);
+
+ if (owner->IsWithinMeleeRange(TargetedMovementGeneratorBase::GetTarget()))
+ owner->Attack(TargetedMovementGeneratorBase::GetTarget(), true);
+
+ if (owner->GetTypeId() == TYPEID_UNIT)
+ owner->ToCreature()->SetCannotReachTarget(false);
}
+template<class T>
+void ChaseMovementGenerator<T>::MovementInform(T*) { }
+
template<>
-void FollowMovementGenerator<Player>::_updateSpeed(Player* /*owner*/)
+void ChaseMovementGenerator<Creature>::MovementInform(Creature* owner)
{
- // nothing to do for Player
+ // Pass back the GUIDLow of the target. If it is pet's owner then PetAI will handle
+ if (owner->AI())
+ owner->AI()->MovementInform(CHASE_MOTION_TYPE, GetTarget()->GetGUID().GetCounter());
}
+//---- FollowMovementGenerator
+
+template<class T>
+void FollowMovementGenerator<T>::UpdateSpeed(T*) { }
+
+template<>
+void FollowMovementGenerator<Player>::UpdateSpeed(Player* /*owner*/) { }
+
template<>
-void FollowMovementGenerator<Creature>::_updateSpeed(Creature* owner)
+void FollowMovementGenerator<Creature>::UpdateSpeed(Creature* owner)
{
- // pet only sync speed with owner
- /// Make sure we are not in the process of a map change (IsInWorld)
- if (!owner->IsPet() || !owner->IsInWorld() || !i_target.isValid() || i_target->GetGUID() != owner->GetOwnerGUID())
+ // Pet only sync speed with owner
+ // Make sure we are not in the process of a map change (IsInWorld)
+ if (!owner->IsPet() || !owner->IsInWorld() || !IsTargetValid() || GetTarget()->GetGUID() != owner->GetOwnerGUID())
return;
owner->UpdateSpeed(MOVE_RUN);
@@ -293,27 +294,19 @@ void FollowMovementGenerator<Creature>::_updateSpeed(Creature* owner)
owner->UpdateSpeed(MOVE_SWIM);
}
-template<>
-void FollowMovementGenerator<Player>::DoInitialize(Player* owner)
-{
- owner->AddUnitState(UNIT_STATE_FOLLOW | UNIT_STATE_FOLLOW_MOVE);
- _updateSpeed(owner);
- _setTargetLocation(owner, true);
-}
-
-template<>
-void FollowMovementGenerator<Creature>::DoInitialize(Creature* owner)
+template<class T>
+void FollowMovementGenerator<T>::DoInitialize(T* owner)
{
- owner->AddUnitState(UNIT_STATE_FOLLOW | UNIT_STATE_FOLLOW_MOVE);
- _updateSpeed(owner);
- _setTargetLocation(owner, true);
+ owner->AddUnitState(UNIT_STATE_FOLLOW);
+ UpdateSpeed(owner);
+ TargetedMovementGenerator<T, FollowMovementGenerator<T>>::SetTargetLocation(owner, true);
}
template<class T>
void FollowMovementGenerator<T>::DoFinalize(T* owner)
{
owner->ClearUnitState(UNIT_STATE_FOLLOW | UNIT_STATE_FOLLOW_MOVE);
- _updateSpeed(owner);
+ UpdateSpeed(owner);
}
template<class T>
@@ -323,36 +316,85 @@ void FollowMovementGenerator<T>::DoReset(T* owner)
}
template<class T>
-void FollowMovementGenerator<T>::MovementInform(T* /*unit*/) { }
+void FollowMovementGenerator<T>::ClearUnitStateMove(T* owner)
+{
+ owner->ClearUnitState(UNIT_STATE_FOLLOW_MOVE);
+}
+
+template<class T>
+void FollowMovementGenerator<T>::AddUnitStateMove(T* owner)
+{
+ owner->AddUnitState(UNIT_STATE_FOLLOW_MOVE);
+}
+
+template<class T>
+void FollowMovementGenerator<T>::ReachTarget(T* owner)
+{
+ ClearUnitStateMove(owner);
+}
+
+template<>
+bool FollowMovementGenerator<Creature>::EnableWalking() const
+{
+ return IsTargetValid() && GetTarget()->IsWalking();
+}
+
+template<>
+bool FollowMovementGenerator<Player>::EnableWalking() const
+{
+ return false;
+}
+
+template<class T>
+void FollowMovementGenerator<T>::MovementInform(T*) { }
template<>
void FollowMovementGenerator<Creature>::MovementInform(Creature* unit)
{
// Pass back the GUIDLow of the target. If it is pet's owner then PetAI will handle
if (unit->AI())
- unit->AI()->MovementInform(FOLLOW_MOTION_TYPE, i_target.getTarget()->GetGUID().GetCounter());
+ unit->AI()->MovementInform(FOLLOW_MOTION_TYPE, GetTarget()->GetGUID().GetCounter());
}
//-----------------------------------------------//
-template void TargetedMovementGeneratorMedium<Player, ChaseMovementGenerator<Player> >::_setTargetLocation(Player*, bool);
-template void TargetedMovementGeneratorMedium<Player, FollowMovementGenerator<Player> >::_setTargetLocation(Player*, bool);
-template void TargetedMovementGeneratorMedium<Creature, ChaseMovementGenerator<Creature> >::_setTargetLocation(Creature*, bool);
-template void TargetedMovementGeneratorMedium<Creature, FollowMovementGenerator<Creature> >::_setTargetLocation(Creature*, bool);
-template bool TargetedMovementGeneratorMedium<Player, ChaseMovementGenerator<Player> >::DoUpdate(Player*, uint32);
-template bool TargetedMovementGeneratorMedium<Player, FollowMovementGenerator<Player> >::DoUpdate(Player*, uint32);
-template bool TargetedMovementGeneratorMedium<Creature, ChaseMovementGenerator<Creature> >::DoUpdate(Creature*, uint32);
-template bool TargetedMovementGeneratorMedium<Creature, FollowMovementGenerator<Creature> >::DoUpdate(Creature*, uint32);
-
-template void ChaseMovementGenerator<Player>::_reachTarget(Player*);
-template void ChaseMovementGenerator<Creature>::_reachTarget(Creature*);
+
+template TargetedMovementGenerator<Player, ChaseMovementGenerator<Player> >::~TargetedMovementGenerator();
+template TargetedMovementGenerator<Player, FollowMovementGenerator<Player> >::~TargetedMovementGenerator();
+template TargetedMovementGenerator<Creature, ChaseMovementGenerator<Creature> >::~TargetedMovementGenerator();
+template TargetedMovementGenerator<Creature, FollowMovementGenerator<Creature> >::~TargetedMovementGenerator();
+template bool TargetedMovementGenerator<Player, ChaseMovementGenerator<Player> >::DoUpdate(Player*, uint32);
+template bool TargetedMovementGenerator<Player, FollowMovementGenerator<Player> >::DoUpdate(Player*, uint32);
+template bool TargetedMovementGenerator<Creature, ChaseMovementGenerator<Creature> >::DoUpdate(Creature*, uint32);
+template bool TargetedMovementGenerator<Creature, FollowMovementGenerator<Creature> >::DoUpdate(Creature*, uint32);
+template void TargetedMovementGenerator<Player, ChaseMovementGenerator<Player> >::SetTargetLocation(Player*, bool);
+template void TargetedMovementGenerator<Player, FollowMovementGenerator<Player> >::SetTargetLocation(Player*, bool);
+template void TargetedMovementGenerator<Creature, ChaseMovementGenerator<Creature> >::SetTargetLocation(Creature*, bool);
+template void TargetedMovementGenerator<Creature, FollowMovementGenerator<Creature> >::SetTargetLocation(Creature*, bool);
+
template void ChaseMovementGenerator<Player>::DoFinalize(Player*);
template void ChaseMovementGenerator<Creature>::DoFinalize(Creature*);
template void ChaseMovementGenerator<Player>::DoReset(Player*);
template void ChaseMovementGenerator<Creature>::DoReset(Creature*);
+template void ChaseMovementGenerator<Player>::ClearUnitStateMove(Player*);
+template void ChaseMovementGenerator<Creature>::ClearUnitStateMove(Creature*);
+template void ChaseMovementGenerator<Player>::AddUnitStateMove(Player*);
+template void ChaseMovementGenerator<Creature>::AddUnitStateMove(Creature*);
+template bool ChaseMovementGenerator<Player>::HasLostTarget(Player*) const;
+template bool ChaseMovementGenerator<Creature>::HasLostTarget(Creature*) const;
+template void ChaseMovementGenerator<Player>::ReachTarget(Player*);
+template void ChaseMovementGenerator<Creature>::ReachTarget(Creature*);
template void ChaseMovementGenerator<Player>::MovementInform(Player*);
+template void FollowMovementGenerator<Player>::DoInitialize(Player*);
+template void FollowMovementGenerator<Creature>::DoInitialize(Creature*);
template void FollowMovementGenerator<Player>::DoFinalize(Player*);
template void FollowMovementGenerator<Creature>::DoFinalize(Creature*);
template void FollowMovementGenerator<Player>::DoReset(Player*);
template void FollowMovementGenerator<Creature>::DoReset(Creature*);
+template void FollowMovementGenerator<Player>::ClearUnitStateMove(Player*);
+template void FollowMovementGenerator<Creature>::ClearUnitStateMove(Creature*);
+template void FollowMovementGenerator<Player>::AddUnitStateMove(Player*);
+template void FollowMovementGenerator<Creature>::AddUnitStateMove(Creature*);
+template void FollowMovementGenerator<Player>::ReachTarget(Player*);
+template void FollowMovementGenerator<Creature>::ReachTarget(Creature*);
template void FollowMovementGenerator<Player>::MovementInform(Player*);
diff --git a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h
index 25029dcdfca..6bfb3bbbc28 100755
--- a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h
+++ b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h
@@ -22,95 +22,93 @@
#include "MovementGenerator.h"
#include "FollowerReference.h"
#include "Timer.h"
-#include "Unit.h"
-#include "PathGenerator.h"
class TargetedMovementGeneratorBase
{
public:
- TargetedMovementGeneratorBase(Unit* target) { i_target.link(target, this); }
+ TargetedMovementGeneratorBase(Unit* target)
+ {
+ _target.link(target, this);
+ }
+
+ bool IsTargetValid() const { return _target.isValid(); }
+ Unit* GetTarget() const { return _target.getTarget(); }
void stopFollowing() { }
- protected:
- FollowerReference i_target;
+
+ private:
+ FollowerReference _target;
};
template<class T, typename D>
-class TargetedMovementGeneratorMedium : public MovementGeneratorMedium< T, D >, public TargetedMovementGeneratorBase
+class TargetedMovementGenerator : public MovementGeneratorMedium< T, D >, public TargetedMovementGeneratorBase
{
- protected:
- TargetedMovementGeneratorMedium(Unit* target, float offset, float angle) :
- TargetedMovementGeneratorBase(target), i_path(NULL),
- i_recheckDistance(0), i_offset(offset), i_angle(angle),
- i_recalculateTravel(false), i_targetReached(false)
- {
- }
- ~TargetedMovementGeneratorMedium() { delete i_path; }
-
public:
+ explicit TargetedMovementGenerator(Unit* target, float offset, float angle) : TargetedMovementGeneratorBase(target), _path(nullptr), _timer(0), _offset(offset), _angle(angle), _recalculateTravel(false), _targetReached(false), _interrupt(false) { }
+ ~TargetedMovementGenerator();
+
bool DoUpdate(T*, uint32);
- Unit* GetTarget() const { return i_target.getTarget(); }
-
- void unitSpeedChanged() override { i_recalculateTravel = true; }
- bool IsReachable() const { return (i_path) ? (i_path->GetPathType() & PATHFIND_NORMAL) : true; }
- protected:
- void _setTargetLocation(T* owner, bool updateDestination);
-
- PathGenerator* i_path;
- TimeTrackerSmall i_recheckDistance;
- float i_offset;
- float i_angle;
- bool i_recalculateTravel : 1;
- bool i_targetReached : 1;
+
+ void UnitSpeedChanged() override { _recalculateTravel = true; }
+
+ virtual void ClearUnitStateMove(T*) { }
+ virtual void AddUnitStateMove(T*) { }
+ virtual bool HasLostTarget(T*) const { return false; }
+ virtual void ReachTarget(T*) { }
+ virtual bool EnableWalking() const { return false; }
+ virtual void MovementInform(T*) { }
+
+ bool IsReachable() const;
+ void SetTargetLocation(T* owner, bool updateDestination);
+
+ private:
+ PathGenerator* _path;
+ TimeTrackerSmall _timer;
+ float _offset;
+ float _angle;
+ bool _recalculateTravel;
+ bool _targetReached;
+ bool _interrupt;
};
template<class T>
-class ChaseMovementGenerator : public TargetedMovementGeneratorMedium<T, ChaseMovementGenerator<T> >
+class ChaseMovementGenerator : public TargetedMovementGenerator<T, ChaseMovementGenerator<T> >
{
public:
- ChaseMovementGenerator(Unit* target)
- : TargetedMovementGeneratorMedium<T, ChaseMovementGenerator<T> >(target) { }
- ChaseMovementGenerator(Unit* target, float offset, float angle)
- : TargetedMovementGeneratorMedium<T, ChaseMovementGenerator<T> >(target, offset, angle) { }
- ~ChaseMovementGenerator() { }
+ explicit ChaseMovementGenerator(Unit* target, float offset, float angle) : TargetedMovementGenerator<T, ChaseMovementGenerator<T> >(target, offset, angle) { }
MovementGeneratorType GetMovementGeneratorType() const override { return CHASE_MOTION_TYPE; }
void DoInitialize(T*);
void DoFinalize(T*);
void DoReset(T*);
- void MovementInform(T*);
- static void _clearUnitStateMove(T* u) { u->ClearUnitState(UNIT_STATE_CHASE_MOVE); }
- static void _addUnitStateMove(T* u) { u->AddUnitState(UNIT_STATE_CHASE_MOVE); }
- bool EnableWalking() const { return false;}
- bool _lostTarget(T* u) const { return u->GetVictim() != this->GetTarget(); }
- void _reachTarget(T*);
+ void ClearUnitStateMove(T*) override;
+ void AddUnitStateMove(T*) override;
+ bool HasLostTarget(T*) const override;
+ void ReachTarget(T*) override;
+ void MovementInform(T*) override;
};
template<class T>
-class FollowMovementGenerator : public TargetedMovementGeneratorMedium<T, FollowMovementGenerator<T> >
+class FollowMovementGenerator : public TargetedMovementGenerator<T, FollowMovementGenerator<T> >
{
public:
- FollowMovementGenerator(Unit* target)
- : TargetedMovementGeneratorMedium<T, FollowMovementGenerator<T> >(target){ }
- FollowMovementGenerator(Unit* target, float offset, float angle)
- : TargetedMovementGeneratorMedium<T, FollowMovementGenerator<T> >(target, offset, angle) { }
- ~FollowMovementGenerator() { }
+ explicit FollowMovementGenerator(Unit* target, float offset, float angle) : TargetedMovementGenerator<T, FollowMovementGenerator<T> >(target, offset, angle) { }
MovementGeneratorType GetMovementGeneratorType() const override { return FOLLOW_MOTION_TYPE; }
void DoInitialize(T*);
void DoFinalize(T*);
void DoReset(T*);
- void MovementInform(T*);
- static void _clearUnitStateMove(T* u) { u->ClearUnitState(UNIT_STATE_FOLLOW_MOVE); }
- static void _addUnitStateMove(T* u) { u->AddUnitState(UNIT_STATE_FOLLOW_MOVE); }
- bool EnableWalking() const;
- bool _lostTarget(T*) const { return false; }
- void _reachTarget(T*) { }
+ void ClearUnitStateMove(T*) override;
+ void AddUnitStateMove(T*) override;
+ bool HasLostTarget(T*) const override { return false; }
+ void ReachTarget(T*) override;
+ bool EnableWalking() const override;
+ void MovementInform(T*) override;
private:
- void _updateSpeed(T* owner);
+ void UpdateSpeed(T* owner);
};
#endif