Fix godmode mispredicts (#18524)

Co-authored-by: Leon Friedrich <60421075+ElectroJr@users.noreply.github.com>
This commit is contained in:
metalgearsloth
2023-08-04 14:53:07 +10:00
committed by GitHub
parent a695b15e17
commit 94e2c7a4b0
8 changed files with 138 additions and 104 deletions

View File

@@ -0,0 +1,8 @@
using Content.Shared.Damage.Systems;
namespace Content.Client.Damage;
public sealed class GodmodeSystem : SharedGodmodeSystem
{
}

View File

@@ -50,6 +50,7 @@ using Robust.Shared.Random;
using Robust.Shared.Utility; using Robust.Shared.Utility;
using Timer = Robust.Shared.Timing.Timer; using Timer = Robust.Shared.Timing.Timer;
using Content.Shared.Cluwne; using Content.Shared.Cluwne;
using Content.Shared.Damage.Systems;
namespace Content.Server.Administration.Systems; namespace Content.Server.Administration.Systems;
@@ -65,7 +66,7 @@ public sealed partial class AdminVerbSystem
[Dependency] private readonly FixtureSystem _fixtures = default!; [Dependency] private readonly FixtureSystem _fixtures = default!;
[Dependency] private readonly FlammableSystem _flammableSystem = default!; [Dependency] private readonly FlammableSystem _flammableSystem = default!;
[Dependency] private readonly GhostKickManager _ghostKickManager = default!; [Dependency] private readonly GhostKickManager _ghostKickManager = default!;
[Dependency] private readonly GodmodeSystem _godmodeSystem = default!; [Dependency] private readonly SharedGodmodeSystem _sharedGodmodeSystem = default!;
[Dependency] private readonly InventorySystem _inventorySystem = default!; [Dependency] private readonly InventorySystem _inventorySystem = default!;
[Dependency] private readonly MovementSpeedModifierSystem _movementSpeedModifierSystem = default!; [Dependency] private readonly MovementSpeedModifierSystem _movementSpeedModifierSystem = default!;
[Dependency] private readonly PolymorphSystem _polymorphSystem = default!; [Dependency] private readonly PolymorphSystem _polymorphSystem = default!;
@@ -119,7 +120,7 @@ public sealed partial class AdminVerbSystem
Icon = new SpriteSpecifier.Rsi(new ("/Textures/Objects/Fun/Tabletop/chessboard.rsi"), "chessboard"), Icon = new SpriteSpecifier.Rsi(new ("/Textures/Objects/Fun/Tabletop/chessboard.rsi"), "chessboard"),
Act = () => Act = () =>
{ {
_godmodeSystem.EnableGodmode(args.Target); // So they don't suffocate. _sharedGodmodeSystem.EnableGodmode(args.Target); // So they don't suffocate.
EnsureComp<TabletopDraggableComponent>(args.Target); EnsureComp<TabletopDraggableComponent>(args.Target);
RemComp<PhysicsComponent>(args.Target); // So they can be dragged around. RemComp<PhysicsComponent>(args.Target); // So they can be dragged around.
var xform = Transform(args.Target); var xform = Transform(args.Target);

View File

@@ -21,6 +21,7 @@ using Content.Shared.Administration;
using Content.Shared.Atmos; using Content.Shared.Atmos;
using Content.Shared.Construction.Components; using Content.Shared.Construction.Components;
using Content.Shared.Damage; using Content.Shared.Damage;
using Content.Shared.Damage.Components;
using Content.Shared.Database; using Content.Shared.Database;
using Content.Shared.Doors.Components; using Content.Shared.Doors.Components;
using Content.Shared.Hands.Components; using Content.Shared.Hands.Components;
@@ -135,7 +136,7 @@ public sealed partial class AdminVerbSystem
Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/VerbIcons/plus.svg.192dpi.png")), Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/VerbIcons/plus.svg.192dpi.png")),
Act = () => Act = () =>
{ {
_godmodeSystem.EnableGodmode(args.Target); _sharedGodmodeSystem.EnableGodmode(args.Target);
}, },
Impact = LogImpact.Extreme, Impact = LogImpact.Extreme,
Message = Loc.GetString("admin-trick-make-indestructible-description"), Message = Loc.GetString("admin-trick-make-indestructible-description"),
@@ -152,7 +153,7 @@ public sealed partial class AdminVerbSystem
Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/VerbIcons/plus.svg.192dpi.png")), Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/VerbIcons/plus.svg.192dpi.png")),
Act = () => Act = () =>
{ {
_godmodeSystem.DisableGodmode(args.Target); _sharedGodmodeSystem.DisableGodmode(args.Target);
}, },
Impact = LogImpact.Extreme, Impact = LogImpact.Extreme,
Message = Loc.GetString("admin-trick-make-vulnerable-description"), Message = Loc.GetString("admin-trick-make-vulnerable-description"),

View File

@@ -1,6 +1,7 @@
using Content.Server.Administration; using Content.Server.Administration;
using Content.Server.Damage.Systems; using Content.Server.Damage.Systems;
using Content.Shared.Administration; using Content.Shared.Administration;
using Content.Shared.Damage.Systems;
using Robust.Server.Player; using Robust.Server.Player;
using Robust.Shared.Console; using Robust.Shared.Console;
@@ -57,7 +58,7 @@ namespace Content.Server.Damage.Commands
return; return;
} }
var godmodeSystem = EntitySystem.Get<GodmodeSystem>(); var godmodeSystem = EntitySystem.Get<SharedGodmodeSystem>();
var enabled = godmodeSystem.ToggleGodmode(entity); var enabled = godmodeSystem.ToggleGodmode(entity);
var name = entityManager.GetComponent<MetaDataComponent>(entity).EntityName; var name = entityManager.GetComponent<MetaDataComponent>(entity).EntityName;

View File

@@ -1,14 +0,0 @@
using Content.Server.Damage.Systems;
using Content.Shared.Damage;
namespace Content.Server.Damage.Components;
/// <summary>
///
/// </summary>
[RegisterComponent, Access(typeof(GodmodeSystem))]
public sealed class GodmodeComponent : Component
{
public bool WasMovedByPressure;
public DamageSpecifier? OldDamage = null;
}

View File

@@ -1,98 +1,37 @@
using Content.Server.Atmos.Components; using Content.Server.Atmos.Components;
using Content.Server.Damage.Components; using Content.Shared.Damage.Components;
using Content.Shared.Damage;
using Content.Shared.Damage.Systems; using Content.Shared.Damage.Systems;
using Content.Shared.FixedPoint;
using Content.Shared.Rejuvenate;
using Content.Shared.StatusEffect;
using JetBrains.Annotations;
namespace Content.Server.Damage.Systems namespace Content.Server.Damage.Systems;
public sealed class GodmodeSystem : SharedGodmodeSystem
{ {
[UsedImplicitly] public override void EnableGodmode(EntityUid uid, GodmodeComponent? godmode = null)
public sealed class GodmodeSystem : EntitySystem
{ {
[Dependency] private readonly DamageableSystem _damageable = default!; godmode ??= EnsureComp<GodmodeComponent>(uid);
public override void Initialize() base.EnableGodmode(uid, godmode);
if (TryComp<MovedByPressureComponent>(uid, out var moved))
{ {
base.Initialize(); godmode.WasMovedByPressure = moved.Enabled;
moved.Enabled = false;
SubscribeLocalEvent<GodmodeComponent, BeforeDamageChangedEvent>(OnBeforeDamageChanged);
SubscribeLocalEvent<GodmodeComponent, BeforeStatusEffectAddedEvent>(OnBeforeStatusEffect);
SubscribeLocalEvent<GodmodeComponent, BeforeStaminaDamageEvent>(OnBeforeStaminaDamage);
} }
}
private void OnBeforeDamageChanged(EntityUid uid, GodmodeComponent component, ref BeforeDamageChangedEvent args) public override void DisableGodmode(EntityUid uid, GodmodeComponent? godmode = null)
{
if (!Resolve(uid, ref godmode, false))
return;
base.DisableGodmode(uid, godmode);
if (godmode.Deleted)
return;
if (TryComp<MovedByPressureComponent>(uid, out var moved))
{ {
args.Cancelled = true; moved.Enabled = godmode.WasMovedByPressure;
}
private void OnBeforeStatusEffect(EntityUid uid, GodmodeComponent component, ref BeforeStatusEffectAddedEvent args)
{
args.Cancelled = true;
}
private void OnBeforeStaminaDamage(EntityUid uid, GodmodeComponent component, ref BeforeStaminaDamageEvent args)
{
args.Cancelled = true;
}
public void EnableGodmode(EntityUid uid)
{
var godmode = EnsureComp<GodmodeComponent>(uid);
if (TryComp<MovedByPressureComponent>(uid, out var moved))
{
godmode.WasMovedByPressure = moved.Enabled;
moved.Enabled = false;
}
if (TryComp<DamageableComponent>(uid, out var damageable))
{
godmode.OldDamage = new(damageable.Damage);
}
// Rejuv to cover other stuff
RaiseLocalEvent(uid, new RejuvenateEvent());
}
public void DisableGodmode(EntityUid uid)
{
if (!TryComp<GodmodeComponent>(uid, out var godmode))
return;
if (TryComp<MovedByPressureComponent>(uid, out var moved))
{
moved.Enabled = godmode.WasMovedByPressure;
}
if (!TryComp<DamageableComponent>(uid, out var damageable))
return;
if (godmode.OldDamage != null)
{
_damageable.SetDamage(uid, damageable, godmode.OldDamage);
}
RemComp<GodmodeComponent>(uid);
}
/// <summary>
/// Toggles godmode for a given entity.
/// </summary>
/// <param name="uid">The entity to toggle godmode for.</param>
/// <returns>true if enabled, false if disabled.</returns>
public bool ToggleGodmode(EntityUid uid)
{
if (HasComp<GodmodeComponent>(uid))
{
DisableGodmode(uid);
return false;
}
EnableGodmode(uid);
return true;
} }
} }
} }

View File

@@ -0,0 +1,14 @@
using Content.Shared.Damage.Systems;
using Robust.Shared.GameStates;
namespace Content.Shared.Damage.Components;
[RegisterComponent, NetworkedComponent, Access(typeof(SharedGodmodeSystem))]
public sealed class GodmodeComponent : Component
{
[DataField("wasMovedByPressure")]
public bool WasMovedByPressure;
[DataField("oldDamage")]
public DamageSpecifier? OldDamage = null;
}

View File

@@ -0,0 +1,84 @@
using Content.Shared.Damage.Components;
using Content.Shared.Rejuvenate;
using Content.Shared.Slippery;
using Content.Shared.StatusEffect;
namespace Content.Shared.Damage.Systems;
public abstract class SharedGodmodeSystem : EntitySystem
{
[Dependency] private readonly DamageableSystem _damageable = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<GodmodeComponent, BeforeDamageChangedEvent>(OnBeforeDamageChanged);
SubscribeLocalEvent<GodmodeComponent, BeforeStatusEffectAddedEvent>(OnBeforeStatusEffect);
SubscribeLocalEvent<GodmodeComponent, BeforeStaminaDamageEvent>(OnBeforeStaminaDamage);
SubscribeLocalEvent<GodmodeComponent, SlipAttemptEvent>(OnSlipAttempt);
}
private void OnSlipAttempt(EntityUid uid, GodmodeComponent component, SlipAttemptEvent args)
{
args.Cancel();
}
private void OnBeforeDamageChanged(EntityUid uid, GodmodeComponent component, ref BeforeDamageChangedEvent args)
{
args.Cancelled = true;
}
private void OnBeforeStatusEffect(EntityUid uid, GodmodeComponent component, ref BeforeStatusEffectAddedEvent args)
{
args.Cancelled = true;
}
private void OnBeforeStaminaDamage(EntityUid uid, GodmodeComponent component, ref BeforeStaminaDamageEvent args)
{
args.Cancelled = true;
}
public virtual void EnableGodmode(EntityUid uid, GodmodeComponent? godmode = null)
{
godmode ??= EnsureComp<GodmodeComponent>(uid);
if (TryComp<DamageableComponent>(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 (TryComp<DamageableComponent>(uid, out var damageable) && godmode.OldDamage != null)
{
_damageable.SetDamage(uid, damageable, godmode.OldDamage);
}
RemComp<GodmodeComponent>(uid);
}
/// <summary>
/// Toggles godmode for a given entity.
/// </summary>
/// <param name="uid">The entity to toggle godmode for.</param>
/// <returns>true if enabled, false if disabled.</returns>
public bool ToggleGodmode(EntityUid uid)
{
if (TryComp<GodmodeComponent>(uid, out var godmode))
{
DisableGodmode(uid, godmode);
return false;
}
EnableGodmode(uid, godmode);
return true;
}
}