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);