using Content.Shared.Stealth; using Content.Shared.Stealth.Components; using Content.Shared.Whitelist; using Robust.Shared.Physics.Events; using Robust.Shared.Physics.Systems; using Robust.Shared.Timing; namespace Content.Server.Psionics { /// /// Allows an entity to become psionically invisible when touching certain entities. /// public sealed class PsionicInvisibleContactsSystem : EntitySystem { [Dependency] private readonly SharedStealthSystem _stealth = default!; [Dependency] private readonly IGameTiming _gameTiming = default!; [Dependency] private readonly EntityWhitelistSystem _whitelistSystem = default!; public override void Initialize() { base.Initialize(); SubscribeLocalEvent(OnEntityEnter); SubscribeLocalEvent(OnEntityExit); UpdatesAfter.Add(typeof(SharedPhysicsSystem)); } private void OnEntityEnter(EntityUid uid, PsionicInvisibleContactsComponent component, ref StartCollideEvent args) { var otherUid = args.OtherEntity; var ourEntity = args.OurEntity; if (_whitelistSystem.IsWhitelistFail(component.Whitelist, otherUid)) return; // This will go up twice per web hit, since webs also have a flammable fixture. // It goes down twice per web exit, so everything's fine. ++component.Stages; if (HasComp(ourEntity)) return; EnsureComp(ourEntity); var stealth = EnsureComp(ourEntity); _stealth.SetVisibility(ourEntity, 0.66f, stealth); } private void OnEntityExit(EntityUid uid, PsionicInvisibleContactsComponent component, ref EndCollideEvent args) { var otherUid = args.OtherEntity; var ourEntity = args.OurEntity; if (_whitelistSystem.IsWhitelistFail(component.Whitelist, otherUid)) return; if (!HasComp(ourEntity)) return; if (--component.Stages > 0) return; RemComp(ourEntity); var stealth = EnsureComp(ourEntity); // Just to be sure... _stealth.SetVisibility(ourEntity, 1f, stealth); RemComp(ourEntity); } } }