aboutsummaryrefslogtreecommitdiff
path: root/src/game/TargetedMovementGenerator.cpp
diff options
context:
space:
mode:
authormaximius <none@none>2009-10-17 15:51:44 -0700
committermaximius <none@none>2009-10-17 15:51:44 -0700
commite585187b248f48b3c6e9247b49fa07c6565d65e5 (patch)
tree637c5b7ddacf41040bef4ea4f75a97da64c6a9bc /src/game/TargetedMovementGenerator.cpp
parent26b5e033ffde3d161382fc9addbfa99738379641 (diff)
*Backed out changeset 3be01fb200a5
--HG-- branch : trunk
Diffstat (limited to 'src/game/TargetedMovementGenerator.cpp')
-rw-r--r--src/game/TargetedMovementGenerator.cpp33
1 files changed, 33 insertions, 0 deletions
diff --git a/src/game/TargetedMovementGenerator.cpp b/src/game/TargetedMovementGenerator.cpp
index 344df244f0b..3b001c1ed3c 100644
--- a/src/game/TargetedMovementGenerator.cpp
+++ b/src/game/TargetedMovementGenerator.cpp
@@ -17,6 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+
#include "ByteBuffer.h"
#include "TargetedMovementGenerator.h"
#include "Errors.h"
@@ -24,7 +25,9 @@
#include "CreatureAI.h"
#include "DestinationHolderImp.h"
#include "World.h"
+
#define SMALL_ALPHA 0.05f
+
#include <cmath>
/*
struct StackCleaner
@@ -38,6 +41,7 @@ struct StackCleaner
}
};
*/
+
template<class T>
TargetedMovementGenerator<T>::TargetedMovementGenerator(Unit &target, float offset, float angle)
: TargetedMovementGeneratorBase(target)
@@ -45,14 +49,17 @@ TargetedMovementGenerator<T>::TargetedMovementGenerator(Unit &target, float offs
{
target.GetPosition(i_targetX, i_targetY, i_targetZ);
}
+
template<class T>
bool
TargetedMovementGenerator<T>::_setTargetLocation(T &owner)
{
if (!i_target.isValid() || !i_target->IsInWorld())
return false;
+
if( owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED) )
return false;
+
float x, y, z;
Traveller<T> traveller(owner);
if(i_destinationHolder.HasDestination())
@@ -89,6 +96,7 @@ TargetedMovementGenerator<T>::_setTargetLocation(T &owner)
if(i_target->IsWithinDist(&owner, i_offset * 0.8f))
stop = true;
}
+
if(stop)
{
owner.GetPosition(x, y, z);
@@ -98,9 +106,11 @@ TargetedMovementGenerator<T>::_setTargetLocation(T &owner)
return false;
}
}
+
if(i_target->GetExactDistSq(i_targetX, i_targetY, i_targetZ) < 0.01f)
return false;
}
+
if(!i_offset)
{
// to nearest random contact position
@@ -116,6 +126,7 @@ TargetedMovementGenerator<T>::_setTargetLocation(T &owner)
// to at i_offset distance from target and i_angle from target facing
i_target->GetClosePoint(x,y,z,owner.GetObjectSize(),i_offset,i_angle);
}
+
/*
We MUST not check the distance difference and avoid setting the new location for smaller distances.
By that we risk having far too many GetContactPoint() calls freezing the whole system.
@@ -126,6 +137,7 @@ TargetedMovementGenerator<T>::_setTargetLocation(T &owner)
we will calculate a new contact point each update loop, but will never move to it.
The system will freeze.
ralf
+
//We don't update Mob Movement, if the difference between New destination and last destination is < BothObjectSize
float bothObjectSize = i_target->GetObjectSize() + owner.GetObjectSize() + CONTACT_DISTANCE;
if( i_destinationHolder.HasDestination() && i_destinationHolder.GetDestinationDiff(x,y,z) < bothObjectSize )
@@ -136,6 +148,7 @@ TargetedMovementGenerator<T>::_setTargetLocation(T &owner)
i_destinationHolder.StartTravel(traveller);
return true;
}
+
template<class T>
void
TargetedMovementGenerator<T>::Initialize(T &owner)
@@ -144,30 +157,37 @@ TargetedMovementGenerator<T>::Initialize(T &owner)
owner.AddUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
else
owner.RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
+
_setTargetLocation(owner);
}
+
template<class T>
void
TargetedMovementGenerator<T>::Finalize(T &owner)
{
owner.clearUnitState(UNIT_STAT_CHASE);
}
+
template<class T>
void
TargetedMovementGenerator<T>::Reset(T &owner)
{
Initialize(owner);
}
+
template<class T>
bool
TargetedMovementGenerator<T>::Update(T &owner, const uint32 & time_diff)
{
if (!i_target.isValid() || !i_target->IsInWorld())
return false;
+
if (!&owner || !owner.isAlive())
return true;
+
if (owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_FLEEING | UNIT_STAT_DISTRACTED))
return true;
+
// prevent movement while casting spells with cast time or channel time
if (owner.hasUnitState(UNIT_STAT_CASTING))
{
@@ -175,10 +195,13 @@ TargetedMovementGenerator<T>::Update(T &owner, const uint32 & time_diff)
owner.StopMoving();
return true;
}
+
// prevent crash after creature killed pet
if (!owner.hasUnitState(UNIT_STAT_FOLLOW) && owner.getVictim() != i_target.getTarget())
return true;
+
Traveller<T> traveller(owner);
+
if (!i_destinationHolder.HasDestination())
_setTargetLocation(owner);
else if (owner.IsStopped() && !i_destinationHolder.HasArrived())
@@ -187,11 +210,13 @@ TargetedMovementGenerator<T>::Update(T &owner, const uint32 & time_diff)
i_destinationHolder.StartTravel(traveller);
return true;
}
+
if (i_destinationHolder.UpdateTraveller(traveller, time_diff))
{
// put targeted movement generators on a higher priority
//if (owner.GetObjectSize())
//i_destinationHolder.ResetUpdate(50);
+
// target moved
if (i_targetX != i_target->GetPositionX() || i_targetY != i_target->GetPositionY()
|| i_targetZ != i_target->GetPositionZ())
@@ -200,36 +225,44 @@ TargetedMovementGenerator<T>::Update(T &owner, const uint32 & time_diff)
owner.SetInFront(i_target.getTarget());
i_target->GetPosition(i_targetX, i_targetY, i_targetZ);
}
+
if ((owner.IsStopped() && !i_destinationHolder.HasArrived()) || i_recalculateTravel)
{
i_recalculateTravel = false;
//Angle update will take place into owner.StopMoving()
owner.SetInFront(i_target.getTarget());
+
owner.StopMoving();
if(owner.IsWithinMeleeRange(i_target.getTarget()) && !owner.hasUnitState(UNIT_STAT_FOLLOW))
owner.Attack(i_target.getTarget(),true);
}
}
+
// Implemented for PetAI to handle resetting flags when pet owner reached
if (i_destinationHolder.HasArrived())
MovementInform(owner);
+
return true;
}
+
template<class T>
Unit*
TargetedMovementGenerator<T>::GetTarget() const
{
return i_target.getTarget();
}
+
template<class T>
void TargetedMovementGenerator<T>::MovementInform(T &unit)
{
}
+
template <> void TargetedMovementGenerator<Creature>::MovementInform(Creature &unit)
{
// Pass back the GUIDLow of the target. If it is pet's owner then PetAI will handle
unit.AI()->MovementInform(TARGETED_MOTION_TYPE, i_target.getTarget()->GetGUIDLow());
}
+
template void TargetedMovementGenerator<Player>::MovementInform(Player&); // Not implemented for players
template TargetedMovementGenerator<Player>::TargetedMovementGenerator(Unit &target, float offset, float angle);
template TargetedMovementGenerator<Creature>::TargetedMovementGenerator(Unit &target, float offset, float angle);