fix(anim): Phase L.1c anchor monster MoveTo prediction
Keep the retail MoveTo speed/runRate parsing from 9812965 for animation playback, but do not use the partial MoveTo state as a body-position solver. Until the full retail MoveToManager target path is ported, retain UpdatePosition-derived velocity for server-controlled creature position and prevent that velocity from clobbering the packet-derived animation cycle speed.
This commit is contained in:
parent
9812965183
commit
882a07cfde
1 changed files with 17 additions and 13 deletions
|
|
@ -226,8 +226,9 @@ public sealed class GameWindow : IDisposable
|
|||
/// <summary>
|
||||
/// True while a server MoveToObject/MoveToPosition packet is the
|
||||
/// active locomotion source. Retail runs these through MoveToManager
|
||||
/// and CMotionInterp using the packet's runRate; deriving velocity
|
||||
/// from sparse UpdatePosition deltas under-speeds combat chases.
|
||||
/// and CMotionInterp using the packet's runRate; until we port the
|
||||
/// full target solver, use this only to protect packet-derived
|
||||
/// animation speed from velocity-cycle clobbering.
|
||||
/// </summary>
|
||||
public bool ServerMoveToActive;
|
||||
/// <summary>
|
||||
|
|
@ -2452,16 +2453,6 @@ public sealed class GameWindow : IDisposable
|
|||
if (_remoteDeadReckon.TryGetValue(update.Guid, out var remoteMot))
|
||||
{
|
||||
remoteMot.ServerMoveToActive = update.MotionState.IsServerControlledMoveTo;
|
||||
if (remoteMot.ServerMoveToActive && !IsPlayerGuid(update.Guid))
|
||||
{
|
||||
// Retail MoveTo packets already carry enough state
|
||||
// for CMotionInterp to drive velocity. A velocity
|
||||
// inferred from sparse UpdatePosition packets lags
|
||||
// during combat chases and visibly under-speeds the
|
||||
// run cycle until the next hard snap.
|
||||
remoteMot.HasServerVelocity = false;
|
||||
remoteMot.ServerVelocity = System.Numerics.Vector3.Zero;
|
||||
}
|
||||
|
||||
// Forward axis (Ready / WalkForward / RunForward / WalkBackward).
|
||||
remoteMot.Motion.DoInterpretedMotion(
|
||||
|
|
@ -2685,6 +2676,11 @@ public sealed class GameWindow : IDisposable
|
|||
if (IsPlayerGuid(serverGuid)) return;
|
||||
if (rm.Airborne) return;
|
||||
if (ae.Sequencer is null) return;
|
||||
// MoveTo packets already seeded the retail speed/runRate cycle.
|
||||
// Keep UpdatePosition-derived velocity for render position only;
|
||||
// using it to choose the cycle reverts fast chases back to slow
|
||||
// velocity-estimated animation.
|
||||
if (rm.ServerMoveToActive) return;
|
||||
|
||||
var plan = AcDream.Core.Physics.ServerControlledLocomotion
|
||||
.PlanFromVelocity(velocity);
|
||||
|
|
@ -2771,7 +2767,6 @@ public sealed class GameWindow : IDisposable
|
|||
System.Numerics.Vector3? serverVelocity = update.Velocity;
|
||||
if (serverVelocity is null
|
||||
&& !IsPlayerGuid(update.Guid)
|
||||
&& !rmState.ServerMoveToActive
|
||||
&& rmState.LastServerPosTime > 0.0)
|
||||
{
|
||||
double elapsed = nowSec - rmState.LastServerPosTime;
|
||||
|
|
@ -5047,6 +5042,15 @@ public sealed class GameWindow : IDisposable
|
|||
rm.Body.Velocity = rm.ServerVelocity;
|
||||
}
|
||||
}
|
||||
else if (!IsPlayerGuid(serverGuid) && rm.ServerMoveToActive)
|
||||
{
|
||||
// We only parse enough of MoveTo to recover retail
|
||||
// animation speed. Do not let apply_current_movement
|
||||
// extrapolate position from an incomplete target
|
||||
// solver; hold until the next UpdatePosition-derived
|
||||
// velocity arrives.
|
||||
rm.Body.Velocity = System.Numerics.Vector3.Zero;
|
||||
}
|
||||
else
|
||||
{
|
||||
rm.Motion.apply_current_movement(cancelMoveTo: false, allowJump: false);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue