Core/Movement: sync spline code with master branch
This commit is contained in:
1 parent
dfa6f7a709
commit
770f9e11db
10 files changed
+143
-138
No files matched your search
@@ -542,9 +542,8 @@ void Unit::UpdateSplineMovement(uint32 t_diff)
|
||||
if (arrived)
|
||||
{
|
||||
DisableSpline();
|
||||
|
||||
if (movespline->HasAnimation())
|
||||
SetAnimationTier(movespline->GetAnimationTier());
|
||||
if (Optional<AnimationTier> animTier = movespline->GetAnimation())
|
||||
SetAnimationTier(*animTier);
|
||||
}
|
||||
|
||||
UpdateSplinePosition();
|
||||
@@ -564,6 +563,8 @@ void Unit::UpdateSplinePosition()
|
||||
|
||||
if (TransportBase* transport = GetDirectTransport())
|
||||
transport->CalculatePassengerPosition(loc.x, loc.y, loc.z, &loc.orientation);
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
if (HasUnitState(UNIT_STATE_CANNOT_TURN))
|
||||
@@ -13649,6 +13650,21 @@ void Unit::SetFacingToObject(WorldObject const* object, bool force)
|
||||
init.Launch();
|
||||
}
|
||||
|
||||
void Unit::SetFacingToPoint(Position const& point, bool force)
|
||||
{
|
||||
// do not face when already moving
|
||||
if (!force && (!IsStopped() || !movespline->Finalized()))
|
||||
return;
|
||||
|
||||
/// @todo figure out under what conditions creature will move towards object instead of facing it where it currently is.
|
||||
Movement::MoveSplineInit init(this);
|
||||
init.MoveTo(GetPositionX(), GetPositionY(), GetPositionZ(), false);
|
||||
if (GetTransport())
|
||||
init.DisableTransportPathTransformations(); // It makes no sense to target global orientation
|
||||
init.SetFacing(point.GetPositionX(), point.GetPositionY(), point.GetPositionZ());
|
||||
init.Launch();
|
||||
}
|
||||
|
||||
bool Unit::SetWalk(bool enable)
|
||||
{
|
||||
if (enable == IsWalking())
|
||||
|
||||
@@ -1214,12 +1214,10 @@ class TC_GAME_API Unit : public WorldObject
|
||||
virtual bool SetHover(bool enable, bool packetOnly = false, bool updateAnimationTier = true);
|
||||
void SendSetVehicleRecId(uint32 vehicleId);
|
||||
|
||||
// Sets the internal orientation value to face the provided target. Does NOT have clientside effects.
|
||||
void SetOrientationTowards(WorldObject const* target);
|
||||
// Launches a spline to face the given orientation.
|
||||
void SetFacingTo(float const ori, bool force = true);
|
||||
// Launches a spline to face the given object
|
||||
void SetFacingToObject(WorldObject const* object, bool force = true);
|
||||
void SetFacingToPoint(Position const& point, bool force = true);
|
||||
|
||||
bool IsAlive() const { return (m_deathState == ALIVE); }
|
||||
bool isDying() const { return (m_deathState == JUST_DIED); }
|
||||
|
||||
@@ -43,21 +43,22 @@ Location MoveSpline::computePosition(int32 time_point, int32 point_index) const
|
||||
else if (splineflags.falling)
|
||||
computeFallElevation(time_point, c.z);
|
||||
|
||||
if (splineflags.done && splineflags.isFacing())
|
||||
if (splineflags.done && facing.type != MONSTER_MOVE_NORMAL)
|
||||
{
|
||||
if (splineflags.final_angle)
|
||||
if (facing.type == MONSTER_MOVE_FACING_ANGLE)
|
||||
c.orientation = facing.angle;
|
||||
else if (splineflags.final_point)
|
||||
else if (facing.type == MONSTER_MOVE_FACING_SPOT)
|
||||
c.orientation = std::atan2(facing.f.y - c.y, facing.f.x - c.x);
|
||||
//nothing to do for MoveSplineFlag::Final_Target flag
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!splineflags.hasFlag(MoveSplineFlag::OrientationFixed | MoveSplineFlag::Falling | MoveSplineFlag::Unknown0))
|
||||
if (!splineflags.hasFlag(MoveSplineFlag::OrientationFixed | MoveSplineFlag::Falling | MoveSplineFlag::Unknown_0x8))
|
||||
{
|
||||
Vector3 hermite;
|
||||
spline.evaluate_derivative(point_Idx, u, hermite);
|
||||
c.orientation = std::atan2(hermite.y, hermite.x);
|
||||
if (hermite.x != 0.f || hermite.y != 0.f)
|
||||
c.orientation = std::atan2(hermite.y, hermite.x);
|
||||
}
|
||||
|
||||
if (splineflags.backward)
|
||||
@@ -186,6 +187,9 @@ void MoveSpline::Initialize(MoveSplineInitArgs const& args)
|
||||
time_passed = 0;
|
||||
vertical_acceleration = 0.f;
|
||||
effect_start_time = 0;
|
||||
anim_tier = args.animTier;
|
||||
splineIsFacingOnly = args.path.size() == 2 && args.facing.type != MONSTER_MOVE_NORMAL && ((args.path[1] - args.path[0]).length() < 0.1f);
|
||||
|
||||
velocity = args.velocity;
|
||||
|
||||
// Check if its a stop spline
|
||||
@@ -201,12 +205,16 @@ void MoveSpline::Initialize(MoveSplineInitArgs const& args)
|
||||
// spline initialized, duration known and i able to compute parabolic acceleration
|
||||
if (args.flags & (MoveSplineFlag::Parabolic | MoveSplineFlag::Animation))
|
||||
{
|
||||
effect_start_time = Duration() * args.time_perc;
|
||||
if (args.flags.parabolic && effect_start_time < Duration())
|
||||
int32 spline_duration = Duration();
|
||||
effect_start_time = spline_duration * args.effect_start_time_percent + args.effect_start_time.count();
|
||||
if (effect_start_time > spline_duration)
|
||||
effect_start_time = spline_duration;
|
||||
|
||||
if (args.flags.parabolic && effect_start_time < spline_duration)
|
||||
{
|
||||
if (args.parabolic_amplitude != 0.0f)
|
||||
{
|
||||
float f_duration = MSToSec(Duration() - effect_start_time);
|
||||
float f_duration = MSToSec(spline_duration - effect_start_time);
|
||||
vertical_acceleration = args.parabolic_amplitude * 8.f / (f_duration * f_duration);
|
||||
}
|
||||
else if (args.vertical_acceleration != 0.0f)
|
||||
@@ -219,14 +227,15 @@ void MoveSpline::Initialize(MoveSplineInitArgs const& args)
|
||||
|
||||
MoveSpline::MoveSpline() : m_Id(0), time_passed(0),
|
||||
vertical_acceleration(0.f), initialOrientation(0.f), effect_start_time(0), point_Idx(0), point_Idx_offset(0), velocity(0.f),
|
||||
onTransport(false)
|
||||
onTransport(false), splineIsFacingOnly(false)
|
||||
{
|
||||
splineflags.done = true;
|
||||
}
|
||||
|
||||
MoveSplineInitArgs::MoveSplineInitArgs(size_t path_capacity /*= 16*/) : path_Idx_offset(0), velocity(0.f),
|
||||
parabolic_amplitude(0.f), vertical_acceleration(0.f), time_perc(0.f), splineId(0), initialOrientation(0.f), walk(false),
|
||||
HasVelocity(false), TransformForTransport(true)
|
||||
parabolic_amplitude(0.f), vertical_acceleration(0.0f), effect_start_time_percent(0.f), effect_start_time(0ms),
|
||||
splineId(0), initialOrientation(0.f),
|
||||
walk(false), HasVelocity(false), TransformForTransport(true)
|
||||
{
|
||||
path.reserve(path_capacity);
|
||||
}
|
||||
@@ -250,35 +259,22 @@ bool MoveSplineInitArgs::Validate(Unit* unit) const
|
||||
}
|
||||
CHECK(path.size() > 1);
|
||||
CHECK(velocity >= 0.01f);
|
||||
CHECK(time_perc >= 0.f && time_perc <= 1.f);
|
||||
//CHECK(_checkPathLengths());
|
||||
CHECK(effect_start_time_percent >= 0.f && effect_start_time_percent <= 1.f);
|
||||
CHECK(_checkPathLengths());
|
||||
return true;
|
||||
#undef CHECK
|
||||
}
|
||||
|
||||
// MONSTER_MOVE packet format limitation for not CatmullRom movement:
|
||||
// each vertex offset packed into 11 bytes
|
||||
bool MoveSplineInitArgs::_checkPathBounds() const
|
||||
// check path lengths - why are we even starting such short movement?
|
||||
bool MoveSplineInitArgs::_checkPathLengths() const
|
||||
{
|
||||
if (!(flags & MoveSplineFlag::Catmullrom) && path.size() > 2)
|
||||
{
|
||||
enum{
|
||||
MAX_OFFSET = (1 << 11) / 2
|
||||
};
|
||||
Vector3 middle = (path.front()+path.back()) / 2;
|
||||
Vector3 offset;
|
||||
for (uint32 i = 1; i < path.size()-1; ++i)
|
||||
{
|
||||
offset = path[i] - middle;
|
||||
if (std::fabs(offset.x) >= float(MAX_OFFSET) || std::fabs(offset.y) >= float(MAX_OFFSET) || std::fabs(offset.z) >= float(MAX_OFFSET))
|
||||
{
|
||||
TC_LOG_ERROR("misc", "MoveSplineInitArgs::_checkPathBounds check failed");
|
||||
if (path.size() > 2 || facing.type == MONSTER_MOVE_NORMAL)
|
||||
for (uint32 i = 0; i < path.size() - 1; ++i)
|
||||
if ((path[i + 1] - path[i]).length() < 0.1f)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// ============================================================================================
|
||||
|
||||
MoveSpline::UpdateResult MoveSpline::_updateState(int32& ms_time_diff)
|
||||
@@ -365,11 +361,11 @@ std::string MoveSpline::ToString() const
|
||||
str << "MoveSpline" << std::endl;
|
||||
str << "spline Id: " << GetId() << std::endl;
|
||||
str << "flags: " << splineflags.ToString() << std::endl;
|
||||
if (splineflags.final_angle)
|
||||
if (facing.type == MONSTER_MOVE_FACING_ANGLE)
|
||||
str << "facing angle: " << facing.angle;
|
||||
else if (splineflags.final_target)
|
||||
else if (facing.type == MONSTER_MOVE_FACING_TARGET)
|
||||
str << "facing target: " << facing.target.ToString();
|
||||
else if (splineflags.final_point)
|
||||
else if (facing.type == MONSTER_MOVE_FACING_SPOT)
|
||||
str << "facing point: " << facing.f.x << " " << facing.f.y << " " << facing.f.z;
|
||||
str << std::endl;
|
||||
str << "time passed: " << time_passed << std::endl;
|
||||
|
||||
@@ -82,6 +82,7 @@ namespace Movement
|
||||
int32 point_Idx;
|
||||
int32 point_Idx_offset;
|
||||
float velocity;
|
||||
Optional<AnimationTier> anim_tier;
|
||||
|
||||
void init_spline(MoveSplineInitArgs const& args);
|
||||
|
||||
@@ -141,10 +142,10 @@ namespace Movement
|
||||
int32 MaxPathIdx() const { return spline.last() - 1; }
|
||||
bool HasStarted() const { return time_passed > 0; }
|
||||
|
||||
bool HasAnimation() const { return splineflags.animation; }
|
||||
AnimationTier GetAnimationTier() const { return static_cast<AnimationTier>(splineflags.animTier); }
|
||||
Optional<AnimationTier> GetAnimation() const { return anim_tier; }
|
||||
|
||||
bool onTransport;
|
||||
bool splineIsFacingOnly;
|
||||
std::string ToString() const;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -30,13 +30,15 @@ namespace Movement
|
||||
enum eFlags
|
||||
{
|
||||
None = 0x00000000,
|
||||
// x00-x07 used as animation Ids storage in pair with Animation flag
|
||||
Unknown0 = 0x00000008, // NOT VERIFIED
|
||||
Unknown_0x1 = 0x00000001, // NOT VERIFIED
|
||||
Unknown_0x2 = 0x00000002, // NOT VERIFIED
|
||||
Unknown_0x4 = 0x00000004, // NOT VERIFIED
|
||||
Unknown_0x8 = 0x00000008, // NOT VERIFIED - does someting related to falling/fixed orientation
|
||||
FallingSlow = 0x00000010,
|
||||
Done = 0x00000020,
|
||||
Falling = 0x00000040, // Affects elevation computation, can't be combined with Parabolic flag
|
||||
No_Spline = 0x00000080,
|
||||
Unknown2 = 0x00000100, // NOT VERIFIED
|
||||
Unknown_0x100 = 0x00000100, // NOT VERIFIED
|
||||
Flying = 0x00000200, // Smooth movement(Catmullrom interpolation mode), flying animation
|
||||
OrientationFixed = 0x00000400, // Model orientation fixed
|
||||
Catmullrom = 0x00000800, // Used Catmullrom interpolation mode
|
||||
@@ -45,30 +47,28 @@ namespace Movement
|
||||
Frozen = 0x00004000, // Will never arrive
|
||||
TransportEnter = 0x00008000,
|
||||
TransportExit = 0x00010000,
|
||||
Unknown3 = 0x00020000, // NOT VERIFIED
|
||||
Unknown4 = 0x00040000, // NOT VERIFIED
|
||||
Unknown_0x20000 = 0x00020000, // NOT VERIFIED
|
||||
Unknown_0x40000 = 0x00040000, // NOT VERIFIED
|
||||
Backward = 0x00080000,
|
||||
SmoothGroundPath = 0x00100000,
|
||||
CanSwim = 0x00200000,
|
||||
UncompressedPath = 0x00400000,
|
||||
Unknown6 = 0x00800000, // NOT VERIFIED
|
||||
Unknown_0x800000 = 0x00800000, // NOT VERIFIED
|
||||
Animation = 0x01000000, // Plays animation after some time passed
|
||||
Parabolic = 0x02000000, // Affects elevation computation, can't be combined with Falling flag
|
||||
Final_Point = 0x04000000,
|
||||
Final_Target = 0x08000000,
|
||||
Final_Angle = 0x10000000,
|
||||
Unknown7 = 0x20000000, // NOT VERIFIED
|
||||
Unknown8 = 0x40000000, // NOT VERIFIED
|
||||
Unknown9 = 0x80000000, // NOT VERIFIED
|
||||
FadeObject = 0x04000000,
|
||||
Steering = 0x08000000,
|
||||
UnlimitedSpeed = 0x10000000,
|
||||
Unknown_0x20000000 = 0x20000000, // NOT VERIFIED
|
||||
Unknown_0x40000000 = 0x40000000, // NOT VERIFIED
|
||||
Unknown_0x80000000 = 0x80000000, // NOT VERIFIED
|
||||
|
||||
// Masks
|
||||
Mask_Final_Facing = Final_Point | Final_Target | Final_Angle,
|
||||
// animation ids stored here, see AimationTier enum, used with Animation flag
|
||||
Mask_Animations = 0x7,
|
||||
// flags that shouldn't be appended into SMSG_MONSTER_MOVE\SMSG_MONSTER_MOVE_TRANSPORT packet, should be more probably
|
||||
Mask_No_Monster_Move = Mask_Final_Facing | Mask_Animations | Done,
|
||||
Mask_No_Monster_Move = Done,
|
||||
// Unused, not suported flags
|
||||
Mask_Unused = No_Spline|Frozen|Unknown0|Unknown2|Unknown3|Unknown4|Unknown6|Unknown7|Unknown8|Unknown9
|
||||
Mask_Unused = No_Spline | Enter_Cycle | Frozen | Unknown_0x8 | Unknown_0x100 | Unknown_0x20000 | Unknown_0x40000
|
||||
| Unknown_0x800000 | FadeObject | Steering | UnlimitedSpeed | Unknown_0x20000000 | Unknown_0x40000000 | Unknown_0x80000000
|
||||
};
|
||||
|
||||
inline uint32& raw() { return (uint32&)*this; }
|
||||
@@ -81,7 +81,6 @@ namespace Movement
|
||||
|
||||
bool isSmooth() const { return (raw() & Catmullrom) != 0; }
|
||||
bool isLinear() const { return !isSmooth(); }
|
||||
bool isFacing() const { return (raw() & Mask_Final_Facing) != 0; }
|
||||
|
||||
bool hasAllFlags(uint32 f) const { return (raw() & f) == f; }
|
||||
bool hasFlag(uint32 f) const { return (raw() & f) != 0; }
|
||||
@@ -94,24 +93,23 @@ namespace Movement
|
||||
void operator &= (uint32 f) { raw() &= f; }
|
||||
void operator |= (uint32 f) { raw() |= f; }
|
||||
|
||||
void EnableAnimation(uint8 anim) { raw() = (raw() & ~(Mask_Animations | Falling | Parabolic | FallingSlow)) | Animation | (anim & Mask_Animations); }
|
||||
void EnableParabolic() { raw() = (raw() & ~(Mask_Animations | Falling | Animation | FallingSlow)) | Parabolic; }
|
||||
void EnableAnimation() { raw() = (raw() & ~(Falling | Parabolic | FallingSlow | FadeObject)) | Animation; }
|
||||
void EnableParabolic() { raw() = (raw() & ~(Falling | Animation | FallingSlow | FadeObject)) | Parabolic; }
|
||||
void EnableFlying() { raw() = (raw() & ~(Falling)) | Flying; }
|
||||
void EnableFalling() { raw() = (raw() & ~(Mask_Animations | Parabolic | Animation | Flying)) | Falling; }
|
||||
void EnableFalling() { raw() = (raw() & ~(Parabolic | Animation | Flying)) | Falling; }
|
||||
void EnableCatmullRom() { raw() = (raw() & ~SmoothGroundPath) | Catmullrom; }
|
||||
void EnableFacingPoint() { raw() = (raw() & ~Mask_Final_Facing) | Final_Point; }
|
||||
void EnableFacingAngle() { raw() = (raw() & ~Mask_Final_Facing) | Final_Angle; }
|
||||
void EnableFacingTarget() { raw() = (raw() & ~Mask_Final_Facing) | Final_Target; }
|
||||
void EnableTransportEnter() { raw() = (raw() & ~TransportExit) | TransportEnter; }
|
||||
void EnableTransportExit() { raw() = (raw() & ~TransportEnter) | TransportExit; }
|
||||
|
||||
uint8 animTier : 3;
|
||||
bool unknown0 : 1;
|
||||
bool unknown0x1 : 1;
|
||||
bool unknown0x2 : 1;
|
||||
bool unknown0x4 : 1;
|
||||
bool unknown0x8 : 1;
|
||||
bool fallingSlow : 1;
|
||||
bool done : 1;
|
||||
bool falling : 1;
|
||||
bool no_spline : 1;
|
||||
bool unknown2 : 1;
|
||||
bool unknown0x100 : 1;
|
||||
bool flying : 1;
|
||||
bool orientationFixed : 1;
|
||||
bool catmullrom : 1;
|
||||
@@ -120,21 +118,21 @@ namespace Movement
|
||||
bool frozen : 1;
|
||||
bool transportEnter : 1;
|
||||
bool transportExit : 1;
|
||||
bool unknown3 : 1;
|
||||
bool unknown4 : 1;
|
||||
bool unknown0x20000 : 1;
|
||||
bool unknown0x40000 : 1;
|
||||
bool backward : 1;
|
||||
bool smoothGroundPath : 1;
|
||||
bool canSwim : 1;
|
||||
bool uncompressedPath : 1;
|
||||
bool unknown6 : 1;
|
||||
bool unknown0x800000 : 1;
|
||||
bool animation : 1;
|
||||
bool parabolic : 1;
|
||||
bool final_point : 1;
|
||||
bool final_target : 1;
|
||||
bool final_angle : 1;
|
||||
bool unknown7 : 1;
|
||||
bool unknown8 : 1;
|
||||
bool unknown9 : 1;
|
||||
bool fadeObject : 1;
|
||||
bool steering : 1;
|
||||
bool unlimitedSpeed : 1;
|
||||
bool unknown0x20000000 : 1;
|
||||
bool unknown0x40000000 : 1;
|
||||
bool unknown0x80000000 : 1;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ namespace Movement
|
||||
{
|
||||
MoveSpline& move_spline = *unit->movespline;
|
||||
|
||||
bool transport = unit->GetTransGUID() != 0;
|
||||
bool transport = !unit->GetTransGUID().IsEmpty();
|
||||
Location real_position;
|
||||
// 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
|
||||
@@ -91,7 +91,7 @@ namespace Movement
|
||||
args.path[0] = real_position;
|
||||
args.initialOrientation = real_position.orientation;
|
||||
args.flags.enter_cycle = args.flags.cyclic;
|
||||
move_spline.onTransport = (unit->GetTransGUID() != 0);
|
||||
move_spline.onTransport = transport;
|
||||
|
||||
uint32 moveFlags = unit->m_movementInfo.GetMovementFlags();
|
||||
if (!args.flags.backward)
|
||||
@@ -99,6 +99,9 @@ namespace Movement
|
||||
else
|
||||
moveFlags = (moveFlags & ~MOVEMENTFLAG_FORWARD) | MOVEMENTFLAG_BACKWARD;
|
||||
|
||||
if (moveFlags & MOVEMENTFLAG_ROOT)
|
||||
moveFlags &= ~MOVEMENTFLAG_MASK_MOVING;
|
||||
|
||||
if (!args.HasVelocity)
|
||||
{
|
||||
// If spline is initialized with SetWalk method it only means we need to select
|
||||
@@ -125,6 +128,7 @@ namespace Movement
|
||||
packet.MoverGUID = unit->GetGUID();
|
||||
packet.Pos = Position(real_position.x, real_position.y, real_position.z, real_position.orientation);
|
||||
packet.InitializeSplineData(move_spline);
|
||||
|
||||
if (unit->m_movementInfo.HasExtraMovementFlag(MOVEMENTFLAG2_IS_VEHICLE_EXIT_VOLUNTARY))
|
||||
packet.SplineData.Move.VehicleExitVoluntary = true;
|
||||
|
||||
@@ -147,7 +151,7 @@ namespace Movement
|
||||
if (move_spline.Finalized())
|
||||
return;
|
||||
|
||||
bool transport = unit->GetTransGUID() != 0;
|
||||
bool transport = !unit->GetTransGUID().IsEmpty();
|
||||
Location loc;
|
||||
if (move_spline.onTransport == transport)
|
||||
loc = move_spline.ComputePosition();
|
||||
@@ -174,15 +178,7 @@ namespace Movement
|
||||
packet.MoverGUID = unit->GetGUID();
|
||||
packet.Pos = Position(loc.x, loc.y, loc.z, loc.orientation);
|
||||
packet.SplineData.ID = move_spline.GetId();
|
||||
|
||||
if (unit->IsAlive())
|
||||
packet.SplineData.Move.Face = MONSTER_MOVE_STOP;
|
||||
else
|
||||
{
|
||||
// Stopping splines for killed creatures send a normal packet with their current position as first path point
|
||||
packet.SplineData.Move.Face = MONSTER_MOVE_NORMAL;
|
||||
packet.SplineData.Move.Points.push_back({ loc.x, loc.y, loc.z });
|
||||
}
|
||||
packet.SplineData.Move.Face = MONSTER_MOVE_STOP;
|
||||
|
||||
if (transport)
|
||||
{
|
||||
@@ -213,13 +209,19 @@ namespace Movement
|
||||
args.facing.f.x = finalSpot.x;
|
||||
args.facing.f.y = finalSpot.y;
|
||||
args.facing.f.z = finalSpot.z;
|
||||
args.flags.EnableFacingPoint();
|
||||
args.facing.type = MONSTER_MOVE_FACING_SPOT;
|
||||
}
|
||||
|
||||
void MoveSplineInit::SetFacing(float x, float y, float z)
|
||||
{
|
||||
SetFacing({ x, y, z });
|
||||
}
|
||||
|
||||
void MoveSplineInit::SetFacing(Unit const* target)
|
||||
{
|
||||
args.flags.EnableFacingTarget();
|
||||
args.facing.angle = unit->GetAngle(target);
|
||||
args.facing.target = target->GetGUID();
|
||||
args.facing.type = MONSTER_MOVE_FACING_TARGET;
|
||||
}
|
||||
|
||||
void MoveSplineInit::SetFacing(float angle)
|
||||
@@ -233,7 +235,7 @@ namespace Movement
|
||||
}
|
||||
|
||||
args.facing.angle = G3D::wrap(angle, 0.f, (float)G3D::twoPi());
|
||||
args.flags.EnableFacingAngle();
|
||||
args.facing.type = MONSTER_MOVE_FACING_ANGLE;
|
||||
}
|
||||
|
||||
void MoveSplineInit::MovebyPath(PointsArray const& controls, int32 path_offset)
|
||||
|
||||
@@ -75,7 +75,7 @@ namespace Movement
|
||||
/* Plays animation after movement done
|
||||
* can't be combined with parabolic movement
|
||||
*/
|
||||
void SetAnimation(AnimationTier anim);
|
||||
void SetAnimation(AnimationTier anim, Milliseconds transitionStartTime = 0ms);
|
||||
|
||||
/* Adds final facing animation
|
||||
* sets unit's facing to specified point/angle after all path done
|
||||
@@ -83,6 +83,7 @@ namespace Movement
|
||||
*/
|
||||
void SetFacing(float angle);
|
||||
void SetFacing(Vector3 const& point);
|
||||
void SetFacing(float x, float y, float z);
|
||||
void SetFacing(Unit const* target);
|
||||
|
||||
/* Initializes movement by path
|
||||
@@ -174,7 +175,7 @@ namespace Movement
|
||||
|
||||
inline void MoveSplineInit::SetParabolic(float amplitude, float time_shift)
|
||||
{
|
||||
args.time_perc = time_shift;
|
||||
args.effect_start_time_percent = time_shift;
|
||||
args.parabolic_amplitude = amplitude;
|
||||
args.vertical_acceleration = 0.0f;
|
||||
args.flags.EnableParabolic();
|
||||
@@ -182,16 +183,18 @@ namespace Movement
|
||||
|
||||
inline void MoveSplineInit::SetParabolicVerticalAcceleration(float vertical_acceleration, float time_shift)
|
||||
{
|
||||
args.time_perc = time_shift;
|
||||
args.effect_start_time_percent = time_shift;
|
||||
args.parabolic_amplitude = 0.0f;
|
||||
args.vertical_acceleration = vertical_acceleration;
|
||||
args.flags.EnableParabolic();
|
||||
}
|
||||
|
||||
inline void MoveSplineInit::SetAnimation(AnimationTier anim)
|
||||
inline void MoveSplineInit::SetAnimation(AnimationTier anim, Milliseconds transitionStartTime /*= 0ms*/)
|
||||
{
|
||||
args.time_perc = 0.f;
|
||||
args.flags.EnableAnimation((uint8)anim);
|
||||
args.effect_start_time_percent = 0.f;
|
||||
args.effect_start_time = transitionStartTime;
|
||||
args.animTier = anim;
|
||||
args.flags.EnableAnimation();
|
||||
}
|
||||
|
||||
inline void MoveSplineInit::DisableTransportPathTransformations() { args.TransformForTransport = false; }
|
||||
|
||||
@@ -18,12 +18,15 @@
|
||||
#ifndef TRINITYSERVER_MOVESPLINEINIT_ARGS_H
|
||||
#define TRINITYSERVER_MOVESPLINEINIT_ARGS_H
|
||||
|
||||
#include "Duration.h"
|
||||
#include "MoveSplineFlag.h"
|
||||
#include "ObjectGuid.h"
|
||||
#include <vector>
|
||||
#include "Optional.h"
|
||||
|
||||
class Unit;
|
||||
|
||||
enum class AnimationTier : uint8;
|
||||
|
||||
namespace Movement
|
||||
{
|
||||
typedef std::vector<Vector3> PointsArray;
|
||||
@@ -37,7 +40,9 @@ namespace Movement
|
||||
ObjectGuid target;
|
||||
float angle;
|
||||
|
||||
FacingInfo() : angle(0.0f) { f.x = f.y = f.z = 0.0f; }
|
||||
MonsterMoveType type;
|
||||
|
||||
FacingInfo() : angle(0.0f), type(MONSTER_MOVE_NORMAL) { f.x = f.y = f.z = 0.0f; }
|
||||
};
|
||||
|
||||
struct MoveSplineInitArgs
|
||||
@@ -53,9 +58,11 @@ namespace Movement
|
||||
float velocity;
|
||||
float parabolic_amplitude;
|
||||
float vertical_acceleration;
|
||||
float time_perc;
|
||||
float effect_start_time_percent; // fraction of total spline duration
|
||||
Milliseconds effect_start_time; // absolute value
|
||||
uint32 splineId;
|
||||
float initialOrientation;
|
||||
Optional<AnimationTier> animTier;
|
||||
bool walk;
|
||||
bool HasVelocity;
|
||||
bool TransformForTransport;
|
||||
@@ -64,7 +71,7 @@ namespace Movement
|
||||
bool Validate(Unit* unit) const;
|
||||
|
||||
private:
|
||||
bool _checkPathBounds() const;
|
||||
bool _checkPathLengths() const;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -35,15 +35,18 @@ namespace Movement
|
||||
|
||||
void PacketBuilder::WriteCreateBits(MoveSpline const& moveSpline, ByteBuffer& data)
|
||||
{
|
||||
if (!data.WriteBit(!moveSpline.Finalized()))
|
||||
|
||||
bool hasSplineMove = data.WriteBit(!moveSpline.Finalized() && !moveSpline.splineIsFacingOnly);
|
||||
if (!hasSplineMove)
|
||||
return;
|
||||
|
||||
data.WriteBits(uint8(moveSpline.spline.mode()), 2);
|
||||
data.WriteBit(moveSpline.splineflags & (MoveSplineFlag::Parabolic | MoveSplineFlag::Animation));
|
||||
data.WriteBits(moveSpline.getPath().size(), 22);
|
||||
switch (moveSpline.splineflags & MoveSplineFlag::Mask_Final_Facing)
|
||||
|
||||
switch (moveSpline.facing.type)
|
||||
{
|
||||
case MoveSplineFlag::Final_Target:
|
||||
case MONSTER_MOVE_FACING_TARGET:
|
||||
{
|
||||
ObjectGuid targetGuid(moveSpline.facing.target);
|
||||
data.WriteBits(2, 2);
|
||||
@@ -57,10 +60,10 @@ namespace Movement
|
||||
data.WriteBit(targetGuid[5]);
|
||||
break;
|
||||
}
|
||||
case MoveSplineFlag::Final_Angle:
|
||||
case MONSTER_MOVE_FACING_ANGLE:
|
||||
data.WriteBits(0, 2);
|
||||
break;
|
||||
case MoveSplineFlag::Final_Point:
|
||||
case MONSTER_MOVE_FACING_SPOT:
|
||||
data.WriteBits(1, 2);
|
||||
break;
|
||||
default:
|
||||
@@ -68,13 +71,13 @@ namespace Movement
|
||||
break;
|
||||
}
|
||||
|
||||
data.WriteBit((moveSpline.splineflags & MoveSplineFlag::Parabolic) && moveSpline.effect_start_time < moveSpline.Duration());
|
||||
data.WriteBit((moveSpline.splineflags & MoveSplineFlag::Parabolic) != 0 && moveSpline.effect_start_time < moveSpline.Duration());
|
||||
data.WriteBits(moveSpline.splineflags.raw(), 25);
|
||||
}
|
||||
|
||||
void PacketBuilder::WriteCreateData(MoveSpline const& moveSpline, ByteBuffer& data)
|
||||
{
|
||||
if (!moveSpline.Finalized())
|
||||
if (!moveSpline.Finalized() && !moveSpline.splineIsFacingOnly)
|
||||
{
|
||||
MoveSplineFlag const& splineFlags = moveSpline.splineflags;
|
||||
|
||||
@@ -83,9 +86,9 @@ namespace Movement
|
||||
|
||||
data << moveSpline.timePassed();
|
||||
|
||||
if (splineFlags.final_angle)
|
||||
if (moveSpline.facing.type == MONSTER_MOVE_FACING_ANGLE)
|
||||
data << moveSpline.facing.angle;
|
||||
else if (splineFlags.final_target)
|
||||
else if (moveSpline.facing.type == MONSTER_MOVE_FACING_TARGET)
|
||||
{
|
||||
ObjectGuid facingGuid(moveSpline.facing.target);
|
||||
data.WriteByteSeq(facingGuid[5]);
|
||||
@@ -106,7 +109,7 @@ namespace Movement
|
||||
data << float(moveSpline.getPath()[i].y);
|
||||
}
|
||||
|
||||
if (splineFlags.final_point)
|
||||
if (moveSpline.facing.type == MONSTER_MOVE_FACING_SPOT)
|
||||
data << moveSpline.facing.f.x << moveSpline.facing.f.z << moveSpline.facing.f.y;
|
||||
|
||||
data << float(1.f); // splineInfo.duration_mod_next; added in 3.1
|
||||
|
||||
@@ -377,31 +377,16 @@ void WorldPackets::Movement::MonsterMove::InitializeSplineData(::Movement::MoveS
|
||||
::Movement::MoveSplineFlag splineFlags = moveSpline.splineflags;
|
||||
splineFlags.enter_cycle = moveSpline.isCyclic();
|
||||
movementSpline.Flags = uint32(splineFlags & uint32(~::Movement::MoveSplineFlag::Mask_No_Monster_Move));
|
||||
|
||||
switch (moveSpline.splineflags & ::Movement::MoveSplineFlag::Mask_Final_Facing)
|
||||
{
|
||||
case ::Movement::MoveSplineFlag::Final_Point:
|
||||
movementSpline.Face = ::Movement::MONSTER_MOVE_FACING_SPOT;
|
||||
movementSpline.FaceSpot = Position(moveSpline.facing.f.x, moveSpline.facing.f.y, moveSpline.facing.f.z);
|
||||
break;
|
||||
case ::Movement::MoveSplineFlag::Final_Target:
|
||||
movementSpline.Face = ::Movement::MONSTER_MOVE_FACING_TARGET;
|
||||
movementSpline.FaceGUID = moveSpline.facing.target;
|
||||
break;
|
||||
case ::Movement::MoveSplineFlag::Final_Angle:
|
||||
movementSpline.Face = ::Movement::MONSTER_MOVE_FACING_ANGLE;
|
||||
movementSpline.FaceDirection = moveSpline.facing.angle;
|
||||
break;
|
||||
default:
|
||||
movementSpline.Face = ::Movement::MONSTER_MOVE_NORMAL;
|
||||
break;
|
||||
}
|
||||
movementSpline.Face = moveSpline.facing.type;
|
||||
movementSpline.FaceDirection = moveSpline.facing.angle;
|
||||
movementSpline.FaceGUID = moveSpline.facing.target;
|
||||
movementSpline.FaceSpot = Position(moveSpline.facing.f.x, moveSpline.facing.f.y, moveSpline.facing.f.z);
|
||||
|
||||
if (splineFlags.animation)
|
||||
{
|
||||
movementSpline.Animation.emplace();
|
||||
movementSpline.Animation->AnimTier = splineFlags.animTier;
|
||||
movementSpline.Animation->TierTransStartTime = moveSpline.effect_start_time;
|
||||
movementSpline.Animation->AnimTier = AsUnderlyingType(*moveSpline.anim_tier);
|
||||
}
|
||||
|
||||
movementSpline.MoveTime = moveSpline.Duration();
|
||||
@@ -498,8 +483,6 @@ ByteBuffer& WorldPackets::operator<<(ByteBuffer& data, Movement::MovementSpline
|
||||
|
||||
switch (movementSpline.Face)
|
||||
{
|
||||
case ::Movement::MONSTER_MOVE_NORMAL:
|
||||
break;
|
||||
case ::Movement::MONSTER_MOVE_FACING_SPOT:
|
||||
data << movementSpline.FaceSpot;
|
||||
break;
|
||||
@@ -509,8 +492,6 @@ ByteBuffer& WorldPackets::operator<<(ByteBuffer& data, Movement::MovementSpline
|
||||
case ::Movement::MONSTER_MOVE_FACING_ANGLE:
|
||||
data << float(movementSpline.FaceDirection);
|
||||
break;
|
||||
default:
|
||||
return data;
|
||||
}
|
||||
|
||||
data << int32(movementSpline.Flags);
|
||||
|
||||
Reference in new issue
Block a user