using Content.Shared.IdentityManagement; using Content.Shared.Mindshield.Components; using Content.Shared.Popups; using Content.Shared.Revolutionary.Components; using Content.Shared.Stunnable; using Robust.Shared.GameStates; using Robust.Shared.Player; using Content.Shared.Antag; namespace Content.Shared.Revolutionary; public abstract class SharedRevolutionarySystem : EntitySystem { [Dependency] private readonly SharedPopupSystem _popupSystem = default!; [Dependency] private readonly SharedStunSystem _sharedStun = default!; public override void Initialize() { base.Initialize(); SubscribeLocalEvent(MindShieldImplanted); SubscribeLocalEvent(OnRevCompGetStateAttempt); SubscribeLocalEvent(OnRevCompGetStateAttempt); SubscribeLocalEvent(DirtyRevComps); SubscribeLocalEvent(DirtyRevComps); SubscribeLocalEvent(DirtyRevComps); } /// /// When the mindshield is implanted in the rev it will popup saying they were deconverted. In Head Revs it will remove the mindshield component. /// private void MindShieldImplanted(EntityUid uid, MindShieldComponent comp, MapInitEvent init) { if (HasComp(uid)) { RemCompDeferred(uid); return; } if (HasComp(uid)) { var stunTime = TimeSpan.FromSeconds(4); var name = Identity.Entity(uid, EntityManager); RemComp(uid); _sharedStun.TryUpdateParalyzeDuration(uid, stunTime); _popupSystem.PopupEntity(Loc.GetString("rev-break-control", ("name", name)), uid); } } /// /// Determines if a HeadRev component should be sent to the client. /// private void OnRevCompGetStateAttempt(EntityUid uid, HeadRevolutionaryComponent comp, ref ComponentGetStateAttemptEvent args) { args.Cancelled = !CanGetState(args.Player); } /// /// Determines if a Rev component should be sent to the client. /// private void OnRevCompGetStateAttempt(EntityUid uid, RevolutionaryComponent comp, ref ComponentGetStateAttemptEvent args) { args.Cancelled = !CanGetState(args.Player); } /// /// The criteria that determine whether a Rev/HeadRev component should be sent to a client. /// /// The Player the component will be sent to. /// private bool CanGetState(ICommonSession? player) { //Apparently this can be null in replays so I am just returning true. if (player?.AttachedEntity is not {} uid) return true; if (HasComp(uid) || HasComp(uid)) return true; return HasComp(uid); } /// /// Dirties all the Rev components so they are sent to clients. /// /// We need to do this because if a rev component was not earlier sent to a client and for example the client /// becomes a rev then we need to send all the components to it. To my knowledge there is no way to do this on a /// per client basis so we are just dirtying all the components. /// private void DirtyRevComps(EntityUid someUid, T someComp, ComponentStartup ev) { var revComps = AllEntityQuery(); while (revComps.MoveNext(out var uid, out var comp)) { Dirty(uid, comp); } var headRevComps = AllEntityQuery(); while (headRevComps.MoveNext(out var uid, out var comp)) { Dirty(uid, comp); } } }