Fix godmode mispredicts (#18524)
Co-authored-by: Leon Friedrich <60421075+ElectroJr@users.noreply.github.com>
This commit is contained in:
8
Content.Client/Damage/GodmodeSystem.cs
Normal file
8
Content.Client/Damage/GodmodeSystem.cs
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
using Content.Shared.Damage.Systems;
|
||||||
|
|
||||||
|
namespace Content.Client.Damage;
|
||||||
|
|
||||||
|
public sealed class GodmodeSystem : SharedGodmodeSystem
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
|||||||
@@ -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"),
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
|
||||||
}
|
|
||||||
@@ -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);
|
||||||
{
|
|
||||||
base.Initialize();
|
|
||||||
|
|
||||||
SubscribeLocalEvent<GodmodeComponent, BeforeDamageChangedEvent>(OnBeforeDamageChanged);
|
|
||||||
SubscribeLocalEvent<GodmodeComponent, BeforeStatusEffectAddedEvent>(OnBeforeStatusEffect);
|
|
||||||
SubscribeLocalEvent<GodmodeComponent, BeforeStaminaDamageEvent>(OnBeforeStaminaDamage);
|
|
||||||
}
|
|
||||||
|
|
||||||
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 void EnableGodmode(EntityUid uid)
|
|
||||||
{
|
|
||||||
var godmode = EnsureComp<GodmodeComponent>(uid);
|
|
||||||
|
|
||||||
if (TryComp<MovedByPressureComponent>(uid, out var moved))
|
if (TryComp<MovedByPressureComponent>(uid, out var moved))
|
||||||
{
|
{
|
||||||
godmode.WasMovedByPressure = moved.Enabled;
|
godmode.WasMovedByPressure = moved.Enabled;
|
||||||
moved.Enabled = false;
|
moved.Enabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TryComp<DamageableComponent>(uid, out var damageable))
|
|
||||||
{
|
|
||||||
godmode.OldDamage = new(damageable.Damage);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rejuv to cover other stuff
|
public override void DisableGodmode(EntityUid uid, GodmodeComponent? godmode = null)
|
||||||
RaiseLocalEvent(uid, new RejuvenateEvent());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void DisableGodmode(EntityUid uid)
|
|
||||||
{
|
{
|
||||||
if (!TryComp<GodmodeComponent>(uid, out var godmode))
|
if (!Resolve(uid, ref godmode, false))
|
||||||
|
return;
|
||||||
|
|
||||||
|
base.DisableGodmode(uid, godmode);
|
||||||
|
|
||||||
|
if (godmode.Deleted)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (TryComp<MovedByPressureComponent>(uid, out var moved))
|
if (TryComp<MovedByPressureComponent>(uid, out var moved))
|
||||||
{
|
{
|
||||||
moved.Enabled = godmode.WasMovedByPressure;
|
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
14
Content.Shared/Damage/Components/GodmodeComponent.cs
Normal file
14
Content.Shared/Damage/Components/GodmodeComponent.cs
Normal 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;
|
||||||
|
}
|
||||||
84
Content.Shared/Damage/Systems/SharedGodmodeSystem.cs
Normal file
84
Content.Shared/Damage/Systems/SharedGodmodeSystem.cs
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user