feat(vfx): port retail hidden and teleport presentation
Preserve canonical live-object ownership across Hidden transitions and remote teleport placement so effects, collision, streaming, and targeting remain synchronized.
This commit is contained in:
parent
a51ebc66e9
commit
1e98d81448
46 changed files with 4883 additions and 127 deletions
|
|
@ -149,6 +149,17 @@ public sealed class PlayerMovementController
|
|||
/// </summary>
|
||||
public uint LocalEntityId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Applies the canonical server PhysicsState to the local body. Retail's
|
||||
/// <c>CPhysicsObj::SetState</c> replaces these persistent bits before its
|
||||
/// next acceleration/integration decision.
|
||||
/// </summary>
|
||||
public void ApplyPhysicsState(PhysicsStateFlags state)
|
||||
{
|
||||
_body.State = state;
|
||||
_body.calc_acceleration();
|
||||
}
|
||||
|
||||
public bool IsAirborne => !_body.OnWalkable;
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -571,6 +582,86 @@ public sealed class PlayerMovementController
|
|||
return Vector3.Lerp(_prevPhysicsPos, _currPhysicsPos, alpha);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retail Hidden slice of <c>CPhysicsObj::UpdatePositionInternal</c>
|
||||
/// (0x00512C30). Input, PartArray root motion, and physics integration are
|
||||
/// skipped, while PositionManager composition and the manager tail remain
|
||||
/// live. A composed offset still commits through CTransition so cell
|
||||
/// membership and contact state cannot become stale behind the hidden mesh.
|
||||
/// </summary>
|
||||
public MovementResult TickHidden(float dt)
|
||||
{
|
||||
_simTimeSeconds += dt;
|
||||
_physicsAccum = 0f;
|
||||
Vector3 previousPosition = _body.Position;
|
||||
bool previousContact = _body.InContact;
|
||||
bool previousOnWalkable = _body.OnWalkable;
|
||||
|
||||
if (PositionManager is { } manager)
|
||||
{
|
||||
var delta = new AcDream.Core.Physics.Motion.MotionDeltaFrame();
|
||||
manager.AdjustOffset(delta, dt);
|
||||
if (delta.Origin != Vector3.Zero)
|
||||
_body.Position += Vector3.Transform(delta.Origin, _body.Orientation);
|
||||
if (!delta.Orientation.IsIdentity)
|
||||
{
|
||||
Yaw = AcDream.Core.Physics.Motion.MoveToMath.YawFromHeading(
|
||||
AcDream.Core.Physics.Motion.MoveToMath.HeadingFromYaw(Yaw)
|
||||
+ delta.GetHeading());
|
||||
_body.Orientation = Quaternion.CreateFromAxisAngle(
|
||||
Vector3.UnitZ,
|
||||
Yaw - MathF.PI / 2f);
|
||||
}
|
||||
}
|
||||
|
||||
if (_body.Position != previousPosition && CellId != 0 && _physics.LandblockCount > 0)
|
||||
{
|
||||
ResolveResult resolved = _physics.ResolveWithTransition(
|
||||
previousPosition,
|
||||
_body.Position,
|
||||
CellId,
|
||||
sphereRadius: 0.48f,
|
||||
sphereHeight: 1.835f,
|
||||
stepUpHeight: StepUpHeight,
|
||||
stepDownHeight: StepDownHeight,
|
||||
isOnGround: previousOnWalkable,
|
||||
body: _body,
|
||||
moverFlags: ObjectInfoState.IsPlayer | ObjectInfoState.EdgeSlide,
|
||||
movingEntityId: LocalEntityId);
|
||||
_body.Position = resolved.Position;
|
||||
PhysicsObjUpdate.CommitSetPositionTransition(
|
||||
_body,
|
||||
resolved.InContact,
|
||||
resolved.OnWalkable,
|
||||
resolved.CollisionNormalValid,
|
||||
resolved.CollisionNormal,
|
||||
previousContact,
|
||||
previousOnWalkable,
|
||||
Movement.HitGround,
|
||||
_motion.LeaveGround);
|
||||
UpdateCellId(resolved.CellId, "hidden-position-manager");
|
||||
}
|
||||
|
||||
Movement.UseTime();
|
||||
PositionManager?.UseTime();
|
||||
_prevPhysicsPos = _body.Position;
|
||||
_currPhysicsPos = _body.Position;
|
||||
_wasAirborneLastFrame = !_body.OnWalkable;
|
||||
|
||||
return new MovementResult(
|
||||
Position: _body.Position,
|
||||
RenderPosition: _body.Position,
|
||||
CellId: CellId,
|
||||
IsOnGround: _body.OnWalkable,
|
||||
MotionStateChanged: false,
|
||||
ForwardCommand: null,
|
||||
SidestepCommand: null,
|
||||
TurnCommand: null,
|
||||
ForwardSpeed: null,
|
||||
SidestepSpeed: null,
|
||||
TurnSpeed: null);
|
||||
}
|
||||
|
||||
public MovementResult Update(float dt, MovementInput input)
|
||||
{
|
||||
_simTimeSeconds += dt;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue