using AcDream.Core.Physics;
namespace AcDream.App.Physics;
///
/// Ordered App seam for retail CPhysicsObj::teleport_hook
/// (0x00514ED0). The action bundle keeps the port independently
/// testable while the concrete movement/interpolation/target owners remain
/// in the composition root.
///
public static class RemoteTeleportHook
{
private const WeenieError TeleportCancelContext = (WeenieError)0x3Cu;
public static bool Execute(
RemoteTeleportHookActions actions,
Func? isCurrent = null)
{
ArgumentNullException.ThrowIfNull(actions.CancelMoveTo);
ArgumentNullException.ThrowIfNull(actions.UnStick);
ArgumentNullException.ThrowIfNull(actions.StopInterpolating);
ArgumentNullException.ThrowIfNull(actions.UnConstrain);
ArgumentNullException.ThrowIfNull(actions.NotifyTeleported);
ArgumentNullException.ThrowIfNull(actions.ReportCollisionEnd);
bool Current() => isCurrent?.Invoke() ?? true;
if (!Current())
return false;
actions.CancelMoveTo(TeleportCancelContext);
if (!Current())
return false;
actions.UnStick();
if (!Current())
return false;
actions.StopInterpolating();
if (!Current())
return false;
actions.UnConstrain();
if (!Current())
return false;
actions.NotifyTeleported();
if (!Current())
return false;
actions.ReportCollisionEnd();
return Current();
}
}
public sealed record RemoteTeleportHookActions(
Action CancelMoveTo,
Action UnStick,
Action StopInterpolating,
Action UnConstrain,
Action NotifyTeleported,
Action ReportCollisionEnd);