Predict some power PowerReceiver stuff (#33834)

* Predict some power PowerReceiver stuff

Need it for some atmos device prediction.

* Also this
This commit is contained in:
metalgearsloth
2025-03-10 13:00:49 +11:00
committed by GitHub
parent 6689cae5a1
commit 75a7407e33
9 changed files with 96 additions and 61 deletions

View File

@@ -27,6 +27,8 @@ public sealed class PowerReceiverSystem : SharedPowerReceiverSystem
return;
component.Powered = state.Powered;
component.NeedsPower = state.NeedsPower;
component.PowerDisabled = state.PowerDisabled;
}
public override bool ResolveApc(EntityUid entity, [NotNullWhen(true)] ref SharedApcPowerReceiverComponent? component)

View File

@@ -24,7 +24,7 @@ namespace Content.Server.Power.Components
/// When false, causes this to appear powered even if not receiving power from an Apc.
/// </summary>
[ViewVariables(VVAccess.ReadWrite)]
public bool NeedsPower
public override bool NeedsPower
{
get => _needsPower;
set
@@ -41,9 +41,9 @@ namespace Content.Server.Power.Components
/// <summary>
/// When true, causes this to never appear powered.
/// </summary>
[ViewVariables(VVAccess.ReadWrite)]
[DataField("powerDisabled")]
public bool PowerDisabled {
public override bool PowerDisabled
{
get => !NetworkLoad.Enabled;
set => NetworkLoad.Enabled = !value;
}

View File

@@ -1,18 +1,12 @@
using System.Diagnostics.CodeAnalysis;
using Content.Server.Administration.Logs;
using Content.Server.Administration.Managers;
using Content.Server.Power.Components;
using Content.Shared.Administration;
using Content.Shared.Database;
using Content.Shared.Examine;
using Content.Shared.Hands.Components;
using Content.Shared.Power;
using Content.Shared.Power.Components;
using Content.Shared.Power.EntitySystems;
using Content.Shared.Verbs;
using Robust.Server.Audio;
using Robust.Server.GameObjects;
using Robust.Shared.Audio;
using Robust.Shared.GameStates;
using Robust.Shared.Utility;
@@ -20,9 +14,8 @@ namespace Content.Server.Power.EntitySystems
{
public sealed class PowerReceiverSystem : SharedPowerReceiverSystem
{
[Dependency] private readonly IAdminLogManager _adminLogger = default!;
[Dependency] private readonly IAdminManager _adminManager = default!;
[Dependency] private readonly AudioSystem _audio = default!;
private EntityQuery<ApcPowerReceiverComponent> _recQuery;
private EntityQuery<ApcPowerProviderComponent> _provQuery;
@@ -63,7 +56,10 @@ namespace Content.Server.Power.EntitySystems
Text = Loc.GetString("verb-debug-toggle-need-power"),
Category = VerbCategory.Debug,
Icon = new SpriteSpecifier.Texture(new ("/Textures/Interface/VerbIcons/smite.svg.192dpi.png")), // "smite" is a lightning bolt
Act = () => component.NeedsPower = !component.NeedsPower
Act = () =>
{
SetNeedsPower(uid, !component.NeedsPower, component);
}
});
}
@@ -143,7 +139,9 @@ namespace Content.Server.Power.EntitySystems
{
args.State = new ApcPowerReceiverComponentState
{
Powered = component.Powered
Powered = component.Powered,
NeedsPower = component.NeedsPower,
PowerDisabled = component.PowerDisabled,
};
}
@@ -164,36 +162,6 @@ namespace Content.Server.Power.EntitySystems
return !_recQuery.Resolve(uid, ref receiver, false) || receiver.Powered;
}
/// <summary>
/// Turn this machine on or off.
/// Returns true if we turned it on, false if we turned it off.
/// </summary>
public bool TogglePower(EntityUid uid, bool playSwitchSound = true, ApcPowerReceiverComponent? receiver = null, EntityUid? user = null)
{
if (!_recQuery.Resolve(uid, ref receiver, false))
return true;
// it'll save a lot of confusion if 'always powered' means 'always powered'
if (!receiver.NeedsPower)
{
receiver.PowerDisabled = false;
return true;
}
receiver.PowerDisabled = !receiver.PowerDisabled;
if (user != null)
_adminLogger.Add(LogType.Action, LogImpact.Low, $"{ToPrettyString(user.Value):player} hit power button on {ToPrettyString(uid)}, it's now {(!receiver.PowerDisabled ? "on" : "off")}");
if (playSwitchSound)
{
_audio.PlayPvs(new SoundPathSpecifier("/Audio/Machines/machine_switch.ogg"), uid,
AudioParams.Default.WithVolume(-2f));
}
return !receiver.PowerDisabled; // i.e. PowerEnabled
}
public void SetLoad(ApcPowerReceiverComponent comp, float load)
{
comp.Load = load;

View File

@@ -11,6 +11,7 @@ using Content.Shared.Atmos;
using Content.Shared.DeviceNetwork;
using Content.Shared.Examine;
using Content.Shared.Power;
using Content.Shared.Power.EntitySystems;
using Content.Shared.Power.Generation.Teg;
using Content.Shared.Rounding;
using Robust.Server.GameObjects;
@@ -66,11 +67,12 @@ public sealed class TegSystem : EntitySystem
/// </summary>
public const string DeviceNetworkCommandSyncData = "teg_sync_data";
[Dependency] private readonly AmbientSoundSystem _ambientSound = default!;
[Dependency] private readonly AppearanceSystem _appearance = default!;
[Dependency] private readonly AtmosphereSystem _atmosphere = default!;
[Dependency] private readonly DeviceNetworkSystem _deviceNetwork = default!;
[Dependency] private readonly AppearanceSystem _appearance = default!;
[Dependency] private readonly PointLightSystem _pointLight = default!;
[Dependency] private readonly AmbientSoundSystem _ambientSound = default!;
[Dependency] private readonly SharedPowerReceiverSystem _receiver = default!;
private EntityQuery<NodeContainerComponent> _nodeContainerQuery;
@@ -241,8 +243,7 @@ public sealed class TegSystem : EntitySystem
var powerReceiver = Comp<ApcPowerReceiverComponent>(uid);
powerReceiver.PowerDisabled = !group.IsFullyBuilt;
_receiver.SetPowerDisabled(uid, !group.IsFullyBuilt, powerReceiver);
UpdateAppearance(uid, component, powerReceiver, group);
}

View File

@@ -1,6 +1,7 @@
using Content.Server.Electrocution;
using Content.Shared.Electrocution;
using Content.Server.Power.Components;
using Content.Server.Power.EntitySystems;
using Content.Server.Wires;
using Content.Shared.Power;
using Content.Shared.Wires;
@@ -61,15 +62,17 @@ public sealed partial class PowerWireAction : BaseWireAction
return;
}
var receiverSys = EntityManager.System<PowerReceiverSystem>();
if (pulsed)
{
power.PowerDisabled = true;
receiverSys.SetPowerDisabled(owner, true, power);
return;
}
if (AllWiresCut(owner))
{
power.PowerDisabled = true;
receiverSys.SetPowerDisabled(owner, true, power);
}
else
{
@@ -79,7 +82,7 @@ public sealed partial class PowerWireAction : BaseWireAction
return;
}
power.PowerDisabled = false;
receiverSys.SetPowerDisabled(owner, false, power);
}
}

View File

@@ -12,6 +12,7 @@ using Content.Shared.Paper;
using Content.Shared.Placeable;
using Content.Shared.Popups;
using Content.Shared.Power;
using Content.Shared.Power.EntitySystems;
using Content.Shared.Research.Components;
using Content.Shared.Xenoarchaeology.Equipment;
using Content.Shared.Xenoarchaeology.XenoArtifacts;
@@ -33,15 +34,16 @@ public sealed class ArtifactAnalyzerSystem : EntitySystem
{
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly IPrototypeManager _prototype = default!;
[Dependency] private readonly SharedAudioSystem _audio = default!;
[Dependency] private readonly SharedAmbientSoundSystem _ambientSound = default!;
[Dependency] private readonly SharedPopupSystem _popup = default!;
[Dependency] private readonly UserInterfaceSystem _ui = default!;
[Dependency] private readonly ArtifactSystem _artifact = default!;
[Dependency] private readonly MetaDataSystem _metaSystem = default!;
[Dependency] private readonly PaperSystem _paper = default!;
[Dependency] private readonly ResearchSystem _research = default!;
[Dependency] private readonly MetaDataSystem _metaSystem = default!;
[Dependency] private readonly SharedAmbientSoundSystem _ambientSound = default!;
[Dependency] private readonly SharedAudioSystem _audio = default!;
[Dependency] private readonly SharedPopupSystem _popup = default!;
[Dependency] private readonly SharedPowerReceiverSystem _receiver = default!;
[Dependency] private readonly TraversalDistorterSystem _traversalDistorter = default!;
[Dependency] private readonly UserInterfaceSystem _ui = default!;
/// <inheritdoc/>
public override void Initialize()
@@ -492,17 +494,13 @@ public sealed class ArtifactAnalyzerSystem : EntitySystem
private void OnAnalyzeStart(EntityUid uid, ActiveArtifactAnalyzerComponent component, ComponentStartup args)
{
if (TryComp<ApcPowerReceiverComponent>(uid, out var powa))
powa.NeedsPower = true;
_receiver.SetNeedsPower(uid, true);
_ambientSound.SetAmbience(uid, true);
}
private void OnAnalyzeEnd(EntityUid uid, ActiveArtifactAnalyzerComponent component, ComponentShutdown args)
{
if (TryComp<ApcPowerReceiverComponent>(uid, out var powa))
powa.NeedsPower = false;
_receiver.SetNeedsPower(uid, false);
_ambientSound.SetAmbience(uid, false);
}

View File

@@ -6,4 +6,6 @@ namespace Content.Shared.Power.Components;
public sealed class ApcPowerReceiverComponentState : ComponentState
{
public bool Powered;
public bool NeedsPower;
public bool PowerDisabled;
}

View File

@@ -7,4 +7,10 @@ public abstract partial class SharedApcPowerReceiverComponent : Component
{
[ViewVariables]
public bool Powered;
[ViewVariables]
public virtual bool NeedsPower { get; set; }
[ViewVariables]
public virtual bool PowerDisabled { get; set; }
}

View File

@@ -1,12 +1,67 @@
using System.Diagnostics.CodeAnalysis;
using Content.Shared.Administration.Logs;
using Content.Shared.Database;
using Content.Shared.Power.Components;
using Robust.Shared.Audio;
using Robust.Shared.Audio.Systems;
namespace Content.Shared.Power.EntitySystems;
public abstract class SharedPowerReceiverSystem : EntitySystem
{
[Dependency] private readonly ISharedAdminLogManager _adminLogger = default!;
[Dependency] private readonly SharedAudioSystem _audio = default!;
public abstract bool ResolveApc(EntityUid entity, [NotNullWhen(true)] ref SharedApcPowerReceiverComponent? component);
public void SetNeedsPower(EntityUid uid, bool value, SharedApcPowerReceiverComponent? receiver = null)
{
if (!ResolveApc(uid, ref receiver) || receiver.NeedsPower == value)
return;
receiver.NeedsPower = value;
Dirty(uid, receiver);
}
public void SetPowerDisabled(EntityUid uid, bool value, SharedApcPowerReceiverComponent? receiver = null)
{
if (!ResolveApc(uid, ref receiver) || receiver.PowerDisabled == value)
return;
receiver.PowerDisabled = value;
Dirty(uid, receiver);
}
/// <summary>
/// Turn this machine on or off.
/// Returns true if we turned it on, false if we turned it off.
/// </summary>
public bool TogglePower(EntityUid uid, bool playSwitchSound = true, SharedApcPowerReceiverComponent? receiver = null, EntityUid? user = null)
{
if (!ResolveApc(uid, ref receiver))
return true;
// it'll save a lot of confusion if 'always powered' means 'always powered'
if (!receiver.NeedsPower)
{
SetPowerDisabled(uid, false, receiver);
return true;
}
SetPowerDisabled(uid, !receiver.PowerDisabled, receiver);
if (user != null)
_adminLogger.Add(LogType.Action, LogImpact.Low, $"{ToPrettyString(user.Value):player} hit power button on {ToPrettyString(uid)}, it's now {(!receiver.PowerDisabled ? "on" : "off")}");
if (playSwitchSound)
{
_audio.PlayPredicted(new SoundPathSpecifier("/Audio/Machines/machine_switch.ogg"), uid, user: user,
AudioParams.Default.WithVolume(-2f));
}
return !receiver.PowerDisabled; // i.e. PowerEnabled
}
/// <summary>
/// Checks if entity is APC-powered device, and if it have power.
/// </summary>