refactor(interaction): add selection interaction owner

Introduce a tested controller for selection mutations, target-mode interception, outbound ordering, Use/PickUp lifetime, and live-incarnation cleanup, plus narrow movement and WorldSession transport adapters.
This commit is contained in:
Erik 2026-07-21 07:24:26 +02:00
parent e74f2ca99a
commit fa8d5232cc
5 changed files with 754 additions and 1 deletions

View file

@ -0,0 +1,57 @@
using AcDream.App.Input;
using AcDream.Core.Physics;
using AcDream.Core.Physics.Motion;
namespace AcDream.App.Interaction;
internal interface IPlayerInteractionMovementSink
{
bool BeginApproach(InteractionApproach approach);
}
/// <summary>
/// Installs retail's client-side TurnToObject/MoveToObject prediction through
/// the same MovementManager used by authoritative movement packets.
/// </summary>
internal sealed class PlayerInteractionMovementSink(
Func<PlayerMovementController?> player)
: IPlayerInteractionMovementSink
{
private readonly Func<PlayerMovementController?> _player = player
?? throw new ArgumentNullException(nameof(player));
public bool BeginApproach(InteractionApproach approach)
{
PlayerMovementController? controller = _player();
if (controller?.MoveTo is null)
return false;
var parameters = new MovementParameters
{
DistanceToObject = approach.UseRadius,
CanCharge = approach.CanCharge,
};
var movement = new MovementStruct
{
ObjectId = approach.Target.ServerGuid,
TopLevelId = approach.Target.ServerGuid,
Pos = new Position(
approach.Player.CellId,
approach.Target.Entity.Position,
System.Numerics.Quaternion.Identity),
Params = parameters,
Type = approach.IsCloseRange
? MovementType.TurnToObject
: MovementType.MoveToObject,
Radius = approach.TargetRadius,
Height = approach.TargetHeight,
};
// P1's wire MoveToObject store marks the command non-autonomous.
// The speculative local install must do the same or the next raw-input
// pump overwrites it before ACE's authoritative movement arrives.
controller.SetLastMoveWasAutonomous(false);
controller.Movement.PerformMovement(movement);
return true;
}
}