using Content.Shared.Disposal.Components; using Content.Shared.Disposal.Holder; using Content.Shared.Follower; using Content.Shared.Follower.Components; using Content.Shared.Interaction.Events; namespace Content.Shared.Disposal.Unit; /// /// This system handles entities that are currently being flushed through /// the disposals system. These entities should all have a temporary /// . /// public abstract partial class SharedBeingDisposedSystem : EntitySystem { [Dependency] private SharedDisposalHolderSystem _disposalHolder = default!; public override void Initialize() { base.Initialize(); SubscribeLocalEvent(OnTransition); SubscribeLocalEvent(OnShutdown); SubscribeLocalEvent(OnStartedFollowing); SubscribeLocalEvent(OnStoppedFollowing); SubscribeLocalEvent(OnInteractionAttempt); SubscribeLocalEvent(OnAttackAttempt); } private void OnTransition(Entity ent, ref DisposalSystemTransitionEvent args) { if (!TryComp(ent.Comp.Holder, out var holder)) return; if (!TryComp(ent, out var followed)) return; // Any followers of the entity will also be attached to its disposal holder. // This is so that movement under subfloors can be predicted by follower clients. foreach (var follower in followed.Following) { _disposalHolder.AttachEntity((ent.Comp.Holder, holder), follower); } } private void OnShutdown(Entity ent, ref ComponentShutdown args) { // Remove followers from the disposal holder if (!TryComp(ent, out var followed)) return; foreach (var follower in followed.Following) { _disposalHolder.DetachEntity(follower); } } private void OnStartedFollowing(Entity ent, ref EntityStartedFollowingEvent args) { // Attach new followers to the disposal holder to prevent mispredicts if (!TryComp(ent.Comp.Holder, out var holder)) return; _disposalHolder.AttachEntity((ent.Comp.Holder, holder), args.Follower); } private void OnStoppedFollowing(Entity ent, ref EntityStoppedFollowingEvent args) { // Remove departing followers from the disposal holder _disposalHolder.DetachEntity(args.Follower); } private void OnInteractionAttempt(Entity ent, ref InteractionAttemptEvent args) { // Prevent interactions while travelling through disposals args.Cancelled = true; } private void OnAttackAttempt(Entity ent, ref AttackAttemptEvent args) { // Prevent attacking while travelling through disposals args.Cancel(); } }