Delta-v/Content.Shared/_FarHorizons/Power/Generation/FissionGenerator/SharedTurbineSystem.cs

224 lines
8.8 KiB
C#

using Content.Shared.Administration.Logs;
using Content.Shared.Damage.Components;
using Content.Shared.Damage.Systems;
using Content.Shared.Electrocution;
using Content.Shared.Examine;
using Content.Shared.Interaction;
using Content.Shared.Popups;
using Content.Shared.Repairable;
using Content.Shared.Tools.Systems;
using Robust.Shared.Audio;
using Robust.Shared.Audio.Systems;
using Robust.Shared.Prototypes;
namespace Content.Shared._FarHorizons.Power.Generation.FissionGenerator;
// Ported and modified from goonstation by Jhrushbe.
// CC-BY-NC-SA-3.0
// https://github.com/goonstation/goonstation/blob/ff86b044/code/obj/nuclearreactor/turbine.dm
public abstract class SharedTurbineSystem : EntitySystem
{
[Dependency] private readonly ISharedAdminLogManager _adminLogger = default!;
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
[Dependency] protected readonly SharedAudioSystem _audio = default!;
[Dependency] private readonly SharedPopupSystem _popupSystem = default!;
[Dependency] private readonly SharedToolSystem _toolSystem = default!;
[Dependency] private readonly EntityManager _entityManager = default!;
[Dependency] private readonly DamageableSystem _damageableSystem = default!;
[Dependency] private readonly IPrototypeManager _proto = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<TurbineComponent, ExaminedEvent>(OnExamined);
SubscribeLocalEvent<TurbineComponent, InteractUsingEvent>(RepairTurbine);
SubscribeLocalEvent<TurbineComponent, RepairDoAfterEvent>(OnRepairTurbineFinished);
}
private void OnExamined(Entity<TurbineComponent> ent, ref ExaminedEvent args)
{
var comp = ent.Comp;
if (!Comp<TransformComponent>(ent).Anchored || !args.IsInDetailsRange) // Not anchored? Out of range? No status.
return;
using (args.PushGroup(nameof(TurbineComponent)))
{
if(comp.CurrentStator == null)
args.PushMarkup(Loc.GetString("gas-turbine-examine-stator-null"));
if (comp.CurrentBlade == null)
args.PushMarkup(Loc.GetString("gas-turbine-examine-blade-null"));
else
{
switch (comp.RPM)
{
case float n when n is >= 0 and <= 1:
args.PushMarkup(Loc.GetString("turbine-spinning-0")); // " The blades are not spinning."
break;
case float n when n is > 1 and <= 60:
args.PushMarkup(Loc.GetString("turbine-spinning-1")); // " The blades are turning slowly."
break;
case float n when n > 60 && n <= comp.BestRPM * 0.5:
args.PushMarkup(Loc.GetString("turbine-spinning-2")); // " The blades are spinning."
break;
case float n when n > comp.BestRPM * 0.5 && n <= comp.BestRPM * 1.2:
args.PushMarkup(Loc.GetString("turbine-spinning-3")); // " The blades are spinning quickly."
break;
case float n when n > comp.BestRPM * 1.2 && n <= float.PositiveInfinity:
args.PushMarkup(Loc.GetString("turbine-spinning-4")); // " The blades are spinning out of control!"
break;
default:
break;
}
}
if (comp.Ruined)
{
args.PushMarkup(Loc.GetString("turbine-ruined")); // " It's completely broken!"
}
else if (comp.BladeHealth <= 0.25 * comp.BladeHealthMax)
{
args.PushMarkup(Loc.GetString("turbine-damaged-3")); // " It's critically damaged!"
}
else if (comp.BladeHealth <= 0.5 * comp.BladeHealthMax)
{
args.PushMarkup(Loc.GetString("turbine-damaged-2")); // " The turbine looks badly damaged."
}
else if (comp.BladeHealth <= 0.75 * comp.BladeHealthMax)
{
args.PushMarkup(Loc.GetString("turbine-damaged-1")); // " The turbine looks a bit scuffed."
}
else
{
args.PushMarkup(Loc.GetString("turbine-damaged-0")); // " It appears to be in good condition."
}
}
}
protected void UpdateAppearance(EntityUid uid, TurbineComponent? comp = null, AppearanceComponent? appearance = null)
{
if (!Resolve(uid, ref comp, ref appearance, false))
return;
_appearance.SetData(uid, TurbineVisuals.TurbineRuined, comp.Ruined);
_appearance.SetData(uid, TurbineVisuals.DamageSpark, comp.IsSparking);
_appearance.SetData(uid, TurbineVisuals.DamageSmoke, comp.IsSmoking);
}
protected void PlayAudio(SoundSpecifier? sound, EntityUid uid, out EntityUid? audioStream, AudioParams? audioParams = null)
{
if (sound == null || audioParams == null)
{
audioStream = null;
return;
}
var loop = audioParams.Value.WithLoop(true);
var stream = false
? _audio.PlayPredicted(sound, uid, uid, loop)
: _audio.PlayPvs(sound, uid, loop);
audioStream = stream?.Entity is { } entity ? entity : null;
}
protected static bool AdjustStatorLoad(TurbineComponent turbine, float change)
{
var newSet = Math.Max(turbine.StatorLoad + change, 1000f);
if (turbine.StatorLoad != newSet)
{
turbine.StatorLoad = newSet;
return true;
}
return false;
}
#region Repairs
private void RepairTurbine(EntityUid uid, TurbineComponent comp, ref InteractUsingEvent args)
{
if (args.Handled)
return;
if(_toolSystem.HasQuality(args.Used, comp.RepairTool))
{
if (comp.CurrentBlade == null)
{
_popupSystem.PopupEntity(Loc.GetString("gas-turbine-repair-fail-blade"), args.User, args.User, PopupType.Medium);
args.Handled = true;
return;
}
if (comp.CurrentStator == null)
{
_popupSystem.PopupEntity(Loc.GetString("gas-turbine-repair-fail-stator"), args.User, args.User, PopupType.Medium);
args.Handled = true;
return;
}
if (comp.BladeHealth >= comp.BladeHealthMax && !comp.Ruined)
return;
args.Handled = _toolSystem.UseTool(args.Used, args.User, uid, comp.RepairDelay, comp.RepairTool, new RepairDoAfterEvent(), comp.RepairFuelCost);
}
}
//Gotta love server/client desync
protected virtual void OnRepairTurbineFinished(EntityUid uid, TurbineComponent comp, ref RepairDoAfterEvent args)
{
if (comp.Ruined)
{
comp.Ruined = false;
if (comp.BladeHealth <= 0) { comp.BladeHealth = 1; }
UpdateHealthIndicators(uid, comp);
}
else if (comp.BladeHealth < comp.BladeHealthMax)
{
comp.BladeHealth++;
UpdateHealthIndicators(uid, comp);
}
else if (comp.BladeHealth >= comp.BladeHealthMax)
{
// This should technically never occur, but just in case...
}
if (!_entityManager.TryGetComponent<DamageableComponent>(uid, out var damageableComponent))
return;
_damageableSystem.SetAllDamage((uid, damageableComponent), 0);
}
protected void UpdateHealthIndicators(EntityUid uid, TurbineComponent comp)
{
if (comp.BladeHealth <= 0.75 * comp.BladeHealthMax && !comp.IsSparking)
{
comp.IsSparking = true;
_audio.PlayPvs(new SoundPathSpecifier("/Audio/Effects/PowerSink/electric.ogg"), uid, AudioParams.Default.WithPitchScale(0.75f));
_popupSystem.PopupEntity(Loc.GetString("turbine-spark", ("owner", uid)), uid, PopupType.MediumCaution);
}
else if (comp.BladeHealth > 0.75 * comp.BladeHealthMax && comp.IsSparking)
{
comp.IsSparking = false;
_popupSystem.PopupEntity(Loc.GetString("turbine-spark-stop", ("owner", uid)), uid, PopupType.Medium);
}
if (comp.BladeHealth <= 0.5 * comp.BladeHealthMax && !comp.IsSmoking)
{
comp.IsSmoking = true;
_popupSystem.PopupEntity(Loc.GetString("turbine-smoke", ("owner", uid)), uid, PopupType.MediumCaution);
}
else if (comp.BladeHealth > 0.5 * comp.BladeHealthMax && comp.IsSmoking)
{
comp.IsSmoking = false;
_popupSystem.PopupEntity(Loc.GetString("turbine-smoke-stop", ("owner", uid)), uid, PopupType.Medium);
}
_entityManager.EnsureComponent<ElectrifiedComponent>(uid).Enabled = comp.IsSparking;
UpdateAppearance(uid, comp);
}
#endregion
}