Files
tbd-station-14/Content.Server/Radio/EntitySystems/JammerSystem.cs
metalgearsloth 63dfd21b14 Predict dumping (#32394)
* Predict dumping

- This got soaped really fucking hard.
- Dumping is predicted, this required disposals to be predicte.d
- Disposals required mailing (because it's tightly coupled), and a smidge of other content systems.
- I also had to fix a compnetworkgenerator issue at the same time so it wouldn't mispredict.

* Fix a bunch of stuff

* nasty merge

* Some reviews

* Some more reviews while I stash

* Fix merge

* Fix merge

* Half of review

* Review

* re(h)f

* lizards

* feexes

* feex
2025-04-19 16:20:40 +10:00

121 lines
4.4 KiB
C#

using Content.Server.Power.EntitySystems;
using Content.Server.PowerCell;
using Content.Shared.DeviceNetwork.Components;
using Content.Shared.Interaction;
using Content.Shared.PowerCell.Components;
using Content.Shared.Radio.EntitySystems;
using Content.Shared.Radio.Components;
using Content.Shared.DeviceNetwork.Systems;
namespace Content.Server.Radio.EntitySystems;
public sealed class JammerSystem : SharedJammerSystem
{
[Dependency] private readonly PowerCellSystem _powerCell = default!;
[Dependency] private readonly BatterySystem _battery = default!;
[Dependency] private readonly SharedTransformSystem _transform = default!;
[Dependency] private readonly SharedDeviceNetworkJammerSystem _jammer = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<RadioJammerComponent, ActivateInWorldEvent>(OnActivate);
SubscribeLocalEvent<ActiveRadioJammerComponent, PowerCellChangedEvent>(OnPowerCellChanged);
SubscribeLocalEvent<RadioSendAttemptEvent>(OnRadioSendAttempt);
}
public override void Update(float frameTime)
{
var query = EntityQueryEnumerator<ActiveRadioJammerComponent, RadioJammerComponent>();
while (query.MoveNext(out var uid, out var _, out var jam))
{
if (_powerCell.TryGetBatteryFromSlot(uid, out var batteryUid, out var battery))
{
if (!_battery.TryUseCharge(batteryUid.Value, GetCurrentWattage((uid, jam)) * frameTime, battery))
{
ChangeLEDState(uid, false);
RemComp<ActiveRadioJammerComponent>(uid);
RemComp<DeviceNetworkJammerComponent>(uid);
}
else
{
var percentCharged = battery.CurrentCharge / battery.MaxCharge;
var chargeLevel = percentCharged switch
{
> 0.50f => RadioJammerChargeLevel.High,
< 0.15f => RadioJammerChargeLevel.Low,
_ => RadioJammerChargeLevel.Medium,
};
ChangeChargeLevel(uid, chargeLevel);
}
}
}
}
private void OnActivate(Entity<RadioJammerComponent> ent, ref ActivateInWorldEvent args)
{
if (args.Handled || !args.Complex)
return;
var activated = !HasComp<ActiveRadioJammerComponent>(ent) &&
_powerCell.TryGetBatteryFromSlot(ent.Owner, out var battery) &&
battery.CurrentCharge > GetCurrentWattage(ent);
if (activated)
{
ChangeLEDState(ent.Owner, true);
EnsureComp<ActiveRadioJammerComponent>(ent);
EnsureComp<DeviceNetworkJammerComponent>(ent, out var jammingComp);
_jammer.SetRange((ent, jammingComp), GetCurrentRange(ent));
_jammer.AddJammableNetwork((ent, jammingComp), DeviceNetworkComponent.DeviceNetIdDefaults.Wireless.ToString());
}
else
{
ChangeLEDState(ent.Owner, false);
RemCompDeferred<ActiveRadioJammerComponent>(ent);
RemCompDeferred<DeviceNetworkJammerComponent>(ent);
}
var state = Loc.GetString(activated ? "radio-jammer-component-on-state" : "radio-jammer-component-off-state");
var message = Loc.GetString("radio-jammer-component-on-use", ("state", state));
Popup.PopupEntity(message, args.User, args.User);
args.Handled = true;
}
private void OnPowerCellChanged(Entity<ActiveRadioJammerComponent> ent, ref PowerCellChangedEvent args)
{
if (args.Ejected)
{
ChangeLEDState(ent.Owner, false);
RemCompDeferred<ActiveRadioJammerComponent>(ent);
}
}
private void OnRadioSendAttempt(ref RadioSendAttemptEvent args)
{
if (ShouldCancelSend(args.RadioSource))
{
args.Cancelled = true;
}
}
private bool ShouldCancelSend(EntityUid sourceUid)
{
var source = Transform(sourceUid).Coordinates;
var query = EntityQueryEnumerator<ActiveRadioJammerComponent, RadioJammerComponent, TransformComponent>();
while (query.MoveNext(out var uid, out _, out var jam, out var transform))
{
if (_transform.InRange(source, transform.Coordinates, GetCurrentRange((uid, jam))))
{
return true;
}
}
return false;
}
}