Implements IWeenieObject with GetRunRate and GetJumpHeight from decompiled client, cross-referenced against ACE MovementSystem. Default skills (Run=200, Jump=100) used until skill parsing ships. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
81 lines
2.5 KiB
C#
81 lines
2.5 KiB
C#
namespace AcDream.Core.Physics;
|
|
|
|
/// <summary>
|
|
/// IWeenieObject implementation for the local player. Provides skill-based
|
|
/// run rate and jump velocity calculations.
|
|
///
|
|
/// Formulas from decompiled acclient.exe, cross-referenced against
|
|
/// ACE MovementSystem.GetRunRate and MovementSystem.GetJumpHeight.
|
|
/// </summary>
|
|
public sealed class PlayerWeenie : IWeenieObject
|
|
{
|
|
private int _runSkill;
|
|
private int _jumpSkill;
|
|
private float _burden;
|
|
|
|
public PlayerWeenie(int runSkill = 0, int jumpSkill = 0, float burden = 0f)
|
|
{
|
|
_runSkill = runSkill;
|
|
_jumpSkill = jumpSkill;
|
|
_burden = burden;
|
|
}
|
|
|
|
public void SetSkills(int runSkill, int jumpSkill)
|
|
{
|
|
_runSkill = runSkill;
|
|
_jumpSkill = jumpSkill;
|
|
}
|
|
|
|
public void SetBurden(float burden) => _burden = burden;
|
|
|
|
public bool InqRunRate(out float rate)
|
|
{
|
|
rate = GetRunRate(_burden, _runSkill);
|
|
return true;
|
|
}
|
|
|
|
public bool InqJumpVelocity(float extent, out float vz)
|
|
{
|
|
float height = GetJumpHeight(_burden, _jumpSkill, extent);
|
|
vz = MathF.Sqrt(height * 19.6f);
|
|
return true;
|
|
}
|
|
|
|
public bool CanJump(float extent) => true; // burden/stamina checks deferred
|
|
|
|
/// <summary>
|
|
/// RunRate = (burdenMod * (runSkill / (runSkill + 200)) * 11 + 4) / 4
|
|
/// Capped at 4.5 when runSkill >= 800.
|
|
/// Source: decompiled + ACE MovementSystem.GetRunRate
|
|
/// </summary>
|
|
public static float GetRunRate(float burden, int runSkill)
|
|
{
|
|
if (runSkill >= 800) return 18f / 4f;
|
|
float loadMod = GetBurdenMod(burden);
|
|
return (loadMod * ((float)runSkill / (runSkill + 200) * 11f) + 4f) / 4f;
|
|
}
|
|
|
|
/// <summary>
|
|
/// JumpHeight = burdenMod * (jumpSkill / (jumpSkill + 1300) * 22.2 + 0.05) * extent
|
|
/// Clamped to minimum 0.35m.
|
|
/// Source: decompiled + ACE MovementSystem.GetJumpHeight
|
|
/// </summary>
|
|
public static float GetJumpHeight(float burden, int jumpSkill, float extent)
|
|
{
|
|
extent = Math.Clamp(extent, 0f, 1f);
|
|
float loadMod = GetBurdenMod(burden);
|
|
float height = loadMod * ((float)jumpSkill / (jumpSkill + 1300f) * 22.2f + 0.05f) * extent;
|
|
return MathF.Max(height, 0.35f);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Encumbrance modifier: 1.0 when unloaded, linearly decreasing to 0 at 200%.
|
|
/// Source: decompiled + ACE EncumbranceSystem.GetBurdenMod
|
|
/// </summary>
|
|
public static float GetBurdenMod(float burden)
|
|
{
|
|
if (burden < 1f) return 1f;
|
|
if (burden < 2f) return 2f - burden;
|
|
return 0f;
|
|
}
|
|
}
|