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:
Shauren
2012-05-31 19:45:11 +02:00
parent 851f43b0a6
commit 425eeb8280
14 changed files with 146 additions and 58 deletions
+2 -4
View File
@@ -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);
+2 -2
View File
@@ -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();