fix(client): restore retail interaction parity
Harden keyboard and camera routing, inventory and vendor interactions, chat/emotes, relog portal flow, and paperdoll rendering. Add retail research, connected gate coverage, and release-gate validation.
This commit is contained in:
parent
0c699240e0
commit
f6fe0f2a4f
151 changed files with 10162 additions and 1211 deletions
|
|
@ -110,7 +110,11 @@ public readonly record struct MovementResult(
|
|||
// MovementManager's complete RawMotionState into MoveToStatePack. An
|
||||
// absent style bit unpacks as NonCombat, so the canonical raw style must
|
||||
// travel with every input-boundary snapshot sent to ACE.
|
||||
uint CurrentStyle = 0x8000003Du);
|
||||
uint CurrentStyle = 0x8000003Du,
|
||||
// Retail SendMovementEvent snapshots the COMPLETE RawMotionState
|
||||
// synchronously. Command-originated motions use this one-shot override so
|
||||
// the action FIFO/state survives the render-tick input projection.
|
||||
RawMotionState? RawMotionStateOverride = null);
|
||||
|
||||
/// <summary>
|
||||
/// Portal-space state for the player movement controller.
|
||||
|
|
@ -530,6 +534,25 @@ public sealed class PlayerMovementController
|
|||
/// </summary>
|
||||
public JumpChargeSnapshot JumpCharge
|
||||
=> new(_jumpCharging, _jumpCharging ? _jumpExtent : 0f);
|
||||
|
||||
/// <summary>
|
||||
/// Retail <c>CommandInterpreter::IsStandingStill</c>: the exact motion-
|
||||
/// interpreter predicate consumed by Escape before it reaches selection
|
||||
/// or the Gameplay Options fallback.
|
||||
/// </summary>
|
||||
internal bool IsStandingStill => _motion.IsStandingStill();
|
||||
|
||||
/// <summary>
|
||||
/// Retail <c>ClientCombatSystem::FinishJump</c> (0x0056A9B0): end an
|
||||
/// in-progress jump power build without executing the jump and clear the
|
||||
/// standing-long-jump arm on the motion interpreter.
|
||||
/// </summary>
|
||||
internal void FinishJump()
|
||||
{
|
||||
_jumpCharging = false;
|
||||
_jumpExtent = 0f;
|
||||
_motion.StandingLongJump = false;
|
||||
}
|
||||
// Matching v11.4186 x86 resolves GetPowerBarLevel's collapsed x87
|
||||
// operands: ATTACK_POWERUP_TIME=1.0 s, DUAL_WIELD_POWERUP_TIME=0.8 s.
|
||||
// Jump uses the same shared powerbar function, so its normal fill rate is
|
||||
|
|
@ -656,6 +679,8 @@ public sealed class PlayerMovementController
|
|||
private readonly AcDream.Core.Physics.Motion.MotionDeltaFrame
|
||||
_positionManagerDeltaScratch = new();
|
||||
private bool _externalMovementEventPending;
|
||||
private RawMotionState? _externalRawMotionStatePending;
|
||||
private uint _localActionStamp;
|
||||
|
||||
// ── R4-V5: the verbatim retail MoveToManager replaces B.6 auto-walk ──
|
||||
// The B.6 DriveServerAutoWalk overlay (synthesized turn-first phase,
|
||||
|
|
@ -1441,6 +1466,34 @@ public sealed class PlayerMovementController
|
|||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retail <c>ACCmdInterp::SetMotion</c> (<c>0x0058B310</c>) with
|
||||
/// start=true: submit one raw command through the local physics-object
|
||||
/// boundary and publish the resulting movement edge on the next turn.
|
||||
/// </summary>
|
||||
internal bool RequestCommandMotion(uint motion)
|
||||
{
|
||||
EnsurePublishedForRuntimeOperation();
|
||||
TakeControlFromServer();
|
||||
var parameters =
|
||||
new AcDream.Core.Physics.Motion.MovementParameters
|
||||
{
|
||||
Autonomous = true,
|
||||
ActionStamp = _localActionStamp,
|
||||
};
|
||||
if (DoMotionAtPhysicsObjectBoundary(motion, parameters)
|
||||
!= WeenieError.None)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((motion & 0x10000000u) != 0u)
|
||||
_localActionStamp++;
|
||||
_externalRawMotionStatePending = new RawMotionState(_motion.RawState);
|
||||
_externalMovementEventPending = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
public void SetCharacterSkills(int runSkill, int jumpSkill)
|
||||
{
|
||||
EnsureConfigurationMutable();
|
||||
|
|
@ -2452,6 +2505,9 @@ public sealed class PlayerMovementController
|
|||
bool externallyRequestedMovementEvent =
|
||||
_externalMovementEventPending;
|
||||
_externalMovementEventPending = false;
|
||||
RawMotionState? externalRawMotionState =
|
||||
_externalRawMotionStatePending;
|
||||
_externalRawMotionStatePending = null;
|
||||
bool motionEdgeFired = false;
|
||||
bool movementEventRequested =
|
||||
externallyRequestedMovementEvent;
|
||||
|
|
@ -3189,7 +3245,8 @@ public sealed class PlayerMovementController
|
|||
SidestepUsesRunHold: _activeInputSidestepUsesRunHold
|
||||
&& outSidestepCmd.HasValue,
|
||||
IsMouseLookMovementEvent: mouseMovementEventDue,
|
||||
CurrentStyle: _motion.RawState.CurrentStyle);
|
||||
CurrentStyle: _motion.RawState.CurrentStyle,
|
||||
RawMotionStateOverride: externalRawMotionState);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue