mirror of
https://github.com/araxiaonline/TrinityCore.git
synced 2026-06-14 12:12:34 -04:00
*Handle creature rotation using movement generator. Please tell me if this breaks any script.
--HG-- branch : trunk
This commit is contained in:
@@ -163,6 +163,12 @@ struct TRINITY_DLL_DECL boss_the_lurker_belowAI : public Scripted_NoMovementAI
|
||||
}
|
||||
}
|
||||
|
||||
void MovementInform(uint32 type, uint32 id)
|
||||
{
|
||||
if(type == ROTATE_MOTION_TYPE)
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 diff)
|
||||
{
|
||||
if(!CanStartEvent)//boss is invisible, don't attack
|
||||
@@ -216,10 +222,8 @@ struct TRINITY_DLL_DECL boss_the_lurker_belowAI : public Scripted_NoMovementAI
|
||||
if (SpoutTimer < diff)
|
||||
{
|
||||
m_creature->MonsterTextEmote(EMOTE_SPOUT,0,true);
|
||||
if(rand()%2)
|
||||
m_creature->StartAutoRotate(CREATURE_ROTATE_LEFT,20000);
|
||||
else
|
||||
m_creature->StartAutoRotate(CREATURE_ROTATE_RIGHT,20000);
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
me->GetMotionMaster()->MoveRotate(20000, rand()%2 ? ROTATE_DIRECTION_LEFT : ROTATE_DIRECTION_RIGHT);
|
||||
SpoutTimer = 45000;
|
||||
WhirlTimer = 20000;//whirl directly after spout
|
||||
RotTimer = 20000;
|
||||
@@ -298,7 +302,7 @@ struct TRINITY_DLL_DECL boss_the_lurker_belowAI : public Scripted_NoMovementAI
|
||||
}else WaterboltTimer -= diff;
|
||||
}
|
||||
|
||||
if (!UpdateVictim())
|
||||
if (!UpdateCombatState())
|
||||
return;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
|
||||
@@ -39,6 +39,50 @@ IdleMovementGenerator::Reset(Unit& owner)
|
||||
owner.StopMoving();
|
||||
}
|
||||
|
||||
void RotateMovementGenerator::Initialize(Unit& owner)
|
||||
{
|
||||
if(owner.hasUnitState(UNIT_STAT_MOVE))
|
||||
owner.StopMoving();
|
||||
|
||||
if(owner.getVictim())
|
||||
owner.SetInFront(owner.getVictim());
|
||||
|
||||
owner.addUnitState(UNIT_STAT_ROTATING);
|
||||
|
||||
owner.AttackStop();
|
||||
}
|
||||
|
||||
bool RotateMovementGenerator::Update(Unit& owner, const uint32& diff)
|
||||
{
|
||||
float angle = owner.GetOrientation();
|
||||
if(m_direction == ROTATE_DIRECTION_LEFT)
|
||||
{
|
||||
angle += diff / m_duration * M_PI * 2;
|
||||
if(angle >= M_PI * 2 ) angle = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
angle -= diff / m_duration * M_PI * 2;
|
||||
if(angle < 0) angle = M_PI * 2;
|
||||
}
|
||||
owner.SetOrientation(angle);
|
||||
owner.SendMovementFlagUpdate(); // this is a hack. we do not have anything correct to send in the beginning
|
||||
|
||||
if(m_duration > diff)
|
||||
m_duration -= diff;
|
||||
else
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void RotateMovementGenerator::Finalize(Unit &unit)
|
||||
{
|
||||
unit.clearUnitState(UNIT_STAT_ROTATING);
|
||||
if(unit.GetTypeId() == TYPEID_UNIT)
|
||||
((Creature*)&unit)->AI()->MovementInform(ROTATE_MOTION_TYPE, 0);
|
||||
}
|
||||
|
||||
void
|
||||
DistractMovementGenerator::Initialize(Unit& owner)
|
||||
{
|
||||
|
||||
@@ -36,6 +36,22 @@ class TRINITY_DLL_SPEC IdleMovementGenerator : public MovementGenerator
|
||||
|
||||
extern IdleMovementGenerator si_idleMovement;
|
||||
|
||||
class TRINITY_DLL_SPEC RotateMovementGenerator : public MovementGenerator
|
||||
{
|
||||
public:
|
||||
explicit RotateMovementGenerator(uint32 time, RotateDirection direction) : m_duration(time), m_direction(direction) {}
|
||||
|
||||
void Initialize(Unit& owner);
|
||||
void Finalize(Unit& owner);
|
||||
void Reset(Unit& owner) { Initialize(owner); }
|
||||
bool Update(Unit& owner, const uint32& time_diff);
|
||||
MovementGeneratorType GetMovementGeneratorType() { return ROTATE_MOTION_TYPE; }
|
||||
|
||||
private:
|
||||
uint32 m_duration;
|
||||
RotateDirection m_direction;
|
||||
};
|
||||
|
||||
class TRINITY_DLL_SPEC DistractMovementGenerator : public MovementGenerator
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -511,6 +511,11 @@ void MotionMaster::MovePath(uint32 path_id, bool repeatable)
|
||||
i_owner->GetGUIDLow(), path_id, repeatable ? "YES" : "NO" );
|
||||
}
|
||||
|
||||
void MotionMaster::MoveRotate(uint32 time, RotateDirection direction)
|
||||
{
|
||||
Mutate(new RotateMovementGenerator(time, direction), MOTION_SLOT_ACTIVE);
|
||||
}
|
||||
|
||||
void MotionMaster::propagateSpeedChange()
|
||||
{
|
||||
/*Impl::container_type::iterator it = Impl::c.begin();
|
||||
|
||||
@@ -48,7 +48,8 @@ enum MovementGeneratorType
|
||||
ASSISTANCE_MOTION_TYPE= 11, // PointMovementGenerator.h (first part of flee for assistance)
|
||||
ASSISTANCE_DISTRACT_MOTION_TYPE = 12, // IdleMovementGenerator.h (second part of flee for assistance)
|
||||
TIMED_FLEEING_MOTION_TYPE = 13, // FleeingMovementGenerator.h (alt.second part of flee for assistance)
|
||||
NULL_MOTION_TYPE = 14,
|
||||
ROTATE_MOTION_TYPE = 14,
|
||||
NULL_MOTION_TYPE = 15,
|
||||
};
|
||||
|
||||
enum MovementSlot
|
||||
@@ -66,6 +67,12 @@ enum MMCleanFlag
|
||||
MMCF_RESET = 2 // Flag if need top()->Reset()
|
||||
};
|
||||
|
||||
enum RotateDirection
|
||||
{
|
||||
ROTATE_DIRECTION_LEFT,
|
||||
ROTATE_DIRECTION_RIGHT,
|
||||
};
|
||||
|
||||
// assume it is 25 yard per 0.6 second
|
||||
#define SPEED_CHARGE 42.0f
|
||||
|
||||
@@ -152,6 +159,7 @@ class TRINITY_DLL_SPEC MotionMaster //: private std::stack<MovementGenerator *>
|
||||
void MoveTaxiFlight(uint32 path, uint32 pathnode);
|
||||
void MoveDistract(uint32 time);
|
||||
void MovePath(uint32 path_id, bool repeatable);
|
||||
void MoveRotate(uint32 time, RotateDirection direction);
|
||||
|
||||
MovementGeneratorType GetCurrentMovementGeneratorType() const;
|
||||
MovementGeneratorType GetMotionSlotType(int slot) const;
|
||||
|
||||
@@ -171,8 +171,6 @@ Unit::Unit()
|
||||
// remove aurastates allowing special moves
|
||||
for(uint8 i=0; i < MAX_REACTIVE; ++i)
|
||||
m_reactiveTimer[i] = 0;
|
||||
|
||||
IsRotating = 0;
|
||||
}
|
||||
|
||||
Unit::~Unit()
|
||||
@@ -256,10 +254,7 @@ void Unit::Update( uint32 p_time )
|
||||
ModifyAuraState(AURA_STATE_HEALTHLESS_35_PERCENT, GetHealth() < GetMaxHealth()*0.35f);
|
||||
ModifyAuraState(AURA_STATE_HEALTH_ABOVE_75_PERCENT, GetHealth() > GetMaxHealth()*0.75f);
|
||||
|
||||
if(!IsUnitRotating())
|
||||
i_motionMaster.UpdateMotion(p_time);
|
||||
else
|
||||
AutoRotate(p_time);
|
||||
i_motionMaster.UpdateMotion(p_time);
|
||||
}
|
||||
|
||||
bool Unit::haveOffhandWeapon() const
|
||||
@@ -503,43 +498,6 @@ void Unit::GetRandomContactPoint( const Unit* obj, float &x, float &y, float &z,
|
||||
, GetAngle(obj) + (attacker_number ? (M_PI/2 - M_PI * rand_norm()) * (float)attacker_number / combat_reach * 0.3 : 0));
|
||||
}
|
||||
|
||||
void Unit::StartAutoRotate(uint8 type, uint32 fulltime)
|
||||
{
|
||||
if(getVictim())
|
||||
RotateAngle = GetAngle(getVictim());
|
||||
else
|
||||
RotateAngle = GetOrientation();
|
||||
RotateTimer = fulltime;
|
||||
RotateTimerFull = fulltime;
|
||||
IsRotating = type;
|
||||
LastTargetGUID = GetUInt64Value(UNIT_FIELD_TARGET);
|
||||
SetUInt64Value(UNIT_FIELD_TARGET, 0);
|
||||
}
|
||||
|
||||
void Unit::AutoRotate(uint32 time)
|
||||
{
|
||||
if(!IsRotating)return;
|
||||
if(IsRotating == CREATURE_ROTATE_LEFT)
|
||||
{
|
||||
RotateAngle += (double)time/RotateTimerFull*(double)M_PI*2;
|
||||
if (RotateAngle >= M_PI*2)RotateAngle = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
RotateAngle -= (double)time/RotateTimerFull*(double)M_PI*2;
|
||||
if (RotateAngle < 0)RotateAngle = M_PI*2;
|
||||
}
|
||||
SetOrientation(RotateAngle);
|
||||
StopMoving();
|
||||
if(RotateTimer <= time)
|
||||
{
|
||||
IsRotating = CREATURE_ROTATE_NONE;
|
||||
RotateAngle = 0;
|
||||
RotateTimer = RotateTimerFull;
|
||||
SetUInt64Value(UNIT_FIELD_TARGET, LastTargetGUID);
|
||||
}else RotateTimer -= time;
|
||||
}
|
||||
|
||||
void Unit::RemoveMovementImpairingAuras()
|
||||
{
|
||||
RemoveAurasWithMechanic((1<<MECHANIC_SNARE)|(1<<MECHANIC_ROOT));
|
||||
@@ -3468,12 +3426,6 @@ bool Unit::isInFrontInMap(Unit const* target, float distance, float arc) const
|
||||
return IsWithinDistInMap(target, distance) && HasInArc( arc, target );
|
||||
}
|
||||
|
||||
void Unit::SetInFront(Unit const* target)
|
||||
{
|
||||
if(!IsUnitRotating())
|
||||
SetOrientation(GetAngle(target));
|
||||
}
|
||||
|
||||
bool Unit::isInBackInMap(Unit const* target, float distance, float arc) const
|
||||
{
|
||||
return IsWithinDistInMap(target, distance) && !HasInArc( 2 * M_PI - arc, target );
|
||||
@@ -11329,8 +11281,7 @@ Unit* Creature::SelectVictim()
|
||||
|
||||
if(target)
|
||||
{
|
||||
if(!hasUnitState(UNIT_STAT_STUNNED))
|
||||
SetInFront(target);
|
||||
SetInFront(target);
|
||||
return target;
|
||||
}
|
||||
|
||||
|
||||
@@ -454,13 +454,14 @@ enum UnitState
|
||||
UNIT_STAT_JUMPING = 0x00040000,
|
||||
UNIT_STAT_ONVEHICLE = 0x00080000,
|
||||
UNIT_STAT_MOVE = 0x00100000,
|
||||
//UNIT_STAT_WALK = 0x00200000,
|
||||
UNIT_STAT_ROTATING = 0x00200000,
|
||||
UNIT_STAT_UNATTACKABLE = (UNIT_STAT_IN_FLIGHT | UNIT_STAT_ONVEHICLE),
|
||||
UNIT_STAT_MOVING = (UNIT_STAT_ROAMING | UNIT_STAT_CHASE),
|
||||
UNIT_STAT_CONTROLLED = (UNIT_STAT_CONFUSED | UNIT_STAT_STUNNED | UNIT_STAT_FLEEING),
|
||||
UNIT_STAT_LOST_CONTROL = (UNIT_STAT_CONTROLLED | UNIT_STAT_JUMPING | UNIT_STAT_CHARGING),
|
||||
UNIT_STAT_SIGHTLESS = (UNIT_STAT_LOST_CONTROL),
|
||||
UNIT_STAT_CANNOT_AUTOATTACK = (UNIT_STAT_LOST_CONTROL | UNIT_STAT_CASTING),
|
||||
UNIT_STAT_CANNOT_TURN = (UNIT_STAT_LOST_CONTROL | UNIT_STAT_ROTATING),
|
||||
UNIT_STAT_ALL_STATE = 0xffffffff //(UNIT_STAT_STOPPED | UNIT_STAT_MOVING | UNIT_STAT_IN_COMBAT | UNIT_STAT_IN_FLIGHT)
|
||||
};
|
||||
|
||||
@@ -958,13 +959,6 @@ enum ActionBarIndex
|
||||
ACTION_BAR_INDEX_END = 10,
|
||||
};
|
||||
|
||||
enum Rotation
|
||||
{
|
||||
CREATURE_ROTATE_NONE = 0,
|
||||
CREATURE_ROTATE_LEFT = 1,
|
||||
CREATURE_ROTATE_RIGHT = 2
|
||||
};
|
||||
|
||||
#define MAX_UNIT_ACTION_BAR_INDEX (ACTION_BAR_INDEX_END-ACTION_BAR_INDEX_START)
|
||||
|
||||
struct CharmInfo
|
||||
@@ -1089,9 +1083,6 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
|
||||
void GetRandomContactPoint( const Unit* target, float &x, float &y, float &z, float distance2dMin, float distance2dMax ) const;
|
||||
uint32 m_extraAttacks;
|
||||
bool m_canDualWield;
|
||||
void StartAutoRotate(uint8 type, uint32 fulltime);
|
||||
void AutoRotate(uint32 time);
|
||||
bool IsUnitRotating() {return IsRotating;}
|
||||
|
||||
void _addAttacker(Unit *pAttacker) // must be called only from Unit::Attack(Unit*)
|
||||
{
|
||||
@@ -1117,12 +1108,7 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
|
||||
void RemoveAllAttackers();
|
||||
AttackerSet const& getAttackers() const { return m_attackers; }
|
||||
bool isAttackingPlayer() const;
|
||||
Unit* getVictim() const
|
||||
{
|
||||
if(IsRotating)return NULL;
|
||||
return m_attacking;
|
||||
}
|
||||
|
||||
Unit* getVictim() const { return m_attacking; }
|
||||
|
||||
void CombatStop(bool includingCast = false);
|
||||
void CombatStopWithPets(bool includingCast = false);
|
||||
@@ -1595,7 +1581,11 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
|
||||
void SetBaseWeaponDamage(WeaponAttackType attType ,WeaponDamageRange damageRange, float value) { m_weaponDamage[attType][damageRange] = value; }
|
||||
|
||||
bool isInFrontInMap(Unit const* target,float distance, float arc = M_PI) const;
|
||||
void SetInFront(Unit const* target);
|
||||
void SetInFront(Unit const* target)
|
||||
{
|
||||
if(!hasUnitState(UNIT_STAT_CANNOT_TURN))
|
||||
SetOrientation(GetAngle(target));
|
||||
}
|
||||
bool isInBackInMap(Unit const* target, float distance, float arc = M_PI) const;
|
||||
|
||||
// Visibility system
|
||||
@@ -1975,12 +1965,6 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
|
||||
|
||||
uint32 m_reducedThreatPercent;
|
||||
uint64 m_misdirectionTargetGUID;
|
||||
|
||||
uint8 IsRotating;//0none 1left 2right
|
||||
uint32 RotateTimer;
|
||||
uint32 RotateTimerFull;
|
||||
double RotateAngle;
|
||||
uint64 LastTargetGUID;
|
||||
};
|
||||
|
||||
namespace Trinity
|
||||
|
||||
@@ -1202,10 +1202,6 @@
|
||||
RelativePath="..\..\src\game\Totem.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\game\Traveller.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\game\Unit.cpp"
|
||||
>
|
||||
@@ -1329,6 +1325,10 @@
|
||||
RelativePath="..\..\src\game\TargetedMovementGenerator.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\game\Traveller.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\game\WaypointMovementGenerator.cpp"
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user