Core/Movement: sync spline code with master branch

This commit is contained in:
Ovahlord committed 2023-08-19 15:04:34 +02:00
1 parent dfa6f7a709
commit 770f9e11db
10 files changed
+143 -138

No files matched your search

+19 -3
View File
@@ -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())
+1 -3
View File
@@ -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); }
+31 -35
View File
@@ -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;
+3 -2
View File
@@ -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);