Core/Movement: sync spline code which is relevant for Cataclysm with master branch

This commit is contained in:
Ovahlord committed 2025-03-08 17:20:25 +01:00
1 parent 1d25eabb4b
commit 0e8605edb8
11 files changed
+221 -184

No files matched your search

-16
View File
@@ -569,22 +569,6 @@ void MotionMaster::MoveSmoothPath(uint32 pointId, Position const* pathPoints, si
init.SetSmooth();
init.SetUncompressed();
}
else
{
if (pathSize > 1)
{
G3D::Vector3 middle = (path[0] + path[pathSize]) / 2.f;
for (uint32 i = 1; i < pathSize; ++i)
{
G3D::Vector3 delta = middle - path[i];
if (delta.x > 400 || delta.y > 400 || delta.z > 400)
{
init.SetUncompressed();
break;
}
}
}
}
if (velocity > 0.0f)
init.SetVelocity(velocity);
+47 -22
View File
@@ -36,14 +36,14 @@ Location MoveSpline::computePosition(int32 time_point, int32 point_index) const
c.orientation = initialOrientation;
spline.evaluate_percent(point_index, u, c);
if (splineflags.animation)
if (splineflags.Animation)
;// MoveSplineFlag::Animation disables falling or parabolic movement
else if (splineflags.parabolic)
else if (splineflags.Parabolic)
computeParabolicElevation(time_point, c.z);
else if (splineflags.falling)
else if (splineflags.Falling)
computeFallElevation(time_point, c.z);
if (splineflags.done && facing.type != MONSTER_MOVE_NORMAL)
if (splineflags.Done && facing.type != MONSTER_MOVE_NORMAL)
{
if (facing.type == MONSTER_MOVE_FACING_ANGLE)
c.orientation = facing.angle;
@@ -53,7 +53,7 @@ Location MoveSpline::computePosition(int32 time_point, int32 point_index) const
}
else
{
if (!splineflags.hasFlag(MoveSplineFlag::OrientationFixed | MoveSplineFlag::Falling | MoveSplineFlag::Unknown_0x8))
if (!splineflags.HasFlag(MoveSplineFlagEnum::OrientationFixed | MoveSplineFlagEnum::Falling | MoveSplineFlagEnum::Unknown_0x8))
{
Vector3 hermite;
spline.evaluate_derivative(point_Idx, u, hermite);
@@ -61,7 +61,7 @@ Location MoveSpline::computePosition(int32 time_point, int32 point_index) const
c.orientation = std::atan2(hermite.y, hermite.x);
}
if (splineflags.backward)
if (splineflags.Backward)
c.orientation = -c.orientation;
}
return c;
@@ -145,10 +145,10 @@ struct CommonInitializer
void MoveSpline::init_spline(MoveSplineInitArgs const& args)
{
static SplineBase::EvaluationMode const modes[2] = { SplineBase::ModeLinear, SplineBase::ModeCatmullrom };
if (args.flags.cyclic)
if (args.flags.Cyclic)
{
uint32 cyclic_point = 0;
if (splineflags.enter_cycle)
if (splineflags.Enter_Cycle)
cyclic_point = 1; // shouldn't be modified, came from client
spline.init_cyclic_spline(&args.path[0], args.path.size(), modes[args.flags.isSmooth()], cyclic_point, args.initialOrientation);
}
@@ -156,7 +156,7 @@ void MoveSpline::init_spline(MoveSplineInitArgs const& args)
spline.init_spline(&args.path[0], args.path.size(), modes[args.flags.isSmooth()], args.initialOrientation);
// init spline timestamps
if (splineflags.falling)
if (splineflags.Falling)
{
FallInitializer init(spline.getPoint(spline.first()).z);
spline.initLengths(init);
@@ -193,7 +193,7 @@ void MoveSpline::Initialize(MoveSplineInitArgs const& args)
velocity = args.velocity;
// Check if its a stop spline
if (args.flags.done)
if (args.flags.Done)
{
spline.clear();
return;
@@ -203,14 +203,14 @@ void MoveSpline::Initialize(MoveSplineInitArgs const& args)
// init parabolic / animation
// spline initialized, duration known and i able to compute parabolic acceleration
if (args.flags & (MoveSplineFlag::Parabolic | MoveSplineFlag::Animation))
if (args.flags.HasFlag(MoveSplineFlagEnum::Parabolic | MoveSplineFlagEnum::Animation | MoveSplineFlagEnum::FadeObject))
{
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.flags.Parabolic && effect_start_time < spline_duration)
{
if (args.parabolic_amplitude != 0.0f)
{
@@ -229,7 +229,7 @@ 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), splineIsFacingOnly(false)
{
splineflags.done = true;
splineflags.Done = true;
}
MoveSplineInitArgs::MoveSplineInitArgs(size_t path_capacity /*= 16*/) : path_Idx_offset(0), velocity(0.f),
@@ -246,17 +246,17 @@ MoveSplineInitArgs::~MoveSplineInitArgs() = default;
/// ============================================================================================
bool MoveSplineInitArgs::Validate(Unit* unit) const
bool MoveSplineInitArgs::Validate(Unit const* unit)
{
#define CHECK(exp) \
if (!(exp))\
do if (!(exp))\
{\
if (unit)\
TC_LOG_ERROR("misc.movesplineinitargs", "MoveSplineInitArgs::Validate: expression '%s' failed for GUID: %u Entry: %u", #exp, unit->GetTypeId() == TYPEID_PLAYER ? unit->GetGUID().GetCounter() : unit->ToCreature()->GetSpawnId(), unit->GetEntry());\
else\
TC_LOG_ERROR("misc.movesplineinitargs", "MoveSplineInitArgs::Validate: expression '%s' failed for cyclic spline continuation", #exp); \
return false;\
}
} while (0)
CHECK(path.size() > 1);
CHECK(velocity >= 0.01f);
CHECK(effect_start_time_percent >= 0.f && effect_start_time_percent <= 1.f);
@@ -266,12 +266,37 @@ bool MoveSplineInitArgs::Validate(Unit* unit) const
}
// check path lengths - why are we even starting such short movement?
bool MoveSplineInitArgs::_checkPathLengths() const
bool MoveSplineInitArgs::_checkPathLengths()
{
if (path.size() > 2 || facing.type == MONSTER_MOVE_NORMAL)
for (uint32 i = 0; i < path.size() - 1; ++i)
constexpr float MIN_XY_OFFSET = -(1 << 11) / 4.0f;
constexpr float MIN_Z_OFFSET = -(1 << 10) / 4.0f;
// positive values have 1 less bit limit (if the highest bit was set, value would be sign extended into negative when decompressing)
constexpr float MAX_XY_OFFSET = (1 << 10) / 4.0f;
constexpr float MAX_Z_OFFSET = (1 << 9) / 4.0f;
auto isValidPackedXYOffset = [](float coord) -> bool { return coord > MIN_XY_OFFSET && coord < MAX_XY_OFFSET; };
auto isValidPackedZOffset = [](float coord) -> bool { return coord > MIN_Z_OFFSET && coord < MAX_Z_OFFSET; };
if (path.size() > 2)
{
if ((path[2] - path[1]).length() < 0.1f)
return false;
Vector3 middle = (path.front() + path.back()) / 2;
for (uint32 i = 1; i < path.size() - 1; ++i)
{
if ((path[i + 1] - path[i]).length() < 0.1f)
return false;
// when compression is enabled, each point coord is packed into 11 bits (10 for Z)
if (!flags.UncompressedPath)
if (!isValidPackedXYOffset(middle.x - path[i].x)
|| !isValidPackedXYOffset(middle.y - path[i].y)
|| !isValidPackedZOffset(middle.z - path[i].z))
flags.UncompressedPath = true;
}
}
return true;
}
@@ -309,9 +334,9 @@ MoveSpline::UpdateResult MoveSpline::_updateState(int32& ms_time_diff)
// Remove first point from the path after one full cycle.
// That point was the position of the unit prior to entering the cycle and it shouldn't be repeated with continuous cycles.
if (splineflags.enter_cycle)
if (splineflags.Enter_Cycle)
{
splineflags.enter_cycle = false;
splineflags.Enter_Cycle = false;
MoveSplineInitArgs args{ (size_t)spline.getPointCount() };
args.path.assign(spline.getPoints().begin() + spline.first() + 1, spline.getPoints().begin() + spline.last());
@@ -378,7 +403,7 @@ std::string MoveSpline::ToString() const
void MoveSpline::_Finalize()
{
splineflags.done = true;
splineflags.Done = true;
point_Idx = spline.last() - 1;
time_passed = Duration();
}
+7 -7
View File
@@ -95,16 +95,16 @@ namespace Movement
UpdateResult _updateState(int32& ms_time_diff);
int32 next_timestamp() const { return spline.length(point_Idx + 1); }
int32 segment_time_elapsed() const { return next_timestamp() - time_passed; }
int32 timeElapsed() const { return Duration() - time_passed; }
int32 timePassed() const { return time_passed; }
public:
int32 timeRemaining() const { return Duration() - time_passed; }
int32 timePassed() const { return time_passed; }
int32 Duration() const { return spline.length(); }
MySpline const& _Spline() const { return spline; }
int32 _currentSplineIdx() const { return point_Idx; }
float Velocity() const { return velocity; }
void _Finalize();
void _Interrupt() { splineflags.done = true; }
void _Interrupt() { splineflags.Done = true; }
public:
void Initialize(MoveSplineInitArgs const&);
@@ -132,10 +132,10 @@ namespace Movement
Location ComputePosition(int32 time_offset) const;
uint32 GetId() const { return m_Id; }
bool Finalized() const { return splineflags.done; }
bool isCyclic() const { return splineflags.cyclic; }
bool isFalling() const { return splineflags.falling; }
bool isParabolic() const { return splineflags.parabolic; }
bool Finalized() const { return splineflags.Done; }
bool isCyclic() const { return splineflags.Cyclic; }
bool isFalling() const { return splineflags.Falling; }
bool isParabolic() const { return splineflags.Parabolic; }
Vector3 FinalDestination() const { return Initialized() ? spline.getPoint(spline.last()) : Vector3(); }
Vector3 CurrentDestination() const { return Initialized() ? spline.getPoint(point_Idx + 1) : Vector3(); }
int32 currentPathIdx() const;
+123 -99
View File
@@ -19,122 +19,146 @@
#define TRINITYSERVER_MOVESPLINEFLAG_H
#include "MovementTypedefs.h"
#include "EnumFlag.h"
namespace Movement
{
#pragma pack(push, 1)
class MoveSplineFlag
enum class MoveSplineFlagEnum : uint32
{
public:
enum eFlags
None = 0x00000000,
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,
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
Cyclic = 0x00001000, // Movement by cycled spline
Enter_Cycle = 0x00002000, // Everytimes appears with cyclic flag in monster move packet, erases first spline vertex after first cycle done
Frozen = 0x00004000, // Will never arrive
TransportEnter = 0x00008000,
TransportExit = 0x00010000,
Unknown_0x20000 = 0x00020000, // NOT VERIFIED
Unknown_0x40000 = 0x00040000, // NOT VERIFIED
Backward = 0x00080000,
SmoothGroundPath = 0x00100000,
CanSwim = 0x00200000,
UncompressedPath = 0x00400000,
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
FadeObject = 0x04000000,
Steering = 0x08000000,
UnlimitedSpeed = 0x10000000,
Unknown_0x20000000 = 0x20000000, // NOT VERIFIED
Unknown_0x40000000 = 0x40000000, // NOT VERIFIED
Unknown_0x80000000 = 0x80000000, // NOT VERIFIED
// Masks
// flags that shouldn't be appended into SMSG_MONSTER_MOVE\SMSG_MONSTER_MOVE_TRANSPORT packet, should be more probably
Mask_No_Monster_Move = Done,
// Unused, not suported flags
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
};
DEFINE_ENUM_FLAG(MoveSplineFlagEnum);
consteval MoveSplineFlagEnum GetDisallowedFlagsFor(MoveSplineFlagEnum flag)
{
switch (flag)
{
None = 0x00000000,
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,
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
Cyclic = 0x00001000, // Movement by cycled spline
Enter_Cycle = 0x00002000, // Everytimes appears with cyclic flag in monster move packet, erases first spline vertex after first cycle done
Frozen = 0x00004000, // Will never arrive
TransportEnter = 0x00008000,
TransportExit = 0x00010000,
Unknown_0x20000 = 0x00020000, // NOT VERIFIED
Unknown_0x40000 = 0x00040000, // NOT VERIFIED
Backward = 0x00080000,
SmoothGroundPath = 0x00100000,
CanSwim = 0x00200000,
UncompressedPath = 0x00400000,
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
FadeObject = 0x04000000,
Steering = 0x08000000,
UnlimitedSpeed = 0x10000000,
Unknown_0x20000000 = 0x20000000, // NOT VERIFIED
Unknown_0x40000000 = 0x40000000, // NOT VERIFIED
Unknown_0x80000000 = 0x80000000, // NOT VERIFIED
case MoveSplineFlagEnum::Falling: return MoveSplineFlagEnum::Parabolic | MoveSplineFlagEnum::Animation | MoveSplineFlagEnum::Flying;
case MoveSplineFlagEnum::Flying: return MoveSplineFlagEnum::FallingSlow | MoveSplineFlagEnum::Falling;
case MoveSplineFlagEnum::Catmullrom: return MoveSplineFlagEnum::SmoothGroundPath;
case MoveSplineFlagEnum::TransportEnter: return MoveSplineFlagEnum::TransportExit;
case MoveSplineFlagEnum::TransportExit: return MoveSplineFlagEnum::TransportEnter;
case MoveSplineFlagEnum::SmoothGroundPath: return MoveSplineFlagEnum::Steering;
case MoveSplineFlagEnum::Animation: return MoveSplineFlagEnum::Falling | MoveSplineFlagEnum::Parabolic | MoveSplineFlagEnum::FallingSlow | MoveSplineFlagEnum::FadeObject;
case MoveSplineFlagEnum::Parabolic: return MoveSplineFlagEnum::Falling | MoveSplineFlagEnum::Animation | MoveSplineFlagEnum::FallingSlow | MoveSplineFlagEnum::FadeObject;
case MoveSplineFlagEnum::FadeObject: return MoveSplineFlagEnum::Falling | MoveSplineFlagEnum::Parabolic | MoveSplineFlagEnum::FallingSlow | MoveSplineFlagEnum::Animation;
case MoveSplineFlagEnum::Steering: return MoveSplineFlagEnum::SmoothGroundPath;
default: break;
}
return MoveSplineFlagEnum::None;
}
// Masks
// flags that shouldn't be appended into SMSG_MONSTER_MOVE\SMSG_MONSTER_MOVE_TRANSPORT packet, should be more probably
Mask_No_Monster_Move = Done,
// Unused, not suported flags
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; }
inline uint32 const& raw() const { return (uint32 const&)*this; }
MoveSplineFlag() { raw() = 0; }
MoveSplineFlag(uint32 f) { raw() = f; }
union MoveSplineFlag
{
constexpr MoveSplineFlag() : Raw(MoveSplineFlagEnum::None) {}
constexpr MoveSplineFlag(MoveSplineFlagEnum f) : Raw(f) {}
// Constant interface
bool isSmooth() const { return (raw() & Catmullrom) != 0; }
bool isLinear() const { return !isSmooth(); }
constexpr bool isSmooth() const { return Raw.HasFlag(MoveSplineFlagEnum::Catmullrom); }
constexpr bool isLinear() const { return !isSmooth(); }
bool hasAllFlags(uint32 f) const { return (raw() & f) == f; }
bool hasFlag(uint32 f) const { return (raw() & f) != 0; }
uint32 operator & (uint32 f) const { return (raw() & f); }
uint32 operator | (uint32 f) const { return (raw() | f); }
constexpr bool HasAllFlags(MoveSplineFlagEnum f) const { return Raw.HasAllFlags(f); }
constexpr bool HasFlag(MoveSplineFlagEnum f) const { return Raw.HasFlag(f); }
constexpr MoveSplineFlagEnum operator&(MoveSplineFlagEnum f) const { return (Raw & f); }
constexpr MoveSplineFlagEnum operator|(MoveSplineFlagEnum f) const { return (Raw | f); }
std::string ToString() const;
// Not constant interface
void operator &= (uint32 f) { raw() &= f; }
void operator |= (uint32 f) { raw() |= f; }
constexpr MoveSplineFlag& operator&=(MoveSplineFlagEnum f) { Raw &= f; return *this; }
constexpr MoveSplineFlag& operator|=(MoveSplineFlagEnum f) { Raw |= f; return *this; }
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() & ~(Parabolic | Animation | Flying)) | Falling; }
void EnableCatmullRom() { raw() = (raw() & ~SmoothGroundPath) | Catmullrom; }
void EnableTransportEnter() { raw() = (raw() & ~TransportExit) | TransportEnter; }
void EnableTransportExit() { raw() = (raw() & ~TransportEnter) | TransportExit; }
EnumFlag<MoveSplineFlagEnum> Raw;
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 unknown0x100 : 1;
bool flying : 1;
bool orientationFixed : 1;
bool catmullrom : 1;
bool cyclic : 1;
bool enter_cycle : 1;
bool frozen : 1;
bool transportEnter : 1;
bool transportExit : 1;
bool unknown0x20000 : 1;
bool unknown0x40000 : 1;
bool backward : 1;
bool smoothGroundPath : 1;
bool canSwim : 1;
bool uncompressedPath : 1;
bool unknown0x800000 : 1;
bool animation : 1;
bool parabolic : 1;
bool fadeObject : 1;
bool steering : 1;
bool unlimitedSpeed : 1;
bool unknown0x20000000 : 1;
bool unknown0x40000000 : 1;
bool unknown0x80000000 : 1;
template <MoveSplineFlagEnum Flag>
struct FlagAccessor
{
// force compile time evaluation - workaround for clang <= 14
static constexpr MoveSplineFlagEnum DisallowedFlag = std::integral_constant<MoveSplineFlagEnum, GetDisallowedFlagsFor(Flag)>::value;
constexpr operator bool() const { return (Raw & Flag) != MoveSplineFlagEnum::None; }
constexpr FlagAccessor& operator=(bool val) { if (val) { Raw = Raw & ~DisallowedFlag | Flag; } else Raw &= ~Flag; return *this; }
MoveSplineFlagEnum Raw;
};
#define MAKE_FLAG_ACCESSOR_FIELD(flag) FlagAccessor<MoveSplineFlagEnum::flag> flag
MAKE_FLAG_ACCESSOR_FIELD(Unknown_0x1);
MAKE_FLAG_ACCESSOR_FIELD(Unknown_0x2);
MAKE_FLAG_ACCESSOR_FIELD(Unknown_0x4);
MAKE_FLAG_ACCESSOR_FIELD(Unknown_0x8);
MAKE_FLAG_ACCESSOR_FIELD(FallingSlow);
MAKE_FLAG_ACCESSOR_FIELD(Done);
MAKE_FLAG_ACCESSOR_FIELD(Falling);
MAKE_FLAG_ACCESSOR_FIELD(No_Spline);
MAKE_FLAG_ACCESSOR_FIELD(Unknown_0x100);
MAKE_FLAG_ACCESSOR_FIELD(Flying);
MAKE_FLAG_ACCESSOR_FIELD(OrientationFixed);
MAKE_FLAG_ACCESSOR_FIELD(Catmullrom);
MAKE_FLAG_ACCESSOR_FIELD(Cyclic);
MAKE_FLAG_ACCESSOR_FIELD(Enter_Cycle);
MAKE_FLAG_ACCESSOR_FIELD(Frozen);
MAKE_FLAG_ACCESSOR_FIELD(TransportEnter);
MAKE_FLAG_ACCESSOR_FIELD(TransportExit);
MAKE_FLAG_ACCESSOR_FIELD(Unknown_0x20000);
MAKE_FLAG_ACCESSOR_FIELD(Unknown_0x40000);
MAKE_FLAG_ACCESSOR_FIELD(Backward);
MAKE_FLAG_ACCESSOR_FIELD(SmoothGroundPath);
MAKE_FLAG_ACCESSOR_FIELD(CanSwim);
MAKE_FLAG_ACCESSOR_FIELD(UncompressedPath);
MAKE_FLAG_ACCESSOR_FIELD(Unknown_0x800000);
MAKE_FLAG_ACCESSOR_FIELD(Animation);
MAKE_FLAG_ACCESSOR_FIELD(Parabolic);
MAKE_FLAG_ACCESSOR_FIELD(FadeObject);
MAKE_FLAG_ACCESSOR_FIELD(Steering);
MAKE_FLAG_ACCESSOR_FIELD(UnlimitedSpeed);
MAKE_FLAG_ACCESSOR_FIELD(Unknown_0x20000000);
MAKE_FLAG_ACCESSOR_FIELD(Unknown_0x40000000);
MAKE_FLAG_ACCESSOR_FIELD(Unknown_0x80000000);
#undef MAKE_FLAG_ACCESSOR_FIELD
};
#pragma pack(pop)
}
#endif // TRINITYSERVER_MOVESPLINEFLAG_H
@@ -90,11 +90,11 @@ namespace Movement
// correct first vertex
args.path[0] = real_position;
args.initialOrientation = real_position.orientation;
args.flags.enter_cycle = args.flags.cyclic;
args.flags.Enter_Cycle = args.flags.Cyclic;
move_spline.onTransport = transport;
uint32 moveFlags = unit->m_movementInfo.GetMovementFlags();
if (!args.flags.backward)
if (!args.flags.Backward)
moveFlags = (moveFlags & ~MOVEMENTFLAG_BACKWARD) | MOVEMENTFLAG_FORWARD;
else
moveFlags = (moveFlags & ~MOVEMENTFLAG_FORWARD) | MOVEMENTFLAG_BACKWARD;
@@ -169,7 +169,7 @@ namespace Movement
loc.orientation = unit->GetOrientation();
}
args.flags = MoveSplineFlag::Done;
args.flags = MoveSplineFlagEnum::Done;
unit->m_movementInfo.RemoveMovementFlag(MOVEMENTFLAG_FORWARD);
move_spline.onTransport = transport;
move_spline.Initialize(args);
@@ -194,10 +194,10 @@ namespace Movement
// Elevators also use MOVEMENTFLAG_ONTRANSPORT but we do not keep track of their position changes
args.TransformForTransport = !unit->GetTransGUID().IsEmpty();
// mix existing state into new
args.flags.canSwim = unit->CanSwim();
args.walk = unit->HasUnitMovementFlag(MOVEMENTFLAG_WALKING);
args.flags.flying = unit->HasUnitMovementFlag(MovementFlags(MOVEMENTFLAG_CAN_FLY | MOVEMENTFLAG_DISABLE_GRAVITY));
args.flags.smoothGroundPath = true; // enabled by default, CatmullRom mode or client config "pathSmoothing" will disable this
args.flags.CanSwim = unit->CanSwim();
args.flags.Flying = unit->HasUnitMovementFlag(MovementFlags(MOVEMENTFLAG_CAN_FLY | MOVEMENTFLAG_DISABLE_GRAVITY));
args.flags.SmoothGroundPath = !args.flags.Flying && !args.flags.Steering; // enabled by default, CatmullRom mode or client config "pathSmoothing" will disable this
}
MoveSplineInit::~MoveSplineInit() = default;
@@ -276,8 +276,8 @@ namespace Movement
void MoveSplineInit::SetFall()
{
args.flags.EnableFalling();
args.flags.fallingSlow = unit->HasUnitMovementFlag(MOVEMENTFLAG_FALLING_SLOW);
args.flags.Falling = true;
args.flags.FallingSlow = unit->HasUnitMovementFlag(MOVEMENTFLAG_FALLING_SLOW);
}
Vector3 TransportPathTransform::operator()(Vector3 input)
@@ -162,23 +162,23 @@ namespace Movement
Unit* unit;
};
inline void MoveSplineInit::SetFly() { args.flags.EnableFlying(); }
inline void MoveSplineInit::SetFly() { args.flags.Flying = true; }
inline void MoveSplineInit::SetWalk(bool enable) { args.walk = enable; }
inline void MoveSplineInit::SetSmooth() { args.flags.EnableCatmullRom(); }
inline void MoveSplineInit::SetUncompressed() { args.flags.uncompressedPath = true; }
inline void MoveSplineInit::SetCyclic() { args.flags.cyclic = true; }
inline void MoveSplineInit::SetSmooth() { args.flags.Catmullrom = true; }
inline void MoveSplineInit::SetUncompressed() { args.flags.UncompressedPath = true; }
inline void MoveSplineInit::SetCyclic() { args.flags.Cyclic = true; }
inline void MoveSplineInit::SetVelocity(float vel) { args.velocity = vel; args.HasVelocity = true; }
inline void MoveSplineInit::SetBackward() { args.flags.backward = true;}
inline void MoveSplineInit::SetTransportEnter() { args.flags.EnableTransportEnter(); }
inline void MoveSplineInit::SetTransportExit() { args.flags.EnableTransportExit(); }
inline void MoveSplineInit::SetOrientationFixed(bool enable) { args.flags.orientationFixed = enable; }
inline void MoveSplineInit::SetBackward() { args.flags.Backward = true; }
inline void MoveSplineInit::SetTransportEnter() { args.flags.TransportEnter = true; }
inline void MoveSplineInit::SetTransportExit() { args.flags.TransportExit = true; }
inline void MoveSplineInit::SetOrientationFixed(bool enable) { args.flags.OrientationFixed = enable; }
inline void MoveSplineInit::SetParabolic(float amplitude, float time_shift)
{
args.effect_start_time_percent = time_shift;
args.parabolic_amplitude = amplitude;
args.vertical_acceleration = 0.0f;
args.flags.EnableParabolic();
args.flags.Parabolic = true;
}
inline void MoveSplineInit::SetParabolicVerticalAcceleration(float vertical_acceleration, float time_shift)
@@ -186,7 +186,7 @@ namespace Movement
args.effect_start_time_percent = time_shift;
args.parabolic_amplitude = 0.0f;
args.vertical_acceleration = vertical_acceleration;
args.flags.EnableParabolic();
args.flags.Parabolic = true;
}
inline void MoveSplineInit::SetAnimation(AnimationTier anim, Milliseconds transitionStartTime /*= 0ms*/)
@@ -194,7 +194,7 @@ namespace Movement
args.effect_start_time_percent = 0.f;
args.effect_start_time = transitionStartTime;
args.animTier = anim;
args.flags.EnableAnimation();
args.flags.Animation = true;
}
inline void MoveSplineInit::DisableTransportPathTransformations() { args.TransformForTransport = false; }
@@ -68,10 +68,10 @@ namespace Movement
bool TransformForTransport;
/** Returns true to show that the arguments were configured correctly and MoveSpline initialization will succeed. */
bool Validate(Unit* unit) const;
bool Validate(Unit const* unit);
private:
bool _checkPathLengths() const;
bool _checkPathLengths();
};
}
@@ -41,7 +41,7 @@ namespace Movement
return;
data.WriteBits(uint8(moveSpline.spline.mode()), 2);
data.WriteBit(moveSpline.splineflags & (MoveSplineFlag::Parabolic | MoveSplineFlag::Animation));
data.WriteBit(moveSpline.splineflags.HasFlag(MoveSplineFlagEnum::Parabolic | MoveSplineFlagEnum::Animation));
data.WriteBits(moveSpline.getPath().size(), 22);
switch (moveSpline.facing.type)
@@ -71,8 +71,8 @@ namespace Movement
break;
}
data.WriteBit((moveSpline.splineflags & MoveSplineFlag::Parabolic) != 0 && moveSpline.effect_start_time < moveSpline.Duration());
data.WriteBits(moveSpline.splineflags.raw(), 25);
data.WriteBit(moveSpline.splineflags.HasFlag(MoveSplineFlagEnum::Parabolic) && moveSpline.effect_start_time < moveSpline.Duration());
data.WriteBits(moveSpline.splineflags.Raw.AsUnderlyingType(), 25);
}
void PacketBuilder::WriteCreateData(MoveSpline const& moveSpline, ByteBuffer& data)
@@ -81,7 +81,7 @@ namespace Movement
{
MoveSplineFlag const& splineFlags = moveSpline.splineflags;
if ((splineFlags & MoveSplineFlag::Parabolic) && moveSpline.effect_start_time < moveSpline.Duration())
if (splineFlags.HasFlag(MoveSplineFlagEnum::Parabolic) && moveSpline.effect_start_time < moveSpline.Duration())
data << moveSpline.vertical_acceleration; // added in 3.1
data << moveSpline.timePassed();
@@ -114,7 +114,7 @@ namespace Movement
data << float(1.f); // splineInfo.duration_mod_next; added in 3.1
data << moveSpline.Duration();
if (splineFlags & (MoveSplineFlag::Parabolic | MoveSplineFlag::Animation))
if (splineFlags.HasFlag(MoveSplineFlagEnum::Parabolic | MoveSplineFlagEnum::Animation))
data << moveSpline.effect_start_time; // added in 3.1
data << float(1.f); // splineInfo.duration_mod; added in 3.1
@@ -19,6 +19,10 @@
#define TRINITYSERVER_TYPEDEFS_H
#include "Common.h"
enum MovementFlags : uint32;
enum MovementFlags2 : uint32;
namespace G3D
{
class Vector3;
@@ -78,8 +82,8 @@ namespace Movement
TC_GAME_API extern float gravity;
TC_GAME_API extern UInt32Counter splineIdGen;
extern std::string MovementFlags_ToString(uint32 flags);
extern std::string MovementFlagsExtra_ToString(uint32 flags);
TC_GAME_API extern std::string MovementFlags_ToString(MovementFlags flags);
TC_GAME_API extern std::string MovementFlags_ToString(MovementFlags2 flags);
}
#endif // TRINITYSERVER_TYPEDEFS_H
@@ -16,6 +16,7 @@
*/
#include "MoveSplineFlag.h"
#include "MovementTypedefs.h"
#include <cmath>
namespace Movement
@@ -178,10 +179,10 @@ namespace Movement
STR(Unknown9 ), // 0x80000000,
};
template<class Flags, int N>
template<class Flags, uint32 N>
void print_flags(Flags t, char const* (&names)[N], std::string& str)
{
for (int i = 0; i < N; ++i)
for (uint32 i = 0; i < N; ++i)
{
if ((t & Flags(1 << i)) && names[i] != nullptr)
str.append(" ").append(names[i]);
@@ -191,18 +192,18 @@ namespace Movement
std::string MoveSplineFlag::ToString() const
{
std::string str;
print_flags(raw(), g_SplineFlag_names, str);
print_flags(Raw.AsUnderlyingType(), g_SplineFlag_names, str);
return str;
}
std::string MovementFlags_ToString(uint32 flags)
std::string MovementFlags_ToString(MovementFlags flags)
{
std::string str;
print_flags(flags, g_MovementFlag_names, str);
return str;
}
std::string MovementFlagsExtra_ToString(uint32 flags)
std::string MovementFlagsExtra_ToString(MovementFlags2 flags)
{
std::string str;
print_flags(flags, g_MovementFlagExtra_names, str);
@@ -375,14 +375,13 @@ void WorldPackets::Movement::MonsterMove::InitializeSplineData(::Movement::MoveS
WorldPackets::Movement::MovementSpline& movementSpline = SplineData.Move;
::Movement::MoveSplineFlag splineFlags = moveSpline.splineflags;
splineFlags.enter_cycle = moveSpline.isCyclic();
movementSpline.Flags = uint32(splineFlags & uint32(~::Movement::MoveSplineFlag::Mask_No_Monster_Move));
movementSpline.Flags = uint32(splineFlags & ~::Movement::MoveSplineFlagEnum::Mask_No_Monster_Move);
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)
if (splineFlags.Animation)
{
movementSpline.Animation.emplace();
movementSpline.Animation->TierTransStartTime = moveSpline.effect_start_time;
@@ -391,7 +390,7 @@ void WorldPackets::Movement::MonsterMove::InitializeSplineData(::Movement::MoveS
movementSpline.MoveTime = moveSpline.Duration();
if (splineFlags.parabolic)
if (splineFlags.Parabolic)
{
movementSpline.JumpExtraData.emplace();
movementSpline.JumpExtraData->JumpGravity = moveSpline.vertical_acceleration;
@@ -401,15 +400,15 @@ void WorldPackets::Movement::MonsterMove::InitializeSplineData(::Movement::MoveS
::Movement::Spline<int32> const& spline = moveSpline.spline;
std::vector<G3D::Vector3> const& array = spline.getPoints();
if (splineFlags & ::Movement::MoveSplineFlag::UncompressedPath)
if (splineFlags.UncompressedPath)
{
uint32 count = spline.getPointCount() - (!splineFlags.cyclic ? 3 : 4);
uint32 count = spline.getPointCount() - (splineFlags.Cyclic ? 4 : 3);
for (uint32 i = 0; i < count; ++i)
movementSpline.Points.emplace_back(array[i + 2].x, array[i + 2].y, array[i + 2].z);
}
else
{
uint32 lastIdx = spline.getPointCount() - 3;
uint32 lastIdx = spline.getPointCount() - (splineFlags.Cyclic ? 4 : 3);
G3D::Vector3 const* realPath = &spline.getPoint(1);
movementSpline.Points.emplace_back(realPath[lastIdx].x, realPath[lastIdx].y, realPath[lastIdx].z);