using Content.Shared.Damage.Components; using Content.Shared.Damage.Events; using Content.Shared.Destructible; using Content.Shared.Nutrition; using Content.Shared.Prototypes; using Content.Shared.Rejuvenate; using Content.Shared.Slippery; using Content.Shared.StatusEffect; using Content.Shared.StatusEffectNew; using Content.Shared.StatusEffectNew.Components; using Robust.Shared.Prototypes; namespace Content.Shared.Damage.Systems; public abstract class SharedGodmodeSystem : EntitySystem { [Dependency] private readonly IPrototypeManager _protoMan = default!; [Dependency] private readonly DamageableSystem _damageable = default!; public override void Initialize() { base.Initialize(); SubscribeLocalEvent(OnBeforeDamageChanged); SubscribeLocalEvent(OnBeforeStatusEffect); SubscribeLocalEvent(OnBeforeOldStatusEffect); SubscribeLocalEvent(OnBeforeStaminaDamage); SubscribeLocalEvent(BeforeEdible); SubscribeLocalEvent(OnSlipAttempt); SubscribeLocalEvent(OnDestruction); } private void OnSlipAttempt(EntityUid uid, GodmodeComponent component, SlipAttemptEvent args) { args.NoSlip = true; } private void OnBeforeDamageChanged(EntityUid uid, GodmodeComponent component, ref BeforeDamageChangedEvent args) { args.Cancelled = true; } private void OnBeforeStatusEffect(EntityUid uid, GodmodeComponent component, ref BeforeStatusEffectAddedEvent args) { if (_protoMan.Index(args.Effect).HasComponent(Factory)) args.Cancelled = true; } private void OnBeforeOldStatusEffect(Entity ent, ref BeforeOldStatusEffectAddedEvent args) { // Old status effect system doesn't distinguish between good and bad status effects args.Cancelled = true; } private void OnBeforeStaminaDamage(EntityUid uid, GodmodeComponent component, ref BeforeStaminaDamageEvent args) { args.Cancelled = true; } private void OnDestruction(Entity ent, ref DestructionAttemptEvent args) { args.Cancel(); } private void BeforeEdible(Entity ent, ref IngestibleEvent args) { args.Cancelled = true; } public virtual void EnableGodmode(EntityUid uid, GodmodeComponent? godmode = null) { godmode ??= EnsureComp(uid); if (TryComp(uid, out var damageable)) { godmode.OldDamage = new DamageSpecifier(damageable.Damage); } // Rejuv to cover other stuff RaiseLocalEvent(uid, new RejuvenateEvent()); } public virtual void DisableGodmode(EntityUid uid, GodmodeComponent? godmode = null) { if (!Resolve(uid, ref godmode, false)) return; if (godmode.OldDamage != null) { _damageable.SetDamage(uid, godmode.OldDamage); } RemComp(uid); } /// /// Toggles godmode for a given entity. /// /// The entity to toggle godmode for. /// true if enabled, false if disabled. public bool ToggleGodmode(EntityUid uid) { if (TryComp(uid, out var godmode)) { DisableGodmode(uid, godmode); return false; } EnableGodmode(uid, godmode); return true; } }