Core/Movement: Implemented methods to animate creatures landing and takeoff and use them in Sindragosa script

This commit is contained in:
Shauren
2011-07-27 12:40:14 +02:00
parent b9a6e2333c
commit 3e5aa2d1ff
6 changed files with 151 additions and 61 deletions
+30 -12
View File
@@ -456,29 +456,36 @@ void Unit::SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint32 T
AddUnitState(UNIT_STAT_MOVE);
}
void Unit::SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint32 MoveFlags, uint32 time, float speedZ, Player* player)
void Unit::SendMonsterMove(MonsterMoveData const& moveData, Player* player)
{
WorldPacket data(SMSG_MONSTER_MOVE, 12+4+1+4+4+4+12+GetPackGUID().size());
WorldPacket data(SMSG_MONSTER_MOVE, GetPackGUID().size() + 1 + 12 + 4 + 1 + 4 + 8 + 4 + 4 + 12);
data.append(GetPackGUID());
data << uint8(0); // new in 3.1
data << uint8(0); // new in 3.1
data << GetPositionX() << GetPositionY() << GetPositionZ();
data << getMSTime();
data << uint8(0);
data << MoveFlags;
data << moveData.SplineFlag;
if (MoveFlags & SPLINEFLAG_TRAJECTORY)
if (moveData.SplineFlag & SPLINEFLAG_ANIMATIONTIER)
{
data << time;
data << speedZ;
data << (uint32)0; // walk time after jump
data << uint8(moveData.AnimationState);
data << uint32(0);
}
else
data << time;
data << uint32(1); // 1 single waypoint
data << NewPosX << NewPosY << NewPosZ; // the single waypoint Point B
data << moveData.Time;
if (moveData.SplineFlag & SPLINEFLAG_TRAJECTORY)
{
data << moveData.SpeedZ;
data << uint32(0); // walk time after jump
}
data << uint32(1); // waypoint count
data << moveData.DestLocation.GetPositionX();
data << moveData.DestLocation.GetPositionY();
data << moveData.DestLocation.GetPositionZ();
if (player)
player->GetSession()->SendPacket(&data);
@@ -486,6 +493,17 @@ void Unit::SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint32 M
SendMessageToSet(&data, true);
}
void Unit::SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint32 MoveFlags, uint32 time, float speedZ, Player* player)
{
MonsterMoveData data;
data.DestLocation.Relocate(NewPosX, NewPosY, NewPosZ);
data.SplineFlag = MoveFlags;
data.Time = time;
data.SpeedZ = speedZ;
SendMonsterMove(data, player);
}
void Unit::SendMonsterMoveExitVehicle(Position const* newPos)
{
WorldPacket data(SMSG_MONSTER_MOVE, 1+12+4+1+4+4+4+12+GetPackGUID().size());
+21 -2
View File
@@ -667,7 +667,7 @@ enum MovementFlags
// TODO: Check if PITCH_UP and PITCH_DOWN really belong here..
MOVEMENTFLAG_MASK_MOVING =
MOVEMENTFLAG_FORWARD | MOVEMENTFLAG_BACKWARD | MOVEMENTFLAG_STRAFE_LEFT | MOVEMENTFLAG_STRAFE_RIGHT |
MOVEMENTFLAG_PITCH_UP | MOVEMENTFLAG_PITCH_DOWN | MOVEMENTFLAG_JUMPING | MOVEMENTFLAG_FALLING | MOVEMENTFLAG_ASCENDING | MOVEMENTFLAG_DESCENDING |
MOVEMENTFLAG_PITCH_UP | MOVEMENTFLAG_PITCH_DOWN | MOVEMENTFLAG_JUMPING | MOVEMENTFLAG_FALLING | MOVEMENTFLAG_ASCENDING | MOVEMENTFLAG_DESCENDING |
MOVEMENTFLAG_SPLINE_ELEVATION,
MOVEMENTFLAG_MASK_TURNING =
@@ -717,7 +717,7 @@ enum SplineFlags
SPLINEFLAG_CATMULL_ROM = 0x00040000,
SPLINEFLAG_UNKNOWN20 = 0x00080000,
SPLINEFLAG_UNKNOWN21 = 0x00100000,
SPLINEFLAG_UNKNOWN22 = 0x00200000,
SPLINEFLAG_ANIMATIONTIER = 0x00200000,
SPLINEFLAG_UNKNOWN23 = 0x00400000,
SPLINEFLAG_TRANSPORT = 0x00800000,
SPLINEFLAG_EXIT_VEHICLE = 0x01000000,
@@ -953,6 +953,24 @@ struct SpellPeriodicAuraLogInfo
uint32 createProcExtendMask(SpellNonMeleeDamage *damageInfo, SpellMissInfo missCondition);
enum UnitAnimationState
{
ANIMATION_ON_GROUND = 0,
ANIMATION_SWIMMING = 1,
ANIMATION_HOVER = 2,
ANIMATION_FLYING = 3,
};
struct MonsterMoveData
{
MonsterMoveData() : SplineFlag(0), AnimationState(ANIMATION_ON_GROUND), Time(0), SpeedZ(0.0f) {}
Position DestLocation;
uint32 SplineFlag;
UnitAnimationState AnimationState; // Only used with SPLINEFLAG_ANIMATIONTIER
uint32 Time;
float SpeedZ; // Only used with SPLINEFLAG_TRAJECTORY
};
#define MAX_DECLINED_NAME_CASES 5
struct DeclinedName
@@ -1555,6 +1573,7 @@ class Unit : public WorldObject
void SendMonsterStop(bool on_death = false);
void SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint32 Time, Player* player = NULL);
void SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint32 MoveFlags, uint32 time, float speedZ, Player* player = NULL);
void SendMonsterMove(MonsterMoveData const& moveData, Player* receiver = NULL);
void SendMonsterMoveExitVehicle(Position const* newPos);
//void SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint8 type, uint32 MovementFlags, uint32 Time, Player* player = NULL);
void SendMonsterMoveTransport(Unit *vehicleOwner);
+70 -36
View File
@@ -37,8 +37,7 @@ inline bool isStatic(MovementGenerator *mv)
return (mv == &si_idleMovement);
}
void
MotionMaster::Initialize()
void MotionMaster::Initialize()
{
// clear ALL movement generators (including default)
while (!empty())
@@ -76,8 +75,7 @@ MotionMaster::~MotionMaster()
}
}
void
MotionMaster::UpdateMotion(uint32 diff)
void MotionMaster::UpdateMotion(uint32 diff)
{
if (i_owner->HasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED)) // what about UNIT_STAT_DISTRACTED? Why is this not included?
return;
@@ -113,8 +111,7 @@ MotionMaster::UpdateMotion(uint32 diff)
}
}
void
MotionMaster::DirectClean(bool reset)
void MotionMaster::DirectClean(bool reset)
{
while (size() > 1)
{
@@ -129,8 +126,7 @@ MotionMaster::DirectClean(bool reset)
top()->Reset(*i_owner);
}
void
MotionMaster::DelayedClean()
void MotionMaster::DelayedClean()
{
while (size() > 1)
{
@@ -141,8 +137,7 @@ MotionMaster::DelayedClean()
}
}
void
MotionMaster::DirectExpire(bool reset)
void MotionMaster::DirectExpire(bool reset)
{
if (size() > 1)
{
@@ -162,8 +157,7 @@ MotionMaster::DirectExpire(bool reset)
top()->Reset(*i_owner);
}
void
MotionMaster::DelayedExpire()
void MotionMaster::DelayedExpire()
{
if (size() > 1)
{
@@ -184,8 +178,7 @@ void MotionMaster::MoveIdle(MovementSlot slot)
Mutate(&si_idleMovement, slot);
}
void
MotionMaster::MoveRandom(float spawndist)
void MotionMaster::MoveRandom(float spawndist)
{
if (i_owner->GetTypeId() == TYPEID_UNIT)
{
@@ -194,8 +187,7 @@ MotionMaster::MoveRandom(float spawndist)
}
}
void
MotionMaster::MoveTargetedHome()
void MotionMaster::MoveTargetedHome()
{
//if (i_owner->HasUnitState(UNIT_STAT_FLEEING))
// return;
@@ -213,8 +205,7 @@ MotionMaster::MoveTargetedHome()
}
}
void
MotionMaster::MoveConfused()
void MotionMaster::MoveConfused()
{
if (i_owner->GetTypeId() == TYPEID_PLAYER)
{
@@ -229,8 +220,7 @@ MotionMaster::MoveConfused()
}
}
void
MotionMaster::MoveChase(Unit* target, float dist, float angle)
void MotionMaster::MoveChase(Unit* target, float dist, float angle)
{
// ignore movement request if target not exist
if (!target || target == i_owner || i_owner->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE))
@@ -255,8 +245,7 @@ MotionMaster::MoveChase(Unit* target, float dist, float angle)
}
}
void
MotionMaster::MoveFollow(Unit* target, float dist, float angle, MovementSlot slot)
void MotionMaster::MoveFollow(Unit* target, float dist, float angle, MovementSlot slot)
{
// ignore movement request if target not exist
if (!target || target == i_owner || i_owner->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE))
@@ -280,8 +269,7 @@ MotionMaster::MoveFollow(Unit* target, float dist, float angle, MovementSlot slo
}
}
void
MotionMaster::MovePoint(uint32 id, float x, float y, float z)
void MotionMaster::MovePoint(uint32 id, float x, float y, float z)
{
if (i_owner->GetTypeId() == TYPEID_PLAYER)
{
@@ -296,6 +284,58 @@ MotionMaster::MovePoint(uint32 id, float x, float y, float z)
}
}
void MotionMaster::MoveLand(uint32 id, Position const& pos, float speed)
{
if (i_owner->GetTypeId() != TYPEID_UNIT)
return;
uint32 moveFlag = SPLINEFLAG_FLYING | SPLINEFLAG_ANIMATIONTIER;
uint32 moveTime = uint32(i_owner->GetExactDist(&pos) / speed) * IN_MILLISECONDS;
// CHARGING state makes the unit use m_TempSpeed and JUMPING prevents sending movement packet in PointMovementGenerator
i_owner->AddUnitState(UNIT_STAT_CHARGING | UNIT_STAT_JUMPING);
i_owner->m_TempSpeed = speed;
float x, y, z;
pos.GetPosition(x, y, z);
sLog->outStaticDebug("Creature (Entry: %u) landing point (ID: %u X: %f Y: %f Z: %f)", i_owner->GetEntry(), id, x, y, z);
Mutate(new PointMovementGenerator<Creature>(id, x, y, z), MOTION_SLOT_ACTIVE);
MonsterMoveData data;
data.DestLocation.Relocate(pos);
data.SplineFlag = moveFlag;
data.Time = moveTime;
data.AnimationState = ANIMATION_ON_GROUND;
i_owner->SendMonsterMove(data);
}
void MotionMaster::MoveTakeoff(uint32 id, Position const& pos, float speed)
{
if (i_owner->GetTypeId() != TYPEID_UNIT)
return;
uint32 moveFlag = SPLINEFLAG_FLYING | SPLINEFLAG_ANIMATIONTIER;
uint32 moveTime = uint32(i_owner->GetExactDist(&pos) / speed) * IN_MILLISECONDS;
// CHARGING state makes the unit use m_TempSpeed and JUMPING prevents sending movement packet in PointMovementGenerator
i_owner->AddUnitState(UNIT_STAT_CHARGING | UNIT_STAT_JUMPING);
i_owner->m_TempSpeed = speed;
float x, y, z;
pos.GetPosition(x, y, z);
sLog->outStaticDebug("Creature (Entry: %u) landing point (ID: %u X: %f Y: %f Z: %f)", i_owner->GetEntry(), id, x, y, z);
Mutate(new PointMovementGenerator<Creature>(id, x, y, z), MOTION_SLOT_ACTIVE);
MonsterMoveData data;
data.DestLocation.Relocate(pos);
data.SplineFlag = moveFlag;
data.Time = moveTime;
data.AnimationState = ANIMATION_FLYING;
i_owner->SendMonsterMove(data);
}
void MotionMaster::MoveKnockbackFrom(float srcX, float srcY, float speedXY, float speedZ)
{
//this function may make players fall below map
@@ -346,8 +386,7 @@ void MotionMaster::MoveJump(float x, float y, float z, float speedXY, float spee
i_owner->SendMonsterMove(x, y, z, moveFlag, time, speedZ);
}
void
MotionMaster::MoveCharge(float x, float y, float z, float speed, uint32 id)
void MotionMaster::MoveCharge(float x, float y, float z, float speed, uint32 id)
{
if (Impl[MOTION_SLOT_CONTROLLED] && Impl[MOTION_SLOT_CONTROLLED]->GetMovementGeneratorType() != DISTRACT_MOTION_TYPE)
return;
@@ -375,8 +414,7 @@ void MotionMaster::MoveFall(float z, uint32 id)
MoveCharge(i_owner->GetPositionX(), i_owner->GetPositionY(), z, SPEED_CHARGE, id);
}
void
MotionMaster::MoveSeekAssistance(float x, float y, float z)
void MotionMaster::MoveSeekAssistance(float x, float y, float z)
{
if (i_owner->GetTypeId() == TYPEID_PLAYER)
{
@@ -392,8 +430,7 @@ MotionMaster::MoveSeekAssistance(float x, float y, float z)
}
}
void
MotionMaster::MoveSeekAssistanceDistract(uint32 time)
void MotionMaster::MoveSeekAssistanceDistract(uint32 time)
{
if (i_owner->GetTypeId() == TYPEID_PLAYER)
{
@@ -407,8 +444,7 @@ MotionMaster::MoveSeekAssistanceDistract(uint32 time)
}
}
void
MotionMaster::MoveFleeing(Unit* enemy, uint32 time)
void MotionMaster::MoveFleeing(Unit* enemy, uint32 time)
{
if (!enemy)
return;
@@ -437,8 +473,7 @@ MotionMaster::MoveFleeing(Unit* enemy, uint32 time)
}
}
void
MotionMaster::MoveTaxiFlight(uint32 path, uint32 pathnode)
void MotionMaster::MoveTaxiFlight(uint32 path, uint32 pathnode)
{
if (i_owner->GetTypeId() == TYPEID_PLAYER)
{
@@ -461,8 +496,7 @@ MotionMaster::MoveTaxiFlight(uint32 path, uint32 pathnode)
}
}
void
MotionMaster::MoveDistract(uint32 timer)
void MotionMaster::MoveDistract(uint32 timer)
{
if (Impl[MOTION_SLOT_CONTROLLED])
return;
+5
View File
@@ -152,6 +152,11 @@ class MotionMaster //: private std::stack<MovementGenerator *>
void MovePoint(uint32 id, const Position &pos)
{ MovePoint(id, pos.m_positionX, pos.m_positionY, pos.m_positionZ); }
void MovePoint(uint32 id, float x, float y, float z);
// These two movement types should only be used with creatures having landing/takeoff animations
void MoveLand(uint32 id, Position const& pos, float speed);
void MoveTakeoff(uint32 id, Position const& pos, float speed);
void MoveCharge(float x, float y, float z, float speed = SPEED_CHARGE, uint32 id = EVENT_CHARGE);
void MoveFall(float z, uint32 id = 0);
void MoveKnockbackFrom(float srcX, float srcY, float speedXY, float speedZ);
@@ -29,8 +29,9 @@ void PointMovementGenerator<T>::Initialize(T &unit)
{
unit.StopMoving();
Traveller<T> traveller(unit);
// knockback effect has UNIT_STAT_JUMPING set, so if here we disable sentmonstermove there will be creature position sync problem between client and server
i_destinationHolder.SetDestination(traveller, i_x, i_y, i_z, true /* !unit.HasUnitState(UNIT_STAT_JUMPING)*/);
// OLD: knockback effect has UNIT_STAT_JUMPING set, so if here we disable sentmonstermove there will be creature position sync problem between client and server
// NEW: reactivated this check - UNIT_STAT_JUMPING is only used in MoveJump, which sends its own packet
i_destinationHolder.SetDestination(traveller, i_x, i_y, i_z, /*true*/ !unit.HasUnitState(UNIT_STAT_JUMPING));
}
template<class T>