using Content.Shared.Movement.Components; namespace Content.Shared.Movement.Systems; public abstract partial class SharedMoverController { private void InitializeRelay() { SubscribeLocalEvent(OnRelayShutdown); SubscribeLocalEvent(OnTargetRelayShutdown); SubscribeLocalEvent(OnAfterRelayTargetState); SubscribeLocalEvent(OnAfterRelayState); } private void OnAfterRelayTargetState(Entity entity, ref AfterAutoHandleStateEvent args) { Physics.UpdateIsPredicted(entity.Owner); } private void OnAfterRelayState(Entity entity, ref AfterAutoHandleStateEvent args) { Physics.UpdateIsPredicted(entity.Owner); } /// /// Sets the relay entity and marks the component as dirty. This only exists because people have previously /// forgotten to Dirty(), so fuck you, you have to use this method now. /// public void SetRelay(EntityUid uid, EntityUid relayEntity) { if (uid == relayEntity) { Log.Error($"An entity attempted to relay movement to itself. Entity:{ToPrettyString(uid)}"); return; } var component = EnsureComp(uid); if (component.RelayEntity == relayEntity) return; if (TryComp(component.RelayEntity, out MovementRelayTargetComponent? oldTarget)) { oldTarget.Source = EntityUid.Invalid; RemComp(component.RelayEntity, oldTarget); Physics.UpdateIsPredicted(component.RelayEntity); } var targetComp = EnsureComp(relayEntity); if (TryComp(targetComp.Source, out RelayInputMoverComponent? oldRelay)) { oldRelay.RelayEntity = EntityUid.Invalid; RemComp(targetComp.Source, oldRelay); Physics.UpdateIsPredicted(targetComp.Source); } Physics.UpdateIsPredicted(uid); Physics.UpdateIsPredicted(relayEntity); component.RelayEntity = relayEntity; targetComp.Source = uid; Dirty(uid, component); Dirty(relayEntity, targetComp); } private void OnRelayShutdown(Entity entity, ref ComponentShutdown args) { Physics.UpdateIsPredicted(entity.Owner); Physics.UpdateIsPredicted(entity.Comp.RelayEntity); if (TryComp(entity.Comp.RelayEntity, out var inputMover)) SetMoveInput((entity.Comp.RelayEntity, inputMover), MoveButtons.None); if (Timing.ApplyingState) return; if (TryComp(entity.Comp.RelayEntity, out MovementRelayTargetComponent? target) && target.LifeStage <= ComponentLifeStage.Running) RemComp(entity.Comp.RelayEntity, target); } private void OnTargetRelayShutdown(Entity entity, ref ComponentShutdown args) { Physics.UpdateIsPredicted(entity.Owner); Physics.UpdateIsPredicted(entity.Comp.Source); if (Timing.ApplyingState) return; if (TryComp(entity.Comp.Source, out RelayInputMoverComponent? relay) && relay.LifeStage <= ComponentLifeStage.Running) RemComp(entity.Comp.Source, relay); } }