mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-02-05 16:39:08 +01:00
Core/Movement: Switch to uncompressed paths in spline packets automatically when too large or too small delta between points is detected
(cherry picked from commit 377b51f768)
This commit is contained in:
@@ -571,25 +571,6 @@ void WaypointMovementGenerator<Creature>::StartMove(Creature* owner, bool relaun
|
||||
if (_speed)
|
||||
init.SetVelocity(*_speed);
|
||||
|
||||
if (init.Path().size() > 2)
|
||||
{
|
||||
G3D::Vector3 mid = (init.Path().front() + init.Path().back()) / 2.0f;
|
||||
auto itr = init.Path().begin() + 1;
|
||||
auto end = itr + (init.Path().size() - 2);
|
||||
while (itr != end)
|
||||
{
|
||||
G3D::Vector3 offset = *itr - mid;
|
||||
if (std::fabs(offset.x) >= 128.0f || std::fabs(offset.y) >= 128.0f || std::fabs(offset.z) >= 64.0f)
|
||||
{
|
||||
// when distance is too great, send path in uncompressed state otherwise too much precision is lost on each point
|
||||
init.SetUncompressed();
|
||||
break;
|
||||
}
|
||||
|
||||
++itr;
|
||||
}
|
||||
}
|
||||
|
||||
Milliseconds duration(init.Launch());
|
||||
|
||||
if (!IsExactSplinePath()
|
||||
|
||||
@@ -238,37 +238,59 @@ MoveSpline::MoveSpline() : m_Id(0), time_passed(0),
|
||||
|
||||
/// ============================================================================================
|
||||
|
||||
bool MoveSplineInitArgs::Validate(Unit* unit) const
|
||||
bool MoveSplineInitArgs::Validate(Unit const* unit)
|
||||
{
|
||||
#define CHECK(exp, verbose) \
|
||||
if (!(exp))\
|
||||
do if (!(exp))\
|
||||
{\
|
||||
if (unit)\
|
||||
TC_LOG_ERROR("misc.movesplineinitargs", "MoveSplineInitArgs::Validate: expression '{}' failed for {}", #exp, (verbose ? unit->GetDebugInfo() : unit->GetGUID().ToString()));\
|
||||
TC_LOG_ERROR("misc.movesplineinitargs", "MoveSplineInitArgs::Validate: expression '{}' failed for {}", #exp, verbose);\
|
||||
else\
|
||||
TC_LOG_ERROR("misc.movesplineinitargs", "MoveSplineInitArgs::Validate: expression '{}' failed for cyclic spline continuation", #exp); \
|
||||
return false;\
|
||||
}
|
||||
CHECK(path.size() > 1, true);
|
||||
CHECK(velocity >= 0.01f, true);
|
||||
CHECK(effect_start_time_percent >= 0.f && effect_start_time_percent <= 1.f, true);
|
||||
CHECK(_checkPathLengths(), false);
|
||||
} while (0)
|
||||
CHECK(path.size() > 1, unit->GetDebugInfo());
|
||||
CHECK(velocity >= 0.01f, unit->GetDebugInfo());
|
||||
CHECK(effect_start_time_percent >= 0.f && effect_start_time_percent <= 1.f, unit->GetDebugInfo());
|
||||
CHECK(_checkPathLengths(), unit->GetGUID());
|
||||
if (spellEffectExtra)
|
||||
{
|
||||
CHECK(!spellEffectExtra->ProgressCurveId || sCurveStore.LookupEntry(spellEffectExtra->ProgressCurveId), true);
|
||||
CHECK(!spellEffectExtra->ParabolicCurveId || sCurveStore.LookupEntry(spellEffectExtra->ParabolicCurveId), true);
|
||||
CHECK(!spellEffectExtra->ProgressCurveId || sCurveStore.LookupEntry(spellEffectExtra->ProgressCurveId), unit->GetDebugInfo());
|
||||
CHECK(!spellEffectExtra->ParabolicCurveId || sCurveStore.LookupEntry(spellEffectExtra->ParabolicCurveId), unit->GetDebugInfo());
|
||||
}
|
||||
return true;
|
||||
#undef CHECK
|
||||
}
|
||||
|
||||
// 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_OFFSET = 1.0f / 4.0f;
|
||||
constexpr float MAX_XY_OFFSET = (1 << 11) / 4.0f;
|
||||
constexpr float MAX_Z_OFFSET = (1 << 10) / 4.0f;
|
||||
|
||||
auto isValidPackedXYOffset = [](float coord) -> bool { return coord < MAX_XY_OFFSET && (coord < 0.1f || coord >= MIN_OFFSET); };
|
||||
auto isValidPackedZOffset = [](float coord) -> bool { return coord < MAX_Z_OFFSET && (coord < 0.1f || coord >= MIN_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(std::fabs(path[i].x - middle.x))
|
||||
|| !isValidPackedXYOffset(std::fabs(path[i].y - middle.y))
|
||||
|| !isValidPackedZOffset(std::fabs(path[i].z - middle.z)))
|
||||
flags.uncompressedPath = true;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -97,9 +97,9 @@ 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; }
|
||||
|
||||
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; }
|
||||
|
||||
@@ -84,10 +84,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();
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user