remove robotics console emag checking, make it a bit fairer (#27876)

This commit is contained in:
deltanedas
2024-06-17 03:30:10 +00:00
committed by GitHub
parent 7ff557d1ef
commit c332677971
12 changed files with 123 additions and 42 deletions

View File

@@ -134,7 +134,7 @@ public sealed partial class RoboticsConsoleWindow : FancyWindow
BorgInfo.SetMessage(text); BorgInfo.SetMessage(text);
// how the turntables // how the turntables
DisableButton.Disabled = !data.HasBrain; DisableButton.Disabled = !(data.HasBrain && data.CanDisable);
DestroyButton.Disabled = _timing.CurTime < _console.Comp1.NextDestroy; DestroyButton.Disabled = _timing.CurTime < _console.Comp1.NextDestroy;
} }

View File

@@ -1,7 +1,7 @@
namespace Content.Server.Explosion.Components; namespace Content.Server.Explosion.Components;
/// <summary> /// <summary>
/// Disallows starting the timer by hand, must be stuck or triggered by a system. /// Disallows starting the timer by hand, must be stuck or triggered by a system using <c>StartTimer</c>.
/// </summary> /// </summary>
[RegisterComponent] [RegisterComponent]
public sealed partial class AutomatedTimerComponent : Component public sealed partial class AutomatedTimerComponent : Component

View File

@@ -26,13 +26,7 @@ public sealed partial class TriggerSystem
if (!component.StartOnStick) if (!component.StartOnStick)
return; return;
HandleTimerTrigger( StartTimer((uid, component), args.User);
uid,
args.User,
component.Delay,
component.BeepInterval,
component.InitialBeepDelay,
component.BeepSound);
} }
private void OnExamined(EntityUid uid, OnUseTimerTriggerComponent component, ExaminedEvent args) private void OnExamined(EntityUid uid, OnUseTimerTriggerComponent component, ExaminedEvent args)
@@ -54,14 +48,7 @@ public sealed partial class TriggerSystem
args.Verbs.Add(new AlternativeVerb() args.Verbs.Add(new AlternativeVerb()
{ {
Text = Loc.GetString("verb-start-detonation"), Text = Loc.GetString("verb-start-detonation"),
Act = () => HandleTimerTrigger( Act = () => StartTimer((uid, component), args.User),
uid,
args.User,
component.Delay,
component.BeepInterval,
component.InitialBeepDelay,
component.BeepSound
),
Priority = 2 Priority = 2
}); });
} }
@@ -174,13 +161,7 @@ public sealed partial class TriggerSystem
if (component.DoPopup) if (component.DoPopup)
_popupSystem.PopupEntity(Loc.GetString("trigger-activated", ("device", uid)), args.User, args.User); _popupSystem.PopupEntity(Loc.GetString("trigger-activated", ("device", uid)), args.User, args.User);
HandleTimerTrigger( StartTimer((uid, component), args.User);
uid,
args.User,
component.Delay,
component.BeepInterval,
component.InitialBeepDelay,
component.BeepSound);
args.Handled = true; args.Handled = true;
} }

View File

@@ -265,6 +265,18 @@ namespace Content.Server.Explosion.EntitySystems
comp.TimeRemaining += amount; comp.TimeRemaining += amount;
} }
/// <summary>
/// Start the timer for triggering the device.
/// </summary>
public void StartTimer(Entity<OnUseTimerTriggerComponent?> ent, EntityUid? user)
{
if (!Resolve(ent, ref ent.Comp, false))
return;
var comp = ent.Comp;
HandleTimerTrigger(ent, user, comp.Delay, comp.BeepInterval, comp.InitialBeepDelay, comp.BeepSound);
}
public void HandleTimerTrigger(EntityUid uid, EntityUid? user, float delay, float beepInterval, float? initialBeepDelay, SoundSpecifier? beepSound) public void HandleTimerTrigger(EntityUid uid, EntityUid? user, float delay, float beepInterval, float? initialBeepDelay, SoundSpecifier? beepSound)
{ {
if (delay <= 0) if (delay <= 0)

View File

@@ -1,5 +1,6 @@
using Content.Shared.DeviceNetwork; using Content.Shared.DeviceNetwork;
using Content.Shared.Emag.Components; using Content.Shared.Emag.Components;
using Content.Shared.Movement.Components;
using Content.Shared.Popups; using Content.Shared.Popups;
using Content.Shared.Robotics; using Content.Shared.Robotics;
using Content.Shared.Silicons.Borgs.Components; using Content.Shared.Silicons.Borgs.Components;
@@ -26,6 +27,9 @@ public sealed partial class BorgSystem
var query = EntityQueryEnumerator<BorgTransponderComponent, BorgChassisComponent, DeviceNetworkComponent, MetaDataComponent>(); var query = EntityQueryEnumerator<BorgTransponderComponent, BorgChassisComponent, DeviceNetworkComponent, MetaDataComponent>();
while (query.MoveNext(out var uid, out var comp, out var chassis, out var device, out var meta)) while (query.MoveNext(out var uid, out var comp, out var chassis, out var device, out var meta))
{ {
if (comp.NextDisable is {} nextDisable && now >= nextDisable)
DoDisable((uid, comp, chassis, meta));
if (now < comp.NextBroadcast) if (now < comp.NextBroadcast)
continue; continue;
@@ -33,13 +37,16 @@ public sealed partial class BorgSystem
if (_powerCell.TryGetBatteryFromSlot(uid, out var battery)) if (_powerCell.TryGetBatteryFromSlot(uid, out var battery))
charge = battery.CurrentCharge / battery.MaxCharge; charge = battery.CurrentCharge / battery.MaxCharge;
var hasBrain = chassis.BrainEntity != null && !comp.FakeDisabled;
var canDisable = comp.NextDisable == null && !comp.FakeDisabling;
var data = new CyborgControlData( var data = new CyborgControlData(
comp.Sprite, comp.Sprite,
comp.Name, comp.Name,
meta.EntityName, meta.EntityName,
charge, charge,
chassis.ModuleCount, chassis.ModuleCount,
chassis.BrainEntity != null); hasBrain,
canDisable);
var payload = new NetworkPayload() var payload = new NetworkPayload()
{ {
@@ -52,6 +59,24 @@ public sealed partial class BorgSystem
} }
} }
private void DoDisable(Entity<BorgTransponderComponent, BorgChassisComponent, MetaDataComponent> ent)
{
ent.Comp1.NextDisable = null;
if (ent.Comp1.FakeDisabling)
{
ent.Comp1.FakeDisabled = true;
ent.Comp1.FakeDisabling = false;
return;
}
if (ent.Comp2.BrainEntity is not {} brain)
return;
var message = Loc.GetString(ent.Comp1.DisabledPopup, ("name", Name(ent, ent.Comp3)));
Popup.PopupEntity(message, ent);
_container.Remove(brain, ent.Comp2.BrainContainer);
}
private void OnPacketReceived(Entity<BorgTransponderComponent> ent, ref DeviceNetworkPacketEvent args) private void OnPacketReceived(Entity<BorgTransponderComponent> ent, ref DeviceNetworkPacketEvent args)
{ {
var payload = args.Data; var payload = args.Data;
@@ -61,28 +86,28 @@ public sealed partial class BorgSystem
if (command == RoboticsConsoleConstants.NET_DISABLE_COMMAND) if (command == RoboticsConsoleConstants.NET_DISABLE_COMMAND)
Disable(ent); Disable(ent);
else if (command == RoboticsConsoleConstants.NET_DESTROY_COMMAND) else if (command == RoboticsConsoleConstants.NET_DESTROY_COMMAND)
Destroy(ent.Owner); Destroy(ent);
} }
private void Disable(Entity<BorgTransponderComponent, BorgChassisComponent?> ent) private void Disable(Entity<BorgTransponderComponent, BorgChassisComponent?> ent)
{ {
if (!Resolve(ent, ref ent.Comp2) || ent.Comp2.BrainEntity is not {} brain) if (!Resolve(ent, ref ent.Comp2) || ent.Comp2.BrainEntity == null || ent.Comp1.NextDisable != null)
return; return;
// this won't exactly be stealthy but if you are malf its better than actually disabling you // update ui immediately
ent.Comp1.NextBroadcast = _timing.CurTime;
// pretend the borg is being disabled forever now
if (CheckEmagged(ent, "disabled")) if (CheckEmagged(ent, "disabled"))
return; ent.Comp1.FakeDisabling = true;
else
Popup.PopupEntity(Loc.GetString(ent.Comp1.DisablingPopup), ent);
var message = Loc.GetString(ent.Comp1.DisabledPopup, ("name", Name(ent))); ent.Comp1.NextDisable = _timing.CurTime + ent.Comp1.DisableDelay;
Popup.PopupEntity(message, ent);
_container.Remove(brain, ent.Comp2.BrainContainer);
} }
private void Destroy(Entity<ExplosiveComponent?> ent) private void Destroy(Entity<BorgTransponderComponent> ent)
{ {
if (!Resolve(ent, ref ent.Comp))
return;
// this is stealthy until someone realises you havent exploded // this is stealthy until someone realises you havent exploded
if (CheckEmagged(ent, "destroyed")) if (CheckEmagged(ent, "destroyed"))
{ {
@@ -91,7 +116,12 @@ public sealed partial class BorgSystem
return; return;
} }
_explosion.TriggerExplosive(ent, ent.Comp, delete: false); var message = Loc.GetString(ent.Comp.DestroyingPopup, ("name", Name(ent)));
Popup.PopupEntity(message, ent);
_trigger.StartTimer(ent.Owner, user: null);
// prevent a shitter borg running into people
RemComp<InputMoverComponent>(ent);
} }
private bool CheckEmagged(EntityUid uid, string name) private bool CheckEmagged(EntityUid uid, string name)

View File

@@ -43,8 +43,8 @@ public sealed partial class BorgSystem : SharedBorgSystem
[Dependency] private readonly ActionsSystem _actions = default!; [Dependency] private readonly ActionsSystem _actions = default!;
[Dependency] private readonly AlertsSystem _alerts = default!; [Dependency] private readonly AlertsSystem _alerts = default!;
[Dependency] private readonly DeviceNetworkSystem _deviceNetwork = default!; [Dependency] private readonly DeviceNetworkSystem _deviceNetwork = default!;
[Dependency] private readonly ExplosionSystem _explosion = default!;
[Dependency] private readonly SharedAppearanceSystem _appearance = default!; [Dependency] private readonly SharedAppearanceSystem _appearance = default!;
[Dependency] private readonly TriggerSystem _trigger = default!;
[Dependency] private readonly HandsSystem _hands = default!; [Dependency] private readonly HandsSystem _hands = default!;
[Dependency] private readonly MetaDataSystem _metaData = default!; [Dependency] private readonly MetaDataSystem _metaData = default!;
[Dependency] private readonly SharedMindSystem _mind = default!; [Dependency] private readonly SharedMindSystem _mind = default!;

View File

@@ -36,7 +36,7 @@ public sealed partial class RoboticsConsoleComponent : Component
/// Radio message sent when destroying a borg. /// Radio message sent when destroying a borg.
/// </summary> /// </summary>
[DataField] [DataField]
public LocId DestroyMessage = "robotics-console-cyborg-destroyed"; public LocId DestroyMessage = "robotics-console-cyborg-destroying";
/// <summary> /// <summary>
/// Cooldown on destroying borgs to prevent complete abuse. /// Cooldown on destroying borgs to prevent complete abuse.

View File

@@ -97,6 +97,13 @@ public record struct CyborgControlData
[DataField] [DataField]
public bool HasBrain; public bool HasBrain;
/// <summary>
/// Whether the borg can currently be disabled if the brain is installed,
/// if on cooldown then can't queue up multiple disables.
/// </summary>
[DataField]
public bool CanDisable;
/// <summary> /// <summary>
/// When this cyborg's data will be deleted. /// When this cyborg's data will be deleted.
/// Set by the console when receiving the packet. /// Set by the console when receiving the packet.
@@ -104,7 +111,7 @@ public record struct CyborgControlData
[DataField(customTypeSerializer: typeof(TimeOffsetSerializer))] [DataField(customTypeSerializer: typeof(TimeOffsetSerializer))]
public TimeSpan Timeout = TimeSpan.Zero; public TimeSpan Timeout = TimeSpan.Zero;
public CyborgControlData(SpriteSpecifier? chassisSprite, string chassisName, string name, float charge, int moduleCount, bool hasBrain) public CyborgControlData(SpriteSpecifier? chassisSprite, string chassisName, string name, float charge, int moduleCount, bool hasBrain, bool canDisable)
{ {
ChassisSprite = chassisSprite; ChassisSprite = chassisSprite;
ChassisName = chassisName; ChassisName = chassisName;
@@ -112,6 +119,7 @@ public record struct CyborgControlData
Charge = charge; Charge = charge;
ModuleCount = moduleCount; ModuleCount = moduleCount;
HasBrain = hasBrain; HasBrain = hasBrain;
CanDisable = canDisable;
} }
} }

View File

@@ -23,12 +23,25 @@ public sealed partial class BorgTransponderComponent : Component
public string Name = string.Empty; public string Name = string.Empty;
/// <summary> /// <summary>
/// Popup shown to everyone when a borg is disabled. /// Popup shown to everyone after a borg is disabled.
/// Gets passed a string "name". /// Gets passed a string "name".
/// </summary> /// </summary>
[DataField] [DataField]
public LocId DisabledPopup = "borg-transponder-disabled-popup"; public LocId DisabledPopup = "borg-transponder-disabled-popup";
/// <summary>
/// Popup shown to the borg when it is being disabled.
/// </summary>
[DataField]
public LocId DisablingPopup = "borg-transponder-disabling-popup";
/// <summary>
/// Popup shown to everyone when a borg is being destroyed.
/// Gets passed a string "name".
/// </summary>
[DataField]
public LocId DestroyingPopup = "borg-transponder-destroying-popup";
/// <summary> /// <summary>
/// How long to wait between each broadcast. /// How long to wait between each broadcast.
/// </summary> /// </summary>
@@ -40,4 +53,28 @@ public sealed partial class BorgTransponderComponent : Component
/// </summary> /// </summary>
[DataField(customTypeSerializer: typeof(TimeOffsetSerializer))] [DataField(customTypeSerializer: typeof(TimeOffsetSerializer))]
public TimeSpan NextBroadcast = TimeSpan.Zero; public TimeSpan NextBroadcast = TimeSpan.Zero;
/// <summary>
/// When to next disable the borg.
/// </summary>
[DataField(customTypeSerializer: typeof(TimeOffsetSerializer))]
public TimeSpan? NextDisable;
/// <summary>
/// How long to wait to disable the borg after RD has ordered it.
/// </summary>
[DataField]
public TimeSpan DisableDelay = TimeSpan.FromSeconds(5);
/// <summary>
/// Pretend that the borg cannot be disabled due to being on delay.
/// </summary>
[DataField]
public bool FakeDisabling;
/// <summary>
/// Pretend that the borg has no brain inserted.
/// </summary>
[DataField]
public bool FakeDisabled;
} }

View File

@@ -21,5 +21,7 @@ borg-ui-module-counter = {$actual}/{$max}
# Transponder # Transponder
borg-transponder-disabled-popup = A brain shoots out the top of {$name}! borg-transponder-disabled-popup = A brain shoots out the top of {$name}!
borg-transponder-disabling-popup = Your transponder begins to lock you out of the chassis!
borg-transponder-destroying-popup = The self destruct of {$name} starts beeping!
borg-transponder-emagged-disabled-popup = Your transponder's lights go out! borg-transponder-emagged-disabled-popup = Your transponder's lights go out!
borg-transponder-emagged-destroyed-popup = Your transponder's fuse blows! borg-transponder-emagged-destroyed-popup = Your transponder's fuse blows!

View File

@@ -16,4 +16,4 @@ robotics-console-locked-message = Controls locked, swipe ID.
robotics-console-disable = Disable robotics-console-disable = Disable
robotics-console-destroy = Destroy robotics-console-destroy = Destroy
robotics-console-cyborg-destroyed = The cyborg {$name} has been remotely destroyed. robotics-console-cyborg-destroying = {$name} is being remotely detonated!

View File

@@ -227,9 +227,20 @@
deviceNetId: Wireless deviceNetId: Wireless
receiveFrequencyId: CyborgControl receiveFrequencyId: CyborgControl
transmitFrequencyId: RoboticsConsole transmitFrequencyId: RoboticsConsole
- type: OnUseTimerTrigger
delay: 10
examinable: false
beepSound:
path: /Audio/Effects/Cargo/buzz_two.ogg
params:
volume: -4
# prevent any funnies if someone makes a cyborg item...
- type: AutomatedTimer
- type: ExplodeOnTrigger
# explosion does most of its damage in the center and less at the edges # explosion does most of its damage in the center and less at the edges
- type: Explosive - type: Explosive
explosionType: Minibomb explosionType: Minibomb
deleteAfterExplosion: false # let damage threshold gib the borg
totalIntensity: 30 totalIntensity: 30
intensitySlope: 20 intensitySlope: 20
maxIntensity: 20 maxIntensity: 20