Fixed containment fields dying even when one side still had power (#41006)
* Containment fields only die if both sides lose power Currently, if either side of a containment field loses power, the field dies, even if the other side is still powered. This commit changes the behavior to only destroy the field if neither side of the field has enough power. * discard --------- Co-authored-by: ArtisticRoomba <145879011+ArtisticRoomba@users.noreply.github.com>
This commit is contained in:
parent
73c9c02539
commit
60ce323e5e
|
|
@ -12,6 +12,7 @@ using Robust.Server.GameObjects;
|
|||
using Robust.Shared.Physics;
|
||||
using Robust.Shared.Physics.Components;
|
||||
using Robust.Shared.Physics.Events;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Server.Singularity.EntitySystems;
|
||||
|
||||
|
|
@ -152,32 +153,62 @@ public sealed class ContainmentFieldGeneratorSystem : EntitySystem
|
|||
|
||||
/// <summary>
|
||||
/// Deletes the fields and removes the respective connections for the generators.
|
||||
/// If a predicate is provided, only remove fields and connections if the predicate returns true.
|
||||
/// </summary>
|
||||
private void RemoveConnections(Entity<ContainmentFieldGeneratorComponent> generator)
|
||||
/// <param name="generator">The field generator component</param>
|
||||
/// <param name="removePredicate">An optional predicate that takes in this generator entity and the other generator entity.
|
||||
/// It should return true if the connection should be removed, and false otherwise.
|
||||
/// If a predicate isn't provided, all connections will be removed.</param>
|
||||
private void RemoveConnections(
|
||||
Entity<ContainmentFieldGeneratorComponent> generator,
|
||||
Func<Entity<ContainmentFieldGeneratorComponent>, Entity<ContainmentFieldGeneratorComponent>, bool>? removePredicate = null)
|
||||
{
|
||||
var (uid, component) = generator;
|
||||
foreach (var (direction, value) in component.Connections)
|
||||
var anyFieldsRemoved = false;
|
||||
|
||||
foreach (var (direction, (otherGen, fields)) in component.Connections)
|
||||
{
|
||||
foreach (var field in value.Item2)
|
||||
if (removePredicate is not null && !removePredicate(generator, otherGen))
|
||||
{
|
||||
// Do not delete a connection only if the provided predicate says not to.
|
||||
continue;
|
||||
}
|
||||
|
||||
anyFieldsRemoved = true;
|
||||
|
||||
foreach (var field in fields)
|
||||
{
|
||||
QueueDel(field);
|
||||
}
|
||||
value.Item1.Comp.Connections.Remove(direction.GetOpposite());
|
||||
|
||||
if (value.Item1.Comp.Connections.Count == 0) //Change isconnected only if there's no more connections
|
||||
component.Connections.Remove(direction);
|
||||
|
||||
otherGen.Comp.Connections.Remove(direction.GetOpposite());
|
||||
|
||||
if (otherGen.Comp.Connections.Count == 0) //Change isconnected only if there's no more connections
|
||||
{
|
||||
value.Item1.Comp.IsConnected = false;
|
||||
ChangeOnLightVisualizer(value.Item1);
|
||||
otherGen.Comp.IsConnected = false;
|
||||
ChangeOnLightVisualizer(otherGen);
|
||||
}
|
||||
|
||||
ChangeFieldVisualizer(value.Item1);
|
||||
ChangeFieldVisualizer(otherGen);
|
||||
}
|
||||
|
||||
if (!anyFieldsRemoved)
|
||||
{
|
||||
// No fields were removed, so no logging or other updates are necessary.
|
||||
return;
|
||||
}
|
||||
|
||||
_popupSystem.PopupEntity(Loc.GetString("comp-containment-disconnected"), uid, PopupType.LargeCaution);
|
||||
|
||||
if (component.Connections.Count == 0)
|
||||
{
|
||||
component.IsConnected = false;
|
||||
ChangeOnLightVisualizer(generator);
|
||||
}
|
||||
component.Connections.Clear();
|
||||
if (component.IsConnected)
|
||||
_popupSystem.PopupEntity(Loc.GetString("comp-containment-disconnected"), uid, PopupType.LargeCaution);
|
||||
component.IsConnected = false;
|
||||
ChangeOnLightVisualizer(generator);
|
||||
ChangeFieldVisualizer(generator);
|
||||
|
||||
_adminLogger.Add(LogType.FieldGeneration, LogImpact.Medium, $"{ToPrettyString(uid)} lost field connections"); // Ideally LogImpact would depend on if there is a singulo nearby
|
||||
}
|
||||
|
||||
|
|
@ -199,7 +230,7 @@ public sealed class ContainmentFieldGeneratorSystem : EntitySystem
|
|||
if (component.PowerBuffer >= component.PowerMinimum)
|
||||
{
|
||||
var directions = Enum.GetValues<Direction>().Length;
|
||||
for (int i = 0; i < directions-1; i+=2)
|
||||
for (int i = 0; i < directions - 1; i += 2)
|
||||
{
|
||||
var dir = (Direction)i;
|
||||
|
||||
|
|
@ -220,7 +251,9 @@ public sealed class ContainmentFieldGeneratorSystem : EntitySystem
|
|||
|
||||
if (component.PowerBuffer < component.PowerMinimum && component.Connections.Count != 0)
|
||||
{
|
||||
RemoveConnections(generator);
|
||||
// Only remove connections if the generators on BOTH sides of the field don't have enough power.
|
||||
// Since we only run this code if we know this gen doesn't have enough power, we only have to check the other gen.
|
||||
RemoveConnections(generator, (_, otherGen) => otherGen.Comp.PowerBuffer < otherGen.Comp.PowerMinimum);
|
||||
}
|
||||
|
||||
ChangePowerVisualizer(power, generator);
|
||||
|
|
@ -393,7 +426,7 @@ public sealed class ContainmentFieldGeneratorSystem : EntitySystem
|
|||
{
|
||||
_visualizer.SetData(generator, ContainmentFieldGeneratorVisuals.FieldLight, generator.Comp.Connections.Count switch
|
||||
{
|
||||
>1 => FieldLevelVisuals.MultipleFields,
|
||||
> 1 => FieldLevelVisuals.MultipleFields,
|
||||
1 => FieldLevelVisuals.OneField,
|
||||
_ => generator.Comp.Enabled ? FieldLevelVisuals.On : FieldLevelVisuals.NoLevel
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in New Issue