Core/Movement
* Implemented creature movement on transports * Set minimum speed for creature allowed to start movement (too low speed leads to overflows in movement time calculations which in turn leads to crashes)
This commit is contained in:
@@ -298,7 +298,7 @@ void MotionMaster::MovePoint(uint32 id, float x, float y, float z)
|
||||
}
|
||||
}
|
||||
|
||||
void MotionMaster::MoveLand(uint32 id, Position const& pos, float speed)
|
||||
void MotionMaster::MoveLand(uint32 id, Position const& pos)
|
||||
{
|
||||
float x, y, z;
|
||||
pos.GetPosition(x, y, z);
|
||||
@@ -307,13 +307,12 @@ void MotionMaster::MoveLand(uint32 id, Position const& pos, float speed)
|
||||
|
||||
Movement::MoveSplineInit init(*_owner);
|
||||
init.MoveTo(x,y,z);
|
||||
init.SetVelocity(speed);
|
||||
init.SetAnimation(Movement::ToGround);
|
||||
init.Launch();
|
||||
Mutate(new EffectMovementGenerator(id), MOTION_SLOT_ACTIVE);
|
||||
}
|
||||
|
||||
void MotionMaster::MoveTakeoff(uint32 id, Position const& pos, float speed)
|
||||
void MotionMaster::MoveTakeoff(uint32 id, Position const& pos)
|
||||
{
|
||||
float x, y, z;
|
||||
pos.GetPosition(x, y, z);
|
||||
@@ -322,7 +321,6 @@ void MotionMaster::MoveTakeoff(uint32 id, Position const& pos, float speed)
|
||||
|
||||
Movement::MoveSplineInit init(*_owner);
|
||||
init.MoveTo(x,y,z);
|
||||
init.SetVelocity(speed);
|
||||
init.SetAnimation(Movement::ToFly);
|
||||
init.Launch();
|
||||
Mutate(new EffectMovementGenerator(id), MOTION_SLOT_ACTIVE);
|
||||
|
||||
@@ -157,8 +157,8 @@ class MotionMaster //: private std::stack<MovementGenerator *>
|
||||
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 MoveLand(uint32 id, Position const& pos);
|
||||
void MoveTakeoff(uint32 id, Position const& pos);
|
||||
|
||||
void MoveCharge(float x, float y, float z, float speed = SPEED_CHARGE, uint32 id = EVENT_CHARGE);
|
||||
void MoveKnockbackFrom(float srcX, float srcY, float speedXY, float speedZ);
|
||||
|
||||
@@ -203,7 +203,7 @@ bool MoveSplineInitArgs::Validate() const
|
||||
return false;\
|
||||
}
|
||||
CHECK(path.size() > 1);
|
||||
CHECK(velocity > 0.f);
|
||||
CHECK(velocity > 0.1f);
|
||||
CHECK(time_perc >= 0.f && time_perc <= 1.f);
|
||||
//CHECK(_checkPathBounds());
|
||||
return true;
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
#include "MoveSpline.h"
|
||||
#include "MovementPacketBuilder.h"
|
||||
#include "Unit.h"
|
||||
#include "Transport.h"
|
||||
#include "Vehicle.h"
|
||||
|
||||
namespace Movement
|
||||
{
|
||||
@@ -58,17 +60,25 @@ namespace Movement
|
||||
{
|
||||
MoveSpline& move_spline = *unit.movespline;
|
||||
|
||||
Location real_position(unit.GetPositionX(),unit.GetPositionY(),unit.GetPositionZMinusOffset(),unit.GetOrientation());
|
||||
// there is a big chane that current position is unknown if current state is not finalized, need compute it
|
||||
bool transport = false;
|
||||
Location real_position(unit.GetPositionX(), unit.GetPositionY(), unit.GetPositionZMinusOffset(), unit.GetOrientation());
|
||||
if (unit.HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT))
|
||||
{
|
||||
transport = true;
|
||||
real_position.x = unit.GetTransOffsetX();
|
||||
real_position.y = unit.GetTransOffsetY();
|
||||
real_position.z = unit.GetTransOffsetZ();
|
||||
real_position.orientation = unit.GetTransOffsetO();
|
||||
}
|
||||
|
||||
// there is a big chance that current position is unknown if current state is not finalized, need compute it
|
||||
// this also allows calculate spline position and update map position in much greater intervals
|
||||
if (!move_spline.Finalized())
|
||||
real_position = move_spline.ComputePosition();
|
||||
|
||||
// should i do the things that user should do? - no.
|
||||
if (args.path.empty())
|
||||
{
|
||||
// should i do the things that user should do?
|
||||
MoveTo(real_position);
|
||||
}
|
||||
return;
|
||||
|
||||
// corrent first vertex
|
||||
args.path[0] = real_position;
|
||||
@@ -82,7 +92,7 @@ namespace Movement
|
||||
|
||||
moveFlags |= (MOVEMENTFLAG_SPLINE_ENABLED|MOVEMENTFLAG_FORWARD);
|
||||
|
||||
if (args.velocity == 0.f)
|
||||
if (!args.HasVelocity)
|
||||
args.velocity = unit.GetSpeed(SelectSpeedType(moveFlags));
|
||||
|
||||
if (!args.Validate())
|
||||
@@ -94,8 +104,20 @@ namespace Movement
|
||||
unit.m_movementInfo.SetMovementFlags((MovementFlags)moveFlags);
|
||||
move_spline.Initialize(args);
|
||||
|
||||
WorldPacket data(SMSG_MONSTER_MOVE, 64);
|
||||
WorldPacket data(!transport ? SMSG_MONSTER_MOVE : SMSG_MONSTER_MOVE_TRANSPORT, 64);
|
||||
data.append(unit.GetPackGUID());
|
||||
if (transport)
|
||||
{
|
||||
if (unit.GetVehicle())
|
||||
data.appendPackGUID(unit.GetVehicleBase()->GetGUID());
|
||||
else if (unit.GetTransport())
|
||||
data.appendPackGUID(unit.GetTransGUID());
|
||||
else
|
||||
data << uint8(0);
|
||||
|
||||
data << int8(unit.GetTransSeat());
|
||||
}
|
||||
|
||||
PacketBuilder::WriteMonsterMove(move_spline, data);
|
||||
unit.SendMessageToSet(&data,true);
|
||||
}
|
||||
@@ -119,4 +141,33 @@ namespace Movement
|
||||
args.facing.angle = G3D::wrap(angle, 0.f, (float)G3D::twoPi());
|
||||
args.flags.EnableFacingAngle();
|
||||
}
|
||||
|
||||
void MoveSplineInit::MoveTo(Vector3 const& dest)
|
||||
{
|
||||
args.path_Idx_offset = 0;
|
||||
args.path.resize(2);
|
||||
TransportPathTransform transform(unit);
|
||||
args.path[1] = transform(dest);
|
||||
}
|
||||
|
||||
Vector3 TransportPathTransform::operator()(Vector3 input)
|
||||
{
|
||||
if (_owner.HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT))
|
||||
{
|
||||
if (Unit* vehicle = _owner.GetVehicleBase())
|
||||
{
|
||||
input.x -= vehicle->GetPositionX();
|
||||
input.y -= vehicle->GetPositionY();
|
||||
input.z -= vehicle->GetPositionZMinusOffset();
|
||||
}
|
||||
else if (Transport* transport = _owner.GetTransport())
|
||||
{
|
||||
float unused = 0.0f;
|
||||
transport->CalculatePassengerOffset(input.x, input.y, input.z, unused);
|
||||
}
|
||||
}
|
||||
|
||||
return input;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -33,6 +33,17 @@ namespace Movement
|
||||
FlyToGround = 3, // 463 = FlyToGround
|
||||
};
|
||||
|
||||
// Transforms coordinates from global to transport offsets
|
||||
class TransportPathTransform
|
||||
{
|
||||
public:
|
||||
TransportPathTransform(Unit& owner) : _owner(owner) { }
|
||||
Vector3 operator()(Vector3 input);
|
||||
|
||||
private:
|
||||
Unit& _owner;
|
||||
};
|
||||
|
||||
/* Initializes and launches spline movement
|
||||
*/
|
||||
class MoveSplineInit
|
||||
@@ -123,14 +134,15 @@ namespace Movement
|
||||
inline void MoveSplineInit::SetSmooth() { args.flags.EnableCatmullRom();}
|
||||
inline void MoveSplineInit::SetCyclic() { args.flags.cyclic = true;}
|
||||
inline void MoveSplineInit::SetFall() { args.flags.EnableFalling();}
|
||||
inline void MoveSplineInit::SetVelocity(float vel){ args.velocity = vel;}
|
||||
inline void MoveSplineInit::SetVelocity(float vel) { args.velocity = vel; args.HasVelocity = true; }
|
||||
inline void MoveSplineInit::SetOrientationInversed() { args.flags.orientationInversed = true;}
|
||||
inline void MoveSplineInit::SetOrientationFixed(bool enable) { args.flags.orientationFixed = enable;}
|
||||
|
||||
inline void MoveSplineInit::MovebyPath(const PointsArray& controls, int32 path_offset)
|
||||
{
|
||||
args.path_Idx_offset = path_offset;
|
||||
args.path.assign(controls.begin(),controls.end());
|
||||
args.path.resize(controls.size());
|
||||
std::transform(controls.begin(), controls.end(), args.path.begin(), TransportPathTransform(unit));
|
||||
}
|
||||
|
||||
inline void MoveSplineInit::MoveTo(float x, float y, float z)
|
||||
@@ -139,13 +151,6 @@ namespace Movement
|
||||
MoveTo(v);
|
||||
}
|
||||
|
||||
inline void MoveSplineInit::MoveTo(const Vector3& dest)
|
||||
{
|
||||
args.path_Idx_offset = 0;
|
||||
args.path.resize(2);
|
||||
args.path[1] = dest;
|
||||
}
|
||||
|
||||
inline void MoveSplineInit::SetParabolic(float amplitude, float time_shift)
|
||||
{
|
||||
args.time_perc = time_shift;
|
||||
|
||||
@@ -42,7 +42,7 @@ namespace Movement
|
||||
struct MoveSplineInitArgs
|
||||
{
|
||||
MoveSplineInitArgs(size_t path_capacity = 16) : path_Idx_offset(0),
|
||||
velocity(0.f), parabolic_amplitude(0.f), time_perc(0.f), splineId(0), initialOrientation(0.f)
|
||||
velocity(0.f), parabolic_amplitude(0.f), time_perc(0.f), splineId(0), initialOrientation(0.f), HasVelocity(false)
|
||||
{
|
||||
path.reserve(path_capacity);
|
||||
}
|
||||
@@ -56,6 +56,7 @@ namespace Movement
|
||||
float time_perc;
|
||||
uint32 splineId;
|
||||
float initialOrientation;
|
||||
bool HasVelocity;
|
||||
|
||||
/** Returns true to show that the arguments were configured correctly and MoveSpline initialization will succeed. */
|
||||
bool Validate() const;
|
||||
|
||||
@@ -44,20 +44,8 @@ namespace Movement
|
||||
void PacketBuilder::WriteCommonMonsterMovePart(const MoveSpline& move_spline, WorldPacket& data)
|
||||
{
|
||||
MoveSplineFlag splineflags = move_spline.splineflags;
|
||||
/*if (unit->HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT))
|
||||
{
|
||||
data.SetOpcode(SMSG_MONSTER_MOVE_TRANSPORT);
|
||||
if (unit->GetVehicle())
|
||||
data << unit->GetVehicle()->GetBase()->GetPackGUID();
|
||||
else if (unit->GetTransport())
|
||||
data << unit->GetTransport()->GetPackGUID();
|
||||
else
|
||||
data << uint64(0);
|
||||
|
||||
data << int8(unit->GetTransSeat());
|
||||
}*/
|
||||
|
||||
data << uint8(0);
|
||||
data << uint8(0); // sets/unsets MOVEMENTFLAG2_UNK7 (0x40)
|
||||
data << move_spline.spline.getPoint(move_spline.spline.first());
|
||||
data << move_spline.GetId();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user