feat(movement): send jump packet to server (opcode 0xF61B)

Build and send GameAction(Jump) with extent + world-space launch
velocity + sequence counters. Wire format from holtburger
JumpActionData::pack. Server can now validate and replicate jumps
to nearby clients.

Also compute RunRate locally via PlayerWeenie.InqRunRate when
running (server doesn't echo UpdateMotion ForwardSpeed to sender).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Erik 2026-04-14 10:23:52 +02:00
parent bb7eced168
commit 5634e7114b
3 changed files with 74 additions and 6 deletions

View file

@ -32,7 +32,8 @@ public readonly record struct MovementResult(
float? ForwardSpeed,
float? SidestepSpeed,
float? TurnSpeed,
float? JumpExtent = null); // non-null when a jump was triggered this frame
float? JumpExtent = null, // non-null when a jump was triggered this frame
Vector3? JumpVelocity = null); // world-space launch velocity (sent in jump packet)
/// <summary>
/// Portal-space state for the player movement controller.
@ -259,6 +260,7 @@ public sealed class PlayerMovementController
// Release to execute: jump(extent) validates + sets JumpExtent,
// then LeaveGround() applies the scaled velocity via get_leave_ground_velocity.
float? outJumpExtent = null;
Vector3? outJumpVelocity = null;
if (input.Jump && _body.OnWalkable)
{
@ -278,6 +280,7 @@ public sealed class PlayerMovementController
{
_motion.LeaveGround();
outJumpExtent = _jumpExtent;
outJumpVelocity = _body.Velocity; // capture after LeaveGround applies it
}
_jumpCharging = false;
_jumpExtent = 0f;
@ -411,6 +414,7 @@ public sealed class PlayerMovementController
ForwardSpeed: outForwardSpeed,
SidestepSpeed: outSidestepSpeed,
TurnSpeed: outTurnSpeed,
JumpExtent: outJumpExtent);
JumpExtent: outJumpExtent,
JumpVelocity: outJumpVelocity);
}
}

View file

@ -1936,11 +1936,18 @@ public sealed class GameWindow : IDisposable
_liveSession.SendGameAction(body);
}
if (result.JumpExtent.HasValue)
if (result.JumpExtent.HasValue && result.JumpVelocity.HasValue)
{
// TODO: send jump packet to server (format needs research from holtburger).
// Local jump physics work without server acknowledgment for now.
Console.WriteLine($"jump: extent={result.JumpExtent.Value:F2}");
var seq = _liveSession.NextGameActionSequence();
var jumpBody = AcDream.Core.Net.Messages.JumpAction.Build(
gameActionSequence: seq,
extent: result.JumpExtent.Value,
velocity: result.JumpVelocity.Value,
instanceSequence: _liveSession.InstanceSequence,
serverControlSequence: _liveSession.ServerControlSequence,
teleportSequence: _liveSession.TeleportSequence,
forcePositionSequence: _liveSession.ForcePositionSequence);
_liveSession.SendGameAction(jumpBody);
}
}