mirror of
https://github.com/space-syndicate/space-station-14.git
synced 2026-10-10 02:41:18 +03:00
* Scope creep my ass * why was this shit not pushed???? * gone... * fix that * review plus buildd * asfsafsafsafsafas * grug * burber * I'll fix this later * shrimply die * also this * it's snerf or snuthin * assaads * round snend * aaaa * fix this shit for real * actually, don't start GameRules until MapInit now that I think aboot it. * forgot u * don't actually need this part nullable * Deffer comp removal * one liner * do that too * chungus * Honestly makes more sense here, plus WHY are we doing all that shit on "GameRuleAdded" rather than GameRuleStarted(?) * deferred removal :V * aaaaaaaaaaaaaaa * whhop * Whoop * better * landmine that I placed for myself then forgot about lmao * cleanup * FUCKING `!` * gotovo * amogus * please don't check by metadata I beg * waawsasfdfsasfa * sfafsasfafsas * fdsaasffsasfa * code * fix * fasasffasfasfsad * chungaas * I may be stupid * gra * graaaaaaaaaaaaaaaaa * comment * gra * clearing is not predicted and would require major refactors, so don't cache on client. * lame shit :P * last holes * nukeopsfsafsasafsfafsa * why was that shit public bruh * bubrbgwahrghfaka * dynamic * revert change that did nothing lmao
135 lines
5.2 KiB
C#
135 lines
5.2 KiB
C#
using Content.Server.Chat.Systems;
|
|
using Content.Server.Explosion.EntitySystems;
|
|
using Content.Server.Power.Components;
|
|
using Content.Server.Power.EntitySystems;
|
|
using Content.Server.Station.Systems;
|
|
using Content.Shared.Examine;
|
|
using Content.Shared.Power.Components;
|
|
using Robust.Shared.Audio.Systems;
|
|
using Robust.Shared.Timing;
|
|
using Robust.Shared.Utility;
|
|
|
|
namespace Content.Server.PowerSink
|
|
{
|
|
public sealed partial class PowerSinkSystem : EntitySystem
|
|
{
|
|
/// <summary>
|
|
/// Percentage of battery full to trigger the announcement warning at.
|
|
/// </summary>
|
|
private const float WarningMessageThreshold = 0.70f;
|
|
|
|
private readonly float[] _warningSoundThresholds = new[] { .80f, .90f, .95f, .98f };
|
|
|
|
/// <summary>
|
|
/// Length of time to delay explosion from battery full state -- this is used to play
|
|
/// a brief SFX winding up the explosion.
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
private readonly TimeSpan _explosionDelayTime = TimeSpan.FromSeconds(1.465);
|
|
|
|
[Dependency] private IGameTiming _gameTiming = default!;
|
|
[Dependency] private ChatSystem _chat = default!;
|
|
[Dependency] private ExplosionSystem _explosionSystem = default!;
|
|
[Dependency] private SharedAudioSystem _audio = default!;
|
|
[Dependency] private ServerStationSystem _station = default!;
|
|
[Dependency] private BatterySystem _battery = default!;
|
|
|
|
public override void Initialize()
|
|
{
|
|
base.Initialize();
|
|
|
|
SubscribeLocalEvent<PowerSinkComponent, ExaminedEvent>(OnExamine);
|
|
}
|
|
|
|
private void OnExamine(EntityUid uid, PowerSinkComponent component, ExaminedEvent args)
|
|
{
|
|
if (!args.IsInDetailsRange || !TryComp<PowerConsumerComponent>(uid, out var consumer))
|
|
return;
|
|
|
|
var drainAmount = (int) consumer.NetworkLoad.ReceivingPower / 1000;
|
|
args.PushMarkup(
|
|
Loc.GetString(
|
|
"powersink-examine-drain-amount",
|
|
("amount", drainAmount),
|
|
("markupDrainColor", "orange"))
|
|
);
|
|
}
|
|
|
|
public override void Update(float frameTime)
|
|
{
|
|
var toRemove = new RemQueue<(EntityUid Entity, PowerSinkComponent Sink)>();
|
|
var query = EntityQueryEnumerator<PowerSinkComponent, BatteryComponent, TransformComponent>();
|
|
|
|
// Realistically it's gonna be like <5 per station.
|
|
while (query.MoveNext(out var entity, out var component, out var battery, out var transform))
|
|
{
|
|
if (!transform.Anchored)
|
|
continue;
|
|
|
|
var currentBatteryThreshold = _battery.GetChargeLevel((entity, battery));
|
|
|
|
// Check for warning message threshold
|
|
if (!component.SentImminentExplosionWarningMessage &&
|
|
currentBatteryThreshold >= WarningMessageThreshold)
|
|
{
|
|
NotifyStationOfImminentExplosion(entity, component);
|
|
}
|
|
|
|
// Check for warning sound threshold
|
|
foreach (var testThreshold in _warningSoundThresholds)
|
|
{
|
|
if (currentBatteryThreshold >= testThreshold &&
|
|
testThreshold > component.HighestWarningSoundThreshold)
|
|
{
|
|
component.HighestWarningSoundThreshold = currentBatteryThreshold; // Don't re-play in future until next threshold hit
|
|
_audio.PlayPvs(component.ElectricSound, entity); // Play SFX
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Check for explosion
|
|
if (!_battery.IsFull((entity, battery)))
|
|
continue;
|
|
|
|
if (component.ExplosionTime == null)
|
|
{
|
|
// Set explosion sequence to start soon
|
|
component.ExplosionTime = _gameTiming.CurTime.Add(_explosionDelayTime);
|
|
|
|
// Wind-up SFX
|
|
_audio.PlayPvs(component.ChargeFireSound, entity); // Play SFX
|
|
}
|
|
else if (_gameTiming.CurTime >= component.ExplosionTime)
|
|
{
|
|
// Explode!
|
|
toRemove.Add((entity, component));
|
|
}
|
|
}
|
|
|
|
foreach (var (entity, component) in toRemove)
|
|
{
|
|
_explosionSystem.QueueExplosion(entity, "PowerSink", 2000f, 4f, 20f, canCreateVacuum: true);
|
|
RemComp(entity, component);
|
|
}
|
|
}
|
|
|
|
private void NotifyStationOfImminentExplosion(EntityUid uid, PowerSinkComponent powerSinkComponent)
|
|
{
|
|
if (powerSinkComponent.SentImminentExplosionWarningMessage)
|
|
return;
|
|
|
|
powerSinkComponent.SentImminentExplosionWarningMessage = true;
|
|
var station = _station.GetOwningStation(uid);
|
|
|
|
if (station == null)
|
|
return;
|
|
|
|
_chat.DispatchStationAnnouncement(
|
|
station.Value,
|
|
Loc.GetString("powersink-imminent-explosion-announcement"),
|
|
playDefaultSound: true,
|
|
colorOverride: Color.Yellow
|
|
);
|
|
}
|
|
}
|
|
}
|