aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/game/TargetedMovementGenerator.cpp85
-rw-r--r--src/game/TargetedMovementGenerator.h9
2 files changed, 60 insertions, 34 deletions
diff --git a/src/game/TargetedMovementGenerator.cpp b/src/game/TargetedMovementGenerator.cpp
index a7757aaeaaf..f6d7cb12b18 100644
--- a/src/game/TargetedMovementGenerator.cpp
+++ b/src/game/TargetedMovementGenerator.cpp
@@ -42,28 +42,60 @@ struct StackCleaner
*/
template<class T>
-void
+TargetedMovementGenerator<T>::TargetedMovementGenerator(Unit &target, float offset, float angle)
+: TargetedMovementGeneratorBase(target)
+, i_offset(offset), i_angle(angle), i_recalculateTravel(false)
+{
+ target.GetPosition(i_targetX, i_targetY, i_targetZ);
+}
+
+template<class T>
+bool
TargetedMovementGenerator<T>::_setTargetLocation(T &owner)
{
if( !i_target.isValid() || !&owner )
- return;
+ return false;
if( owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED) )
- return;
+ return false;
float x, y, z;
Traveller<T> traveller(owner);
- // prevent redundant micro-movement for pets, other followers.
- if(i_offset ? i_target->IsWithinDistInMap(&owner, i_offset + 1.0f) : i_target->IsWithinMeleeRange(&owner))
+ if(i_destinationHolder.HasDestination())
{
- owner.GetPosition(x, y, z);
- i_destinationHolder.SetDestination(traveller, x, y, z, false);
- return;
- }
+ if(i_destinationHolder.HasArrived())
+ {
+ // prevent redundant micro-movement
+ if(i_offset ? i_target->IsWithinDistInMap(&owner, i_offset + 1.0f) : i_target->IsWithinMeleeRange(&owner))
+ return false;
+ }
+ else
+ {
+ bool stop = false;
+ if(!i_offset)
+ {
+ if(i_target->IsWithinMeleeRange(&owner, 0))
+ stop = true;
+ }
+ else if(!i_angle && !owner.hasUnitState(UNIT_STAT_FOLLOW))
+ {
+ if(i_target->IsWithinDist(&owner, i_offset * 0.8))
+ stop = true;
+ }
- // chaser is on the way, and target did not move much
- if(GetDestination(x, y, z) && i_target->IsWithinDist3d(x, y, z, 0.3f))
- return;
+ if(stop)
+ {
+ i_target->GetPosition(x, y, z);
+ i_destinationHolder.SetDestination(traveller, x, y, z);
+ i_destinationHolder.StartTravel(traveller, false);
+ i_target->StopMoving();
+ return false;
+ }
+ }
+
+ if(i_target->GetDistanceSq(i_targetX, i_targetY, i_targetZ) < 0.01f)
+ return false;
+ }
if(!i_offset)
{
@@ -102,6 +134,7 @@ TargetedMovementGenerator<T>::_setTargetLocation(T &owner)
if (owner.GetTypeId() == TYPEID_UNIT && ((Creature*)&owner)->canFly())
owner.AddUnitMovementFlag(MOVEMENTFLAG_FLYING2);
i_destinationHolder.StartTravel(traveller);
+ return true;
}
template<class T>
@@ -174,23 +207,17 @@ TargetedMovementGenerator<T>::Update(T &owner, const uint32 & time_diff)
if (i_destinationHolder.UpdateTraveller(traveller, time_diff))
{
// put targeted movement generators on a higher priority
- if (owner.GetObjectSize())
- i_destinationHolder.ResetUpdate(50);
-
- //float dist = owner.GetCombatReach() + i_target.getTarget()->GetCombatReach() + sWorld.getRate(RATE_TARGET_POS_RECALCULATION_RANGE);
+ //if (owner.GetObjectSize())
+ //i_destinationHolder.ResetUpdate(50);
- //More distance let have better performance, less distance let have more sensitive reaction at target move.
-
- // try to counter precision differences
- //if( i_destinationHolder.GetDistance2dFromDestSq(*i_target.getTarget()) >= dist * dist)
- if(i_offset ? !i_target->IsWithinDistInMap(&owner, i_offset + 1.0f) : !i_target->IsWithinMeleeRange(&owner))
+ // target moved
+ if(i_targetX != i_target->GetPositionX() || i_targetY != i_target->GetPositionY()
+ || i_targetZ != i_target->GetPositionZ())
{
- owner.SetInFront(i_target.getTarget()); // Set new Angle For Map::
- _setTargetLocation(owner); //Calculate New Dest and Send data To Player
+ if(_setTargetLocation(owner) || !owner.hasUnitState(UNIT_STAT_FOLLOW))
+ owner.SetInFront(i_target.getTarget());
+ i_target->GetPosition(i_targetX, i_targetY, i_targetZ);
}
- // Update the Angle of the target only for Map::, no need to send packet for player
- else if ( !i_angle && !owner.HasInArc( 0.01f, i_target.getTarget() ) )
- owner.SetInFront(i_target.getTarget());
if(( owner.IsStopped() && !i_destinationHolder.HasArrived() ) || i_recalculateTravel )
{
@@ -213,8 +240,10 @@ TargetedMovementGenerator<T>::GetTarget() const
return i_target.getTarget();
}
-template void TargetedMovementGenerator<Player>::_setTargetLocation(Player &);
-template void TargetedMovementGenerator<Creature>::_setTargetLocation(Creature &);
+template TargetedMovementGenerator<Player>::TargetedMovementGenerator(Unit &target, float offset, float angle);
+template TargetedMovementGenerator<Creature>::TargetedMovementGenerator(Unit &target, float offset, float angle);
+template bool TargetedMovementGenerator<Player>::_setTargetLocation(Player &);
+template bool TargetedMovementGenerator<Creature>::_setTargetLocation(Creature &);
template void TargetedMovementGenerator<Player>::Initialize(Player &);
template void TargetedMovementGenerator<Creature>::Initialize(Creature &);
template void TargetedMovementGenerator<Player>::Finalize(Player &);
diff --git a/src/game/TargetedMovementGenerator.h b/src/game/TargetedMovementGenerator.h
index e3b262ac746..1f886625f3a 100644
--- a/src/game/TargetedMovementGenerator.h
+++ b/src/game/TargetedMovementGenerator.h
@@ -40,11 +40,7 @@ class TRINITY_DLL_SPEC TargetedMovementGenerator
: public MovementGeneratorMedium< T, TargetedMovementGenerator<T> >, public TargetedMovementGeneratorBase
{
public:
-
- TargetedMovementGenerator(Unit &target)
- : TargetedMovementGeneratorBase(target), i_offset(0), i_angle(0), i_recalculateTravel(false) {}
- TargetedMovementGenerator(Unit &target, float offset, float angle)
- : TargetedMovementGeneratorBase(target), i_offset(offset), i_angle(angle), i_recalculateTravel(false) {}
+ TargetedMovementGenerator(Unit &target, float offset = 0, float angle = 0);
~TargetedMovementGenerator() {}
void Initialize(T &);
@@ -65,12 +61,13 @@ class TRINITY_DLL_SPEC TargetedMovementGenerator
void unitSpeedChanged() { i_recalculateTravel=true; }
private:
- void _setTargetLocation(T &);
+ bool _setTargetLocation(T &);
float i_offset;
float i_angle;
DestinationHolder< Traveller<T> > i_destinationHolder;
bool i_recalculateTravel;
+ float i_targetX, i_targetY, i_targetZ;
};
#endif