Files
wwdpublic/Content.Server/ParticleAccelerator/EntitySystems/ParticleAcceleratorSystem.ControlBox.cs
sleepyyapril 885ee5a831 Wizmerge for Station AI (#1351)
<!--
This is a semi-strict format, you can add/remove sections as needed but
the order/format should be kept the same
Remove these comments before submitting
-->

# Description

the adding AI is now up to y'all because i'm not touching loadout code
for name datasets, but it shouldn't be too bad from here

---------

Signed-off-by: sleepyyapril <123355664+sleepyyapril@users.noreply.github.com>
Signed-off-by: SolStar <44028047+ewokswagger@users.noreply.github.com>
Signed-off-by: deltanedas <39013340+deltanedas@users.noreply.github.com>
Co-authored-by: themias <89101928+themias@users.noreply.github.com>
Co-authored-by: Verm <32827189+Vermidia@users.noreply.github.com>
Co-authored-by: DrSmugleaf <10968691+DrSmugleaf@users.noreply.github.com>
Co-authored-by: Sphiral <145869023+SphiraI@users.noreply.github.com>
Co-authored-by: Ed <96445749+TheShuEd@users.noreply.github.com>
Co-authored-by: Mr. 27 <45323883+Dutch-VanDerLinde@users.noreply.github.com>
Co-authored-by: metalgearsloth <comedian_vs_clown@hotmail.com>
Co-authored-by: Alzore <140123969+Blackern5000@users.noreply.github.com>
Co-authored-by: ravage <142820619+ravage123321@users.noreply.github.com>
Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
Co-authored-by: Intoxicating-Innocence <188202277+Intoxicating-Innocence@users.noreply.github.com>
Co-authored-by: Saphire <lattice@saphi.re>
Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com>
Co-authored-by: Errant <35878406+Errant-4@users.noreply.github.com>
Co-authored-by: Tayrtahn <tayrtahn@gmail.com>
Co-authored-by: CaasGit <87243814+CaasGit@users.noreply.github.com>
Co-authored-by: BramvanZijp <56019239+BramvanZijp@users.noreply.github.com>
Co-authored-by: Boaz1111 <149967078+Boaz1111@users.noreply.github.com>
Co-authored-by: NakataRin <45946146+NakataRin@users.noreply.github.com>
Co-authored-by: Kara <lunarautomaton6@gmail.com>
Co-authored-by: Plykiya <58439124+Plykiya@users.noreply.github.com>
Co-authored-by: SlamBamActionman <slambamactionman@gmail.com>
Co-authored-by: Doomsdrayk <robotdoughnut@comcast.net>
Co-authored-by: Brandon Hu <103440971+Brandon-Huu@users.noreply.github.com>
Co-authored-by: SlamBamActionman <83650252+SlamBamActionman@users.noreply.github.com>
Co-authored-by: ElectroJr <leonsfriedrich@gmail.com>
Co-authored-by: Pieter-Jan Briers <pieterjan.briers+git@gmail.com>
Co-authored-by: DrSmugleaf <DrSmugleaf@users.noreply.github.com>
Co-authored-by: Julian Giebel <juliangiebel@live.de>
Co-authored-by: nikthechampiongr <32041239+nikthechampiongr@users.noreply.github.com>
Co-authored-by: Repo <47093363+Titian3@users.noreply.github.com>
Co-authored-by: Chief-Engineer <119664036+Chief-Engineer@users.noreply.github.com>
Co-authored-by: icekot8 <93311212+icekot8@users.noreply.github.com>
Co-authored-by: AJCM-git <60196617+AJCM-git@users.noreply.github.com>
Co-authored-by: Leon Friedrich <60421075+ElectroJr@users.noreply.github.com>
Co-authored-by: no <165581243+pissdemon@users.noreply.github.com>
Co-authored-by: Tornado Tech <54727692+Tornado-Technology@users.noreply.github.com>
Co-authored-by: osjarw <62134478+osjarw@users.noreply.github.com>
Co-authored-by: Simon <63975668+Simyon264@users.noreply.github.com>
Co-authored-by: TGRCDev <tgrc@tgrc.dev>
Co-authored-by: Milon <milonpl.git@proton.me>
Co-authored-by: deltanedas <39013340+deltanedas@users.noreply.github.com>
Co-authored-by: ShadowCommander <10494922+ShadowCommander@users.noreply.github.com>
Co-authored-by: Fildrance <fildrance@gmail.com>
Co-authored-by: pa.pecherskij <pa.pecherskij@interfax.ru>
Co-authored-by: chavonadelal <156101927+chavonadelal@users.noreply.github.com>
Co-authored-by: SolStar <44028047+ewokswagger@users.noreply.github.com>
Co-authored-by: K-Dynamic <20566341+K-Dynamic@users.noreply.github.com>
Co-authored-by: lzk <124214523+lzk228@users.noreply.github.com>
Co-authored-by: ArchRBX <5040911+ArchRBX@users.noreply.github.com>
Co-authored-by: archrbx <punk.gear5260@fastmail.com>
Co-authored-by: Radezolid <snappednexus@gmail.com>
Co-authored-by: Nemanja <98561806+EmoGarbage404@users.noreply.github.com>
Co-authored-by: EmoGarbage404 <retron404@gmail.com>
Co-authored-by: MilenVolf <63782763+MilenVolf@users.noreply.github.com>
Co-authored-by: Velcroboy <107660393+IamVelcroboy@users.noreply.github.com>
Co-authored-by: Velcroboy <velcroboy333@hotmail.com>
Co-authored-by: neuPanda <chriseparton@gmail.com>
Co-authored-by: neuPanda <spainman0@yahoo.com>
Co-authored-by: Dvir <39403717+dvir001@users.noreply.github.com>
Co-authored-by: Whatstone <whatston3@gmail.com>
Co-authored-by: VideoKompany <135313844+VlaDOS1408@users.noreply.github.com>

(cherry picked from commit 93ed70acfeda357133a701f637d3faeec02749bb)
2025-01-14 00:13:42 +03:00

402 lines
15 KiB
C#

using Content.Server.ParticleAccelerator.Components;
using Content.Server.Power.Components;
using Content.Shared.Database;
using Content.Shared.Singularity.Components;
using Robust.Shared.Utility;
using System.Diagnostics;
using Content.Server.Administration.Managers;
using Content.Shared.CCVar;
using Content.Shared.Power;
using Robust.Shared.Audio;
using Robust.Shared.Audio.Systems;
using Robust.Shared.Timing;
using Robust.Shared.Player;
namespace Content.Server.ParticleAccelerator.EntitySystems;
public sealed partial class ParticleAcceleratorSystem
{
[Dependency] private readonly IAdminManager _adminManager = default!;
[Dependency] private readonly SharedAudioSystem _audio = default!;
[Dependency] private readonly IGameTiming _timing = default!;
private void InitializeControlBoxSystem()
{
SubscribeLocalEvent<ParticleAcceleratorControlBoxComponent, ComponentStartup>(OnComponentStartup);
SubscribeLocalEvent<ParticleAcceleratorControlBoxComponent, ComponentShutdown>(OnComponentShutdown);
SubscribeLocalEvent<ParticleAcceleratorControlBoxComponent, PowerChangedEvent>(OnControlBoxPowerChange);
SubscribeLocalEvent<ParticleAcceleratorControlBoxComponent, ParticleAcceleratorSetEnableMessage>(OnUISetEnableMessage);
SubscribeLocalEvent<ParticleAcceleratorControlBoxComponent, ParticleAcceleratorSetPowerStateMessage>(OnUISetPowerMessage);
SubscribeLocalEvent<ParticleAcceleratorControlBoxComponent, ParticleAcceleratorRescanPartsMessage>(OnUIRescanMessage);
}
public override void Update(float frameTime)
{
var curTime = _gameTiming.CurTime;
var query = EntityQueryEnumerator<ParticleAcceleratorControlBoxComponent>();
while (query.MoveNext(out var uid, out var controller))
{
if (controller.Firing && curTime >= controller.NextFire)
Fire(uid, curTime, controller);
}
}
[Conditional("DEBUG")]
private void EverythingIsWellToFire(ParticleAcceleratorControlBoxComponent controller)
{
DebugTools.Assert(controller.Powered);
DebugTools.Assert(controller.SelectedStrength != ParticleAcceleratorPowerState.Standby);
DebugTools.Assert(controller.Assembled);
DebugTools.Assert(EntityManager.EntityExists(controller.PortEmitter));
DebugTools.Assert(EntityManager.EntityExists(controller.ForeEmitter));
DebugTools.Assert(EntityManager.EntityExists(controller.StarboardEmitter));
}
public void Fire(EntityUid uid, TimeSpan curTime, ParticleAcceleratorControlBoxComponent? comp = null)
{
if (!Resolve(uid, ref comp))
return;
comp.LastFire = curTime;
comp.NextFire = curTime + comp.ChargeTime;
EverythingIsWellToFire(comp);
var strength = comp.SelectedStrength;
FireEmitter(comp.PortEmitter!.Value, strength);
FireEmitter(comp.ForeEmitter!.Value, strength);
FireEmitter(comp.StarboardEmitter!.Value, strength);
}
public void SwitchOn(EntityUid uid, EntityUid? user = null, ParticleAcceleratorControlBoxComponent? comp = null)
{
if (!Resolve(uid, ref comp))
return;
DebugTools.Assert(comp.Assembled);
if (comp.Enabled || !comp.CanBeEnabled)
return;
if (user is { } player)
_adminLogger.Add(LogType.Action, LogImpact.Low, $"{ToPrettyString(player):player} has turned {ToPrettyString(uid)} on");
comp.Enabled = true;
UpdatePowerDraw(uid, comp);
if (!TryComp<PowerConsumerComponent>(comp.PowerBox, out var powerConsumer)
|| powerConsumer.ReceivedPower >= powerConsumer.DrawRate * ParticleAcceleratorControlBoxComponent.RequiredPowerRatio)
PowerOn(uid, comp);
UpdateUI(uid, comp);
}
public void SwitchOff(EntityUid uid, EntityUid? user = null, ParticleAcceleratorControlBoxComponent? comp = null)
{
if (!Resolve(uid, ref comp))
return;
if (!comp.Enabled)
return;
if (user is { } player)
_adminLogger.Add(LogType.Action, LogImpact.Low, $"{ToPrettyString(player):player} has turned {ToPrettyString(uid)} off");
comp.Enabled = false;
UpdatePowerDraw(uid, comp);
PowerOff(uid, comp);
UpdateUI(uid, comp);
}
public void PowerOn(EntityUid uid, ParticleAcceleratorControlBoxComponent? comp = null)
{
if (!Resolve(uid, ref comp))
return;
DebugTools.Assert(comp.Enabled);
DebugTools.Assert(comp.Assembled);
if (comp.Powered)
return;
comp.Powered = true;
UpdatePowerDraw(uid, comp);
UpdateFiring(uid, comp);
UpdatePartVisualStates(uid, comp);
UpdateUI(uid, comp);
}
public void PowerOff(EntityUid uid, ParticleAcceleratorControlBoxComponent? comp = null)
{
if (!Resolve(uid, ref comp))
return;
if (!comp.Powered)
return;
comp.Powered = false;
UpdatePowerDraw(uid, comp);
UpdateFiring(uid, comp);
UpdatePartVisualStates(uid, comp);
UpdateUI(uid, comp);
}
public void SetStrength(EntityUid uid, ParticleAcceleratorPowerState strength, EntityUid? user = null, ParticleAcceleratorControlBoxComponent? comp = null)
{
if (!Resolve(uid, ref comp))
return;
if (comp.StrengthLocked)
return;
strength = (ParticleAcceleratorPowerState) MathHelper.Clamp(
(int) strength,
(int) ParticleAcceleratorPowerState.Standby,
(int) comp.MaxStrength
);
if (strength == comp.SelectedStrength)
return;
if (user is { } player)
{
var impact = strength switch
{
ParticleAcceleratorPowerState.Standby => LogImpact.Low,
ParticleAcceleratorPowerState.Level0 => LogImpact.Medium,
ParticleAcceleratorPowerState.Level1 => LogImpact.High,
ParticleAcceleratorPowerState.Level2
or ParticleAcceleratorPowerState.Level3
or _ => LogImpact.Extreme,
};
_adminLogger.Add(LogType.Action, impact, $"{ToPrettyString(player):player} has set the strength of {ToPrettyString(uid)} to {strength}");
var alertMinPowerState = (ParticleAcceleratorPowerState)_cfg.GetCVar(CCVars.AdminAlertParticleAcceleratorMinPowerState);
if (strength >= alertMinPowerState)
{
var pos = Transform(uid);
if (_timing.CurTime > comp.EffectCooldown)
{
_chat.SendAdminAlert(player, Loc.GetString("particle-accelerator-admin-power-strength-warning",
("machine", ToPrettyString(uid)),
("powerState", strength),
("coordinates", pos.Coordinates)));
_audio.PlayGlobal("/Audio/Misc/adminlarm.ogg",
Filter.Empty().AddPlayers(_adminManager.ActiveAdmins), false,
AudioParams.Default.WithVolume(-8f));
comp.EffectCooldown = _timing.CurTime + comp.CooldownDuration;
}
}
}
comp.SelectedStrength = strength;
UpdateAppearance(uid, comp);
UpdatePartVisualStates(uid, comp);
if (comp.Enabled)
{
UpdatePowerDraw(uid, comp);
UpdateFiring(uid, comp);
}
}
private void UpdateFiring(EntityUid uid, ParticleAcceleratorControlBoxComponent? comp = null)
{
if (!Resolve(uid, ref comp))
return;
if (!comp.Powered || comp.SelectedStrength < ParticleAcceleratorPowerState.Level0)
{
comp.Firing = false;
return;
}
EverythingIsWellToFire(comp);
var curTime = _gameTiming.CurTime;
comp.LastFire = curTime;
comp.NextFire = curTime + comp.ChargeTime;
comp.Firing = true;
}
private void UpdatePowerDraw(EntityUid uid, ParticleAcceleratorControlBoxComponent? comp = null)
{
if (!Resolve(uid, ref comp))
return;
if (!TryComp<PowerConsumerComponent>(comp.PowerBox, out var powerConsumer))
return;
var powerDraw = comp.BasePowerDraw;
if (comp.Enabled)
powerDraw += comp.LevelPowerDraw * (int) comp.SelectedStrength;
powerConsumer.DrawRate = powerDraw;
}
private void UpdateUI(EntityUid uid, ParticleAcceleratorControlBoxComponent? comp = null)
{
if (!Resolve(uid, ref comp))
return;
if (!_uiSystem.HasUi(uid, ParticleAcceleratorControlBoxUiKey.Key))
return;
var draw = 0f;
var receive = 0f;
if (TryComp<PowerConsumerComponent>(comp.PowerBox, out var powerConsumer))
{
draw = powerConsumer.DrawRate;
receive = powerConsumer.ReceivedPower;
}
_uiSystem.SetUiState(uid, ParticleAcceleratorControlBoxUiKey.Key, new ParticleAcceleratorUIState(
comp.Assembled,
comp.Enabled,
comp.SelectedStrength,
(int) draw,
(int) receive,
comp.StarboardEmitter != null,
comp.ForeEmitter != null,
comp.PortEmitter != null,
comp.PowerBox != null,
comp.FuelChamber != null,
comp.EndCap != null,
comp.InterfaceDisabled,
comp.MaxStrength,
comp.StrengthLocked
));
}
private void UpdateAppearance(EntityUid uid, ParticleAcceleratorControlBoxComponent? comp = null, AppearanceComponent? appearance = null)
{
if (!Resolve(uid, ref comp))
return;
_appearanceSystem.SetData(
uid,
ParticleAcceleratorVisuals.VisualState,
TryComp<ApcPowerReceiverComponent>(uid, out var apcPower) && !apcPower.Powered
? ParticleAcceleratorVisualState.Unpowered
: (ParticleAcceleratorVisualState) comp.SelectedStrength,
appearance
);
}
private void UpdatePartVisualStates(EntityUid uid, ParticleAcceleratorControlBoxComponent? controller = null)
{
if (!Resolve(uid, ref controller))
return;
var state = controller.Powered ? (ParticleAcceleratorVisualState) controller.SelectedStrength : ParticleAcceleratorVisualState.Unpowered;
// UpdatePartVisualState(ControlBox); (We are the control box)
if (controller.FuelChamber.HasValue)
_appearanceSystem.SetData(controller.FuelChamber!.Value, ParticleAcceleratorVisuals.VisualState, state);
if (controller.PowerBox.HasValue)
_appearanceSystem.SetData(controller.PowerBox!.Value, ParticleAcceleratorVisuals.VisualState, state);
if (controller.PortEmitter.HasValue)
_appearanceSystem.SetData(controller.PortEmitter!.Value, ParticleAcceleratorVisuals.VisualState, state);
if (controller.ForeEmitter.HasValue)
_appearanceSystem.SetData(controller.ForeEmitter!.Value, ParticleAcceleratorVisuals.VisualState, state);
if (controller.StarboardEmitter.HasValue)
_appearanceSystem.SetData(controller.StarboardEmitter!.Value, ParticleAcceleratorVisuals.VisualState, state);
//no endcap because it has no powerlevel-sprites
}
private IEnumerable<EntityUid> AllParts(EntityUid uid, ParticleAcceleratorControlBoxComponent? comp = null)
{
if (Resolve(uid, ref comp))
{
if (comp.FuelChamber.HasValue)
yield return comp.FuelChamber.Value;
if (comp.EndCap.HasValue)
yield return comp.EndCap.Value;
if (comp.PowerBox.HasValue)
yield return comp.PowerBox.Value;
if (comp.PortEmitter.HasValue)
yield return comp.PortEmitter.Value;
if (comp.ForeEmitter.HasValue)
yield return comp.ForeEmitter.Value;
if (comp.StarboardEmitter.HasValue)
yield return comp.StarboardEmitter.Value;
}
}
private void OnComponentStartup(EntityUid uid, ParticleAcceleratorControlBoxComponent comp, ComponentStartup args)
{
if (TryComp<ParticleAcceleratorPartComponent>(uid, out var part))
part.Master = uid;
}
private void OnComponentShutdown(EntityUid uid, ParticleAcceleratorControlBoxComponent comp, ComponentShutdown args)
{
if (TryComp<ParticleAcceleratorPartComponent>(uid, out var partStatus))
partStatus.Master = null;
var partQuery = GetEntityQuery<ParticleAcceleratorPartComponent>();
foreach (var part in AllParts(uid, comp))
{
if (partQuery.TryGetComponent(part, out var partData))
partData.Master = null;
}
}
// This is the power state for the PA control box itself.
// Keep in mind that the PA itself can keep firing as long as the HV cable under the power box has... power.
private void OnControlBoxPowerChange(EntityUid uid, ParticleAcceleratorControlBoxComponent comp, ref PowerChangedEvent args)
{
UpdateAppearance(uid, comp);
if (!args.Powered)
_uiSystem.CloseUi(uid, ParticleAcceleratorControlBoxUiKey.Key);
}
private void OnUISetEnableMessage(EntityUid uid, ParticleAcceleratorControlBoxComponent comp, ParticleAcceleratorSetEnableMessage msg)
{
if (!ParticleAcceleratorControlBoxUiKey.Key.Equals(msg.UiKey))
return;
if (comp.InterfaceDisabled)
return;
if (TryComp<ApcPowerReceiverComponent>(uid, out var apcPower) && !apcPower.Powered)
return;
if (msg.Enabled)
{
if (comp.Assembled)
SwitchOn(uid, msg.Actor, comp);
}
else
SwitchOff(uid, msg.Actor, comp);
UpdateUI(uid, comp);
}
private void OnUISetPowerMessage(EntityUid uid, ParticleAcceleratorControlBoxComponent comp, ParticleAcceleratorSetPowerStateMessage msg)
{
if (!ParticleAcceleratorControlBoxUiKey.Key.Equals(msg.UiKey))
return;
if (comp.InterfaceDisabled)
return;
if (TryComp<ApcPowerReceiverComponent>(uid, out var apcPower) && !apcPower.Powered)
return;
SetStrength(uid, msg.State, msg.Actor, comp);
UpdateUI(uid, comp);
}
private void OnUIRescanMessage(EntityUid uid, ParticleAcceleratorControlBoxComponent comp, ParticleAcceleratorRescanPartsMessage msg)
{
if (!ParticleAcceleratorControlBoxUiKey.Key.Equals(msg.UiKey))
return;
if (comp.InterfaceDisabled)
return;
if (TryComp<ApcPowerReceiverComponent>(uid, out var apcPower) && !apcPower.Powered)
return;
RescanParts(uid, msg.Actor, comp);
UpdateUI(uid, comp);
}
}