diff --git a/src/server/game/Movement/MotionMaster.cpp b/src/server/game/Movement/MotionMaster.cpp index 40476c5597..12e4a3aa85 100644 --- a/src/server/game/Movement/MotionMaster.cpp +++ b/src/server/game/Movement/MotionMaster.cpp @@ -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); diff --git a/src/server/game/Movement/Spline/MoveSpline.cpp b/src/server/game/Movement/Spline/MoveSpline.cpp index 660341274e..1c99ef5f35 100644 --- a/src/server/game/Movement/Spline/MoveSpline.cpp +++ b/src/server/game/Movement/Spline/MoveSpline.cpp @@ -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(); } diff --git a/src/server/game/Movement/Spline/MoveSpline.h b/src/server/game/Movement/Spline/MoveSpline.h index b45f9f9f00..f03da7c77b 100644 --- a/src/server/game/Movement/Spline/MoveSpline.h +++ b/src/server/game/Movement/Spline/MoveSpline.h @@ -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; diff --git a/src/server/game/Movement/Spline/MoveSplineFlag.h b/src/server/game/Movement/Spline/MoveSplineFlag.h index 47b29d58da..28e7830285 100644 --- a/src/server/game/Movement/Spline/MoveSplineFlag.h +++ b/src/server/game/Movement/Spline/MoveSplineFlag.h @@ -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 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 + struct FlagAccessor + { + // force compile time evaluation - workaround for clang <= 14 + static constexpr MoveSplineFlagEnum DisallowedFlag = std::integral_constant::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 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 diff --git a/src/server/game/Movement/Spline/MoveSplineInit.cpp b/src/server/game/Movement/Spline/MoveSplineInit.cpp index cdcae35768..8a9770c7ee 100644 --- a/src/server/game/Movement/Spline/MoveSplineInit.cpp +++ b/src/server/game/Movement/Spline/MoveSplineInit.cpp @@ -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) diff --git a/src/server/game/Movement/Spline/MoveSplineInit.h b/src/server/game/Movement/Spline/MoveSplineInit.h index 886197022b..dafcf32c65 100644 --- a/src/server/game/Movement/Spline/MoveSplineInit.h +++ b/src/server/game/Movement/Spline/MoveSplineInit.h @@ -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; } diff --git a/src/server/game/Movement/Spline/MoveSplineInitArgs.h b/src/server/game/Movement/Spline/MoveSplineInitArgs.h index 0cf98b48ea..bd188da6dc 100644 --- a/src/server/game/Movement/Spline/MoveSplineInitArgs.h +++ b/src/server/game/Movement/Spline/MoveSplineInitArgs.h @@ -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(); }; } diff --git a/src/server/game/Movement/Spline/MovementPacketBuilder.cpp b/src/server/game/Movement/Spline/MovementPacketBuilder.cpp index d3f8d1390b..1e89841643 100644 --- a/src/server/game/Movement/Spline/MovementPacketBuilder.cpp +++ b/src/server/game/Movement/Spline/MovementPacketBuilder.cpp @@ -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 diff --git a/src/server/game/Movement/Spline/MovementTypedefs.h b/src/server/game/Movement/Spline/MovementTypedefs.h index 513eef1dac..3bd40b494b 100644 --- a/src/server/game/Movement/Spline/MovementTypedefs.h +++ b/src/server/game/Movement/Spline/MovementTypedefs.h @@ -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 diff --git a/src/server/game/Movement/Spline/MovementUtil.cpp b/src/server/game/Movement/Spline/MovementUtil.cpp index 0258d3a1e1..a6cf262d01 100644 --- a/src/server/game/Movement/Spline/MovementUtil.cpp +++ b/src/server/game/Movement/Spline/MovementUtil.cpp @@ -16,6 +16,7 @@ */ #include "MoveSplineFlag.h" +#include "MovementTypedefs.h" #include namespace Movement @@ -178,10 +179,10 @@ namespace Movement STR(Unknown9 ), // 0x80000000, }; - template + template 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); diff --git a/src/server/game/Server/Packets/MovementPackets.cpp b/src/server/game/Server/Packets/MovementPackets.cpp index 0742e452c1..160d7e0901 100644 --- a/src/server/game/Server/Packets/MovementPackets.cpp +++ b/src/server/game/Server/Packets/MovementPackets.cpp @@ -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 const& spline = moveSpline.spline; std::vector 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);