Add multipart machines system (#35969)
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
using Content.Server.ParticleAccelerator.Components;
|
||||
using Content.Server.Power.Components;
|
||||
using Content.Shared.Database;
|
||||
using Content.Shared.Machines.Components;
|
||||
using Content.Shared.Singularity.Components;
|
||||
using Robust.Shared.Utility;
|
||||
using System.Diagnostics;
|
||||
@@ -10,6 +11,8 @@ using Content.Shared.Power;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Audio.Systems;
|
||||
using Robust.Shared.Player;
|
||||
using Content.Shared.ParticleAccelerator;
|
||||
using Content.Shared.Machines.Events;
|
||||
|
||||
namespace Content.Server.ParticleAccelerator.EntitySystems;
|
||||
|
||||
@@ -20,12 +23,11 @@ public sealed partial class ParticleAcceleratorSystem
|
||||
|
||||
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);
|
||||
SubscribeLocalEvent<ParticleAcceleratorControlBoxComponent, MultipartMachineAssemblyStateChanged>(OnMachineAssembledChanged);
|
||||
}
|
||||
|
||||
public override void Update(float frameTime)
|
||||
@@ -40,14 +42,12 @@ public sealed partial class ParticleAcceleratorSystem
|
||||
}
|
||||
|
||||
[Conditional("DEBUG")]
|
||||
private void EverythingIsWellToFire(ParticleAcceleratorControlBoxComponent controller)
|
||||
private void EverythingIsWellToFire(ParticleAcceleratorControlBoxComponent controller,
|
||||
Entity<MultipartMachineComponent> machine)
|
||||
{
|
||||
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));
|
||||
DebugTools.Assert(machine.Comp.IsAssembled);
|
||||
}
|
||||
|
||||
public void Fire(EntityUid uid, TimeSpan curTime, ParticleAcceleratorControlBoxComponent? comp = null)
|
||||
@@ -58,12 +58,17 @@ public sealed partial class ParticleAcceleratorSystem
|
||||
comp.LastFire = curTime;
|
||||
comp.NextFire = curTime + comp.ChargeTime;
|
||||
|
||||
EverythingIsWellToFire(comp);
|
||||
if (!TryComp<MultipartMachineComponent>(uid, out var machineComp))
|
||||
return;
|
||||
|
||||
var machine = (uid, machineComp);
|
||||
EverythingIsWellToFire(comp, machine);
|
||||
|
||||
var strength = comp.SelectedStrength;
|
||||
FireEmitter(comp.PortEmitter!.Value, strength);
|
||||
FireEmitter(comp.ForeEmitter!.Value, strength);
|
||||
FireEmitter(comp.StarboardEmitter!.Value, strength);
|
||||
|
||||
FireEmitter(_multipartMachine.GetPartEntity(machine, AcceleratorParts.PortEmitter)!.Value, strength);
|
||||
FireEmitter(_multipartMachine.GetPartEntity(machine, AcceleratorParts.ForeEmitter)!.Value, strength);
|
||||
FireEmitter(_multipartMachine.GetPartEntity(machine, AcceleratorParts.StarboardEmitter)!.Value, strength);
|
||||
}
|
||||
|
||||
public void SwitchOn(EntityUid uid, EntityUid? user = null, ParticleAcceleratorControlBoxComponent? comp = null)
|
||||
@@ -71,7 +76,7 @@ public sealed partial class ParticleAcceleratorSystem
|
||||
if (!Resolve(uid, ref comp))
|
||||
return;
|
||||
|
||||
DebugTools.Assert(comp.Assembled);
|
||||
DebugTools.Assert(_multipartMachine.IsAssembled((uid, null)));
|
||||
|
||||
if (comp.Enabled || !comp.CanBeEnabled)
|
||||
return;
|
||||
@@ -82,9 +87,11 @@ public sealed partial class ParticleAcceleratorSystem
|
||||
comp.Enabled = true;
|
||||
UpdatePowerDraw(uid, comp);
|
||||
|
||||
if (!TryComp<PowerConsumerComponent>(comp.PowerBox, out var powerConsumer)
|
||||
|| powerConsumer.ReceivedPower >= powerConsumer.DrawRate * ParticleAcceleratorControlBoxComponent.RequiredPowerRatio)
|
||||
if (!TryComp<PowerConsumerComponent>(_multipartMachine.GetPartEntity(uid, AcceleratorParts.PowerBox), out var powerConsumer)
|
||||
|| powerConsumer.ReceivedPower >= powerConsumer.DrawRate * ParticleAcceleratorControlBoxComponent.RequiredPowerRatio)
|
||||
{
|
||||
PowerOn(uid, comp);
|
||||
}
|
||||
|
||||
UpdateUI(uid, comp);
|
||||
}
|
||||
@@ -112,7 +119,7 @@ public sealed partial class ParticleAcceleratorSystem
|
||||
return;
|
||||
|
||||
DebugTools.Assert(comp.Enabled);
|
||||
DebugTools.Assert(comp.Assembled);
|
||||
DebugTools.Assert(_multipartMachine.IsAssembled((uid, null)));
|
||||
|
||||
if (comp.Powered)
|
||||
return;
|
||||
@@ -211,7 +218,10 @@ public sealed partial class ParticleAcceleratorSystem
|
||||
return;
|
||||
}
|
||||
|
||||
EverythingIsWellToFire(comp);
|
||||
if (!TryComp<MultipartMachineComponent>(uid, out var machine))
|
||||
return;
|
||||
|
||||
EverythingIsWellToFire(comp, (uid, machine));
|
||||
|
||||
var curTime = _gameTiming.CurTime;
|
||||
comp.LastFire = curTime;
|
||||
@@ -223,7 +233,8 @@ public sealed partial class ParticleAcceleratorSystem
|
||||
{
|
||||
if (!Resolve(uid, ref comp))
|
||||
return;
|
||||
if (!TryComp<PowerConsumerComponent>(comp.PowerBox, out var powerConsumer))
|
||||
|
||||
if (!TryComp<PowerConsumerComponent>(_multipartMachine.GetPartEntity(uid, AcceleratorParts.PowerBox), out var powerConsumer))
|
||||
return;
|
||||
|
||||
var powerDraw = comp.BasePowerDraw;
|
||||
@@ -244,30 +255,35 @@ public sealed partial class ParticleAcceleratorSystem
|
||||
var draw = 0f;
|
||||
var receive = 0f;
|
||||
|
||||
if (TryComp<PowerConsumerComponent>(comp.PowerBox, out var powerConsumer))
|
||||
if (TryComp<PowerConsumerComponent>(_multipartMachine.GetPartEntity(uid, AcceleratorParts.PowerBox), out var powerConsumer))
|
||||
{
|
||||
draw = powerConsumer.DrawRate;
|
||||
receive = powerConsumer.ReceivedPower;
|
||||
}
|
||||
|
||||
_uiSystem.SetUiState(uid,
|
||||
ParticleAcceleratorControlBoxUiKey.Key,
|
||||
new ParticleAcceleratorUIState(
|
||||
comp.Assembled,
|
||||
if (!TryComp<MultipartMachineComponent>(uid, out var machineComp))
|
||||
return;
|
||||
|
||||
var machine = (uid, machineComp);
|
||||
|
||||
var uiState = new ParticleAcceleratorUIState(
|
||||
machineComp.IsAssembled,
|
||||
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,
|
||||
(int)draw,
|
||||
(int)receive,
|
||||
_multipartMachine.HasPart(machine, AcceleratorParts.StarboardEmitter),
|
||||
_multipartMachine.HasPart(machine, AcceleratorParts.ForeEmitter),
|
||||
_multipartMachine.HasPart(machine, AcceleratorParts.PortEmitter),
|
||||
_multipartMachine.HasPart(machine, AcceleratorParts.PowerBox),
|
||||
_multipartMachine.HasPart(machine, AcceleratorParts.FuelChamber),
|
||||
_multipartMachine.HasPart(machine, AcceleratorParts.EndCap),
|
||||
comp.InterfaceDisabled,
|
||||
comp.MaxStrength,
|
||||
comp.StrengthLocked
|
||||
));
|
||||
);
|
||||
|
||||
_uiSystem.SetUiState(uid, ParticleAcceleratorControlBoxUiKey.Key, uiState);
|
||||
}
|
||||
|
||||
private void UpdateAppearance(EntityUid uid, ParticleAcceleratorControlBoxComponent? comp = null, AppearanceComponent? appearance = null)
|
||||
@@ -292,55 +308,58 @@ public sealed partial class ParticleAcceleratorSystem
|
||||
|
||||
var state = controller.Powered ? (ParticleAcceleratorVisualState) controller.SelectedStrength : ParticleAcceleratorVisualState.Unpowered;
|
||||
|
||||
if (!TryComp<MultipartMachineComponent>(uid, out var machineComp))
|
||||
return;
|
||||
|
||||
var machine = (uid, machineComp);
|
||||
|
||||
// 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);
|
||||
if (_multipartMachine.TryGetPartEntity(machine, AcceleratorParts.FuelChamber, out var fuelChamber))
|
||||
_appearanceSystem.SetData(fuelChamber.Value, ParticleAcceleratorVisuals.VisualState, state);
|
||||
if (_multipartMachine.TryGetPartEntity(machine, AcceleratorParts.PowerBox, out var powerBox))
|
||||
_appearanceSystem.SetData(powerBox.Value, ParticleAcceleratorVisuals.VisualState, state);
|
||||
if (_multipartMachine.TryGetPartEntity(machine, AcceleratorParts.PortEmitter, out var portEmitter))
|
||||
_appearanceSystem.SetData(portEmitter.Value, ParticleAcceleratorVisuals.VisualState, state);
|
||||
if (_multipartMachine.TryGetPartEntity(machine, AcceleratorParts.ForeEmitter, out var foreEmitter))
|
||||
_appearanceSystem.SetData(foreEmitter.Value, ParticleAcceleratorVisuals.VisualState, state);
|
||||
if (_multipartMachine.TryGetPartEntity(machine, AcceleratorParts.StarboardEmitter, out var starboardEmitter))
|
||||
_appearanceSystem.SetData(starboardEmitter.Value, ParticleAcceleratorVisuals.VisualState, state);
|
||||
//no endcap because it has no powerlevel-sprites
|
||||
}
|
||||
|
||||
private IEnumerable<EntityUid> AllParts(EntityUid uid, ParticleAcceleratorControlBoxComponent? comp = null)
|
||||
/// <summary>
|
||||
/// Handles when a multipart machine has had some assembled/disassembled state change, or had parts added/removed.
|
||||
/// </summary>
|
||||
/// <param name="ent">Multipart machine entity</param>
|
||||
/// <param name="args">Args for this event</param>
|
||||
private void OnMachineAssembledChanged(Entity<ParticleAcceleratorControlBoxComponent> ent, ref MultipartMachineAssemblyStateChanged args)
|
||||
{
|
||||
if (Resolve(uid, ref comp))
|
||||
if (args.IsAssembled)
|
||||
{
|
||||
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;
|
||||
UpdatePowerDraw(ent, ent.Comp);
|
||||
UpdateUI(ent, ent.Comp);
|
||||
}
|
||||
}
|
||||
|
||||
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))
|
||||
else
|
||||
{
|
||||
if (partQuery.TryGetComponent(part, out var partData))
|
||||
partData.Master = null;
|
||||
if (ent.Comp.Powered)
|
||||
{
|
||||
SwitchOff(ent, args.User, ent.Comp);
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdateAppearance(ent, ent.Comp);
|
||||
UpdateUI(ent, ent.Comp);
|
||||
}
|
||||
|
||||
// Because the parts are already removed from the multipart machine, updating the visual appearance won't find any valid entities.
|
||||
// We know which parts have been removed so we can update the visual state to unpowered in a more manual way here.
|
||||
foreach (var (key, part) in args.PartsRemoved)
|
||||
{
|
||||
if (key is AcceleratorParts.EndCap)
|
||||
continue; // No endcap powerlevel-sprites
|
||||
|
||||
_appearanceSystem.SetData(part, ParticleAcceleratorVisuals.VisualState, ParticleAcceleratorVisualState.Unpowered);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -365,7 +384,7 @@ public sealed partial class ParticleAcceleratorSystem
|
||||
|
||||
if (msg.Enabled)
|
||||
{
|
||||
if (comp.Assembled)
|
||||
if (_multipartMachine.IsAssembled((uid, null)))
|
||||
SwitchOn(uid, msg.Actor, comp);
|
||||
}
|
||||
else
|
||||
@@ -397,9 +416,13 @@ public sealed partial class ParticleAcceleratorSystem
|
||||
if (TryComp<ApcPowerReceiverComponent>(uid, out var apcPower) && !apcPower.Powered)
|
||||
return;
|
||||
|
||||
RescanParts(uid, msg.Actor, comp);
|
||||
if (!TryComp<MultipartMachineComponent>(uid, out var machineComp))
|
||||
return;
|
||||
|
||||
UpdateUI(uid, comp);
|
||||
// User has requested a manual rescan of the machine, if anything HAS changed that the multipart
|
||||
// machine system has missed then a AssemblyStateChanged event will be raised at the machine.
|
||||
var machine = new Entity<MultipartMachineComponent>(uid, machineComp);
|
||||
_multipartMachine.Rescan(machine, msg.Actor);
|
||||
}
|
||||
|
||||
public static int GetPANumericalLevel(ParticleAcceleratorPowerState state)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using Content.Server.ParticleAccelerator.Components;
|
||||
using Content.Server.Singularity.Components;
|
||||
using Content.Shared.ParticleAccelerator.Components;
|
||||
using Content.Shared.Projectiles;
|
||||
using Content.Shared.Singularity.Components;
|
||||
using Robust.Shared.Physics.Components;
|
||||
|
||||
@@ -1,177 +0,0 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Content.Server.ParticleAccelerator.Components;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.Map.Components;
|
||||
using Robust.Shared.Physics.Events;
|
||||
|
||||
namespace Content.Server.ParticleAccelerator.EntitySystems;
|
||||
|
||||
[UsedImplicitly]
|
||||
public sealed partial class ParticleAcceleratorSystem
|
||||
{
|
||||
private void InitializePartSystem()
|
||||
{
|
||||
SubscribeLocalEvent<ParticleAcceleratorPartComponent, ComponentShutdown>(OnComponentShutdown);
|
||||
SubscribeLocalEvent<ParticleAcceleratorPartComponent, MoveEvent>(OnMoveEvent);
|
||||
SubscribeLocalEvent<ParticleAcceleratorPartComponent, PhysicsBodyTypeChangedEvent>(BodyTypeChanged);
|
||||
}
|
||||
|
||||
public void RescanParts(EntityUid uid, EntityUid? user = null, ParticleAcceleratorControlBoxComponent? controller = null)
|
||||
{
|
||||
if (!Resolve(uid, ref controller))
|
||||
return;
|
||||
|
||||
if (controller.CurrentlyRescanning)
|
||||
return;
|
||||
|
||||
var partQuery = GetEntityQuery<ParticleAcceleratorPartComponent>();
|
||||
foreach (var part in AllParts(uid, controller))
|
||||
{
|
||||
if (partQuery.TryGetComponent(part, out var partState))
|
||||
partState.Master = null;
|
||||
}
|
||||
|
||||
controller.Assembled = false;
|
||||
controller.FuelChamber = null;
|
||||
controller.EndCap = null;
|
||||
controller.PowerBox = null;
|
||||
controller.PortEmitter = null;
|
||||
controller.ForeEmitter = null;
|
||||
controller.StarboardEmitter = null;
|
||||
|
||||
var xformQuery = GetEntityQuery<TransformComponent>();
|
||||
if (!xformQuery.TryGetComponent(uid, out var xform) || !xform.Anchored)
|
||||
{
|
||||
SwitchOff(uid, user, controller);
|
||||
return;
|
||||
}
|
||||
|
||||
var gridUid = xform.GridUid;
|
||||
if (gridUid == null || gridUid != xform.ParentUid || !TryComp<MapGridComponent>(gridUid, out var grid))
|
||||
{
|
||||
SwitchOff(uid, user, controller);
|
||||
return;
|
||||
}
|
||||
|
||||
// Find fuel chamber first by scanning cardinals.
|
||||
var fuelQuery = GetEntityQuery<ParticleAcceleratorFuelChamberComponent>();
|
||||
foreach (var adjacent in _mapSystem.GetCardinalNeighborCells(gridUid.Value, grid, xform.Coordinates))
|
||||
{
|
||||
if (fuelQuery.HasComponent(adjacent)
|
||||
&& partQuery.TryGetComponent(adjacent, out var partState)
|
||||
&& partState.Master == null)
|
||||
{
|
||||
controller.FuelChamber = adjacent;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (controller.FuelChamber == null)
|
||||
{
|
||||
SwitchOff(uid, user, controller);
|
||||
return;
|
||||
}
|
||||
|
||||
// When we call SetLocalRotation down there to rotate the control box,
|
||||
// that ends up re-entrantly calling RescanParts() through the move event.
|
||||
// You'll have to take my word for it that that breaks everything, yeah?
|
||||
controller.CurrentlyRescanning = true;
|
||||
|
||||
// Automatically rotate the control box sprite to face the fuel chamber
|
||||
var fuelXform = xformQuery.GetComponent(controller.FuelChamber!.Value);
|
||||
var fuelDir = (fuelXform.LocalPosition - xform.LocalPosition).GetDir();
|
||||
_transformSystem.SetLocalRotation(uid, fuelDir.ToAngle(), xform);
|
||||
|
||||
// Calculate offsets for each of the parts of the PA.
|
||||
// These are all done relative to the fuel chamber BC that is basically the center of the machine.
|
||||
var rotation = fuelXform.LocalRotation;
|
||||
var offsetVect = rotation.GetCardinalDir().ToIntVec();
|
||||
var orthoOffsetVect = new Vector2i(-offsetVect.Y, offsetVect.X);
|
||||
|
||||
var positionFuelChamber = _mapSystem.TileIndicesFor(gridUid!.Value, grid, fuelXform.Coordinates); // n // n: End Cap
|
||||
var positionEndCap = positionFuelChamber - offsetVect; // CF // C: Control Box, F: Fuel Chamber
|
||||
var positionPowerBox = positionFuelChamber + offsetVect; // P // P: Power Box
|
||||
var positionPortEmitter = positionFuelChamber + offsetVect * 2 + orthoOffsetVect; // EEE // E: Emitter (Starboard, Fore, Port)
|
||||
var positionForeEmitter = positionFuelChamber + offsetVect * 2;
|
||||
var positionStarboardEmitter = positionFuelChamber + offsetVect * 2 - orthoOffsetVect;
|
||||
|
||||
ScanPart<ParticleAcceleratorEndCapComponent>(gridUid.Value, positionEndCap, rotation, out controller.EndCap, out _, grid);
|
||||
ScanPart<ParticleAcceleratorPowerBoxComponent>(gridUid.Value, positionPowerBox, rotation, out controller.PowerBox, out _, grid);
|
||||
|
||||
if (!ScanPart<ParticleAcceleratorEmitterComponent>(gridUid.Value, positionPortEmitter, rotation, out controller.PortEmitter, out var portEmitter, grid)
|
||||
|| portEmitter.Type != ParticleAcceleratorEmitterType.Port)
|
||||
controller.PortEmitter = null;
|
||||
|
||||
if (!ScanPart<ParticleAcceleratorEmitterComponent>(gridUid.Value, positionForeEmitter, rotation, out controller.ForeEmitter, out var foreEmitter, grid)
|
||||
|| foreEmitter.Type != ParticleAcceleratorEmitterType.Fore)
|
||||
controller.ForeEmitter = null;
|
||||
|
||||
if (!ScanPart<ParticleAcceleratorEmitterComponent>(gridUid.Value, positionStarboardEmitter, rotation, out controller.StarboardEmitter, out var starboardEmitter, grid)
|
||||
|| starboardEmitter.Type != ParticleAcceleratorEmitterType.Starboard)
|
||||
controller.StarboardEmitter = null;
|
||||
|
||||
controller.Assembled =
|
||||
controller.FuelChamber.HasValue
|
||||
&& controller.EndCap.HasValue
|
||||
&& controller.PowerBox.HasValue
|
||||
&& controller.PortEmitter.HasValue
|
||||
&& controller.ForeEmitter.HasValue
|
||||
&& controller.StarboardEmitter.HasValue;
|
||||
|
||||
foreach (var part in AllParts(uid, controller))
|
||||
{
|
||||
if (partQuery.TryGetComponent(part, out var partState))
|
||||
partState.Master = uid;
|
||||
}
|
||||
|
||||
controller.CurrentlyRescanning = false;
|
||||
|
||||
UpdatePowerDraw(uid, controller);
|
||||
UpdateUI(uid, controller);
|
||||
}
|
||||
|
||||
private bool ScanPart<T>(EntityUid uid, Vector2i coordinates, Angle? rotation, [NotNullWhen(true)] out EntityUid? part, [NotNullWhen(true)] out T? comp, MapGridComponent? grid = null)
|
||||
where T : IComponent
|
||||
{
|
||||
if (!Resolve(uid, ref grid))
|
||||
{
|
||||
part = null;
|
||||
comp = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
var compQuery = GetEntityQuery<T>();
|
||||
foreach (var entity in _mapSystem.GetAnchoredEntities(uid, grid, coordinates))
|
||||
{
|
||||
if (compQuery.TryGetComponent(entity, out comp)
|
||||
&& TryComp<ParticleAcceleratorPartComponent>(entity, out var partState) && partState.Master == null
|
||||
&& (rotation == null || Transform(entity).LocalRotation.EqualsApprox(rotation!.Value.Theta)))
|
||||
{
|
||||
part = entity;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
part = null;
|
||||
comp = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
private void OnComponentShutdown(EntityUid uid, ParticleAcceleratorPartComponent comp, ComponentShutdown args)
|
||||
{
|
||||
if (Exists(comp.Master))
|
||||
RescanParts(comp.Master!.Value);
|
||||
}
|
||||
|
||||
private void BodyTypeChanged(EntityUid uid, ParticleAcceleratorPartComponent comp, ref PhysicsBodyTypeChangedEvent args)
|
||||
{
|
||||
if (Exists(comp.Master))
|
||||
RescanParts(comp.Master!.Value);
|
||||
}
|
||||
|
||||
private void OnMoveEvent(EntityUid uid, ParticleAcceleratorPartComponent comp, ref MoveEvent args)
|
||||
{
|
||||
if (Exists(comp.Master))
|
||||
RescanParts(comp.Master!.Value);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
using Content.Server.ParticleAccelerator.Components;
|
||||
using Content.Server.ParticleAccelerator.Components;
|
||||
using Content.Server.Power.EntitySystems;
|
||||
using Content.Shared.Machines.Components;
|
||||
using Content.Shared.ParticleAccelerator.Components;
|
||||
|
||||
namespace Content.Server.ParticleAccelerator.EntitySystems;
|
||||
|
||||
@@ -12,7 +14,7 @@ public sealed partial class ParticleAcceleratorSystem
|
||||
|
||||
private void PowerBoxReceivedChanged(EntityUid uid, ParticleAcceleratorPowerBoxComponent component, ref PowerConsumerReceivedChanged args)
|
||||
{
|
||||
if (!TryComp<ParticleAcceleratorPartComponent>(uid, out var part))
|
||||
if (!TryComp<MultipartMachinePartComponent>(uid, out var part))
|
||||
return;
|
||||
if (!TryComp<ParticleAcceleratorControlBoxComponent>(part.Master, out var controller))
|
||||
return;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using Content.Server.Administration.Logs;
|
||||
using Content.Server.Chat.Managers;
|
||||
using Content.Server.Projectiles;
|
||||
using Content.Server.Machines.EntitySystems;
|
||||
using Robust.Shared.Physics.Systems;
|
||||
using Robust.Shared.Timing;
|
||||
using Robust.Server.GameObjects;
|
||||
@@ -19,13 +20,12 @@ public sealed partial class ParticleAcceleratorSystem : EntitySystem
|
||||
[Dependency] private readonly SharedPhysicsSystem _physicsSystem = default!;
|
||||
[Dependency] private readonly SharedTransformSystem _transformSystem = default!;
|
||||
[Dependency] private readonly UserInterfaceSystem _uiSystem = default!;
|
||||
[Dependency] private readonly MapSystem _mapSystem = default!;
|
||||
[Dependency] private readonly MultipartMachineSystem _multipartMachine = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
InitializeControlBoxSystem();
|
||||
InitializePartSystem();
|
||||
InitializePowerBoxSystem();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user