Core/Movement: sync spline code which is relevant for Cataclysm with master branch
This commit is contained in:
1 parent
1d25eabb4b
commit
0e8605edb8
11 files changed
+221
-184
No files matched your search
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in new issue
Block a user