diff --git a/Content.Client/Content.Client.csproj.DotSettings b/Content.Client/Content.Client.csproj.DotSettings new file mode 100644 index 0000000000..a558236f55 --- /dev/null +++ b/Content.Client/Content.Client.csproj.DotSettings @@ -0,0 +1,2 @@ + + True \ No newline at end of file diff --git a/Content.Client/Doors/AirlockVisualizer.cs b/Content.Client/Doors/AirlockVisualizer.cs index 4f6832b7b6..8f6c0651b1 100644 --- a/Content.Client/Doors/AirlockVisualizer.cs +++ b/Content.Client/Doors/AirlockVisualizer.cs @@ -1,5 +1,6 @@ using System; using Content.Client.Wires; +using Content.Client.Wires.Visualizers; using Content.Shared.Audio; using Content.Shared.Doors; using JetBrains.Annotations; diff --git a/Content.Client/Entry/IgnoredComponents.cs b/Content.Client/Entry/IgnoredComponents.cs index 9b19afe561..b3a76fb612 100644 --- a/Content.Client/Entry/IgnoredComponents.cs +++ b/Content.Client/Entry/IgnoredComponents.cs @@ -55,7 +55,7 @@ namespace Content.Client.Entry "AccessReader", "IdCardConsole", "Airlock", - "WirePlacer", + "CablePlacer", "Drink", "Food", "FoodContainer", @@ -73,6 +73,7 @@ namespace Content.Client.Entry "StorageFill", "Mop", "Bucket", + "CableVis", "Puddle", "CanSpill", "SpeedLoader", @@ -105,12 +106,11 @@ namespace Content.Client.Entry "PowerSupplier", "PowerConsumer", "Battery", - "BatteryStorage", "BatteryDischarger", "Apc", "PowerProvider", - "PowerReceiver", - "Wire", + "ApcPowerReceiver", + "Cable", "StressTestMovement", "Toys", "SurgeryTool", @@ -273,6 +273,8 @@ namespace Content.Client.Entry "ExplosionLaunched", "BeingCloned", "Advertise", + "PowerNetworkBattery", + "BatteryCharger", }; } } diff --git a/Content.Client/Light/Visualizers/EmergencyLightVisualizer.cs b/Content.Client/Light/Visualizers/EmergencyLightVisualizer.cs new file mode 100644 index 0000000000..4c7ed5db08 --- /dev/null +++ b/Content.Client/Light/Visualizers/EmergencyLightVisualizer.cs @@ -0,0 +1,23 @@ +using Content.Shared.Light.Component; +using Robust.Client.GameObjects; +using Robust.Shared.Serialization.Manager.Attributes; + +namespace Content.Client.Light.Visualizers +{ + [DataDefinition] + public sealed class EmergencyLightVisualizer : AppearanceVisualizer + { + public override void OnChangeData(AppearanceComponent component) + { + base.OnChangeData(component); + + if (!component.Owner.TryGetComponent(out SpriteComponent? sprite)) + return; + + if (!component.TryGetData(EmergencyLightVisuals.On, out bool on)) + on = false; + + sprite.LayerSetState(0, on ? "emergency_light_on" : "emergency_light_off"); + } + } +} diff --git a/Content.Client/NodeContainer/NodeGroupSystem.cs b/Content.Client/NodeContainer/NodeGroupSystem.cs new file mode 100644 index 0000000000..4cb7d678c4 --- /dev/null +++ b/Content.Client/NodeContainer/NodeGroupSystem.cs @@ -0,0 +1,99 @@ +using System.Collections.Generic; +using System.Linq; +using Content.Shared.NodeContainer; +using JetBrains.Annotations; +using Robust.Client.Graphics; +using Robust.Client.Input; +using Robust.Client.ResourceManagement; +using Robust.Shared.GameObjects; +using Robust.Shared.IoC; +using Robust.Shared.Map; + +namespace Content.Client.NodeContainer +{ + [UsedImplicitly] + public sealed class NodeGroupSystem : EntitySystem + { + [Dependency] private readonly IOverlayManager _overlayManager = default!; + [Dependency] private readonly IEntityLookup _entityLookup = default!; + [Dependency] private readonly IMapManager _mapManager = default!; + [Dependency] private readonly IInputManager _inputManager = default!; + [Dependency] private readonly IEyeManager _eyeManager = default!; + [Dependency] private readonly IResourceCache _resourceCache = default!; + + public bool VisEnabled { get; private set; } + + public Dictionary Groups { get; } = new(); + public HashSet Filtered { get; } = new(); + + public Dictionary + Entities { get; private set; } = new(); + + public Dictionary<(int group, int node), NodeVis.NodeDatum> NodeLookup { get; private set; } = new(); + + public override void Initialize() + { + base.Initialize(); + + SubscribeNetworkEvent(DataMsgHandler); + } + + public override void Shutdown() + { + base.Shutdown(); + + _overlayManager.RemoveOverlay(); + } + + private void DataMsgHandler(NodeVis.MsgData ev) + { + if (!VisEnabled) + return; + + foreach (var deletion in ev.GroupDeletions) + { + Groups.Remove(deletion); + } + + foreach (var group in ev.Groups) + { + Groups.Add(group.NetId, group); + } + + Entities = Groups.Values + .SelectMany(g => g.Nodes, (data, nodeData) => (data, nodeData)) + .GroupBy(n => n.nodeData.Entity) + .ToDictionary(g => g.Key, g => g.ToArray()); + + NodeLookup = Groups.Values + .SelectMany(g => g.Nodes, (data, nodeData) => (data, nodeData)) + .ToDictionary(n => (n.data.NetId, n.nodeData.NetId), n => n.nodeData); + } + + public void SetVisEnabled(bool enabled) + { + VisEnabled = enabled; + + RaiseNetworkEvent(new NodeVis.MsgEnable(enabled)); + + if (enabled) + { + var overlay = new NodeVisualizationOverlay( + this, + _entityLookup, + _mapManager, + _inputManager, + _eyeManager, + _resourceCache, + EntityManager); + + _overlayManager.AddOverlay(overlay); + } + else + { + Groups.Clear(); + Entities.Clear(); + } + } + } +} diff --git a/Content.Client/NodeContainer/NodeVisCommand.cs b/Content.Client/NodeContainer/NodeVisCommand.cs new file mode 100644 index 0000000000..c6a95fce5b --- /dev/null +++ b/Content.Client/NodeContainer/NodeVisCommand.cs @@ -0,0 +1,56 @@ +using Content.Client.Administration.Managers; +using Content.Shared.Administration; +using Robust.Shared.Console; +using Robust.Shared.GameObjects; +using Robust.Shared.IoC; + +namespace Content.Client.NodeContainer +{ + public sealed class NodeVisCommand : IConsoleCommand + { + public string Command => "nodevis"; + public string Description => "Toggles node group visualization"; + public string Help => ""; + + public void Execute(IConsoleShell shell, string argStr, string[] args) + { + var adminMan = IoCManager.Resolve(); + if (!adminMan.HasFlag(AdminFlags.Debug)) + { + shell.WriteError("You need +DEBUG for this command"); + return; + } + + var sys = EntitySystem.Get(); + sys.SetVisEnabled(!sys.VisEnabled); + } + } + + public sealed class NodeVisFilterCommand : IConsoleCommand + { + public string Command => "nodevisfilter"; + public string Description => "Toggles showing a specific group on nodevis"; + public string Help => "Usage: nodevis [filter]\nOmit filter to list currently masked-off"; + + public void Execute(IConsoleShell shell, string argStr, string[] args) + { + var sys = EntitySystem.Get(); + + if (args.Length == 0) + { + foreach (var filtered in sys.Filtered) + { + shell.WriteLine(filtered); + } + } + else + { + var filter = args[0]; + if (!sys.Filtered.Add(filter)) + { + sys.Filtered.Remove(filter); + } + } + } + } +} diff --git a/Content.Client/NodeContainer/NodeVisualizationOverlay.cs b/Content.Client/NodeContainer/NodeVisualizationOverlay.cs new file mode 100644 index 0000000000..989780f3c8 --- /dev/null +++ b/Content.Client/NodeContainer/NodeVisualizationOverlay.cs @@ -0,0 +1,232 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Content.Client.Resources; +using Robust.Client.Graphics; +using Robust.Client.Input; +using Robust.Client.ResourceManagement; +using Robust.Client.UserInterface.CustomControls; +using Robust.Shared.Enums; +using Robust.Shared.GameObjects; +using Robust.Shared.Map; +using Robust.Shared.Maths; +using Robust.Shared.Timing; +using Robust.Shared.Utility; +using static Content.Shared.NodeContainer.NodeVis; + +namespace Content.Client.NodeContainer +{ + public sealed class NodeVisualizationOverlay : Overlay + { + private readonly NodeGroupSystem _system; + private readonly IEntityLookup _lookup; + private readonly IMapManager _mapManager; + private readonly IInputManager _inputManager; + private readonly IEyeManager _eyeManager; + private readonly IEntityManager _entityManager; + + private readonly Dictionary<(int, int), NodeRenderData> _nodeIndex = new(); + private readonly Dictionary>> _gridIndex = new (); + + private readonly Font _font; + + private (int group, int node)? _hovered; + private float _time; + + public override OverlaySpace Space => OverlaySpace.ScreenSpace | OverlaySpace.WorldSpace; + + public NodeVisualizationOverlay( + NodeGroupSystem system, + IEntityLookup lookup, + IMapManager mapManager, + IInputManager inputManager, + IEyeManager eyeManager, + IResourceCache cache, + IEntityManager entityManager) + { + _system = system; + _lookup = lookup; + _mapManager = mapManager; + _inputManager = inputManager; + _eyeManager = eyeManager; + _entityManager = entityManager; + + _font = cache.GetFont("/Fonts/NotoSans/NotoSans-Regular.ttf", 12); + } + + protected override void Draw(in OverlayDrawArgs args) + { + if ((args.Space & OverlaySpace.WorldSpace) != 0) + { + DrawWorld(args); + } + else if ((args.Space & OverlaySpace.ScreenSpace) != 0) + { + DrawScreen(args); + } + } + + private void DrawScreen(in OverlayDrawArgs args) + { + if (_hovered == null) + return; + + var (groupId, nodeId) = _hovered.Value; + + var group = _system.Groups[groupId]; + var node = _system.NodeLookup[(groupId, nodeId)]; + + var mousePos = _inputManager.MouseScreenPosition.Position; + + var entity = _entityManager.GetEntity(node.Entity); + + var gridId = entity.Transform.GridID; + var grid = _mapManager.GetGrid(gridId); + var gridTile = grid.TileIndicesFor(entity.Transform.Coordinates); + + var sb = new StringBuilder(); + sb.Append($"entity: {entity}\n"); + sb.Append($"group id: {group.GroupId}\n"); + sb.Append($"node: {node.Name}\n"); + sb.Append($"type: {node.Type}\n"); + sb.Append($"grid pos: {gridTile}\n"); + + args.ScreenHandle.DrawString(_font, mousePos + (20, -20), sb.ToString()); + } + + private void DrawWorld(in OverlayDrawArgs overlayDrawArgs) + { + const float nodeSize = 8f / 32; + const float nodeOffset = 6f / 32; + + var handle = overlayDrawArgs.WorldHandle; + + var map = overlayDrawArgs.Viewport.Eye?.Position.MapId ?? default; + if (map == MapId.Nullspace) + return; + + var mouseScreenPos = _inputManager.MouseScreenPosition; + var mouseWorldPos = _eyeManager.ScreenToMap(mouseScreenPos).Position; + + _hovered = default; + + var cursorBox = Box2.CenteredAround(mouseWorldPos, (nodeSize, nodeSize)); + + // Group visible nodes by grid tiles. + var worldBounds = overlayDrawArgs.WorldBounds; + _lookup.FastEntitiesIntersecting(map, ref worldBounds, entity => + { + if (!_system.Entities.TryGetValue(entity.Uid, out var nodeData)) + return; + + var gridId = entity.Transform.GridID; + var grid = _mapManager.GetGrid(gridId); + var gridDict = _gridIndex.GetOrNew(gridId); + var coords = entity.Transform.Coordinates; + + // TODO: This probably shouldn't be capable of returning NaN... + if (float.IsNaN(coords.Position.X) || float.IsNaN(coords.Position.Y)) + return; + + var tile = gridDict.GetOrNew(grid.TileIndicesFor(coords)); + + foreach (var (group, nodeDatum) in nodeData) + { + if (!_system.Filtered.Contains(group.GroupId)) + { + tile.Add((group, nodeDatum)); + } + } + }); + + foreach (var (gridId, gridDict) in _gridIndex) + { + var grid = _mapManager.GetGrid(gridId); + foreach (var (pos, list) in gridDict) + { + var centerPos = grid.GridTileToWorld(pos).Position; + list.Sort(NodeDisplayComparer.Instance); + + var offset = -(list.Count - 1) * nodeOffset / 2; + + foreach (var (group, node) in list) + { + var nodePos = centerPos + (offset, offset); + if (cursorBox.Contains(nodePos)) + _hovered = (group.NetId, node.NetId); + + _nodeIndex[(group.NetId, node.NetId)] = new NodeRenderData(group, node, nodePos); + offset += nodeOffset; + } + } + } + + foreach (var nodeRenderData in _nodeIndex.Values) + { + var pos = nodeRenderData.WorldPos; + var bounds = Box2.CenteredAround(pos, (nodeSize, nodeSize)); + + var groupData = nodeRenderData.GroupData; + var color = groupData.Color; + + if (!_hovered.HasValue) + color.A = 0.5f; + else if (_hovered.Value.group != groupData.NetId) + color.A = 0.2f; + else + color.A = 0.75f + MathF.Sin(_time * 4) * 0.25f; + + handle.DrawRect(bounds, color); + + foreach (var reachable in nodeRenderData.NodeDatum.Reachable) + { + if (_nodeIndex.TryGetValue((groupData.NetId, reachable), out var reachDat)) + { + handle.DrawLine(pos, reachDat.WorldPos, color); + } + } + } + + _nodeIndex.Clear(); + _gridIndex.Clear(); + } + + protected override void FrameUpdate(FrameEventArgs args) + { + base.FrameUpdate(args); + + _time += args.DeltaSeconds; + } + + private sealed class NodeDisplayComparer : IComparer<(GroupData, NodeDatum)> + { + public static readonly NodeDisplayComparer Instance = new(); + + public int Compare((GroupData, NodeDatum) x, (GroupData, NodeDatum) y) + { + var (groupX, nodeX) = x; + var (groupY, nodeY) = y; + + var cmp = groupX.NetId.CompareTo(groupY.NetId); + if (cmp != 0) + return cmp; + + return nodeX.NetId.CompareTo(nodeY.NetId); + } + } + + private sealed class NodeRenderData + { + public GroupData GroupData; + public NodeDatum NodeDatum; + public Vector2 WorldPos; + + public NodeRenderData(GroupData groupData, NodeDatum nodeDatum, Vector2 worldPos) + { + GroupData = groupData; + NodeDatum = nodeDatum; + WorldPos = worldPos; + } + } + } +} diff --git a/Content.Client/APC/ApcBoundUserInterface.cs b/Content.Client/Power/APC/ApcBoundUserInterface.cs similarity index 99% rename from Content.Client/APC/ApcBoundUserInterface.cs rename to Content.Client/Power/APC/ApcBoundUserInterface.cs index 567bb842b8..0df4379d78 100644 --- a/Content.Client/APC/ApcBoundUserInterface.cs +++ b/Content.Client/Power/APC/ApcBoundUserInterface.cs @@ -9,7 +9,7 @@ using Robust.Client.UserInterface.CustomControls; using Robust.Shared.GameObjects; using Robust.Shared.Maths; -namespace Content.Client.APC +namespace Content.Client.Power.APC { [UsedImplicitly] public class ApcBoundUserInterface : BoundUserInterface diff --git a/Content.Client/APC/ApcVisualizer.cs b/Content.Client/Power/APC/ApcVisualizer.cs similarity index 98% rename from Content.Client/APC/ApcVisualizer.cs rename to Content.Client/Power/APC/ApcVisualizer.cs index a112f55b42..85ed0e5d25 100644 --- a/Content.Client/APC/ApcVisualizer.cs +++ b/Content.Client/Power/APC/ApcVisualizer.cs @@ -3,7 +3,7 @@ using JetBrains.Annotations; using Robust.Client.GameObjects; using Robust.Shared.GameObjects; -namespace Content.Client.APC +namespace Content.Client.Power.APC { public class ApcVisualizer : AppearanceVisualizer { diff --git a/Content.Client/SMES/SmesVisualizer.cs b/Content.Client/Power/SMES/SmesVisualizer.cs similarity index 98% rename from Content.Client/SMES/SmesVisualizer.cs rename to Content.Client/Power/SMES/SmesVisualizer.cs index 0937cfb3ad..11fcbd41d5 100644 --- a/Content.Client/SMES/SmesVisualizer.cs +++ b/Content.Client/Power/SMES/SmesVisualizer.cs @@ -4,7 +4,7 @@ using JetBrains.Annotations; using Robust.Client.GameObjects; using Robust.Shared.GameObjects; -namespace Content.Client.SMES +namespace Content.Client.Power.SMES { [UsedImplicitly] public class SmesVisualizer : AppearanceVisualizer diff --git a/Content.Client/Power/Visualizers/CableVisualizer.cs b/Content.Client/Power/Visualizers/CableVisualizer.cs new file mode 100644 index 0000000000..b5c09c7ebc --- /dev/null +++ b/Content.Client/Power/Visualizers/CableVisualizer.cs @@ -0,0 +1,26 @@ +using Content.Shared.Wires; +using Robust.Client.GameObjects; +using Robust.Shared.Serialization.Manager.Attributes; + +namespace Content.Client.Power +{ + [DataDefinition] + public sealed class CableVisualizer : AppearanceVisualizer + { + [DataField("base")] + public string? StateBase; + + public override void OnChangeData(AppearanceComponent component) + { + base.OnChangeData(component); + + if (!component.Owner.TryGetComponent(out SpriteComponent? sprite)) + return; + + if (!component.TryGetData(WireVisVisuals.ConnectedMask, out WireVisDirFlags mask)) + mask = WireVisDirFlags.None; + + sprite.LayerSetState(0, $"{StateBase}{(int) mask}"); + } + } +} diff --git a/Content.Client/Power/PowerDeviceVisualizer.cs b/Content.Client/Power/Visualizers/PowerDeviceVisualizer.cs similarity index 100% rename from Content.Client/Power/PowerDeviceVisualizer.cs rename to Content.Client/Power/Visualizers/PowerDeviceVisualizer.cs diff --git a/Content.Client/Stack/StackVisualizer.cs b/Content.Client/Stack/StackVisualizer.cs index 3b0197ef93..7324bd1b8a 100644 --- a/Content.Client/Stack/StackVisualizer.cs +++ b/Content.Client/Stack/StackVisualizer.cs @@ -66,7 +66,7 @@ namespace Content.Client.Stack /// /// /// - /// false: they are opaque and mutually exclusive (e.g. sprites in a wire coil). Default value + /// false: they are opaque and mutually exclusive (e.g. sprites in a cable coil). Default value /// /// /// true: they are transparent and thus layered one over another in ascending order first diff --git a/Content.Client/Wires/WiresVisualizer.cs b/Content.Client/Wires/Visualizers/WiresVisualizer.cs similarity index 95% rename from Content.Client/Wires/WiresVisualizer.cs rename to Content.Client/Wires/Visualizers/WiresVisualizer.cs index e20fd1cfa4..2ad300e436 100644 --- a/Content.Client/Wires/WiresVisualizer.cs +++ b/Content.Client/Wires/Visualizers/WiresVisualizer.cs @@ -1,7 +1,7 @@ using Robust.Client.GameObjects; using static Content.Shared.Wires.SharedWiresComponent; -namespace Content.Client.Wires +namespace Content.Client.Wires.Visualizers { public class WiresVisualizer : AppearanceVisualizer { diff --git a/Content.IntegrationTests/Tests/Disposal/DisposalUnitTest.cs b/Content.IntegrationTests/Tests/Disposal/DisposalUnitTest.cs index 6f4b5f5555..a75d936594 100644 --- a/Content.IntegrationTests/Tests/Disposal/DisposalUnitTest.cs +++ b/Content.IntegrationTests/Tests/Disposal/DisposalUnitTest.cs @@ -85,7 +85,7 @@ namespace Content.IntegrationTests.Tests.Disposal components: - type: DisposalUnit - type: Anchorable - - type: PowerReceiver + - type: ApcPowerReceiver - type: Physics bodyType: Static @@ -155,7 +155,7 @@ namespace Content.IntegrationTests.Tests.Disposal Flush(unit, false, human, wrench); // Remove power need - Assert.True(disposalUnit.TryGetComponent(out PowerReceiverComponent? power)); + Assert.True(disposalUnit.TryGetComponent(out ApcPowerReceiverComponent? power)); power!.NeedsPower = false; Assert.True(unit.Powered); diff --git a/Content.IntegrationTests/Tests/EntityTest.cs b/Content.IntegrationTests/Tests/EntityTest.cs index b2812c5478..6e5bbb5469 100644 --- a/Content.IntegrationTests/Tests/EntityTest.cs +++ b/Content.IntegrationTests/Tests/EntityTest.cs @@ -2,7 +2,7 @@ using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; -using Content.Server.Battery.Components; +using Content.Server.Power.Components; using Content.Server.PowerCell.Components; using Content.Shared.CCVar; using Content.Shared.Coordinates; diff --git a/Content.IntegrationTests/Tests/GravityGridTest.cs b/Content.IntegrationTests/Tests/GravityGridTest.cs index 078d69762a..69d8c63581 100644 --- a/Content.IntegrationTests/Tests/GravityGridTest.cs +++ b/Content.IntegrationTests/Tests/GravityGridTest.cs @@ -22,7 +22,7 @@ namespace Content.IntegrationTests.Tests id: GravityGeneratorDummy components: - type: GravityGenerator - - type: PowerReceiver + - type: ApcPowerReceiver "; [Test] public async Task Test() @@ -48,9 +48,9 @@ namespace Content.IntegrationTests.Tests generator = entityMan.SpawnEntity("GravityGeneratorDummy", grid2.ToCoordinates()); Assert.That(generator.HasComponent()); - Assert.That(generator.HasComponent()); + Assert.That(generator.HasComponent()); var generatorComponent = generator.GetComponent(); - var powerComponent = generator.GetComponent(); + var powerComponent = generator.GetComponent(); Assert.That(generatorComponent.Status, Is.EqualTo(GravityGeneratorStatus.Unpowered)); powerComponent.NeedsPower = false; }); diff --git a/Content.IntegrationTests/Tests/Power/PowerTest.cs b/Content.IntegrationTests/Tests/Power/PowerTest.cs new file mode 100644 index 0000000000..b8453821f3 --- /dev/null +++ b/Content.IntegrationTests/Tests/Power/PowerTest.cs @@ -0,0 +1,996 @@ +#nullable enable +using System.Threading.Tasks; +using Content.Server.NodeContainer; +using Content.Server.NodeContainer.Nodes; +using Content.Server.Power.Components; +using Content.Server.Power.Nodes; +using Content.Shared.Coordinates; +using NUnit.Framework; +using Robust.Shared.GameObjects; +using Robust.Shared.Map; +using Robust.Shared.Maths; +using Robust.Shared.Timing; + +namespace Content.IntegrationTests.Tests.Power +{ + [Parallelizable(ParallelScope.Fixtures)] + [TestFixture] + public class PowerTest : ContentIntegrationTest + { + private const string Prototypes = @" +- type: entity + id: GeneratorDummy + components: + - type: NodeContainer + nodes: + output: + !type:CableDeviceNode + nodeGroupID: HVPower + - type: PowerSupplier + - type: Transform + anchored: true + +- type: entity + id: ConsumerDummy + components: + - type: Transform + anchored: true + - type: NodeContainer + nodes: + input: + !type:CableDeviceNode + nodeGroupID: HVPower + - type: PowerConsumer + +- type: entity + id: ChargingBatteryDummy + components: + - type: Transform + anchored: true + - type: NodeContainer + nodes: + output: + !type:CableDeviceNode + nodeGroupID: HVPower + - type: PowerNetworkBattery + - type: Battery + - type: BatteryCharger + +- type: entity + id: DischargingBatteryDummy + components: + - type: Transform + anchored: true + - type: NodeContainer + nodes: + output: + !type:CableDeviceNode + nodeGroupID: HVPower + - type: PowerNetworkBattery + - type: Battery + - type: BatteryDischarger + +- type: entity + id: FullBatteryDummy + components: + - type: Transform + anchored: true + - type: NodeContainer + nodes: + output: + !type:CableDeviceNode + nodeGroupID: HVPower + input: + !type:CableTerminalPortNode + nodeGroupID: HVPower + - type: PowerNetworkBattery + - type: Battery + - type: BatteryDischarger + node: output + - type: BatteryCharger + node: input + +- type: entity + id: SubstationDummy + components: + - type: NodeContainer + nodes: + input: + !type:CableDeviceNode + nodeGroupID: HVPower + output: + !type:CableDeviceNode + nodeGroupID: MVPower + - type: BatteryCharger + voltage: High + - type: BatteryDischarger + voltage: Medium + - type: PowerNetworkBattery + maxChargeRate: 1000 + maxSupply: 1000 + supplyRampTolerance: 1000 + - type: Battery + maxCharge: 1000 + startingCharge: 1000 + - type: Transform + anchored: true + +- type: entity + id: ApcDummy + components: + - type: Battery + maxCharge: 10000 + startingCharge: 10000 + - type: PowerNetworkBattery + maxChargeRate: 1000 + maxSupply: 1000 + supplyRampTolerance: 1000 + - type: BatteryCharger + voltage: Medium + - type: BatteryDischarger + voltage: Apc + - type: Apc + voltage: Apc + - type: NodeContainer + nodes: + input: + !type:CableDeviceNode + nodeGroupID: MVPower + output: + !type:CableDeviceNode + nodeGroupID: Apc + - type: Transform + anchored: true + - type: UserInterface + interfaces: + - key: enum.ApcUiKey.Key + type: ApcBoundUserInterface + - type: AccessReader + access: [['Engineering']] + +- type: entity + id: ApcPowerReceiverDummy + components: + - type: ApcPowerReceiver + - type: Transform + anchored: true +"; + + private ServerIntegrationInstance _server = default!; + private IMapManager _mapManager = default!; + private IEntityManager _entityManager = default!; + private IGameTiming _gameTiming = default!; + + [OneTimeSetUp] + public async Task Setup() + { + var options = new ServerIntegrationOptions {ExtraPrototypes = Prototypes}; + _server = StartServerDummyTicker(options); + + await _server.WaitIdleAsync(); + _mapManager = _server.ResolveDependency(); + _entityManager = _server.ResolveDependency(); + _gameTiming = _server.ResolveDependency(); + } + + /// + /// Test small power net with a simple surplus of power over the loads. + /// + [Test] + public async Task TestSimpleSurplus() + { + const float loadPower = 200; + PowerSupplierComponent supplier = default!; + PowerConsumerComponent consumer1 = default!; + PowerConsumerComponent consumer2 = default!; + + _server.Assert(() => + { + var map = _mapManager.CreateMap(); + var grid = _mapManager.CreateGrid(map); + + // Power only works when anchored + for (var i = 0; i < 3; i++) + { + grid.SetTile(new Vector2i(0, i), new Tile(1)); + _entityManager.SpawnEntity("CableHV", grid.ToCoordinates(0, i)); + } + + var generatorEnt = _entityManager.SpawnEntity("GeneratorDummy", grid.ToCoordinates()); + var consumerEnt1 = _entityManager.SpawnEntity("ConsumerDummy", grid.ToCoordinates(0, 1)); + var consumerEnt2 = _entityManager.SpawnEntity("ConsumerDummy", grid.ToCoordinates(0, 2)); + + supplier = generatorEnt.GetComponent(); + consumer1 = consumerEnt1.GetComponent(); + consumer2 = consumerEnt2.GetComponent(); + + // Plenty of surplus and tolerance + supplier.MaxSupply = loadPower * 4; + supplier.SupplyRampTolerance = loadPower * 4; + consumer1.DrawRate = loadPower; + consumer2.DrawRate = loadPower; + }); + + _server.RunTicks(1); //let run a tick for PowerNet to process power + + _server.Assert(() => + { + // Assert both consumers fully powered + Assert.That(consumer1.ReceivedPower, Is.EqualTo(consumer1.DrawRate).Within(0.1)); + Assert.That(consumer2.ReceivedPower, Is.EqualTo(consumer2.DrawRate).Within(0.1)); + + // Assert that load adds up on supply. + Assert.That(supplier.CurrentSupply, Is.EqualTo(loadPower * 2).Within(0.1)); + }); + + await _server.WaitIdleAsync(); + } + + + /// + /// Test small power net with a simple deficit of power over the loads. + /// + [Test] + public async Task TestSimpleDeficit() + { + const float loadPower = 200; + PowerSupplierComponent supplier = default!; + PowerConsumerComponent consumer1 = default!; + PowerConsumerComponent consumer2 = default!; + + _server.Assert(() => + { + var map = _mapManager.CreateMap(); + var grid = _mapManager.CreateGrid(map); + + // Power only works when anchored + for (var i = 0; i < 3; i++) + { + grid.SetTile(new Vector2i(0, i), new Tile(1)); + _entityManager.SpawnEntity("CableHV", grid.ToCoordinates(0, i)); + } + + var generatorEnt = _entityManager.SpawnEntity("GeneratorDummy", grid.ToCoordinates()); + var consumerEnt1 = _entityManager.SpawnEntity("ConsumerDummy", grid.ToCoordinates(0, 1)); + var consumerEnt2 = _entityManager.SpawnEntity("ConsumerDummy", grid.ToCoordinates(0, 2)); + + supplier = generatorEnt.GetComponent(); + consumer1 = consumerEnt1.GetComponent(); + consumer2 = consumerEnt2.GetComponent(); + + // Too little supply, both consumers should get 33% power. + supplier.MaxSupply = loadPower; + supplier.SupplyRampTolerance = loadPower; + consumer1.DrawRate = loadPower; + consumer2.DrawRate = loadPower * 2; + }); + + _server.RunTicks(1); //let run a tick for PowerNet to process power + + _server.Assert(() => + { + // Assert both consumers get 33% power. + Assert.That(consumer1.ReceivedPower, Is.EqualTo(consumer1.DrawRate / 3).Within(0.1)); + Assert.That(consumer2.ReceivedPower, Is.EqualTo(consumer2.DrawRate / 3).Within(0.1)); + + // Supply should be maxed out + Assert.That(supplier.CurrentSupply, Is.EqualTo(supplier.MaxSupply).Within(0.1)); + }); + + await _server.WaitIdleAsync(); + } + + [Test] + public async Task TestSupplyRamp() + { + PowerSupplierComponent supplier = default!; + PowerConsumerComponent consumer = default!; + + _server.Assert(() => + { + var map = _mapManager.CreateMap(); + var grid = _mapManager.CreateGrid(map); + + // Power only works when anchored + for (var i = 0; i < 3; i++) + { + grid.SetTile(new Vector2i(0, i), new Tile(1)); + _entityManager.SpawnEntity("CableHV", grid.ToCoordinates(0, i)); + } + + var generatorEnt = _entityManager.SpawnEntity("GeneratorDummy", grid.ToCoordinates()); + var consumerEnt = _entityManager.SpawnEntity("ConsumerDummy", grid.ToCoordinates(0, 2)); + + supplier = generatorEnt.GetComponent(); + consumer = consumerEnt.GetComponent(); + + // Supply has enough total power but needs to ramp up to match. + supplier.MaxSupply = 400; + supplier.SupplyRampRate = 400; + supplier.SupplyRampTolerance = 100; + consumer.DrawRate = 400; + }); + + // Exact values can/will be off by a tick, add tolerance for that. + var tickRate = (float) _gameTiming.TickPeriod.TotalSeconds; + var tickDev = 400 * tickRate * 1.1f; + + _server.RunTicks(1); + + _server.Assert(() => + { + // First tick, supply should be delivering 100 W (max tolerance) and start ramping up. + Assert.That(supplier.CurrentSupply, Is.EqualTo(100).Within(0.1)); + Assert.That(consumer.ReceivedPower, Is.EqualTo(100).Within(0.1)); + }); + + _server.RunTicks(14); + + _server.Assert(() => + { + // After 15 ticks (0.25 seconds), supply ramp pos should be at 100 W and supply at 100, approx. + Assert.That(supplier.CurrentSupply, Is.EqualTo(200).Within(tickDev)); + Assert.That(supplier.SupplyRampPosition, Is.EqualTo(100).Within(tickDev)); + Assert.That(consumer.ReceivedPower, Is.EqualTo(200).Within(tickDev)); + }); + + _server.RunTicks(45); + + _server.Assert(() => + { + // After 1 second total, ramp should be at 400 and supply should be at 400, everybody happy. + Assert.That(supplier.CurrentSupply, Is.EqualTo(400).Within(tickDev)); + Assert.That(supplier.SupplyRampPosition, Is.EqualTo(400).Within(tickDev)); + Assert.That(consumer.ReceivedPower, Is.EqualTo(400).Within(tickDev)); + }); + + await _server.WaitIdleAsync(); + } + + [Test] + public async Task TestBatteryRamp() + { + const float startingCharge = 100_000; + + PowerNetworkBatteryComponent netBattery = default!; + BatteryComponent battery = default!; + PowerConsumerComponent consumer = default!; + + _server.Assert(() => + { + var map = _mapManager.CreateMap(); + var grid = _mapManager.CreateGrid(map); + + // Power only works when anchored + for (var i = 0; i < 3; i++) + { + grid.SetTile(new Vector2i(0, i), new Tile(1)); + _entityManager.SpawnEntity("CableHV", grid.ToCoordinates(0, i)); + } + + var generatorEnt = _entityManager.SpawnEntity("DischargingBatteryDummy", grid.ToCoordinates()); + var consumerEnt = _entityManager.SpawnEntity("ConsumerDummy", grid.ToCoordinates(0, 2)); + + netBattery = generatorEnt.GetComponent(); + battery = generatorEnt.GetComponent(); + consumer = consumerEnt.GetComponent(); + + battery.MaxCharge = startingCharge; + battery.CurrentCharge = startingCharge; + netBattery.MaxSupply = 400; + netBattery.SupplyRampRate = 400; + netBattery.SupplyRampTolerance = 100; + consumer.DrawRate = 400; + }); + + // Exact values can/will be off by a tick, add tolerance for that. + var tickRate = (float) _gameTiming.TickPeriod.TotalSeconds; + var tickDev = 400 * tickRate * 1.1f; + + _server.RunTicks(1); + + _server.Assert(() => + { + // First tick, supply should be delivering 100 W (max tolerance) and start ramping up. + Assert.That(netBattery.CurrentSupply, Is.EqualTo(100).Within(0.1)); + Assert.That(consumer.ReceivedPower, Is.EqualTo(100).Within(0.1)); + }); + + _server.RunTicks(14); + + _server.Assert(() => + { + // After 15 ticks (0.25 seconds), supply ramp pos should be at 100 W and supply at 100, approx. + Assert.That(netBattery.CurrentSupply, Is.EqualTo(200).Within(tickDev)); + Assert.That(netBattery.SupplyRampPosition, Is.EqualTo(100).Within(tickDev)); + Assert.That(consumer.ReceivedPower, Is.EqualTo(200).Within(tickDev)); + + // Trivial integral to calculate expected power spent. + const double spentExpected = (200 + 100) / 2.0 * 0.25; + Assert.That(battery.CurrentCharge, Is.EqualTo(startingCharge - spentExpected).Within(tickDev)); + }); + + _server.RunTicks(45); + + _server.Assert(() => + { + // After 1 second total, ramp should be at 400 and supply should be at 400, everybody happy. + Assert.That(netBattery.CurrentSupply, Is.EqualTo(400).Within(tickDev)); + Assert.That(netBattery.SupplyRampPosition, Is.EqualTo(400).Within(tickDev)); + Assert.That(consumer.ReceivedPower, Is.EqualTo(400).Within(tickDev)); + + // Trivial integral to calculate expected power spent. + const double spentExpected = (400 + 100) / 2.0 * 0.75 + 400 * 0.25; + Assert.That(battery.CurrentCharge, Is.EqualTo(startingCharge - spentExpected).Within(tickDev)); + }); + + await _server.WaitIdleAsync(); + } + + + [Test] + public async Task TestSimpleBatteryChargeDeficit() + { + PowerSupplierComponent supplier = default!; + BatteryComponent battery = default!; + + _server.Assert(() => + { + var map = _mapManager.CreateMap(); + var grid = _mapManager.CreateGrid(map); + + // Power only works when anchored + for (var i = 0; i < 3; i++) + { + grid.SetTile(new Vector2i(0, i), new Tile(1)); + _entityManager.SpawnEntity("CableHV", grid.ToCoordinates(0, i)); + } + + var generatorEnt = _entityManager.SpawnEntity("GeneratorDummy", grid.ToCoordinates()); + var batteryEnt = _entityManager.SpawnEntity("ChargingBatteryDummy", grid.ToCoordinates(0, 2)); + + supplier = generatorEnt.GetComponent(); + var netBattery = batteryEnt.GetComponent(); + battery = batteryEnt.GetComponent(); + + supplier.MaxSupply = 500; + supplier.SupplyRampTolerance = 500; + battery.MaxCharge = 100000; + netBattery.MaxChargeRate = 1000; + netBattery.Efficiency = 0.5f; + }); + + _server.RunTicks(30); // 60 TPS, 0.5 seconds + + _server.Assert(() => + { + // half a second @ 500 W = 250 + // 50% efficiency, so 125 J stored total. + Assert.That(battery.CurrentCharge, Is.EqualTo(125).Within(0.1)); + Assert.That(supplier.CurrentSupply, Is.EqualTo(500).Within(0.1)); + }); + + await _server.WaitIdleAsync(); + } + + [Test] + public async Task TestFullBattery() + { + PowerConsumerComponent consumer = default!; + PowerSupplierComponent supplier = default!; + PowerNetworkBatteryComponent netBattery = default!; + BatteryComponent battery = default!; + + _server.Assert(() => + { + var map = _mapManager.CreateMap(); + var grid = _mapManager.CreateGrid(map); + + // Power only works when anchored + for (var i = 0; i < 4; i++) + { + grid.SetTile(new Vector2i(0, i), new Tile(1)); + _entityManager.SpawnEntity("CableHV", grid.ToCoordinates(0, i)); + } + + var terminal = _entityManager.SpawnEntity("CableTerminal", grid.ToCoordinates(0, 1)); + terminal.Transform.LocalRotation = Angle.FromDegrees(180); + + var batteryEnt = _entityManager.SpawnEntity("FullBatteryDummy", grid.ToCoordinates(0, 2)); + var supplyEnt = _entityManager.SpawnEntity("GeneratorDummy", grid.ToCoordinates(0, 0)); + var consumerEnt = _entityManager.SpawnEntity("ConsumerDummy", grid.ToCoordinates(0, 3)); + + consumer = consumerEnt.GetComponent(); + supplier = supplyEnt.GetComponent(); + netBattery = batteryEnt.GetComponent(); + battery = batteryEnt.GetComponent(); + + // Consumer needs 1000 W, supplier can only provide 800, battery fills in the remaining 200. + consumer.DrawRate = 1000; + supplier.MaxSupply = 800; + supplier.SupplyRampTolerance = 800; + + netBattery.MaxSupply = 400; + netBattery.SupplyRampTolerance = 400; + netBattery.SupplyRampRate = 100_000; + battery.MaxCharge = 100_000; + battery.CurrentCharge = 100_000; + }); + + // Run some ticks so everything is stable. + _server.RunTicks(60); + + // Exact values can/will be off by a tick, add tolerance for that. + var tickRate = (float) _gameTiming.TickPeriod.TotalSeconds; + var tickDev = 400 * tickRate * 1.1f; + + _server.Assert(() => + { + Assert.That(consumer.ReceivedPower, Is.EqualTo(consumer.DrawRate).Within(0.1)); + Assert.That(supplier.CurrentSupply, Is.EqualTo(supplier.MaxSupply).Within(0.1)); + + // Battery's current supply includes passed-through power from the supply. + // Assert ramp position is correct to make sure it's only supplying 200 W for real. + Assert.That(netBattery.CurrentSupply, Is.EqualTo(1000).Within(0.1)); + Assert.That(netBattery.SupplyRampPosition, Is.EqualTo(200).Within(0.1)); + + const int expectedSpent = 200; + Assert.That(battery.CurrentCharge, Is.EqualTo(battery.MaxCharge - expectedSpent).Within(tickDev)); + }); + + await _server.WaitIdleAsync(); + } + + [Test] + public async Task TestFullBatteryEfficiencyPassThrough() + { + PowerConsumerComponent consumer = default!; + PowerSupplierComponent supplier = default!; + PowerNetworkBatteryComponent netBattery = default!; + BatteryComponent battery = default!; + + _server.Assert(() => + { + var map = _mapManager.CreateMap(); + var grid = _mapManager.CreateGrid(map); + + // Power only works when anchored + for (var i = 0; i < 4; i++) + { + grid.SetTile(new Vector2i(0, i), new Tile(1)); + _entityManager.SpawnEntity("CableHV", grid.ToCoordinates(0, i)); + } + + var terminal = _entityManager.SpawnEntity("CableTerminal", grid.ToCoordinates(0, 1)); + terminal.Transform.LocalRotation = Angle.FromDegrees(180); + + var batteryEnt = _entityManager.SpawnEntity("FullBatteryDummy", grid.ToCoordinates(0, 2)); + var supplyEnt = _entityManager.SpawnEntity("GeneratorDummy", grid.ToCoordinates(0, 0)); + var consumerEnt = _entityManager.SpawnEntity("ConsumerDummy", grid.ToCoordinates(0, 3)); + + consumer = consumerEnt.GetComponent(); + supplier = supplyEnt.GetComponent(); + netBattery = batteryEnt.GetComponent(); + battery = batteryEnt.GetComponent(); + + // Consumer needs 1000 W, supply and battery can only provide 400 each. + // BUT the battery has 50% input efficiency, so 50% of the power of the supply gets lost. + consumer.DrawRate = 1000; + supplier.MaxSupply = 400; + supplier.SupplyRampTolerance = 400; + + netBattery.MaxSupply = 400; + netBattery.SupplyRampTolerance = 400; + netBattery.SupplyRampRate = 100_000; + netBattery.Efficiency = 0.5f; + battery.MaxCharge = 1_000_000; + battery.CurrentCharge = 1_000_000; + }); + + // Run some ticks so everything is stable. + _server.RunTicks(60); + + // Exact values can/will be off by a tick, add tolerance for that. + var tickRate = (float) _gameTiming.TickPeriod.TotalSeconds; + var tickDev = 400 * tickRate * 1.1f; + + _server.Assert(() => + { + Assert.That(consumer.ReceivedPower, Is.EqualTo(600).Within(0.1)); + Assert.That(supplier.CurrentSupply, Is.EqualTo(supplier.MaxSupply).Within(0.1)); + + Assert.That(netBattery.CurrentSupply, Is.EqualTo(600).Within(0.1)); + Assert.That(netBattery.SupplyRampPosition, Is.EqualTo(400).Within(0.1)); + + const int expectedSpent = 400; + Assert.That(battery.CurrentCharge, Is.EqualTo(battery.MaxCharge - expectedSpent).Within(tickDev)); + }); + + await _server.WaitIdleAsync(); + } + + [Test] + public async Task TestFullBatteryEfficiencyDemandPassThrough() + { + PowerConsumerComponent consumer1 = default!; + PowerConsumerComponent consumer2 = default!; + PowerSupplierComponent supplier = default!; + + _server.Assert(() => + { + var map = _mapManager.CreateMap(); + var grid = _mapManager.CreateGrid(map); + + // Map layout here is + // C - consumer + // B - battery + // G - generator + // B - battery + // C - consumer + // Connected in the only way that makes sense. + + // Power only works when anchored + for (var i = 0; i < 5; i++) + { + grid.SetTile(new Vector2i(0, i), new Tile(1)); + _entityManager.SpawnEntity("CableHV", grid.ToCoordinates(0, i)); + } + + _entityManager.SpawnEntity("CableTerminal", grid.ToCoordinates(0, 2)); + var terminal = _entityManager.SpawnEntity("CableTerminal", grid.ToCoordinates(0, 2)); + terminal.Transform.LocalRotation = Angle.FromDegrees(180); + + var batteryEnt1 = _entityManager.SpawnEntity("FullBatteryDummy", grid.ToCoordinates(0, 1)); + var batteryEnt2 = _entityManager.SpawnEntity("FullBatteryDummy", grid.ToCoordinates(0, 3)); + var supplyEnt = _entityManager.SpawnEntity("GeneratorDummy", grid.ToCoordinates(0, 2)); + var consumerEnt1 = _entityManager.SpawnEntity("ConsumerDummy", grid.ToCoordinates(0, 0)); + var consumerEnt2 = _entityManager.SpawnEntity("ConsumerDummy", grid.ToCoordinates(0, 4)); + + consumer1 = consumerEnt1.GetComponent(); + consumer2 = consumerEnt2.GetComponent(); + supplier = supplyEnt.GetComponent(); + var netBattery1 = batteryEnt1.GetComponent(); + var netBattery2 = batteryEnt2.GetComponent(); + var battery1 = batteryEnt1.GetComponent(); + var battery2 = batteryEnt2.GetComponent(); + + // There are two loads, 500 W and 1000 W respectively. + // The 500 W load is behind a 50% efficient battery, + // so *effectively* it needs 2x as much power from the supply to run. + // Assert that both are getting 50% power. + // Batteries are empty and only a bridge. + + consumer1.DrawRate = 500; + consumer2.DrawRate = 1000; + supplier.MaxSupply = 1000; + supplier.SupplyRampTolerance = 1000; + + battery1.MaxCharge = 1_000_000; + battery2.MaxCharge = 1_000_000; + + netBattery1.MaxChargeRate = 1_000; + netBattery2.MaxChargeRate = 1_000; + + netBattery1.Efficiency = 0.5f; + + netBattery1.MaxSupply = 1_000_000; + netBattery2.MaxSupply = 1_000_000; + + netBattery1.SupplyRampTolerance = 1_000_000; + netBattery2.SupplyRampTolerance = 1_000_000; + }); + + // Run some ticks so everything is stable. + _server.RunTicks(10); + + _server.Assert(() => + { + Assert.That(consumer1.ReceivedPower, Is.EqualTo(250).Within(0.1)); + Assert.That(consumer2.ReceivedPower, Is.EqualTo(500).Within(0.1)); + Assert.That(supplier.CurrentSupply, Is.EqualTo(supplier.MaxSupply).Within(0.1)); + }); + + await _server.WaitIdleAsync(); + } + + /// + /// Test that power is distributed proportionally, even through batteries. + /// + [Test] + public async Task TestBatteriesProportional() + { + PowerConsumerComponent consumer1 = default!; + PowerConsumerComponent consumer2 = default!; + PowerSupplierComponent supplier = default!; + + _server.Assert(() => + { + var map = _mapManager.CreateMap(); + var grid = _mapManager.CreateGrid(map); + + // Map layout here is + // C - consumer + // B - battery + // G - generator + // B - battery + // C - consumer + // Connected in the only way that makes sense. + + // Power only works when anchored + for (var i = 0; i < 5; i++) + { + grid.SetTile(new Vector2i(0, i), new Tile(1)); + _entityManager.SpawnEntity("CableHV", grid.ToCoordinates(0, i)); + } + + _entityManager.SpawnEntity("CableTerminal", grid.ToCoordinates(0, 2)); + var terminal = _entityManager.SpawnEntity("CableTerminal", grid.ToCoordinates(0, 2)); + terminal.Transform.LocalRotation = Angle.FromDegrees(180); + + var batteryEnt1 = _entityManager.SpawnEntity("FullBatteryDummy", grid.ToCoordinates(0, 1)); + var batteryEnt2 = _entityManager.SpawnEntity("FullBatteryDummy", grid.ToCoordinates(0, 3)); + var supplyEnt = _entityManager.SpawnEntity("GeneratorDummy", grid.ToCoordinates(0, 2)); + var consumerEnt1 = _entityManager.SpawnEntity("ConsumerDummy", grid.ToCoordinates(0, 0)); + var consumerEnt2 = _entityManager.SpawnEntity("ConsumerDummy", grid.ToCoordinates(0, 4)); + + consumer1 = consumerEnt1.GetComponent(); + consumer2 = consumerEnt2.GetComponent(); + supplier = supplyEnt.GetComponent(); + var netBattery1 = batteryEnt1.GetComponent(); + var netBattery2 = batteryEnt2.GetComponent(); + var battery1 = batteryEnt1.GetComponent(); + var battery2 = batteryEnt2.GetComponent(); + + consumer1.DrawRate = 500; + consumer2.DrawRate = 1000; + supplier.MaxSupply = 1000; + supplier.SupplyRampTolerance = 1000; + + battery1.MaxCharge = 1_000_000; + battery2.MaxCharge = 1_000_000; + + netBattery1.MaxChargeRate = 20; + netBattery2.MaxChargeRate = 20; + + netBattery1.MaxSupply = 1_000_000; + netBattery2.MaxSupply = 1_000_000; + + netBattery1.SupplyRampTolerance = 1_000_000; + netBattery2.SupplyRampTolerance = 1_000_000; + }); + + // Run some ticks so everything is stable. + _server.RunTicks(60); + + _server.Assert(() => + { + // NOTE: MaxChargeRate on batteries actually skews the demand. + // So that's why the tolerance is so high, the charge rate is so *low*, + // and we run so many ticks to stabilize. + Assert.That(consumer1.ReceivedPower, Is.EqualTo(333.333).Within(10)); + Assert.That(consumer2.ReceivedPower, Is.EqualTo(666.666).Within(10)); + Assert.That(supplier.CurrentSupply, Is.EqualTo(supplier.MaxSupply).Within(0.1)); + }); + + await _server.WaitIdleAsync(); + } + + [Test] + public async Task TestBatteryEngineCut() + { + PowerConsumerComponent consumer = default!; + PowerSupplierComponent supplier = default!; + PowerNetworkBatteryComponent netBattery = default!; + + _server.Post(() => + { + var map = _mapManager.CreateMap(); + var grid = _mapManager.CreateGrid(map); + + // Power only works when anchored + for (var i = 0; i < 4; i++) + { + grid.SetTile(new Vector2i(0, i), new Tile(1)); + _entityManager.SpawnEntity("CableHV", grid.ToCoordinates(0, i)); + } + + var terminal = _entityManager.SpawnEntity("CableTerminal", grid.ToCoordinates(0, 1)); + terminal.Transform.LocalRotation = Angle.FromDegrees(180); + + var batteryEnt = _entityManager.SpawnEntity("FullBatteryDummy", grid.ToCoordinates(0, 2)); + var supplyEnt = _entityManager.SpawnEntity("GeneratorDummy", grid.ToCoordinates(0, 0)); + var consumerEnt = _entityManager.SpawnEntity("ConsumerDummy", grid.ToCoordinates(0, 3)); + + consumer = consumerEnt.GetComponent(); + supplier = supplyEnt.GetComponent(); + netBattery = batteryEnt.GetComponent(); + var battery = batteryEnt.GetComponent(); + + // Consumer needs 1000 W, supplier can only provide 800, battery fills in the remaining 200. + consumer.DrawRate = 1000; + supplier.MaxSupply = 1000; + supplier.SupplyRampTolerance = 1000; + + netBattery.MaxSupply = 1000; + netBattery.SupplyRampTolerance = 200; + netBattery.SupplyRampRate = 10; + battery.MaxCharge = 100_000; + battery.CurrentCharge = 100_000; + }); + + // Run some ticks so everything is stable. + _server.RunTicks(5); + + _server.Assert(() => + { + // Supply and consumer are fully loaded/supplied. + Assert.That(consumer.ReceivedPower, Is.EqualTo(consumer.DrawRate).Within(0.5)); + Assert.That(supplier.CurrentSupply, Is.EqualTo(supplier.MaxSupply).Within(0.5)); + + // Cut off the supplier + supplier.Enabled = false; + // Remove tolerance on battery too. + netBattery.SupplyRampTolerance = 5; + }); + + _server.RunTicks(3); + + _server.Assert(() => + { + // Assert that network drops to 0 power and starts ramping up + Assert.That(consumer.ReceivedPower, Is.LessThan(50).And.GreaterThan(0)); + Assert.That(netBattery.CurrentReceiving, Is.EqualTo(0)); + Assert.That(netBattery.CurrentSupply, Is.GreaterThan(0)); + }); + + await _server.WaitIdleAsync(); + } + + /// + /// Test that correctly isolates two networks. + /// + [Test] + public async Task TestTerminalNodeGroups() + { + CableNode leftNode = default!; + CableNode rightNode = default!; + Node batteryInput = default!; + Node batteryOutput = default!; + + _server.Assert(() => + { + var map = _mapManager.CreateMap(); + var grid = _mapManager.CreateGrid(map); + + // Power only works when anchored + for (var i = 0; i < 4; i++) + { + grid.SetTile(new Vector2i(0, i), new Tile(1)); + } + + var leftEnt = _entityManager.SpawnEntity("CableHV", grid.ToCoordinates(0, 0)); + _entityManager.SpawnEntity("CableHV", grid.ToCoordinates(0, 1)); + _entityManager.SpawnEntity("CableHV", grid.ToCoordinates(0, 2)); + var rightEnt = _entityManager.SpawnEntity("CableHV", grid.ToCoordinates(0, 3)); + + var terminal = _entityManager.SpawnEntity("CableTerminal", grid.ToCoordinates(0, 1)); + terminal.Transform.LocalRotation = Angle.FromDegrees(180); + + var battery = _entityManager.SpawnEntity("FullBatteryDummy", grid.ToCoordinates(0, 2)); + var batteryNodeContainer = battery.GetComponent(); + + leftNode = leftEnt.GetComponent().GetNode("power"); + rightNode = rightEnt.GetComponent().GetNode("power"); + + batteryInput = batteryNodeContainer.GetNode("input"); + batteryOutput = batteryNodeContainer.GetNode("output"); + }); + + // Run ticks to allow node groups to update. + _server.RunTicks(1); + + _server.Assert(() => + { + Assert.That(batteryInput.NodeGroup, Is.EqualTo(leftNode.NodeGroup)); + Assert.That(batteryOutput.NodeGroup, Is.EqualTo(rightNode.NodeGroup)); + + Assert.That(leftNode.NodeGroup, Is.Not.EqualTo(rightNode.NodeGroup)); + }); + + await _server.WaitIdleAsync(); + } + + [Test] + public async Task ApcChargingTest() + { + PowerNetworkBatteryComponent substationNetBattery = default!; + BatteryComponent apcBattery = default!; + + _server.Assert(() => + { + var map = _mapManager.CreateMap(); + var grid = _mapManager.CreateGrid(map); + + // Power only works when anchored + for (var i = 0; i < 3; i++) + { + grid.SetTile(new Vector2i(0, i), new Tile(1)); + } + + _entityManager.SpawnEntity("CableHV", grid.ToCoordinates(0, 0)); + _entityManager.SpawnEntity("CableHV", grid.ToCoordinates(0, 1)); + _entityManager.SpawnEntity("CableMV", grid.ToCoordinates(0, 1)); + _entityManager.SpawnEntity("CableMV", grid.ToCoordinates(0, 2)); + + var generatorEnt = _entityManager.SpawnEntity("GeneratorDummy", grid.ToCoordinates(0, 0)); + var substationEnt = _entityManager.SpawnEntity("SubstationDummy", grid.ToCoordinates(0, 1)); + var apcEnt = _entityManager.SpawnEntity("ApcDummy", grid.ToCoordinates(0, 2)); + + var generatorSupplier = generatorEnt.GetComponent(); + substationNetBattery = substationEnt.GetComponent(); + apcBattery = apcEnt.GetComponent(); + + generatorSupplier.MaxSupply = 1000; + generatorSupplier.SupplyRampTolerance = 1000; + + apcBattery.CurrentCharge = 0; + }); + + _server.RunTicks(5); //let run a few ticks for PowerNets to reevaluate and start charging apc + + _server.Assert(() => + { + Assert.That(substationNetBattery.CurrentSupply, Is.GreaterThan(0)); //substation should be providing power + Assert.That(apcBattery.CurrentCharge, Is.GreaterThan(0)); //apc battery should have gained charge + }); + + await _server.WaitIdleAsync(); + } + + [Test] + public async Task ApcNetTest() + { + PowerNetworkBatteryComponent apcNetBattery = default!; + ApcPowerReceiverComponent receiver = default!; + + _server.Assert(() => + { + var map = _mapManager.CreateMap(); + var grid = _mapManager.CreateGrid(map); + + // Power only works when anchored + for (var i = 0; i < 3; i++) + { + grid.SetTile(new Vector2i(0, i), new Tile(1)); + } + + var apcEnt = _entityManager.SpawnEntity("ApcDummy", grid.ToCoordinates(0, 0)); + var apcExtensionEnt = _entityManager.SpawnEntity("CableApcExtension", grid.ToCoordinates(0, 0)); + var powerReceiverEnt = _entityManager.SpawnEntity("ApcPowerReceiverDummy", grid.ToCoordinates(0, 2)); + + var provider = apcExtensionEnt.GetComponent(); + receiver = powerReceiverEnt.GetComponent(); + var battery = apcEnt.GetComponent(); + apcNetBattery = apcEnt.GetComponent(); + + provider.PowerTransferRange = 5; //arbitrary range to reach receiver + receiver.PowerReceptionRange = 5; //arbitrary range to reach provider + + battery.MaxCharge = 10000; //arbitrary nonzero amount of charge + battery.CurrentCharge = battery.MaxCharge; //fill battery + + receiver.Load = 1; //arbitrary small amount of power + }); + + _server.RunTicks(1); //let run a tick for ApcNet to process power + + _server.Assert(() => + { + Assert.That(receiver.Powered); + Assert.That(apcNetBattery.CurrentSupply, Is.EqualTo(1).Within(0.1)); + }); + + await _server.WaitIdleAsync(); + } + } +} diff --git a/Content.IntegrationTests/Tests/PowerTest.cs b/Content.IntegrationTests/Tests/PowerTest.cs deleted file mode 100644 index 191288b16a..0000000000 --- a/Content.IntegrationTests/Tests/PowerTest.cs +++ /dev/null @@ -1,292 +0,0 @@ -#nullable enable -using System.Threading.Tasks; -using Content.Server.APC.Components; -using Content.Server.Battery.Components; -using Content.Server.GameObjects.Components; -using Content.Server.Power.Components; -using Content.Shared.Coordinates; -using NUnit.Framework; -using Robust.Shared.GameObjects; -using Robust.Shared.IoC; -using Robust.Shared.Map; -using Robust.Shared.Maths; -using Robust.Shared.Physics; - -namespace Content.IntegrationTests.Tests -{ - [TestFixture] - public class PowerTest : ContentIntegrationTest - { - private const string Prototypes = @" -- type: entity - name: GeneratorDummy - id: GeneratorDummy - components: - - type: NodeContainer - nodes: - output: - !type:AdjacentNode - nodeGroupID: HVPower - - type: PowerSupplier - supplyRate: 3000 - - type: Anchorable - - type: Transform - anchored: true - -- type: entity - name: ConsumerDummy - id: ConsumerDummy - components: - - type: Transform - anchored: true - - type: NodeContainer - nodes: - input: - !type:AdjacentNode - nodeGroupID: HVPower - - type: PowerConsumer - drawRate: 50 - -- type: entity - name: SubstationDummy - id: SubstationDummy - components: - - type: Battery - maxCharge: 1000 - startingCharge: 1000 - - type: NodeContainer - nodes: - input: - !type:AdjacentNode - nodeGroupID: HVPower - output: - !type:AdjacentNode - nodeGroupID: MVPower - - type: PowerConsumer - - type: BatteryStorage - activeDrawRate: 1500 - - type: PowerSupplier - voltage: Medium - - type: BatteryDischarger - activeSupplyRate: 1000 - - type: Transform - anchored: true - -- type: entity - name: ApcDummy - id: ApcDummy - components: - - type: Battery - maxCharge: 10000 - startingCharge: 10000 - - type: BatteryStorage - activeDrawRate: 1000 - - type: PowerProvider - voltage: Apc - - type: Apc - voltage: Apc - - type: PowerConsumer - voltage: Medium - - type: NodeContainer - nodes: - input: - !type:AdjacentNode - nodeGroupID: MVPower - output: - !type:AdjacentNode - nodeGroupID: Apc - - type: Transform - anchored: true - - type: UserInterface - interfaces: - - key: enum.ApcUiKey.Key - type: ApcBoundUserInterface - - type: AccessReader - access: [['Engineering']] - -- type: entity - name: ApcExtensionCableDummy - id: ApcExtensionCableDummy - components: - - type: NodeContainer - nodes: - apc: - !type:AdjacentNode - nodeGroupID: Apc - wire: - !type:AdjacentNode - nodeGroupID: WireNet - - type: PowerProvider - voltage: Apc - - type: Wire - wireType: Apc - - type: Transform - anchored: true - -- type: entity - name: PowerReceiverDummy - id: PowerReceiverDummy - components: - - type: PowerReceiver - - type: Transform - anchored: true -"; - [Test] - public async Task PowerNetTest() - { - var options = new ServerIntegrationOptions{ExtraPrototypes = Prototypes}; - var server = StartServerDummyTicker(options); - - PowerSupplierComponent supplier = default!; - PowerConsumerComponent consumer1 = default!; - PowerConsumerComponent consumer2 = default!; - - server.Assert(() => - { - var mapMan = IoCManager.Resolve(); - var entityMan = IoCManager.Resolve(); - mapMan.CreateMap(new MapId(1)); - var grid = mapMan.CreateGrid(new MapId(1)); - - // Power only works when anchored - grid.SetTile(new Vector2i(0, 0), new Tile(1)); - grid.SetTile(new Vector2i(0, 1), new Tile(1)); - grid.SetTile(new Vector2i(0, 2), new Tile(1)); - - var generatorEnt = entityMan.SpawnEntity("GeneratorDummy", grid.ToCoordinates()); - var consumerEnt1 = entityMan.SpawnEntity("ConsumerDummy", grid.ToCoordinates(0, 1)); - var consumerEnt2 = entityMan.SpawnEntity("ConsumerDummy", grid.ToCoordinates(0, 2)); - - if (generatorEnt.TryGetComponent(out PhysicsComponent? physics)) - { - physics.BodyType = BodyType.Static; - } - - supplier = generatorEnt.GetComponent(); - consumer1 = consumerEnt1.GetComponent(); - consumer2 = consumerEnt2.GetComponent(); - - var supplyRate = 1000; //arbitrary amount of power supply - - supplier.SupplyRate = supplyRate; - consumer1.DrawRate = supplyRate / 2; //arbitrary draw less than supply - consumer2.DrawRate = supplyRate * 2; //arbitrary draw greater than supply - - consumer1.Priority = Priority.First; //power goes to this consumer first - consumer2.Priority = Priority.Last; //any excess power should go to low priority consumer - }); - - server.RunTicks(1); //let run a tick for PowerNet to process power - - server.Assert(() => - { - Assert.That(consumer1.DrawRate, Is.EqualTo(consumer1.ReceivedPower)); //first should be fully powered - Assert.That(consumer2.ReceivedPower, Is.EqualTo(supplier.SupplyRate - consumer1.ReceivedPower)); //second should get remaining power - }); - - await server.WaitIdleAsync(); - } - - [Test] - public async Task ApcChargingTest() - { - var options = new ServerIntegrationOptions{ExtraPrototypes = Prototypes}; - var server = StartServerDummyTicker(options); - - BatteryComponent apcBattery = default!; - PowerSupplierComponent substationSupplier = default!; - - server.Assert(() => - { - var mapMan = IoCManager.Resolve(); - var entityMan = IoCManager.Resolve(); - mapMan.CreateMap(new MapId(1)); - var grid = mapMan.CreateGrid(new MapId(1)); - - // Power only works when anchored - grid.SetTile(new Vector2i(0, 0), new Tile(1)); - grid.SetTile(new Vector2i(0, 1), new Tile(1)); - grid.SetTile(new Vector2i(0, 2), new Tile(1)); - - var generatorEnt = entityMan.SpawnEntity("GeneratorDummy", grid.ToCoordinates()); - var substationEnt = entityMan.SpawnEntity("SubstationDummy", grid.ToCoordinates(0, 1)); - var apcEnt = entityMan.SpawnEntity("ApcDummy", grid.ToCoordinates(0, 2)); - - var generatorSupplier = generatorEnt.GetComponent(); - - substationSupplier = substationEnt.GetComponent(); - var substationStorage = substationEnt.GetComponent(); - var substationDischarger = substationEnt.GetComponent(); - - apcBattery = apcEnt.GetComponent(); - var apcStorage = apcEnt.GetComponent(); - - generatorSupplier.SupplyRate = 1000; //arbitrary nonzero amount of power - substationStorage.ActiveDrawRate = 1000; //arbitrary nonzero power draw - substationDischarger.ActiveSupplyRate = 500; //arbitirary nonzero power supply less than substation storage draw - apcStorage.ActiveDrawRate = 500; //arbitrary nonzero power draw - apcBattery.MaxCharge = 100; //abbitrary nonzero amount of charge - apcBattery.CurrentCharge = 0; //no charge - }); - - server.RunTicks(5); //let run a few ticks for PowerNets to reevaluate and start charging apc - - server.Assert(() => - { - Assert.That(substationSupplier.SupplyRate, Is.Not.EqualTo(0)); //substation should be providing power - Assert.That(apcBattery.CurrentCharge, Is.Not.EqualTo(0)); //apc battery should have gained charge - }); - - await server.WaitIdleAsync(); - } - - [Test] - public async Task ApcNetTest() - { - var options = new ServerIntegrationOptions{ExtraPrototypes = Prototypes}; - var server = StartServerDummyTicker(options); - - PowerReceiverComponent receiver = default!; - - server.Assert(() => - { - var mapMan = IoCManager.Resolve(); - var entityMan = IoCManager.Resolve(); - var mapId = new MapId(1); - mapMan.CreateMap(mapId); - var grid = mapMan.CreateGrid(mapId); - - // Power only works when anchored - grid.SetTile(new Vector2i(0, 0), new Tile(1)); - grid.SetTile(new Vector2i(0, 1), new Tile(1)); - grid.SetTile(new Vector2i(0, 2), new Tile(1)); - - var apcEnt = entityMan.SpawnEntity("ApcDummy", grid.ToCoordinates(0, 0)); - var apcExtensionEnt = entityMan.SpawnEntity("ApcExtensionCableDummy", grid.ToCoordinates(0, 1)); - var powerReceiverEnt = entityMan.SpawnEntity("PowerReceiverDummy", grid.ToCoordinates(0, 2)); - - var apc = apcEnt.GetComponent(); - var provider = apcExtensionEnt.GetComponent(); - receiver = powerReceiverEnt.GetComponent(); - var battery = apcEnt.GetComponent(); - - provider.PowerTransferRange = 5; //arbitrary range to reach receiver - receiver.PowerReceptionRange = 5; //arbitrary range to reach provider - - battery.MaxCharge = 10000; //arbitrary nonzero amount of charge - battery.CurrentCharge = battery.MaxCharge; //fill battery - - receiver.Load = 1; //arbitrary small amount of power - }); - - server.RunTicks(1); //let run a tick for ApcNet to process power - - server.Assert(() => - { - Assert.That(receiver.Powered); - }); - - await server.WaitIdleAsync(); - } - } -} diff --git a/Content.IntegrationTests/Tests/SaveLoadSaveTest.cs b/Content.IntegrationTests/Tests/SaveLoadSaveTest.cs index 9bf40017c0..e77981375b 100644 --- a/Content.IntegrationTests/Tests/SaveLoadSaveTest.cs +++ b/Content.IntegrationTests/Tests/SaveLoadSaveTest.cs @@ -122,7 +122,24 @@ namespace Content.IntegrationTests.Tests two = reader.ReadToEnd(); } - Assert.That(one, Is.EqualTo(two)); + Assert.Multiple(() => { + Assert.That(two, Is.EqualTo(one)); + var failed = TestContext.CurrentContext.Result.Assertions.FirstOrDefault(); + if (failed != null) + { + var oneTmp = Path.GetTempFileName(); + var twoTmp = Path.GetTempFileName(); + + File.WriteAllText(oneTmp, one); + File.WriteAllText(twoTmp, two); + + TestContext.AddTestAttachment(oneTmp, "First save file"); + TestContext.AddTestAttachment(twoTmp, "Second save file"); + TestContext.Error.WriteLine("Complete output:"); + TestContext.Error.WriteLine(oneTmp); + TestContext.Error.WriteLine(twoTmp); + } + }); } } } diff --git a/Content.Server/AME/AMENodeGroup.cs b/Content.Server/AME/AMENodeGroup.cs index 920cff987c..c632f39d91 100644 --- a/Content.Server/AME/AMENodeGroup.cs +++ b/Content.Server/AME/AMENodeGroup.cs @@ -8,6 +8,7 @@ using Content.Server.NodeContainer.NodeGroups; using Content.Server.NodeContainer.Nodes; using Robust.Shared.IoC; using Robust.Shared.Map; +using Robust.Shared.Maths; using Robust.Shared.Random; using Robust.Shared.ViewVariables; @@ -36,19 +37,23 @@ namespace Content.Server.AME public int CoreCount => _cores.Count; - protected override void OnAddNode(Node node) + public override void LoadNodes(List groupNodes) { - base.OnAddNode(node); - if (_masterController == null) + base.LoadNodes(groupNodes); + + foreach (var node in groupNodes) { - node.Owner.TryGetComponent(out var controller); - _masterController = controller; + if (node.Owner.TryGetComponent(out AMEControllerComponent? controller)) + { + _masterController = controller; + } } } - protected override void OnRemoveNode(Node node) + public override void RemoveNode(Node node) { - base.OnRemoveNode(node); + base.RemoveNode(node); + RefreshAMENodes(_masterController); if (_masterController != null && _masterController?.Owner == node.Owner) { _masterController = null; } } @@ -119,7 +124,7 @@ namespace Content.Server.AME // fuel > safeFuelLimit: Slow damage. Can safely run at this level for burst periods if the engine is small and someone is keeping an eye on it. if (_random.Prob(0.5f)) instability = 1; - // overloadVsSizeResult > 5: + // overloadVsSizeResult > 5: if (overloadVsSizeResult > 5) instability = 5; // overloadVsSizeResult > 10: This will explode in at most 5 injections. diff --git a/Content.Server/AME/Components/AMEControllerComponent.cs b/Content.Server/AME/Components/AMEControllerComponent.cs index b6e71fd1c2..ea65e81f94 100644 --- a/Content.Server/AME/Components/AMEControllerComponent.cs +++ b/Content.Server/AME/Components/AMEControllerComponent.cs @@ -33,7 +33,7 @@ namespace Content.Server.AME.Components private AppearanceComponent? _appearance; private PowerSupplierComponent? _powerSupplier; - private bool Powered => !Owner.TryGetComponent(out PowerReceiverComponent? receiver) || receiver.Powered; + private bool Powered => !Owner.TryGetComponent(out ApcPowerReceiverComponent? receiver) || receiver.Powered; [ViewVariables] private int _stability = 100; @@ -92,7 +92,7 @@ namespace Content.Server.AME.Components if(fuelJar != null && _powerSupplier != null) { var availableInject = fuelJar.FuelAmount >= InjectionAmount ? InjectionAmount : fuelJar.FuelAmount; - _powerSupplier.SupplyRate = group.InjectFuel(availableInject, out var overloading); + _powerSupplier.MaxSupply = group.InjectFuel(availableInject, out var overloading); fuelJar.FuelAmount -= availableInject; InjectSound(overloading); UpdateUserInterface(); @@ -252,7 +252,7 @@ namespace Content.Server.AME.Components _appearance?.SetData(AMEControllerVisuals.DisplayState, "off"); if (_powerSupplier != null) { - _powerSupplier.SupplyRate = 0; + _powerSupplier.MaxSupply = 0; } } _injecting = !_injecting; diff --git a/Content.Server/APC/ApcNetNodeGroup.cs b/Content.Server/APC/ApcNetNodeGroup.cs deleted file mode 100644 index 8b2bae38b8..0000000000 --- a/Content.Server/APC/ApcNetNodeGroup.cs +++ /dev/null @@ -1,223 +0,0 @@ -#nullable enable -using System.Collections.Generic; -using System.Linq; -using Content.Server.APC.Components; -using Content.Server.Battery.Components; -using Content.Server.NodeContainer.NodeGroups; -using Content.Server.NodeContainer.Nodes; -using Content.Server.Power.Components; -using Robust.Shared.GameObjects; -using Robust.Shared.Map; -using Robust.Shared.Utility; -using Robust.Shared.ViewVariables; - -namespace Content.Server.APC -{ - public interface IApcNet - { - bool Powered { get; } - - void AddApc(ApcComponent apc); - - void RemoveApc(ApcComponent apc); - - void AddPowerProvider(PowerProviderComponent provider); - - void RemovePowerProvider(PowerProviderComponent provider); - - void UpdatePowerProviderReceivers(PowerProviderComponent provider, int oldLoad, int newLoad); - - void Update(float frameTime); - - GridId? GridId { get; } - } - - [NodeGroup(NodeGroupID.Apc)] - public class ApcNetNodeGroup : BaseNetConnectorNodeGroup, IApcNet - { - [ViewVariables] - private readonly Dictionary _apcBatteries = new(); - - [ViewVariables] - private readonly List _providers = new(); - - [ViewVariables] - public bool Powered { get => _powered; private set => SetPowered(value); } - private bool _powered = false; - - //Debug property - [ViewVariables] - private int TotalReceivers => _providers.SelectMany(provider => provider.LinkedReceivers).Count(); - - [ViewVariables] - private int TotalPowerReceiverLoad { get => _totalPowerReceiverLoad; set => SetTotalPowerReceiverLoad(value); } - - GridId? IApcNet.GridId => GridId; - - private int _totalPowerReceiverLoad = 0; - - public static readonly IApcNet NullNet = new NullApcNet(); - - public override void Initialize(Node sourceNode) - { - base.Initialize(sourceNode); - - EntitySystem.Get().AddApcNet(this); - } - - protected override void AfterRemake(IEnumerable newGroups) - { - base.AfterRemake(newGroups); - - foreach (var group in newGroups) - { - if (group is not ApcNetNodeGroup apcNet) - continue; - - apcNet.Powered = Powered; - } - - StopUpdates(); - } - - protected override void OnGivingNodesForCombine(INodeGroup newGroup) - { - base.OnGivingNodesForCombine(newGroup); - - if (newGroup is ApcNetNodeGroup apcNet) - { - apcNet.Powered = Powered; - } - - StopUpdates(); - } - - private void StopUpdates() - { - EntitySystem.Get().RemoveApcNet(this); - } - - #region IApcNet Methods - - protected override void SetNetConnectorNet(BaseApcNetComponent netConnectorComponent) - { - netConnectorComponent.Net = this; - } - - public void AddApc(ApcComponent apc) - { - if (!apc.Owner.TryGetComponent(out BatteryComponent? battery)) - { - return; - } - - _apcBatteries.Add(apc, battery); - } - - public void RemoveApc(ApcComponent apc) - { - _apcBatteries.Remove(apc); - } - - public void AddPowerProvider(PowerProviderComponent provider) - { - _providers.Add(provider); - - foreach (var receiver in provider.LinkedReceivers) - { - TotalPowerReceiverLoad += receiver.Load; - } - } - - public void RemovePowerProvider(PowerProviderComponent provider) - { - _providers.Remove(provider); - - foreach (var receiver in provider.LinkedReceivers) - { - TotalPowerReceiverLoad -= receiver.Load; - } - } - - public void UpdatePowerProviderReceivers(PowerProviderComponent provider, int oldLoad, int newLoad) - { - DebugTools.Assert(_providers.Contains(provider)); - TotalPowerReceiverLoad -= oldLoad; - TotalPowerReceiverLoad += newLoad; - } - - public void Update(float frameTime) - { - var remainingPowerNeeded = TotalPowerReceiverLoad * frameTime; - - foreach (var apcBatteryPair in _apcBatteries) - { - var apc = apcBatteryPair.Key; - - if (!apc.MainBreakerEnabled) - continue; - - var battery = apcBatteryPair.Value; - - if (battery.CurrentCharge < remainingPowerNeeded) - { - remainingPowerNeeded -= battery.CurrentCharge; - battery.CurrentCharge = 0; - } - else - { - battery.UseCharge(remainingPowerNeeded); - remainingPowerNeeded = 0; - } - - if (remainingPowerNeeded == 0) - break; - } - - Powered = remainingPowerNeeded == 0; - } - - private void SetPowered(bool powered) - { - if (powered != Powered) - { - _powered = powered; - PoweredChanged(); - } - } - - private void PoweredChanged() - { - foreach (var provider in _providers) - { - foreach (var receiver in provider.LinkedReceivers) - { - receiver.ApcPowerChanged(); - } - } - } - - private void SetTotalPowerReceiverLoad(int totalPowerReceiverLoad) - { - DebugTools.Assert(totalPowerReceiverLoad >= 0, $"Expected load equal to or greater than 0, was {totalPowerReceiverLoad}"); - _totalPowerReceiverLoad = totalPowerReceiverLoad; - } - - #endregion - - private class NullApcNet : IApcNet - { - /// - /// It is important that this returns false, so s with a have no power. - /// - public bool Powered => false; - public GridId? GridId => default; - public void AddApc(ApcComponent apc) { } - public void AddPowerProvider(PowerProviderComponent provider) { } - public void RemoveApc(ApcComponent apc) { } - public void RemovePowerProvider(PowerProviderComponent provider) { } - public void UpdatePowerProviderReceivers(PowerProviderComponent provider, int oldLoad, int newLoad) { } - public void Update(float frameTime) { } - } - } -} diff --git a/Content.Server/APC/ApcNetSystem.cs b/Content.Server/APC/ApcNetSystem.cs deleted file mode 100644 index ad19216340..0000000000 --- a/Content.Server/APC/ApcNetSystem.cs +++ /dev/null @@ -1,52 +0,0 @@ -#nullable enable -using System.Collections.Generic; -using Content.Shared.GameTicking; -using JetBrains.Annotations; -using Robust.Shared.GameObjects; -using Robust.Shared.IoC; -using Robust.Shared.Timing; - -namespace Content.Server.APC -{ - [UsedImplicitly] - internal sealed class ApcNetSystem : EntitySystem - { - [Dependency] private readonly IPauseManager _pauseManager = default!; - - private HashSet _apcNets = new(); - - public override void Initialize() - { - base.Initialize(); - - SubscribeLocalEvent(Reset); - } - - public override void Update(float frameTime) - { - foreach (var apcNet in _apcNets) - { - var gridId = apcNet.GridId; - if (gridId != null && !_pauseManager.IsGridPaused(gridId.Value)) - apcNet.Update(frameTime); - } - } - - public void AddApcNet(ApcNetNodeGroup apcNet) - { - _apcNets.Add(apcNet); - } - - public void RemoveApcNet(ApcNetNodeGroup apcNet) - { - _apcNets.Remove(apcNet); - } - - public void Reset(RoundRestartCleanupEvent ev) - { - // NodeGroupSystem does not remake ApcNets affected during restarting until a frame later, - // when their grid is invalid. So, we are clearing them on round restart. - _apcNets.Clear(); - } - } -} diff --git a/Content.Server/APC/Components/BaseApcNetComponent.cs b/Content.Server/APC/Components/BaseApcNetComponent.cs deleted file mode 100644 index 51fa8b3c43..0000000000 --- a/Content.Server/APC/Components/BaseApcNetComponent.cs +++ /dev/null @@ -1,10 +0,0 @@ -#nullable enable -using Content.Server.Power.Components; - -namespace Content.Server.APC.Components -{ - public abstract class BaseApcNetComponent : BaseNetConnectorComponent - { - protected override IApcNet NullNet => ApcNetNodeGroup.NullNet; - } -} diff --git a/Content.Server/Access/Components/IdCardConsoleComponent.cs b/Content.Server/Access/Components/IdCardConsoleComponent.cs index 5debc68a1a..f9de78f2ac 100644 --- a/Content.Server/Access/Components/IdCardConsoleComponent.cs +++ b/Content.Server/Access/Components/IdCardConsoleComponent.cs @@ -34,7 +34,7 @@ namespace Content.Server.Access.Components private ContainerSlot _targetIdContainer = default!; [ViewVariables] private BoundUserInterface? UserInterface => Owner.GetUIOrNull(IdCardConsoleUiKey.Key); - [ViewVariables] private bool Powered => !Owner.TryGetComponent(out PowerReceiverComponent? receiver) || receiver.Powered; + [ViewVariables] private bool Powered => !Owner.TryGetComponent(out ApcPowerReceiverComponent? receiver) || receiver.Powered; private bool PrivilegedIDEmpty => _privilegedIdContainer.ContainedEntities.Count < 1; private bool TargetIDEmpty => _targetIdContainer.ContainedEntities.Count < 1; diff --git a/Content.Server/Arcade/Components/BlockGameArcadeComponent.cs b/Content.Server/Arcade/Components/BlockGameArcadeComponent.cs index 5dce5324bf..6634ae5d9a 100644 --- a/Content.Server/Arcade/Components/BlockGameArcadeComponent.cs +++ b/Content.Server/Arcade/Components/BlockGameArcadeComponent.cs @@ -27,7 +27,7 @@ namespace Content.Server.Arcade.Components public override string Name => "BlockGameArcade"; public override uint? NetID => ContentNetIDs.BLOCKGAME_ARCADE; - [ComponentDependency] private readonly PowerReceiverComponent? _powerReceiverComponent = default!; + [ComponentDependency] private readonly ApcPowerReceiverComponent? _powerReceiverComponent = default!; private bool Powered => _powerReceiverComponent?.Powered ?? false; private BoundUserInterface? UserInterface => Owner.GetUIOrNull(BlockGameUiKey.Key); diff --git a/Content.Server/Arcade/Components/SpaceVillainArcadeComponent.cs b/Content.Server/Arcade/Components/SpaceVillainArcadeComponent.cs index 40f337896a..d2aae64b6a 100644 --- a/Content.Server/Arcade/Components/SpaceVillainArcadeComponent.cs +++ b/Content.Server/Arcade/Components/SpaceVillainArcadeComponent.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; using Content.Server.Power.Components; using Content.Server.UserInterface; using Content.Server.VendingMachines; -using Content.Server.Wires.Components; +using Content.Server.WireHacking; using Content.Shared.ActionBlocker; using Content.Shared.Arcade; using Content.Shared.Interaction; @@ -28,7 +28,7 @@ namespace Content.Server.Arcade.Components { [Dependency] private readonly IRobustRandom _random = null!; - [ComponentDependency] private readonly PowerReceiverComponent? _powerReceiverComponent = default!; + [ComponentDependency] private readonly ApcPowerReceiverComponent? _powerReceiverComponent = default!; [ComponentDependency] private readonly WiresComponent? _wiresComponent = default!; private bool Powered => _powerReceiverComponent != null && _powerReceiverComponent.Powered; diff --git a/Content.Server/Atmos/Components/BaseComputerUserInterfaceComponent.cs b/Content.Server/Atmos/Components/BaseComputerUserInterfaceComponent.cs index 195b1c2623..8023127069 100644 --- a/Content.Server/Atmos/Components/BaseComputerUserInterfaceComponent.cs +++ b/Content.Server/Atmos/Components/BaseComputerUserInterfaceComponent.cs @@ -20,7 +20,7 @@ namespace Content.Server.GameObjects.Components protected readonly object UserInterfaceKey; [ViewVariables] protected BoundUserInterface? UserInterface => Owner.GetUIOrNull(UserInterfaceKey); - [ViewVariables] public bool Powered => !Owner.TryGetComponent(out PowerReceiverComponent? receiver) || receiver.Powered; + [ViewVariables] public bool Powered => !Owner.TryGetComponent(out ApcPowerReceiverComponent? receiver) || receiver.Powered; public BaseComputerUserInterfaceComponent(object key) { diff --git a/Content.Server/Atmos/Components/GasTankComponent.cs b/Content.Server/Atmos/Components/GasTankComponent.cs index add95c5905..d30494b082 100644 --- a/Content.Server/Atmos/Components/GasTankComponent.cs +++ b/Content.Server/Atmos/Components/GasTankComponent.cs @@ -4,9 +4,9 @@ using System; using Content.Server.Atmos.EntitySystems; using Content.Server.Body.Respiratory; using Content.Server.Explosion; -using Content.Server.GameObjects.Components.NodeContainer.Nodes; using Content.Server.Interfaces; using Content.Server.NodeContainer; +using Content.Server.NodeContainer.Nodes; using Content.Server.UserInterface; using Content.Shared.ActionBlocker; using Content.Shared.Actions; diff --git a/Content.Server/Atmos/EntitySystems/AtmosphereSystem.cs b/Content.Server/Atmos/EntitySystems/AtmosphereSystem.cs index f7bdf1839b..2094d2a52e 100644 --- a/Content.Server/Atmos/EntitySystems/AtmosphereSystem.cs +++ b/Content.Server/Atmos/EntitySystems/AtmosphereSystem.cs @@ -1,6 +1,7 @@ using System; using System.Diagnostics.CodeAnalysis; using Content.Server.Atmos.Components; +using Content.Server.NodeContainer.EntitySystems; using Content.Shared.Atmos.EntitySystems; using Content.Shared.Maps; using JetBrains.Annotations; @@ -33,6 +34,8 @@ namespace Content.Server.Atmos.EntitySystems { base.Initialize(); + UpdatesAfter.Add(typeof(NodeGroupSystem)); + InitializeGases(); InitializeCVars(); diff --git a/Content.Server/Atmos/Piping/Binary/Components/GasValveComponent.cs b/Content.Server/Atmos/Piping/Binary/Components/GasValveComponent.cs index 6a239c0700..7a20b63509 100644 --- a/Content.Server/Atmos/Piping/Binary/Components/GasValveComponent.cs +++ b/Content.Server/Atmos/Piping/Binary/Components/GasValveComponent.cs @@ -1,5 +1,5 @@ -using Content.Server.GameObjects.Components.NodeContainer.Nodes; using Content.Server.NodeContainer; +using Content.Server.NodeContainer.Nodes; using Content.Shared.ActionBlocker; using Content.Shared.Interaction; using Content.Shared.Interaction.Helpers; diff --git a/Content.Server/Atmos/Piping/Binary/EntitySystems/GasPassiveGateSystem.cs b/Content.Server/Atmos/Piping/Binary/EntitySystems/GasPassiveGateSystem.cs index dc825a48d6..9d27211ad2 100644 --- a/Content.Server/Atmos/Piping/Binary/EntitySystems/GasPassiveGateSystem.cs +++ b/Content.Server/Atmos/Piping/Binary/EntitySystems/GasPassiveGateSystem.cs @@ -1,8 +1,8 @@ using System; using Content.Server.Atmos.Piping.Binary.Components; using Content.Server.Atmos.Piping.Components; -using Content.Server.GameObjects.Components.NodeContainer.Nodes; using Content.Server.NodeContainer; +using Content.Server.NodeContainer.Nodes; using Content.Shared.Atmos; using JetBrains.Annotations; using Robust.Shared.GameObjects; diff --git a/Content.Server/Atmos/Piping/Binary/EntitySystems/GasPressurePumpSystem.cs b/Content.Server/Atmos/Piping/Binary/EntitySystems/GasPressurePumpSystem.cs index 5e616ea68a..dc38b4da76 100644 --- a/Content.Server/Atmos/Piping/Binary/EntitySystems/GasPressurePumpSystem.cs +++ b/Content.Server/Atmos/Piping/Binary/EntitySystems/GasPressurePumpSystem.cs @@ -1,7 +1,7 @@ using Content.Server.Atmos.Piping.Binary.Components; using Content.Server.Atmos.Piping.Components; -using Content.Server.GameObjects.Components.NodeContainer.Nodes; using Content.Server.NodeContainer; +using Content.Server.NodeContainer.Nodes; using Content.Shared.Atmos; using Content.Shared.Atmos.Piping; using JetBrains.Annotations; diff --git a/Content.Server/Atmos/Piping/Binary/EntitySystems/GasVolumePumpSystem.cs b/Content.Server/Atmos/Piping/Binary/EntitySystems/GasVolumePumpSystem.cs index a157094c88..48e253167b 100644 --- a/Content.Server/Atmos/Piping/Binary/EntitySystems/GasVolumePumpSystem.cs +++ b/Content.Server/Atmos/Piping/Binary/EntitySystems/GasVolumePumpSystem.cs @@ -1,7 +1,7 @@ using Content.Server.Atmos.Piping.Binary.Components; using Content.Server.Atmos.Piping.Components; -using Content.Server.GameObjects.Components.NodeContainer.Nodes; using Content.Server.NodeContainer; +using Content.Server.NodeContainer.Nodes; using JetBrains.Annotations; using Robust.Shared.GameObjects; using Robust.Shared.IoC; diff --git a/Content.Server/Atmos/Piping/EntitySystems/AtmosUnsafeUnanchorSystem.cs b/Content.Server/Atmos/Piping/EntitySystems/AtmosUnsafeUnanchorSystem.cs index b94441e5b4..2f63c28b59 100644 --- a/Content.Server/Atmos/Piping/EntitySystems/AtmosUnsafeUnanchorSystem.cs +++ b/Content.Server/Atmos/Piping/EntitySystems/AtmosUnsafeUnanchorSystem.cs @@ -1,8 +1,8 @@ using Content.Server.Atmos.EntitySystems; using Content.Server.Atmos.Piping.Components; using Content.Server.Construction.Components; -using Content.Server.GameObjects.Components.NodeContainer.Nodes; using Content.Server.NodeContainer; +using Content.Server.NodeContainer.Nodes; using Content.Shared.Atmos; using Content.Shared.Notification.Managers; using JetBrains.Annotations; diff --git a/Content.Server/Atmos/Piping/Trinary/EntitySystems/GasFilterSystem.cs b/Content.Server/Atmos/Piping/Trinary/EntitySystems/GasFilterSystem.cs index 2b543a6a82..a2db87f7bc 100644 --- a/Content.Server/Atmos/Piping/Trinary/EntitySystems/GasFilterSystem.cs +++ b/Content.Server/Atmos/Piping/Trinary/EntitySystems/GasFilterSystem.cs @@ -1,7 +1,7 @@ using Content.Server.Atmos.Piping.Components; using Content.Server.Atmos.Piping.Trinary.Components; -using Content.Server.GameObjects.Components.NodeContainer.Nodes; using Content.Server.NodeContainer; +using Content.Server.NodeContainer.Nodes; using Content.Shared.Atmos; using JetBrains.Annotations; using Robust.Shared.GameObjects; diff --git a/Content.Server/Atmos/Piping/Trinary/EntitySystems/GasMixerSystem.cs b/Content.Server/Atmos/Piping/Trinary/EntitySystems/GasMixerSystem.cs index f2b829854f..3e886d6773 100644 --- a/Content.Server/Atmos/Piping/Trinary/EntitySystems/GasMixerSystem.cs +++ b/Content.Server/Atmos/Piping/Trinary/EntitySystems/GasMixerSystem.cs @@ -1,8 +1,8 @@ using System; using Content.Server.Atmos.Piping.Components; using Content.Server.Atmos.Piping.Trinary.Components; -using Content.Server.GameObjects.Components.NodeContainer.Nodes; using Content.Server.NodeContainer; +using Content.Server.NodeContainer.Nodes; using Content.Shared.Atmos; using JetBrains.Annotations; using Robust.Shared.GameObjects; diff --git a/Content.Server/Atmos/Piping/Unary/EntitySystems/GasCanisterSystem.cs b/Content.Server/Atmos/Piping/Unary/EntitySystems/GasCanisterSystem.cs index 2cfabfeb1f..d12a363475 100644 --- a/Content.Server/Atmos/Piping/Unary/EntitySystems/GasCanisterSystem.cs +++ b/Content.Server/Atmos/Piping/Unary/EntitySystems/GasCanisterSystem.cs @@ -4,9 +4,9 @@ using Content.Server.Atmos.EntitySystems; using Content.Server.Atmos.Piping.Binary.Components; using Content.Server.Atmos.Piping.Components; using Content.Server.Atmos.Piping.Unary.Components; -using Content.Server.GameObjects.Components.NodeContainer.Nodes; using Content.Server.Hands.Components; using Content.Server.NodeContainer; +using Content.Server.NodeContainer.Nodes; using Content.Server.UserInterface; using Content.Shared.ActionBlocker; using Content.Shared.Atmos; @@ -62,7 +62,7 @@ namespace Content.Server.Atmos.Piping.Unary.EntitySystems return; // Create a pipenet if we don't have one already. - portNode.TryAssignGroupIfNeeded(); + portNode.CreateSingleNetImmediate(); Get().Merge(portNode.Air, canister.InitialMixture); portNode.Air.Temperature = canister.InitialMixture.Temperature; portNode.Volume = canister.InitialMixture.Volume; @@ -90,7 +90,7 @@ namespace Content.Server.Atmos.Piping.Unary.EntitySystems } ui.SetState(new GasCanisterBoundUserInterfaceState(metadata.EntityName, portNode.Air.Pressure, - portNode.NodeGroup.Nodes.Count > 1, tankLabel, tankPressure, + portNode.NodeGroup!.Nodes.Count > 1, tankLabel, tankPressure, canister.ReleasePressure, canister.ReleaseValve, canister.MinReleasePressure, canister.MaxReleasePressure)); } diff --git a/Content.Server/Atmos/Piping/Unary/EntitySystems/GasOutletInjectorSystem.cs b/Content.Server/Atmos/Piping/Unary/EntitySystems/GasOutletInjectorSystem.cs index 187cee7b93..1d275837ea 100644 --- a/Content.Server/Atmos/Piping/Unary/EntitySystems/GasOutletInjectorSystem.cs +++ b/Content.Server/Atmos/Piping/Unary/EntitySystems/GasOutletInjectorSystem.cs @@ -1,7 +1,7 @@ using Content.Server.Atmos.Piping.Components; using Content.Server.Atmos.Piping.Unary.Components; -using Content.Server.GameObjects.Components.NodeContainer.Nodes; using Content.Server.NodeContainer; +using Content.Server.NodeContainer.Nodes; using Content.Shared.Atmos; using JetBrains.Annotations; using Robust.Shared.GameObjects; diff --git a/Content.Server/Atmos/Piping/Unary/EntitySystems/GasPassiveVentSystem.cs b/Content.Server/Atmos/Piping/Unary/EntitySystems/GasPassiveVentSystem.cs index c04d3c44ad..e984bd3515 100644 --- a/Content.Server/Atmos/Piping/Unary/EntitySystems/GasPassiveVentSystem.cs +++ b/Content.Server/Atmos/Piping/Unary/EntitySystems/GasPassiveVentSystem.cs @@ -1,8 +1,8 @@ using System; using Content.Server.Atmos.Piping.Components; using Content.Server.Atmos.Piping.Unary.Components; -using Content.Server.GameObjects.Components.NodeContainer.Nodes; using Content.Server.NodeContainer; +using Content.Server.NodeContainer.Nodes; using Content.Shared.Atmos; using JetBrains.Annotations; using Robust.Shared.GameObjects; diff --git a/Content.Server/Atmos/Piping/Unary/EntitySystems/GasPortableSystem.cs b/Content.Server/Atmos/Piping/Unary/EntitySystems/GasPortableSystem.cs index d675ad21c6..4ee5c723fa 100644 --- a/Content.Server/Atmos/Piping/Unary/EntitySystems/GasPortableSystem.cs +++ b/Content.Server/Atmos/Piping/Unary/EntitySystems/GasPortableSystem.cs @@ -2,8 +2,8 @@ using System.Diagnostics.CodeAnalysis; using Content.Server.Atmos.Piping.Binary.Components; using Content.Server.Atmos.Piping.Unary.Components; using Content.Server.Construction.Components; -using Content.Server.GameObjects.Components.NodeContainer.Nodes; using Content.Server.NodeContainer; +using Content.Server.NodeContainer.Nodes; using Content.Shared.Atmos.Piping.Unary.Components; using JetBrains.Annotations; using Robust.Server.GameObjects; diff --git a/Content.Server/Atmos/Piping/Unary/EntitySystems/GasThermoMachineSystem.cs b/Content.Server/Atmos/Piping/Unary/EntitySystems/GasThermoMachineSystem.cs index 43f001d186..748700d13e 100644 --- a/Content.Server/Atmos/Piping/Unary/EntitySystems/GasThermoMachineSystem.cs +++ b/Content.Server/Atmos/Piping/Unary/EntitySystems/GasThermoMachineSystem.cs @@ -1,8 +1,8 @@ using Content.Server.Atmos.EntitySystems; using Content.Server.Atmos.Piping.Components; using Content.Server.Atmos.Piping.Unary.Components; -using Content.Server.GameObjects.Components.NodeContainer.Nodes; using Content.Server.NodeContainer; +using Content.Server.NodeContainer.Nodes; using Content.Shared.Atmos.Piping; using JetBrains.Annotations; using Robust.Server.GameObjects; diff --git a/Content.Server/Atmos/Piping/Unary/EntitySystems/GasVentPumpSystem.cs b/Content.Server/Atmos/Piping/Unary/EntitySystems/GasVentPumpSystem.cs index a310e4a225..16046fd61e 100644 --- a/Content.Server/Atmos/Piping/Unary/EntitySystems/GasVentPumpSystem.cs +++ b/Content.Server/Atmos/Piping/Unary/EntitySystems/GasVentPumpSystem.cs @@ -1,8 +1,8 @@ using System; using Content.Server.Atmos.Piping.Components; using Content.Server.Atmos.Piping.Unary.Components; -using Content.Server.GameObjects.Components.NodeContainer.Nodes; using Content.Server.NodeContainer; +using Content.Server.NodeContainer.Nodes; using Content.Shared.Atmos; using Content.Shared.Atmos.Visuals; using JetBrains.Annotations; diff --git a/Content.Server/Atmos/Piping/Unary/EntitySystems/GasVentScrubberSystem.cs b/Content.Server/Atmos/Piping/Unary/EntitySystems/GasVentScrubberSystem.cs index 17559dbb4b..262924c2b6 100644 --- a/Content.Server/Atmos/Piping/Unary/EntitySystems/GasVentScrubberSystem.cs +++ b/Content.Server/Atmos/Piping/Unary/EntitySystems/GasVentScrubberSystem.cs @@ -2,8 +2,8 @@ using System; using Content.Server.Atmos.EntitySystems; using Content.Server.Atmos.Piping.Components; using Content.Server.Atmos.Piping.Unary.Components; -using Content.Server.GameObjects.Components.NodeContainer.Nodes; using Content.Server.NodeContainer; +using Content.Server.NodeContainer.Nodes; using Content.Shared.Atmos; using Content.Shared.Atmos.Piping.Unary.Visuals; using JetBrains.Annotations; diff --git a/Content.Server/BarSign/BarSignComponent.cs b/Content.Server/BarSign/BarSignComponent.cs index 1a673d1186..a0b953dc22 100644 --- a/Content.Server/BarSign/BarSignComponent.cs +++ b/Content.Server/BarSign/BarSignComponent.cs @@ -35,7 +35,7 @@ namespace Content.Server.BarSign } } - private bool Powered => !Owner.TryGetComponent(out PowerReceiverComponent? receiver) || receiver.Powered; + private bool Powered => !Owner.TryGetComponent(out ApcPowerReceiverComponent? receiver) || receiver.Powered; private void UpdateSignInfo() { diff --git a/Content.Server/Battery/EntitySystems/BatteryDischargerSystem.cs b/Content.Server/Battery/EntitySystems/BatteryDischargerSystem.cs deleted file mode 100644 index 37873eaa61..0000000000 --- a/Content.Server/Battery/EntitySystems/BatteryDischargerSystem.cs +++ /dev/null @@ -1,19 +0,0 @@ -#nullable enable -using Content.Server.Power.Components; -using JetBrains.Annotations; -using Robust.Shared.GameObjects; - -namespace Content.Server.Battery.EntitySystems -{ - [UsedImplicitly] - internal sealed class BatteryDischargerSystem : EntitySystem - { - public override void Update(float frameTime) - { - foreach (var comp in ComponentManager.EntityQuery(false)) - { - comp.Update(frameTime); - } - } - } -} diff --git a/Content.Server/Battery/EntitySystems/BatteryStorageSystem.cs b/Content.Server/Battery/EntitySystems/BatteryStorageSystem.cs deleted file mode 100644 index c32b58e725..0000000000 --- a/Content.Server/Battery/EntitySystems/BatteryStorageSystem.cs +++ /dev/null @@ -1,19 +0,0 @@ -#nullable enable -using Content.Server.Power.Components; -using JetBrains.Annotations; -using Robust.Shared.GameObjects; - -namespace Content.Server.Battery.EntitySystems -{ - [UsedImplicitly] - internal sealed class BatteryStorageSystem : EntitySystem - { - public override void Update(float frameTime) - { - foreach (var comp in ComponentManager.EntityQuery(false)) - { - comp.Update(frameTime); - } - } - } -} diff --git a/Content.Server/Battery/EntitySystems/BatterySystem.cs b/Content.Server/Battery/EntitySystems/BatterySystem.cs deleted file mode 100644 index ace6084dce..0000000000 --- a/Content.Server/Battery/EntitySystems/BatterySystem.cs +++ /dev/null @@ -1,19 +0,0 @@ -#nullable enable -using Content.Server.Battery.Components; -using JetBrains.Annotations; -using Robust.Shared.GameObjects; - -namespace Content.Server.Battery.EntitySystems -{ - [UsedImplicitly] - public class BatterySystem : EntitySystem - { - public override void Update(float frameTime) - { - foreach (var comp in ComponentManager.EntityQuery(true)) - { - comp.OnUpdate(frameTime); - } - } - } -} diff --git a/Content.Server/Botany/Components/SeedExtractorComponent.cs b/Content.Server/Botany/Components/SeedExtractorComponent.cs index 160fdad86a..c195c4f869 100644 --- a/Content.Server/Botany/Components/SeedExtractorComponent.cs +++ b/Content.Server/Botany/Components/SeedExtractorComponent.cs @@ -14,7 +14,7 @@ namespace Content.Server.Botany.Components [RegisterComponent] public class SeedExtractorComponent : Component, IInteractUsing { - [ComponentDependency] private readonly PowerReceiverComponent? _powerReceiver = default!; + [ComponentDependency] private readonly ApcPowerReceiverComponent? _powerReceiver = default!; [Dependency] private readonly IRobustRandom _random = default!; diff --git a/Content.Server/Cargo/Components/CargoConsoleComponent.cs b/Content.Server/Cargo/Components/CargoConsoleComponent.cs index 3adcf4f9bb..4a53d52b48 100644 --- a/Content.Server/Cargo/Components/CargoConsoleComponent.cs +++ b/Content.Server/Cargo/Components/CargoConsoleComponent.cs @@ -59,7 +59,7 @@ namespace Content.Server.Cargo.Components [DataField("requestOnly")] private bool _requestOnly = false; - private bool Powered => !Owner.TryGetComponent(out PowerReceiverComponent? receiver) || receiver.Powered; + private bool Powered => !Owner.TryGetComponent(out ApcPowerReceiverComponent? receiver) || receiver.Powered; private CargoConsoleSystem _cargoConsoleSystem = default!; [ViewVariables] private BoundUserInterface? UserInterface => Owner.GetUIOrNull(CargoConsoleUiKey.Key); @@ -171,7 +171,7 @@ namespace Content.Server.Cargo.Components { foreach (IEntity entity in enumerator) { - if (entity.HasComponent() && entity.TryGetComponent(out var powerReceiver) && powerReceiver.Powered) + if (entity.HasComponent() && entity.TryGetComponent(out var powerReceiver) && powerReceiver.Powered) { cargoTelepad = entity; break; diff --git a/Content.Server/Cargo/Components/CargoTelepadComponent.cs b/Content.Server/Cargo/Components/CargoTelepadComponent.cs index 1d87a7cf2b..ba31eb3d13 100644 --- a/Content.Server/Cargo/Components/CargoTelepadComponent.cs +++ b/Content.Server/Cargo/Components/CargoTelepadComponent.cs @@ -43,14 +43,14 @@ namespace Content.Server.Cargo.Components { if (args.Powered && _currentState == CargoTelepadState.Unpowered) { _currentState = CargoTelepadState.Idle; - if(Owner.TryGetComponent(out var spriteComponent)) + if(Owner.TryGetComponent(out var spriteComponent) && spriteComponent.LayerCount > 0) spriteComponent.LayerSetState(0, "idle"); TeleportLoop(); } else if (!args.Powered) { _currentState = CargoTelepadState.Unpowered; - if (Owner.TryGetComponent(out var spriteComponent)) + if (Owner.TryGetComponent(out var spriteComponent) && spriteComponent.LayerCount > 0) spriteComponent.LayerSetState(0, "offline"); } } @@ -59,14 +59,14 @@ namespace Content.Server.Cargo.Components if (_currentState == CargoTelepadState.Idle && _teleportQueue.Count > 0) { _currentState = CargoTelepadState.Charging; - if (Owner.TryGetComponent(out var spriteComponent)) + if (Owner.TryGetComponent(out var spriteComponent) && spriteComponent.LayerCount > 0) spriteComponent.LayerSetState(0, "idle"); Owner.SpawnTimer((int) (TeleportDelay * 1000), () => { if (!Deleted && !Owner.Deleted && _currentState == CargoTelepadState.Charging && _teleportQueue.Count > 0) { _currentState = CargoTelepadState.Teleporting; - if (Owner.TryGetComponent(out var spriteComponent)) + if (Owner.TryGetComponent(out var spriteComponent) && spriteComponent.LayerCount > 0) spriteComponent.LayerSetState(0, "beam"); Owner.SpawnTimer((int) (TeleportDuration * 1000), () => { @@ -75,7 +75,7 @@ namespace Content.Server.Cargo.Components SoundSystem.Play(Filter.Pvs(Owner), "/Audio/Machines/phasein.ogg", Owner, AudioParams.Default.WithVolume(-8f)); Owner.EntityManager.SpawnEntity(_teleportQueue[0].Product, Owner.Transform.Coordinates); _teleportQueue.RemoveAt(0); - if (Owner.TryGetComponent(out var spriteComponent)) + if (Owner.TryGetComponent(out var spriteComponent) && spriteComponent.LayerCount > 0) spriteComponent.LayerSetState(0, "idle"); _currentState = CargoTelepadState.Idle; TeleportLoop(); diff --git a/Content.Server/Chemistry/Components/ChemMasterComponent.cs b/Content.Server/Chemistry/Components/ChemMasterComponent.cs index b06c5c9479..7ae9b4193f 100644 --- a/Content.Server/Chemistry/Components/ChemMasterComponent.cs +++ b/Content.Server/Chemistry/Components/ChemMasterComponent.cs @@ -40,7 +40,7 @@ namespace Content.Server.Chemistry.Components [ViewVariables] private bool HasBeaker => _beakerContainer.ContainedEntity != null; [ViewVariables] private bool _bufferModeTransfer = true; - [ViewVariables] private bool Powered => !Owner.TryGetComponent(out PowerReceiverComponent? receiver) || receiver.Powered; + [ViewVariables] private bool Powered => !Owner.TryGetComponent(out ApcPowerReceiverComponent? receiver) || receiver.Powered; [ViewVariables] private readonly Solution BufferSolution = new(); diff --git a/Content.Server/Chemistry/Components/ReagentDispenserComponent.cs b/Content.Server/Chemistry/Components/ReagentDispenserComponent.cs index 66c31a9357..938f009b8e 100644 --- a/Content.Server/Chemistry/Components/ReagentDispenserComponent.cs +++ b/Content.Server/Chemistry/Components/ReagentDispenserComponent.cs @@ -51,7 +51,7 @@ namespace Content.Server.Chemistry.Components [ViewVariables] private ReagentUnit _dispenseAmount = ReagentUnit.New(10); [UsedImplicitly] [ViewVariables] private SolutionContainerComponent? Solution => _beakerContainer.ContainedEntity?.GetComponent(); - [ViewVariables] private bool Powered => !Owner.TryGetComponent(out PowerReceiverComponent? receiver) || receiver.Powered; + [ViewVariables] private bool Powered => !Owner.TryGetComponent(out ApcPowerReceiverComponent? receiver) || receiver.Powered; [ViewVariables] private BoundUserInterface? UserInterface => Owner.GetUIOrNull(ReagentDispenserUiKey.Key); diff --git a/Content.Server/Cloning/CloningSystem.cs b/Content.Server/Cloning/CloningSystem.cs index 0e11d02f38..4622ae660b 100644 --- a/Content.Server/Cloning/CloningSystem.cs +++ b/Content.Server/Cloning/CloningSystem.cs @@ -74,7 +74,7 @@ namespace Content.Server.Cloning public override void Update(float frameTime) { - foreach (var (cloning, power) in ComponentManager.EntityQuery(true)) + foreach (var (cloning, power) in ComponentManager.EntityQuery(true)) { if (cloning.UiKnownPowerState != power.Powered) { diff --git a/Content.Server/Cloning/Components/CloningPodComponent.cs b/Content.Server/Cloning/Components/CloningPodComponent.cs index 3b7f81e28c..fba96c8860 100644 --- a/Content.Server/Cloning/Components/CloningPodComponent.cs +++ b/Content.Server/Cloning/Components/CloningPodComponent.cs @@ -26,7 +26,7 @@ namespace Content.Server.Cloning.Components [Dependency] private readonly EuiManager _euiManager = null!; [ViewVariables] - public bool Powered => !Owner.TryGetComponent(out PowerReceiverComponent? receiver) || receiver.Powered; + public bool Powered => !Owner.TryGetComponent(out ApcPowerReceiverComponent? receiver) || receiver.Powered; [ViewVariables] public BoundUserInterface? UserInterface => diff --git a/Content.Server/Communications/CommunicationsConsoleComponent.cs b/Content.Server/Communications/CommunicationsConsoleComponent.cs index 4ed0b34b7b..cf0b768e78 100644 --- a/Content.Server/Communications/CommunicationsConsoleComponent.cs +++ b/Content.Server/Communications/CommunicationsConsoleComponent.cs @@ -25,7 +25,7 @@ namespace Content.Server.Communications { [Dependency] private readonly IGameTiming _gameTiming = default!; [Dependency] private readonly IChatManager _chatManager = default!; - private bool Powered => !Owner.TryGetComponent(out PowerReceiverComponent? receiver) || receiver.Powered; + private bool Powered => !Owner.TryGetComponent(out ApcPowerReceiverComponent? receiver) || receiver.Powered; private RoundEndSystem RoundEndSystem => EntitySystem.Get(); diff --git a/Content.Server/Computer/ComputerComponent.cs b/Content.Server/Computer/ComputerComponent.cs index 22527a5c7f..9e22500007 100644 --- a/Content.Server/Computer/ComputerComponent.cs +++ b/Content.Server/Computer/ComputerComponent.cs @@ -24,7 +24,7 @@ namespace Content.Server.Computer // Let's ensure the container manager and container are here. Owner.EnsureContainer("board", out var _); - if (Owner.TryGetComponent(out PowerReceiverComponent? powerReceiver) && + if (Owner.TryGetComponent(out ApcPowerReceiverComponent? powerReceiver) && Owner.TryGetComponent(out AppearanceComponent? appearance)) { appearance.SetData(ComputerVisuals.Powered, powerReceiver.Powered); diff --git a/Content.Server/Construction/Conditions/AllWiresCut.cs b/Content.Server/Construction/Conditions/AllWiresCut.cs index 0370978f64..0137c057fc 100644 --- a/Content.Server/Construction/Conditions/AllWiresCut.cs +++ b/Content.Server/Construction/Conditions/AllWiresCut.cs @@ -1,6 +1,6 @@ using System.Threading.Tasks; using Content.Server.GameObjects.Components; -using Content.Server.Wires.Components; +using Content.Server.WireHacking; using Content.Shared.Construction; using JetBrains.Annotations; using Robust.Shared.GameObjects; diff --git a/Content.Server/Construction/Conditions/WirePanel.cs b/Content.Server/Construction/Conditions/WirePanel.cs index a966a3c845..c443506a2e 100644 --- a/Content.Server/Construction/Conditions/WirePanel.cs +++ b/Content.Server/Construction/Conditions/WirePanel.cs @@ -1,6 +1,6 @@ using System.Threading.Tasks; using Content.Server.GameObjects.Components; -using Content.Server.Wires.Components; +using Content.Server.WireHacking; using Content.Shared.Construction; using JetBrains.Annotations; using Robust.Shared.GameObjects; diff --git a/Content.Server/Conveyor/ConveyorComponent.cs b/Content.Server/Conveyor/ConveyorComponent.cs index 55e8465154..31983f36ef 100644 --- a/Content.Server/Conveyor/ConveyorComponent.cs +++ b/Content.Server/Conveyor/ConveyorComponent.cs @@ -19,7 +19,7 @@ namespace Content.Server.Conveyor { public override string Name => "Conveyor"; - [ViewVariables] private bool Powered => !Owner.TryGetComponent(out PowerReceiverComponent? receiver) || receiver.Powered; + [ViewVariables] private bool Powered => !Owner.TryGetComponent(out ApcPowerReceiverComponent? receiver) || receiver.Powered; /// /// The angle to move entities by in relation to the owner's rotation. @@ -105,7 +105,7 @@ namespace Content.Server.Conveyor return false; } - if (Owner.TryGetComponent(out PowerReceiverComponent? receiver) && + if (Owner.TryGetComponent(out ApcPowerReceiverComponent? receiver) && !receiver.Powered) { return false; diff --git a/Content.Server/DeviceNetwork/Connections/WiredNetworkConnection.cs b/Content.Server/DeviceNetwork/Connections/WiredNetworkConnection.cs index c49abd3d61..710de4ea34 100644 --- a/Content.Server/DeviceNetwork/Connections/WiredNetworkConnection.cs +++ b/Content.Server/DeviceNetwork/Connections/WiredNetworkConnection.cs @@ -26,7 +26,7 @@ namespace Content.Server.DeviceNetwork.Connections return false; } - if (_owner.TryGetComponent(out var powerReceiver) + if (_owner.TryGetComponent(out var powerReceiver) && TryGetWireNet(powerReceiver, out var ownNet) && metadata.TryParseMetadata(WIRENET, out var senderNet)) { @@ -44,7 +44,7 @@ namespace Content.Server.DeviceNetwork.Connections return new Metadata(); } - if (_owner.TryGetComponent(out var powerReceiver) + if (_owner.TryGetComponent(out var powerReceiver) && TryGetWireNet(powerReceiver, out var net)) { var metadata = new Metadata @@ -63,16 +63,16 @@ namespace Content.Server.DeviceNetwork.Connections return payload; } - private bool TryGetWireNet(PowerReceiverComponent powerReceiver, [NotNullWhen(true)] out INodeGroup? net) + private bool TryGetWireNet(ApcPowerReceiverComponent apcPowerReceiver, [NotNullWhen(true)] out INodeGroup? net) { - if (powerReceiver.Provider is PowerProviderComponent provider && - provider.ProviderOwner.TryGetComponent(out var nodeContainer)) + var provider = apcPowerReceiver.Provider; + if (provider != null && provider.ProviderOwner.TryGetComponent(out var nodeContainer)) { var nodes = nodeContainer.Nodes; foreach (var node in nodes.Values) { - if (node.NodeGroupID == NodeGroupID.WireNet) + if (node.NodeGroupID == NodeGroupID.WireNet && node.NodeGroup != null) { net = node.NodeGroup; return true; diff --git a/Content.Server/Disposal/Mailing/DisposalMailingUnitComponent.cs b/Content.Server/Disposal/Mailing/DisposalMailingUnitComponent.cs index 806ca63dec..bc202065f2 100644 --- a/Content.Server/Disposal/Mailing/DisposalMailingUnitComponent.cs +++ b/Content.Server/Disposal/Mailing/DisposalMailingUnitComponent.cs @@ -117,7 +117,7 @@ namespace Content.Server.Disposal.Mailing [ViewVariables] public bool Powered => - !Owner.TryGetComponent(out PowerReceiverComponent? receiver) || + !Owner.TryGetComponent(out ApcPowerReceiverComponent? receiver) || receiver.Powered; [ViewVariables] @@ -372,7 +372,7 @@ namespace Content.Server.Disposal.Mailing private void TogglePower() { - if (!Owner.TryGetComponent(out PowerReceiverComponent? receiver)) + if (!Owner.TryGetComponent(out ApcPowerReceiverComponent? receiver)) { return; } diff --git a/Content.Server/Disposal/Unit/Components/DisposalUnitComponent.cs b/Content.Server/Disposal/Unit/Components/DisposalUnitComponent.cs index 7d483e4399..c040169240 100644 --- a/Content.Server/Disposal/Unit/Components/DisposalUnitComponent.cs +++ b/Content.Server/Disposal/Unit/Components/DisposalUnitComponent.cs @@ -107,7 +107,7 @@ namespace Content.Server.Disposal.Unit.Components [ViewVariables] public bool Powered => - !Owner.TryGetComponent(out PowerReceiverComponent? receiver) || + !Owner.TryGetComponent(out ApcPowerReceiverComponent? receiver) || receiver.Powered; [ViewVariables] @@ -314,7 +314,7 @@ namespace Content.Server.Disposal.Unit.Components private void TogglePower() { - if (!Owner.TryGetComponent(out PowerReceiverComponent? receiver)) + if (!Owner.TryGetComponent(out ApcPowerReceiverComponent? receiver)) { return; } diff --git a/Content.Server/Doors/Components/AirlockComponent.cs b/Content.Server/Doors/Components/AirlockComponent.cs index d810e71c0b..ae59d4a65c 100644 --- a/Content.Server/Doors/Components/AirlockComponent.cs +++ b/Content.Server/Doors/Components/AirlockComponent.cs @@ -3,7 +3,7 @@ using System; using System.Threading; using Content.Server.Power.Components; using Content.Server.VendingMachines; -using Content.Server.Wires.Components; +using Content.Server.WireHacking; using Content.Shared.Doors; using Content.Shared.Interaction; using Content.Shared.Notification; @@ -36,7 +36,7 @@ namespace Content.Server.Doors.Components private readonly SharedAppearanceComponent? _appearanceComponent = null; [ComponentDependency] - private readonly PowerReceiverComponent? _receiverComponent = null; + private readonly ApcPowerReceiverComponent? _receiverComponent = null; [ComponentDependency] private readonly WiresComponent? _wiresComponent = null; diff --git a/Content.Server/Gravity/GravityGeneratorComponent.cs b/Content.Server/Gravity/GravityGeneratorComponent.cs index 207f032697..b148562c72 100644 --- a/Content.Server/Gravity/GravityGeneratorComponent.cs +++ b/Content.Server/Gravity/GravityGeneratorComponent.cs @@ -26,7 +26,7 @@ namespace Content.Server.Gravity private GravityGeneratorStatus _status; - public bool Powered => !Owner.TryGetComponent(out PowerReceiverComponent? receiver) || receiver.Powered; + public bool Powered => !Owner.TryGetComponent(out ApcPowerReceiverComponent? receiver) || receiver.Powered; public bool SwitchedOn => _switchedOn; diff --git a/Content.Server/IoC/ServerContentIoC.cs b/Content.Server/IoC/ServerContentIoC.cs index 3a9682d0b3..e6f5d5238a 100644 --- a/Content.Server/IoC/ServerContentIoC.cs +++ b/Content.Server/IoC/ServerContentIoC.cs @@ -50,7 +50,6 @@ namespace Content.Server.IoC IoCManager.Register(); IoCManager.Register(); IoCManager.Register(); - IoCManager.Register(); IoCManager.Register(); IoCManager.Register(); IoCManager.Register(); diff --git a/Content.Server/Kitchen/Components/MicrowaveComponent.cs b/Content.Server/Kitchen/Components/MicrowaveComponent.cs index 26ff81bc50..a6453558c5 100644 --- a/Content.Server/Kitchen/Components/MicrowaveComponent.cs +++ b/Content.Server/Kitchen/Components/MicrowaveComponent.cs @@ -67,7 +67,7 @@ namespace Content.Server.Kitchen.Components [ViewVariables] private uint _currentCookTimerTime = 1; - private bool Powered => !Owner.TryGetComponent(out PowerReceiverComponent? receiver) || receiver.Powered; + private bool Powered => !Owner.TryGetComponent(out ApcPowerReceiverComponent? receiver) || receiver.Powered; private bool _hasContents => Owner.TryGetComponent(out SolutionContainerComponent? solution) && (solution.ReagentList.Count > 0 || _storage.ContainedEntities.Count > 0); private bool _uiDirty = true; private bool _lostPower = false; diff --git a/Content.Server/Kitchen/Components/ReagentGrinderComponent.cs b/Content.Server/Kitchen/Components/ReagentGrinderComponent.cs index 2ea4a7a955..4a9ff99166 100644 --- a/Content.Server/Kitchen/Components/ReagentGrinderComponent.cs +++ b/Content.Server/Kitchen/Components/ReagentGrinderComponent.cs @@ -53,7 +53,7 @@ namespace Content.Server.Kitchen.Components [ViewVariables] private bool HasBeaker => _beakerContainer.ContainedEntity != null; [ViewVariables] private BoundUserInterface? UserInterface => Owner.GetUIOrNull(ReagentGrinderUiKey.Key); - private bool Powered => !Owner.TryGetComponent(out PowerReceiverComponent? receiver) || receiver.Powered; + private bool Powered => !Owner.TryGetComponent(out ApcPowerReceiverComponent? receiver) || receiver.Powered; /// /// Should the BoundUI be told to update? diff --git a/Content.Server/Lathe/Components/LatheComponent.cs b/Content.Server/Lathe/Components/LatheComponent.cs index 0bd32992d2..f5494064b8 100644 --- a/Content.Server/Lathe/Components/LatheComponent.cs +++ b/Content.Server/Lathe/Components/LatheComponent.cs @@ -42,7 +42,7 @@ namespace Content.Server.Lathe.Components [ViewVariables] private LatheRecipePrototype? _producingRecipe; [ViewVariables] - private bool Powered => !Owner.TryGetComponent(out PowerReceiverComponent? receiver) || receiver.Powered; + private bool Powered => !Owner.TryGetComponent(out ApcPowerReceiverComponent? receiver) || receiver.Powered; private static readonly TimeSpan InsertionTime = TimeSpan.FromSeconds(0.9f); diff --git a/Content.Server/Light/Components/EmergencyLightComponent.cs b/Content.Server/Light/Components/EmergencyLightComponent.cs index 667ba5c925..f775c18e52 100644 --- a/Content.Server/Light/Components/EmergencyLightComponent.cs +++ b/Content.Server/Light/Components/EmergencyLightComponent.cs @@ -1,9 +1,9 @@ #nullable enable using System; using System.Collections.Generic; -using Content.Server.Battery.Components; using Content.Server.Power.Components; using Content.Shared.Examine; +using Content.Shared.Light.Component; using Robust.Server.GameObjects; using Robust.Shared.GameObjects; using Robust.Shared.Localization; @@ -60,7 +60,7 @@ namespace Content.Server.Light.Components /// public void UpdateState() { - if (!Owner.TryGetComponent(out PowerReceiverComponent? receiver)) + if (!Owner.TryGetComponent(out ApcPowerReceiverComponent? receiver)) { return; } @@ -80,7 +80,7 @@ namespace Content.Server.Light.Components public void OnUpdate(float frameTime) { - if (Owner.Deleted || !Owner.TryGetComponent(out BatteryComponent? battery)) + if (Owner.Deleted || !Owner.TryGetComponent(out BatteryComponent? battery) || Owner.Paused) { return; } @@ -96,9 +96,9 @@ namespace Content.Server.Light.Components else { battery.CurrentCharge += _chargingWattage * frameTime * _chargingEfficiency; - if (battery.BatteryState == BatteryState.Full) + if (battery.IsFullyCharged) { - if (Owner.TryGetComponent(out PowerReceiverComponent? receiver)) + if (Owner.TryGetComponent(out ApcPowerReceiverComponent? receiver)) { receiver.Load = 1; } @@ -110,28 +110,24 @@ namespace Content.Server.Light.Components private void TurnOff() { - if (Owner.TryGetComponent(out SpriteComponent? sprite)) - { - sprite.LayerSetState(0, "emergency_light_off"); - } - if (Owner.TryGetComponent(out PointLightComponent? light)) { light.Enabled = false; } + + if (Owner.TryGetComponent(out AppearanceComponent? appearance)) + appearance.SetData(EmergencyLightVisuals.On, false); } private void TurnOn() { - if (Owner.TryGetComponent(out SpriteComponent? sprite)) - { - sprite.LayerSetState(0, "emergency_light_on"); - } - if (Owner.TryGetComponent(out PointLightComponent? light)) { light.Enabled = true; } + + if (Owner.TryGetComponent(out AppearanceComponent? appearance)) + appearance.SetData(EmergencyLightVisuals.On, true); } public override void HandleMessage(ComponentMessage message, IComponent? component) diff --git a/Content.Server/Light/Components/PoweredLightComponent.cs b/Content.Server/Light/Components/PoweredLightComponent.cs index 2bc11a73f4..3e5ecd5b19 100644 --- a/Content.Server/Light/Components/PoweredLightComponent.cs +++ b/Content.Server/Light/Components/PoweredLightComponent.cs @@ -198,7 +198,7 @@ namespace Content.Server.Light.Components /// public void UpdateLight() { - var powerReceiver = Owner.GetComponent(); + var powerReceiver = Owner.GetComponent(); if (LightBulb == null) // No light bulb. { diff --git a/Content.Server/Medical/Components/MedicalScannerComponent.cs b/Content.Server/Medical/Components/MedicalScannerComponent.cs index bc677a2503..0ee7e60964 100644 --- a/Content.Server/Medical/Components/MedicalScannerComponent.cs +++ b/Content.Server/Medical/Components/MedicalScannerComponent.cs @@ -48,7 +48,7 @@ namespace Content.Server.Medical.Components private readonly Vector2 _ejectOffset = new(0f, 0f); [ViewVariables] - private bool Powered => !Owner.TryGetComponent(out PowerReceiverComponent? receiver) || receiver.Powered; + private bool Powered => !Owner.TryGetComponent(out ApcPowerReceiverComponent? receiver) || receiver.Powered; [ViewVariables] private BoundUserInterface? UserInterface => Owner.GetUIOrNull(MedicalScannerUiKey.Key); diff --git a/Content.Server/NodeContainer/EntitySystems/NodeContainerSystem.cs b/Content.Server/NodeContainer/EntitySystems/NodeContainerSystem.cs index 519ddee323..19b9de4415 100644 --- a/Content.Server/NodeContainer/EntitySystems/NodeContainerSystem.cs +++ b/Content.Server/NodeContainer/EntitySystems/NodeContainerSystem.cs @@ -11,16 +11,51 @@ namespace Content.Server.NodeContainer.EntitySystems { base.Initialize(); + SubscribeLocalEvent(OnInitEvent); + SubscribeLocalEvent(OnStartupEvent); + SubscribeLocalEvent(OnShutdownEvent); SubscribeLocalEvent(OnAnchorStateChanged); SubscribeLocalEvent(OnRotateEvent); } - private void OnAnchorStateChanged(EntityUid uid, NodeContainerComponent component, AnchorStateChangedEvent args) + private static void OnInitEvent(EntityUid uid, NodeContainerComponent component, ComponentInit args) { - component.AnchorUpdate(); + foreach (var (key, node) in component.Nodes) + { + node.Name = key; + node.Initialize(component.Owner); + } } - private void OnRotateEvent(EntityUid uid, NodeContainerComponent container, RotateEvent ev) + private static void OnStartupEvent(EntityUid uid, NodeContainerComponent component, ComponentStartup args) + { + foreach (var node in component.Nodes.Values) + { + node.OnContainerStartup(); + } + } + + private static void OnShutdownEvent(EntityUid uid, NodeContainerComponent component, ComponentShutdown args) + { + foreach (var node in component.Nodes.Values) + { + node.OnContainerShutdown(); + } + } + + private static void OnAnchorStateChanged( + EntityUid uid, + NodeContainerComponent component, + AnchorStateChangedEvent args) + { + foreach (var node in component.Nodes.Values) + { + node.AnchorUpdate(); + node.AnchorStateChanged(); + } + } + + private static void OnRotateEvent(EntityUid uid, NodeContainerComponent container, RotateEvent ev) { if (ev.NewRotation == ev.OldRotation) { diff --git a/Content.Server/NodeContainer/EntitySystems/NodeGroupSystem.cs b/Content.Server/NodeContainer/EntitySystems/NodeGroupSystem.cs index c4a0a5e0a0..ca24e0f8fb 100644 --- a/Content.Server/NodeContainer/EntitySystems/NodeGroupSystem.cs +++ b/Content.Server/NodeContainer/EntitySystems/NodeGroupSystem.cs @@ -1,30 +1,385 @@ using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using Content.Server.Administration.Managers; using Content.Server.NodeContainer.NodeGroups; +using Content.Server.NodeContainer.Nodes; +using Content.Shared.Administration; +using Content.Shared.NodeContainer; using JetBrains.Annotations; +using Robust.Server.Player; +using Robust.Shared.Enums; using Robust.Shared.GameObjects; +using Robust.Shared.IoC; +using Robust.Shared.Log; +using Robust.Shared.Maths; +using Robust.Shared.Utility; namespace Content.Server.NodeContainer.EntitySystems { [UsedImplicitly] public class NodeGroupSystem : EntitySystem { - private readonly HashSet _dirtyNodeGroups = new(); + [Dependency] private readonly IEntityManager _entityManager = default!; - public void AddDirtyNodeGroup(INodeGroup nodeGroup) + [Dependency] private readonly IPlayerManager _playerManager = default!; + [Dependency] private readonly IAdminManager _adminManager = default!; + [Dependency] private readonly INodeGroupFactory _nodeGroupFactory = default!; + [Dependency] private readonly ILogManager _logManager = default!; + + private readonly List _visDeletes = new(); + private readonly List _visSends = new(); + + private readonly HashSet _visPlayers = new(); + private readonly HashSet _toRemake = new(); + private readonly HashSet _toRemove = new(); + private readonly List _toReflood = new(); + + private ISawmill _sawmill = default!; + + public bool VisEnabled => _visPlayers.Count != 0; + + private int _gen = 1; + private int _groupNetIdCounter = 1; + + public override void Initialize() { - _dirtyNodeGroups.Add(nodeGroup); + base.Initialize(); + + _sawmill = _logManager.GetSawmill("nodegroup"); + + _playerManager.PlayerStatusChanged += OnPlayerStatusChanged; + + SubscribeNetworkEvent(HandleEnableMsg); + } + + public override void Shutdown() + { + base.Shutdown(); + + _playerManager.PlayerStatusChanged -= OnPlayerStatusChanged; + } + + private void HandleEnableMsg(NodeVis.MsgEnable msg, EntitySessionEventArgs args) + { + var session = (IPlayerSession) args.SenderSession; + if (!_adminManager.HasAdminFlag(session, AdminFlags.Debug)) + return; + + if (msg.Enabled) + { + _visPlayers.Add(session); + VisSendFullStateImmediate(session); + } + else + { + _visPlayers.Remove(session); + } + } + + private void OnPlayerStatusChanged(object? sender, SessionStatusEventArgs e) + { + if (e.NewStatus == SessionStatus.Disconnected) + _visPlayers.Remove(e.Session); + } + + public void QueueRemakeGroup(BaseNodeGroup group) + { + if (group.Remaking) + return; + + _toRemake.Add(group); + group.Remaking = true; + + foreach (var node in group.Nodes) + { + QueueReflood(node); + } + } + + public void QueueReflood(Node node) + { + if (node.FlaggedForFlood) + return; + + _toReflood.Add(node); + node.FlaggedForFlood = true; + } + + public void QueueNodeRemove(Node node) + { + _toRemove.Add(node); + } + + public void CreateSingleNetImmediate(Node node) + { + if (node.NodeGroup != null) + return; + + QueueReflood(node); + + InitGroup(node, new List {node}); } public override void Update(float frameTime) { base.Update(frameTime); - foreach (var group in _dirtyNodeGroups) + DoGroupUpdates(); + VisDoUpdate(); + } + + private void DoGroupUpdates() + { + // "Why is there a separate queue for group remakes and node refloods when they both cause eachother" + // Future planning for the potential ability to do more intelligent group updating. + + if (_toRemake.Count == 0 && _toReflood.Count == 0 && _toRemove.Count == 0) + return; + + var sw = Stopwatch.StartNew(); + + foreach (var toRemove in _toRemove) { - group.RemakeGroup(); + if (toRemove.NodeGroup == null) + continue; + + var group = (BaseNodeGroup) toRemove.NodeGroup; + + group.RemoveNode(toRemove); + toRemove.NodeGroup = null; + + QueueRemakeGroup(group); } - _dirtyNodeGroups.Clear(); + // Break up all remaking groups. + // Don't clear the list yet, we'll come back to these later. + foreach (var toRemake in _toRemake) + { + QueueRemakeGroup(toRemake); + } + + _gen += 1; + + // Go over all nodes to calculate reachable nodes and make an undirected graph out of them. + // Node.GetReachableNodes() may return results asymmetrically, + // i.e. node A may return B, but B may not return A. + // + // Must be for loop to allow concurrent modification from RemakeGroupImmediate. + for (var i = 0; i < _toReflood.Count; i++) + { + var node = _toReflood[i]; + + if (node.Deleting) + continue; + + ClearReachableIfNecessary(node); + + if (node.NodeGroup?.Remaking == false) + { + QueueRemakeGroup((BaseNodeGroup) node.NodeGroup); + } + + foreach (var compatible in GetCompatibleNodes(node)) + { + ClearReachableIfNecessary(compatible); + + if (compatible.NodeGroup?.Remaking == false) + { + // We are expanding into an existing group, + // remake it so that we can treat it uniformly. + var group = (BaseNodeGroup) compatible.NodeGroup; + QueueRemakeGroup(group); + } + + node.ReachableNodes.Add(compatible); + compatible.ReachableNodes.Add(node); + } + } + + var newGroups = new List(); + + // Flood fill over nodes. Every node will only be flood filled once. + foreach (var node in _toReflood) + { + node.FlaggedForFlood = false; + + // Check if already flood filled. + if (node.FloodGen == _gen || node.Deleting) + continue; + + // Flood fill + var groupNodes = FloodFillNode(node); + + var newGroup = InitGroup(node, groupNodes); + newGroups.Add(newGroup); + } + + // Go over dead groups that need to be cleaned up. + // Tell them to push their data to new groups too. + foreach (var oldGroup in _toRemake) + { + // Group by the NEW group. + var newGrouped = oldGroup.Nodes.GroupBy(n => n.NodeGroup); + + oldGroup.Removed = true; + oldGroup.AfterRemake(newGrouped); + if (VisEnabled) + _visDeletes.Add(oldGroup.NetId); + } + + var refloodCount = _toReflood.Count; + + _toReflood.Clear(); + _toRemake.Clear(); + _toRemove.Clear(); + + foreach (var group in newGroups) + { + foreach (var node in group.Nodes) + { + node.OnPostRebuild(); + } + } + + _sawmill.Debug($"Updated node groups in {sw.Elapsed.TotalMilliseconds}ms. {newGroups.Count} new groups, {refloodCount} nodes processed."); + } + + private void ClearReachableIfNecessary(Node node) + { + if (node.UndirectGen != _gen) + { + node.ReachableNodes.Clear(); + node.UndirectGen = _gen; + } + } + + private BaseNodeGroup InitGroup(Node node, List groupNodes) + { + var newGroup = (BaseNodeGroup) _nodeGroupFactory.MakeNodeGroup(node.NodeGroupID); + newGroup.Initialize(node); + newGroup.NetId = _groupNetIdCounter++; + + var netIdCounter = 0; + foreach (var groupNode in groupNodes) + { + groupNode.NodeGroup = newGroup; + groupNode.NetId = ++netIdCounter; + } + + newGroup.LoadNodes(groupNodes); + + if (VisEnabled) + _visSends.Add(newGroup); + + return newGroup; + } + + private List FloodFillNode(Node rootNode) + { + // All nodes we're filling into that currently have NO network. + var allNodes = new List(); + + var stack = new Stack(); + stack.Push(rootNode); + rootNode.FloodGen = _gen; + + while (stack.TryPop(out var node)) + { + allNodes.Add(node); + + foreach (var reachable in node.ReachableNodes) + { + if (reachable.FloodGen == _gen) + continue; + + reachable.FloodGen = _gen; + stack.Push(reachable); + } + } + + return allNodes; + } + + private static IEnumerable GetCompatibleNodes(Node node) + { + foreach (var reachable in node.GetReachableNodes()) + { + DebugTools.Assert(reachable != node, "GetReachableNodes() should not include self."); + + if (reachable.Connectable && reachable.NodeGroupID == node.NodeGroupID) + yield return reachable; + } + } + + private void VisDoUpdate() + { + if (_visSends.Count == 0 && _visDeletes.Count == 0) + return; + + var msg = new NodeVis.MsgData(); + + msg.GroupDeletions.AddRange(_visDeletes); + msg.Groups.AddRange(_visSends.Select(VisMakeGroupState)); + + _visSends.Clear(); + _visDeletes.Clear(); + + foreach (var player in _visPlayers) + { + RaiseNetworkEvent(msg, player.ConnectedClient); + } + } + + private void VisSendFullStateImmediate(IPlayerSession player) + { + var msg = new NodeVis.MsgData(); + + var allNetworks = ComponentManager + .EntityQuery() + .SelectMany(nc => nc.Nodes.Values) + .Select(n => (BaseNodeGroup?) n.NodeGroup) + .Where(n => n != null) + .Distinct(); + + foreach (var network in allNetworks) + { + msg.Groups.Add(VisMakeGroupState(network!)); + } + + RaiseNetworkEvent(msg, player.ConnectedClient); + } + + private static NodeVis.GroupData VisMakeGroupState(BaseNodeGroup group) + { + return new() + { + NetId = group.NetId, + GroupId = group.GroupId.ToString(), + Color = CalcNodeGroupColor(group), + Nodes = group.Nodes.Select(n => new NodeVis.NodeDatum + { + Name = n.Name, + NetId = n.NetId, + Reachable = n.ReachableNodes.Select(r => r.NetId).ToArray(), + Entity = n.Owner.Uid, + Type = n.GetType().Name + }).ToArray() + }; + } + + private static Color CalcNodeGroupColor(BaseNodeGroup group) + { + return group.GroupId switch + { + NodeGroupID.HVPower => Color.Orange, + NodeGroupID.MVPower => Color.Yellow, + NodeGroupID.Apc => Color.LimeGreen, + NodeGroupID.AMEngine => Color.Purple, + NodeGroupID.Pipe => Color.Blue, + NodeGroupID.WireNet => Color.DarkMagenta, + _ => Color.White + }; } } } diff --git a/Content.Server/NodeContainer/NodeContainerComponent.cs b/Content.Server/NodeContainer/NodeContainerComponent.cs index 2c1e4841bf..b0943f7cb6 100644 --- a/Content.Server/NodeContainer/NodeContainerComponent.cs +++ b/Content.Server/NodeContainer/NodeContainerComponent.cs @@ -20,60 +20,18 @@ namespace Content.Server.NodeContainer { public override string Name => "NodeContainer"; - [ViewVariables] - public IReadOnlyDictionary Nodes => _nodes; + [DataField("nodes")] [ViewVariables] public Dictionary Nodes { get; } = new(); - [DataField("nodes")] - private readonly Dictionary _nodes = new(); - - [DataField("examinable")] - private bool _examinable = false; - - protected override void Initialize() - { - base.Initialize(); - foreach (var node in _nodes.Values) - { - node.Initialize(Owner); - } - } - - protected override void Startup() - { - base.Startup(); - foreach (var node in _nodes.Values) - { - node.OnContainerStartup(); - } - } - - protected override void Shutdown() - { - base.Shutdown(); - - foreach (var node in _nodes.Values) - { - node.OnContainerShutdown(); - } - } - - public void AnchorUpdate() - { - foreach (var node in Nodes.Values) - { - node.AnchorUpdate(); - node.AnchorStateChanged(); - } - } + [DataField("examinable")] private bool _examinable = false; public T GetNode(string identifier) where T : Node { - return (T)_nodes[identifier]; + return (T) Nodes[identifier]; } public bool TryGetNode(string identifier, [NotNullWhen(true)] out T? node) where T : Node { - if (_nodes.TryGetValue(identifier, out var n) && n is T t) + if (Nodes.TryGetValue(identifier, out var n) && n is T t) { node = t; return true; diff --git a/Content.Server/NodeContainer/NodeGroups/BaseNetConnectorNodeGroup.cs b/Content.Server/NodeContainer/NodeGroups/BaseNetConnectorNodeGroup.cs deleted file mode 100644 index bee595ac19..0000000000 --- a/Content.Server/NodeContainer/NodeGroups/BaseNetConnectorNodeGroup.cs +++ /dev/null @@ -1,37 +0,0 @@ -#nullable enable -using System.Collections.Generic; -using System.Linq; -using Content.Server.NodeContainer.Nodes; -using Content.Server.Power.Components; - -namespace Content.Server.NodeContainer.NodeGroups -{ - public abstract class BaseNetConnectorNodeGroup : BaseNodeGroup where TNetConnector : BaseNetConnectorComponent - { - private readonly Dictionary> _netConnectorComponents = new(); - - protected override void OnAddNode(Node node) - { - var newNetConnectorComponents = node.Owner - .GetAllComponents() - .Where(powerComp => (NodeGroupID) powerComp.Voltage == node.NodeGroupID) - .ToList(); - _netConnectorComponents[node] = newNetConnectorComponents; - foreach (var netConnectorComponent in newNetConnectorComponents) - { - SetNetConnectorNet(netConnectorComponent); - } - } - - protected abstract void SetNetConnectorNet(TNetConnector netConnectorComponent); - - protected override void OnRemoveNode(Node node) - { - foreach (var netConnectorComponent in _netConnectorComponents[node]) - { - netConnectorComponent.ClearNet(); - } - _netConnectorComponents.Remove(node); - } - } -} diff --git a/Content.Server/NodeContainer/NodeGroups/BaseNodeGroup.cs b/Content.Server/NodeContainer/NodeGroups/BaseNodeGroup.cs new file mode 100644 index 0000000000..133c8c3a33 --- /dev/null +++ b/Content.Server/NodeContainer/NodeGroups/BaseNodeGroup.cs @@ -0,0 +1,91 @@ +#nullable enable +using System.Collections.Generic; +using System.Linq; +using Content.Server.NodeContainer.EntitySystems; +using Content.Server.NodeContainer.Nodes; +using Robust.Shared.GameObjects; +using Robust.Shared.Map; +using Robust.Shared.ViewVariables; + +namespace Content.Server.NodeContainer.NodeGroups +{ + /// + /// Maintains a collection of s, and performs operations requiring a list of + /// all connected s. + /// + public interface INodeGroup + { + bool Remaking { get; } + + IReadOnlyList Nodes { get; } + + void Create(NodeGroupID groupId); + + void Initialize(Node sourceNode); + + void RemoveNode(Node node); + + void LoadNodes(List groupNodes); + + // In theory, the SS13 curse ensures this method will never be called. + void AfterRemake(IEnumerable> newGroups); + + // TODO: Why is this method needed? + void QueueRemake(); + } + + [NodeGroup(NodeGroupID.Default, NodeGroupID.WireNet)] + public class BaseNodeGroup : INodeGroup + { + public bool Remaking { get; set; } + + IReadOnlyList INodeGroup.Nodes => Nodes; + + [ViewVariables] public readonly List Nodes = new(); + + [ViewVariables] public int NodeCount => Nodes.Count; + + /// + /// Debug variable to indicate that this NodeGroup should not be being used by anything. + /// + [ViewVariables] + public bool Removed { get; set; } = false; + + [ViewVariables] + protected GridId GridId { get; private set; } + + [ViewVariables] + public int NetId; + + [ViewVariables] + public NodeGroupID GroupId { get; private set; } + + public void Create(NodeGroupID groupId) + { + GroupId = groupId; + } + + public virtual void Initialize(Node sourceNode) + { + // TODO: Can we get rid of this GridId? + GridId = sourceNode.Owner.Transform.GridID; + } + + public virtual void RemoveNode(Node node) + { + } + + public virtual void LoadNodes( + List groupNodes) + { + Nodes.AddRange(groupNodes); + } + + public virtual void AfterRemake(IEnumerable> newGroups) { } + + public void QueueRemake() + { + EntitySystem.Get().QueueRemakeGroup(this); + } + } +} diff --git a/Content.Server/NodeContainer/NodeGroups/INodeGroup.cs b/Content.Server/NodeContainer/NodeGroups/INodeGroup.cs deleted file mode 100644 index bc8868bc11..0000000000 --- a/Content.Server/NodeContainer/NodeGroups/INodeGroup.cs +++ /dev/null @@ -1,132 +0,0 @@ -#nullable enable -using System.Collections.Generic; -using Content.Server.NodeContainer.EntitySystems; -using Content.Server.NodeContainer.Nodes; -using Robust.Shared.GameObjects; -using Robust.Shared.Map; -using Robust.Shared.ViewVariables; - -namespace Content.Server.NodeContainer.NodeGroups -{ - /// - /// Maintains a collection of s, and performs operations requiring a list of - /// all connected s. - /// - public interface INodeGroup - { - IReadOnlyList Nodes { get; } - - void Initialize(Node sourceNode); - - void AddNode(Node node); - - void RemoveNode(Node node); - - void CombineGroup(INodeGroup newGroup); - - void RemakeGroup(); - } - - [NodeGroup(NodeGroupID.Default, NodeGroupID.WireNet)] - public class BaseNodeGroup : INodeGroup - { - [ViewVariables] - public IReadOnlyList Nodes => _nodes; - private readonly List _nodes = new(); - - [ViewVariables] - public int NodeCount => Nodes.Count; - - /// - /// Debug variable to indicate that this NodeGroup should not be being used by anything. - /// - [ViewVariables] - public bool Removed { get; private set; } = false; - - public static readonly INodeGroup NullGroup = new NullNodeGroup(); - - protected GridId GridId { get; private set;} - - public virtual void Initialize(Node sourceNode) - { - GridId = sourceNode.Owner.Transform.GridID; - } - - public void AddNode(Node node) - { - _nodes.Add(node); - OnAddNode(node); - } - - public void RemoveNode(Node node) - { - _nodes.Remove(node); - OnRemoveNode(node); - EntitySystem.Get().AddDirtyNodeGroup(this); - } - - public void CombineGroup(INodeGroup newGroup) - { - if (newGroup.Nodes.Count < Nodes.Count) - { - newGroup.CombineGroup(this); - return; - } - - OnGivingNodesForCombine(newGroup); - - foreach (var node in Nodes) - { - node.NodeGroup = newGroup; - } - - Removed = true; - } - - /// - /// Causes all s to remake their groups. Called when a is removed - /// and may have split a group in two, so multiple new groups may need to be formed. - /// - public void RemakeGroup() - { - foreach (var node in Nodes) - { - node.ClearNodeGroup(); - } - - var newGroups = new HashSet(); - - foreach (var node in Nodes) - { - if (node.TryAssignGroupIfNeeded()) - { - node.SpreadGroup(); - newGroups.Add(node.NodeGroup); - } - } - - AfterRemake(newGroups); - - Removed = true; - } - - protected virtual void OnAddNode(Node node) { } - - protected virtual void OnRemoveNode(Node node) { } - - protected virtual void OnGivingNodesForCombine(INodeGroup newGroup) { } - - protected virtual void AfterRemake(IEnumerable newGroups) { } - - protected class NullNodeGroup : INodeGroup - { - public IReadOnlyList Nodes => _nodes; - private readonly List _nodes = new(); - public void Initialize(Node sourceNode) { } - public void AddNode(Node node) { } - public void CombineGroup(INodeGroup newGroup) { } - public void RemoveNode(Node node) { } - public void RemakeGroup() { } - } - } -} diff --git a/Content.Server/NodeContainer/NodeGroups/NodeGroupAttribute.cs b/Content.Server/NodeContainer/NodeGroups/NodeGroupAttribute.cs index d41b8dc265..27ef01eafc 100644 --- a/Content.Server/NodeContainer/NodeGroups/NodeGroupAttribute.cs +++ b/Content.Server/NodeContainer/NodeGroups/NodeGroupAttribute.cs @@ -1,5 +1,6 @@ #nullable enable using System; +using JetBrains.Annotations; namespace Content.Server.NodeContainer.NodeGroups { @@ -9,6 +10,7 @@ namespace Content.Server.NodeContainer.NodeGroups /// have the same type of . Used by . /// [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)] + [MeansImplicitUse] public class NodeGroupAttribute : Attribute { public NodeGroupID[] NodeGroupIDs { get; } diff --git a/Content.Server/NodeContainer/NodeGroups/NodeGroupFactory.cs b/Content.Server/NodeContainer/NodeGroups/NodeGroupFactory.cs index 0391439ec3..33b81a55d5 100644 --- a/Content.Server/NodeContainer/NodeGroups/NodeGroupFactory.cs +++ b/Content.Server/NodeContainer/NodeGroups/NodeGroupFactory.cs @@ -19,7 +19,7 @@ namespace Content.Server.NodeContainer.NodeGroups /// /// Returns a new instance. /// - INodeGroup MakeNodeGroup(Node sourceNode); + INodeGroup MakeNodeGroup(NodeGroupID id); } public class NodeGroupFactory : INodeGroupFactory @@ -45,15 +45,14 @@ namespace Content.Server.NodeContainer.NodeGroups } } - public INodeGroup MakeNodeGroup(Node sourceNode) + public INodeGroup MakeNodeGroup(NodeGroupID id) { - if (_groupTypes.TryGetValue(sourceNode.NodeGroupID, out var type)) - { - var nodeGroup = _typeFactory.CreateInstance(type); - nodeGroup.Initialize(sourceNode); - return nodeGroup; - } - throw new ArgumentException($"{sourceNode.NodeGroupID} did not have an associated {nameof(INodeGroup)}."); + if (!_groupTypes.TryGetValue(id, out var type)) + throw new ArgumentException($"{id} did not have an associated {nameof(INodeGroup)} implementation."); + + var instance = _typeFactory.CreateInstance(type); + instance.Create(id); + return instance; } } diff --git a/Content.Server/NodeContainer/NodeGroups/IPipeNet.cs b/Content.Server/NodeContainer/NodeGroups/PipeNet.cs similarity index 51% rename from Content.Server/NodeContainer/NodeGroups/IPipeNet.cs rename to Content.Server/NodeContainer/NodeGroups/PipeNet.cs index ed740b39a4..573694cdd6 100644 --- a/Content.Server/NodeContainer/NodeGroups/IPipeNet.cs +++ b/Content.Server/NodeContainer/NodeGroups/PipeNet.cs @@ -1,14 +1,15 @@ #nullable enable using System; using System.Collections.Generic; +using System.Linq; using Content.Server.Atmos; using Content.Server.Atmos.Components; using Content.Server.Atmos.EntitySystems; -using Content.Server.GameObjects.Components.NodeContainer.Nodes; using Content.Server.Interfaces; using Content.Server.NodeContainer.Nodes; using Content.Shared.Atmos; using Robust.Shared.GameObjects; +using Robust.Shared.Maths; using Robust.Shared.ViewVariables; namespace Content.Server.NodeContainer.NodeGroups @@ -24,17 +25,15 @@ namespace Content.Server.NodeContainer.NodeGroups [NodeGroup(NodeGroupID.Pipe)] public class PipeNet : BaseNodeGroup, IPipeNet { - [ViewVariables] - public GasMixture Air { get; set; } = new() {Temperature = Atmospherics.T20C}; + [ViewVariables] public GasMixture Air { get; set; } = new() {Temperature = Atmospherics.T20C}; - public static readonly IPipeNet NullNet = new NullPipeNet(); - - [ViewVariables] - private readonly List _pipes = new(); + [ViewVariables] private readonly List _pipes = new(); [ViewVariables] private AtmosphereSystem? _atmosphereSystem; - [ViewVariables] private IGridAtmosphereComponent? GridAtmos => _atmosphereSystem?.GetGridAtmosphere(GridId); + [ViewVariables] + private IGridAtmosphereComponent? GridAtmos => + _atmosphereSystem?.GetGridAtmosphere(GridId); public override void Initialize(Node sourceNode) { @@ -49,35 +48,30 @@ namespace Content.Server.NodeContainer.NodeGroups _atmosphereSystem?.React(Air, this); } - protected override void OnAddNode(Node node) + public override void LoadNodes(List groupNodes) { - if (node is not PipeNode pipeNode) - return; + base.LoadNodes(groupNodes); - _pipes.Add(pipeNode); - pipeNode.JoinPipeNet(this); - Air.Volume += pipeNode.Volume; + foreach (var node in groupNodes) + { + var pipeNode = (PipeNode) node; + _pipes.Add(pipeNode); + pipeNode.JoinPipeNet(this); + Air.Volume += pipeNode.Volume; + } } - protected override void OnRemoveNode(Node node) + public override void RemoveNode(Node node) { - RemoveFromGridAtmos(); - if (node is not PipeNode pipeNode) - return; + base.RemoveNode(node); - pipeNode.ClearPipeNet(); + var pipeNode = (PipeNode) node; + Air.Volume -= pipeNode.Volume; + // TODO: Bad O(n^2) _pipes.Remove(pipeNode); } - protected override void OnGivingNodesForCombine(INodeGroup newGroup) - { - if (newGroup is not IPipeNet newPipeNet) - return; - - EntitySystem.Get().Merge(newPipeNet.Air, Air); - } - - protected override void AfterRemake(IEnumerable newGroups) + public override void AfterRemake(IEnumerable> newGroups) { RemoveFromGridAtmos(); @@ -86,14 +80,15 @@ namespace Content.Server.NodeContainer.NodeGroups foreach (var newGroup in newGroups) { - if (newGroup is not IPipeNet newPipeNet) + if (newGroup.Key is not IPipeNet newPipeNet) continue; var newAir = newPipeNet.Air; + var newVolume = newGroup.Cast().Sum(n => n.Volume); buffer.Clear(); atmosphereSystem.Merge(buffer, Air); - buffer.Multiply(MathF.Min(newAir.Volume / Air.Volume, 1f)); + buffer.Multiply(MathF.Min(newVolume / Air.Volume, 1f)); atmosphereSystem.Merge(newAir, buffer); } } @@ -102,20 +97,5 @@ namespace Content.Server.NodeContainer.NodeGroups { GridAtmos?.RemovePipeNet(this); } - - private class NullPipeNet : NullNodeGroup, IPipeNet - { - private readonly GasMixture _air; - - GasMixture IGasMixtureHolder.Air { get => _air; set { } } - - public NullPipeNet() - { - _air = new GasMixture(1f) {Temperature = Atmospherics.T20C}; - _air.MarkImmutable(); - } - - public void Update() { } - } } } diff --git a/Content.Server/NodeContainer/NodeGroups/PowerNetNodeGroup.cs b/Content.Server/NodeContainer/NodeGroups/PowerNetNodeGroup.cs deleted file mode 100644 index 331a3de40f..0000000000 --- a/Content.Server/NodeContainer/NodeGroups/PowerNetNodeGroup.cs +++ /dev/null @@ -1,164 +0,0 @@ -#nullable enable -using System; -using System.Collections.Generic; -using System.Diagnostics; -using Content.Server.Power.Components; -using Robust.Shared.IoC; -using Robust.Shared.ViewVariables; - -namespace Content.Server.NodeContainer.NodeGroups -{ - public interface IPowerNet - { - void AddSupplier(PowerSupplierComponent supplier); - - void RemoveSupplier(PowerSupplierComponent supplier); - - void UpdateSupplierSupply(PowerSupplierComponent supplier, int oldSupplyRate, int newSupplyRate); - - void AddConsumer(PowerConsumerComponent consumer); - - void RemoveConsumer(PowerConsumerComponent consumer); - - void UpdateConsumerDraw(PowerConsumerComponent consumer, int oldDrawRate, int newDrawRate); - - void UpdateConsumerPriority(PowerConsumerComponent consumer, Priority oldPriority, Priority newPriority); - - void UpdateConsumerReceivedPower(); - } - - [NodeGroup(NodeGroupID.HVPower, NodeGroupID.MVPower)] - public class PowerNetNodeGroup : BaseNetConnectorNodeGroup, IPowerNet - { - private static readonly Priority[] CachedPriorities = (Priority[]) Enum.GetValues(typeof(Priority)); - - [Dependency] private readonly IPowerNetManager _powerNetManager = default!; - - [ViewVariables] - private readonly List _suppliers = new(); - - [ViewVariables] - private int _totalSupply = 0; - - [ViewVariables] - private readonly Dictionary> _consumersByPriority = new(); - - [ViewVariables] - private readonly Dictionary _drawByPriority = new(); - - public static readonly IPowerNet NullNet = new NullPowerNet(); - - public PowerNetNodeGroup() - { - foreach (Priority priority in Enum.GetValues(typeof(Priority))) - { - _consumersByPriority.Add(priority, new List()); - _drawByPriority.Add(priority, 0); - } - } - - protected override void SetNetConnectorNet(BasePowerNetComponent netConnectorComponent) - { - netConnectorComponent.Net = this; - } - - #region IPowerNet Methods - - public void AddSupplier(PowerSupplierComponent supplier) - { - _suppliers.Add(supplier); - _totalSupply += supplier.SupplyRate; - _powerNetManager.AddDirtyPowerNet(this); - } - - public void RemoveSupplier(PowerSupplierComponent supplier) - { - Debug.Assert(_suppliers.Contains(supplier)); - _suppliers.Remove(supplier); - _totalSupply -= supplier.SupplyRate; - _powerNetManager.AddDirtyPowerNet(this); - } - - public void UpdateSupplierSupply(PowerSupplierComponent supplier, int oldSupplyRate, int newSupplyRate) - { - Debug.Assert(_suppliers.Contains(supplier)); - _totalSupply -= oldSupplyRate; - _totalSupply += newSupplyRate; - _powerNetManager.AddDirtyPowerNet(this); - } - - public void AddConsumer(PowerConsumerComponent consumer) - { - _consumersByPriority[consumer.Priority].Add(consumer); - _drawByPriority[consumer.Priority] += consumer.DrawRate; - _powerNetManager.AddDirtyPowerNet(this); - } - - public void RemoveConsumer(PowerConsumerComponent consumer) - { - Debug.Assert(_consumersByPriority[consumer.Priority].Contains(consumer)); - consumer.ReceivedPower = 0; - _consumersByPriority[consumer.Priority].Remove(consumer); - _drawByPriority[consumer.Priority] -= consumer.DrawRate; - _powerNetManager.AddDirtyPowerNet(this); - } - - public void UpdateConsumerDraw(PowerConsumerComponent consumer, int oldDrawRate, int newDrawRate) - { - Debug.Assert(_consumersByPriority[consumer.Priority].Contains(consumer)); - _drawByPriority[consumer.Priority] -= oldDrawRate; - _drawByPriority[consumer.Priority] += newDrawRate; - _powerNetManager.AddDirtyPowerNet(this); - } - - public void UpdateConsumerPriority(PowerConsumerComponent consumer, Priority oldPriority, Priority newPriority) - { - Debug.Assert(_consumersByPriority[oldPriority].Contains(consumer)); - _consumersByPriority[oldPriority].Remove(consumer); - _drawByPriority[oldPriority] -= consumer.DrawRate; - _consumersByPriority[newPriority].Add(consumer); - _drawByPriority[newPriority] += consumer.DrawRate; - _powerNetManager.AddDirtyPowerNet(this); - } - - public void UpdateConsumerReceivedPower() - { - var remainingSupply = _totalSupply; - foreach (var priority in CachedPriorities) - { - var categoryPowerDemand = _drawByPriority[priority]; - if (remainingSupply >= categoryPowerDemand) //can fully power all in category - { - remainingSupply -= categoryPowerDemand; - foreach (var consumer in _consumersByPriority[priority]) - { - consumer.ReceivedPower = consumer.DrawRate; - } - } - else //cannot fully power all, split power - { - var availiablePowerFraction = (float) remainingSupply / categoryPowerDemand; - remainingSupply = 0; - foreach (var consumer in _consumersByPriority[priority]) - { - consumer.ReceivedPower = (int) (consumer.DrawRate * availiablePowerFraction); //give each consumer a fraction of what they requested (rounded down to nearest int) - } - } - } - } - - #endregion - - private class NullPowerNet : IPowerNet - { - public void AddConsumer(PowerConsumerComponent consumer) { } - public void AddSupplier(PowerSupplierComponent supplier) { } - public void UpdateSupplierSupply(PowerSupplierComponent supplier, int oldSupplyRate, int newSupplyRate) { } - public void RemoveConsumer(PowerConsumerComponent consumer) { } - public void RemoveSupplier(PowerSupplierComponent supplier) { } - public void UpdateConsumerDraw(PowerConsumerComponent consumer, int oldDrawRate, int newDrawRate) { } - public void UpdateConsumerPriority(PowerConsumerComponent consumer, Priority oldPriority, Priority newPriority) { } - public void UpdateConsumerReceivedPower() { } - } - } -} diff --git a/Content.Server/NodeContainer/Nodes/AdjacentNode.cs b/Content.Server/NodeContainer/Nodes/AdjacentNode.cs index 43e9c78c1d..c28589aec9 100644 --- a/Content.Server/NodeContainer/Nodes/AdjacentNode.cs +++ b/Content.Server/NodeContainer/Nodes/AdjacentNode.cs @@ -1,5 +1,6 @@ #nullable enable using System.Collections.Generic; +using Robust.Shared.GameObjects; using Robust.Shared.IoC; using Robust.Shared.Map; using Robust.Shared.Serialization.Manager.Attributes; @@ -12,29 +13,19 @@ namespace Content.Server.NodeContainer.Nodes [DataDefinition] public class AdjacentNode : Node { - protected override IEnumerable GetReachableNodes() + public override IEnumerable GetReachableNodes() { if (!Owner.Transform.Anchored) yield break; + var compMgr = IoCManager.Resolve(); var grid = IoCManager.Resolve().GetGrid(Owner.Transform.GridID); - var coords = Owner.Transform.Coordinates; - foreach (var cell in grid.GetCardinalNeighborCells(coords)) + var gridIndex = grid.TileIndicesFor(Owner.Transform.Coordinates); + + foreach (var (_, node) in NodeHelpers.GetCardinalNeighborNodes(compMgr, grid, gridIndex)) { - foreach (var entity in grid.GetLocal(Owner.EntityManager.GetEntity(cell).Transform.Coordinates)) - { - if (!Owner.EntityManager.GetEntity(entity).TryGetComponent(out var container)) - continue; - - foreach (var node in container.Nodes.Values) - { - if (node != null && node != this) - { - yield return node; - } - } - - } + if (node != this) + yield return node; } } } diff --git a/Content.Server/NodeContainer/Nodes/Node.cs b/Content.Server/NodeContainer/Nodes/Node.cs index 614a5bff4c..e427d0d8ec 100644 --- a/Content.Server/NodeContainer/Nodes/Node.cs +++ b/Content.Server/NodeContainer/Nodes/Node.cs @@ -1,11 +1,8 @@ #nullable enable using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; +using Content.Server.NodeContainer.EntitySystems; using Content.Server.NodeContainer.NodeGroups; using Robust.Shared.GameObjects; -using Robust.Shared.IoC; -using Robust.Shared.Physics; using Robust.Shared.Serialization.Manager.Attributes; using Robust.Shared.ViewVariables; @@ -26,20 +23,14 @@ namespace Content.Server.NodeContainer.Nodes [DataField("nodeGroupID")] public NodeGroupID NodeGroupID { get; private set; } = NodeGroupID.Default; - [ViewVariables] - public INodeGroup NodeGroup { get => _nodeGroup; set => SetNodeGroup(value); } - private INodeGroup _nodeGroup = BaseNodeGroup.NullGroup; + [ViewVariables] public INodeGroup? NodeGroup; - [ViewVariables] - public IEntity Owner { get; private set; } = default!; - - [ViewVariables] - private bool _needsGroup = true; + [ViewVariables] public IEntity Owner { get; private set; } = default!; /// /// If this node should be considered for connection by other nodes. /// - public bool Connectable => !_deleting && Anchored; + public bool Connectable => !Deleting && Anchored; protected bool Anchored => !NeedAnchored || Owner.Transform.Anchored; @@ -50,7 +41,15 @@ namespace Content.Server.NodeContainer.Nodes /// /// Prevents a node from being used by other nodes while midway through removal. /// - private bool _deleting; + public bool Deleting; + + public readonly HashSet ReachableNodes = new(); + + internal int FloodGen; + internal int UndirectGen; + internal bool FlaggedForFlood; + internal int NetId; + public string Name = default!; public virtual void Initialize(IEntity owner) { @@ -59,20 +58,23 @@ namespace Content.Server.NodeContainer.Nodes public virtual void OnContainerStartup() { - TryAssignGroupIfNeeded(); - CombineGroupWithReachable(); + EntitySystem.Get().QueueReflood(this); + } + + public void CreateSingleNetImmediate() + { + EntitySystem.Get().CreateSingleNetImmediate(this); } public void AnchorUpdate() { if (Anchored) { - TryAssignGroupIfNeeded(); - CombineGroupWithReachable(); + EntitySystem.Get().QueueReflood(this); } else { - RemoveSelfFromGroup(); + EntitySystem.Get().QueueNodeRemove(this); } } @@ -80,107 +82,21 @@ namespace Content.Server.NodeContainer.Nodes { } + public virtual void OnPostRebuild() + { + + } + public virtual void OnContainerShutdown() { - _deleting = true; - NodeGroup.RemoveNode(this); - } - - public bool TryAssignGroupIfNeeded() - { - if (!_needsGroup || !Connectable) - { - return false; - } - NodeGroup = GetReachableCompatibleGroups().FirstOrDefault() ?? MakeNewGroup(); - return true; - } - - public void SpreadGroup() - { - Debug.Assert(!_needsGroup); - foreach (var node in GetReachableCompatibleNodes()) - { - if (node._needsGroup) - { - node.NodeGroup = NodeGroup; - node.SpreadGroup(); - } - } - } - - public void ClearNodeGroup() - { - _nodeGroup = BaseNodeGroup.NullGroup; - _needsGroup = true; - } - - protected void RefreshNodeGroup() - { - RemoveSelfFromGroup(); - TryAssignGroupIfNeeded(); - CombineGroupWithReachable(); + Deleting = true; + EntitySystem.Get().QueueNodeRemove(this); } /// /// How this node will attempt to find other reachable s to group with. /// Returns a set of s to consider grouping with. Should not return this current . /// - protected abstract IEnumerable GetReachableNodes(); - - private IEnumerable GetReachableCompatibleNodes() - { - foreach (var node in GetReachableNodes()) - { - if (node.NodeGroupID == NodeGroupID && node.Connectable) - { - yield return node; - } - } - } - - private IEnumerable GetReachableCompatibleGroups() - { - foreach (var node in GetReachableCompatibleNodes()) - { - if (!node._needsGroup) - { - var group = node.NodeGroup; - if (group != NodeGroup) - { - yield return group; - } - } - } - } - - private void CombineGroupWithReachable() - { - if (_needsGroup || !Connectable) - return; - - foreach (var group in GetReachableCompatibleGroups()) - { - NodeGroup.CombineGroup(group); - } - } - - private void SetNodeGroup(INodeGroup newGroup) - { - _nodeGroup = newGroup; - NodeGroup.AddNode(this); - _needsGroup = false; - } - - private INodeGroup MakeNewGroup() - { - return IoCManager.Resolve().MakeNodeGroup(this); - } - - private void RemoveSelfFromGroup() - { - NodeGroup.RemoveNode(this); - ClearNodeGroup(); - } + public abstract IEnumerable GetReachableNodes(); } } diff --git a/Content.Server/NodeContainer/Nodes/NodeHelpers.cs b/Content.Server/NodeContainer/Nodes/NodeHelpers.cs new file mode 100644 index 0000000000..115e5a276f --- /dev/null +++ b/Content.Server/NodeContainer/Nodes/NodeHelpers.cs @@ -0,0 +1,89 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using Robust.Shared.GameObjects; +using Robust.Shared.Map; +using Robust.Shared.Maths; + +namespace Content.Server.NodeContainer.Nodes +{ + /// + /// Helper utilities for implementing . + /// + public static class NodeHelpers + { + public static IEnumerable GetNodesInTile(IComponentManager compMgr, IMapGrid grid, Vector2i coords) + { + foreach (var entityUid in grid.GetAnchoredEntities(coords)) + { + if (!compMgr.TryGetComponent(entityUid, out NodeContainerComponent? container)) + continue; + + foreach (var node in container.Nodes.Values) + { + yield return node; + } + } + } + + public static IEnumerable<(Direction dir, Node node)> GetCardinalNeighborNodes( + IComponentManager compMgr, + IMapGrid grid, + Vector2i coords, + bool includeSameTile = true) + { + foreach (var (dir, entityUid) in GetCardinalNeighborCells(grid, coords, includeSameTile)) + { + if (!compMgr.TryGetComponent(entityUid, out NodeContainerComponent? container)) + continue; + + foreach (var node in container.Nodes.Values) + { + yield return (dir, node); + } + } + } + + [SuppressMessage("ReSharper", "EnforceForeachStatementBraces")] + public static IEnumerable<(Direction dir, EntityUid entity)> GetCardinalNeighborCells( + IMapGrid grid, + Vector2i coords, + bool includeSameTile = true) + { + if (includeSameTile) + { + foreach (var uid in grid.GetAnchoredEntities(coords)) + yield return (Direction.Invalid, uid); + } + + foreach (var uid in grid.GetAnchoredEntities(coords + (0, 1))) + yield return (Direction.North, uid); + + foreach (var uid in grid.GetAnchoredEntities(coords + (0, -1))) + yield return (Direction.South, uid); + + foreach (var uid in grid.GetAnchoredEntities(coords + (1, 0))) + yield return (Direction.East, uid); + + foreach (var uid in grid.GetAnchoredEntities(coords + (-1, 0))) + yield return (Direction.West, uid); + } + + public static Vector2i TileOffsetForDir(Direction dir) + { + return dir switch + { + Direction.Invalid => (0, 0), + Direction.South => (0, -1), + Direction.SouthEast => (1, -1), + Direction.East => (1, 0), + Direction.NorthEast => (1, 1), + Direction.North => (0, 1), + Direction.NorthWest => (-1, 1), + Direction.West => (-1, 0), + Direction.SouthWest => (-1, -1), + _ => throw new ArgumentOutOfRangeException(nameof(dir), dir, null) + }; + } + } +} diff --git a/Content.Server/NodeContainer/Nodes/PipeNode.cs b/Content.Server/NodeContainer/Nodes/PipeNode.cs index 54f0c0fb54..68d093188c 100644 --- a/Content.Server/NodeContainer/Nodes/PipeNode.cs +++ b/Content.Server/NodeContainer/Nodes/PipeNode.cs @@ -3,9 +3,8 @@ using System.Collections.Generic; using Content.Server.Atmos; using Content.Server.Atmos.EntitySystems; using Content.Server.Interfaces; -using Content.Server.NodeContainer; +using Content.Server.NodeContainer.EntitySystems; using Content.Server.NodeContainer.NodeGroups; -using Content.Server.NodeContainer.Nodes; using Content.Shared.Atmos; using Robust.Server.GameObjects; using Robust.Shared.Containers; @@ -13,9 +12,10 @@ using Robust.Shared.GameObjects; using Robust.Shared.IoC; using Robust.Shared.Map; using Robust.Shared.Serialization.Manager.Attributes; +using Robust.Shared.Utility; using Robust.Shared.ViewVariables; -namespace Content.Server.GameObjects.Components.NodeContainer.Nodes +namespace Content.Server.NodeContainer.Nodes { /// /// Connects with other s whose @@ -63,21 +63,23 @@ namespace Content.Server.GameObjects.Components.NodeContainer.Nodes set { _connectionsEnabled = value; - RefreshNodeGroup(); + + if (NodeGroup != null) + EntitySystem.Get().QueueRemakeGroup((BaseNodeGroup) NodeGroup); } } + [DataField("connectionsEnabled")] + private bool _connectionsEnabled = true; + [DataField("rotationsEnabled")] public bool RotationsEnabled { get; set; } = true; /// - /// The this pipe is a part of. Set to when not in an . + /// The this pipe is a part of. /// [ViewVariables] - private IPipeNet _pipeNet = PipeNet.NullNet; - - [DataField("connectionsEnabled")] - private bool _connectionsEnabled = true; + private IPipeNet? PipeNet => (IPipeNet?) NodeGroup; /// /// Whether to ignore the pipenet and return the environment's air. @@ -92,8 +94,12 @@ namespace Content.Server.GameObjects.Components.NodeContainer.Nodes [ViewVariables] public GasMixture Air { - get => !EnvironmentalAir ? _pipeNet.Air : Owner.Transform.Coordinates.GetTileAir() ?? GasMixture.SpaceGas; - set => _pipeNet.Air = value; + get => (!EnvironmentalAir ? PipeNet?.Air : Owner.Transform.Coordinates.GetTileAir()) ?? GasMixture.SpaceGas; + set + { + DebugTools.Assert(PipeNet != null); + PipeNet!.Air = value; + } } public void AssumeAir(GasMixture giver) @@ -105,7 +111,7 @@ namespace Content.Server.GameObjects.Components.NodeContainer.Nodes return; } - EntitySystem.Get().Merge(_pipeNet.Air, giver); + EntitySystem.Get().Merge(PipeNet!.Air, giver); } [ViewVariables] @@ -128,13 +134,6 @@ namespace Content.Server.GameObjects.Components.NodeContainer.Nodes public void JoinPipeNet(IPipeNet pipeNet) { - _pipeNet = pipeNet; - OnConnectedDirectionsNeedsUpdating(); - } - - public void ClearPipeNet() - { - _pipeNet = PipeNet.NullNet; OnConnectedDirectionsNeedsUpdating(); } @@ -146,12 +145,11 @@ namespace Content.Server.GameObjects.Components.NodeContainer.Nodes if (!RotationsEnabled) return; var diff = ev.NewRotation - ev.OldRotation; PipeDirection = PipeDirection.RotatePipeDirection(diff); - RefreshNodeGroup(); OnConnectedDirectionsNeedsUpdating(); UpdateAppearance(); } - protected override IEnumerable GetReachableNodes() + public override IEnumerable GetReachableNodes() { for (var i = 0; i < PipeDirectionHelpers.AllPipeDirections; i++) { diff --git a/Content.Server/ParticleAccelerator/Components/ParticleAcceleratorControlBoxComponent.cs b/Content.Server/ParticleAccelerator/Components/ParticleAcceleratorControlBoxComponent.cs index b3ef6644ee..8562cccfbe 100644 --- a/Content.Server/ParticleAccelerator/Components/ParticleAcceleratorControlBoxComponent.cs +++ b/Content.Server/ParticleAccelerator/Components/ParticleAcceleratorControlBoxComponent.cs @@ -6,9 +6,10 @@ using System.Diagnostics.CodeAnalysis; using System.Threading; using Content.Server.Notification; using Content.Server.Power.Components; +using Content.Server.Power.EntitySystems; using Content.Server.UserInterface; using Content.Server.VendingMachines; -using Content.Server.Wires.Components; +using Content.Server.WireHacking; using Content.Shared.ActionBlocker; using Content.Shared.Interaction; using Content.Shared.Interaction.Events; @@ -47,7 +48,7 @@ namespace Content.Server.ParticleAccelerator.Components /// /// Power receiver for the control console itself. /// - [ViewVariables] private PowerReceiverComponent _powerReceiverComponent = default!; + [ViewVariables] private ApcPowerReceiverComponent _apcPowerReceiverComponent = default!; [ViewVariables] private ParticleAcceleratorFuelChamberComponent? _partFuelChamber; [ViewVariables] private ParticleAcceleratorEndCapComponent? _partEndCap; @@ -88,7 +89,7 @@ namespace Content.Server.ParticleAccelerator.Components [ViewVariables(VVAccess.ReadWrite)] [DataField("powerDrawBase")] private int _powerDrawBase = 500; [ViewVariables(VVAccess.ReadWrite)] [DataField("powerDrawMult")] private int _powerDrawMult = 1500; - [ViewVariables] private bool ConsolePowered => _powerReceiverComponent?.Powered ?? true; + [ViewVariables] private bool ConsolePowered => _apcPowerReceiverComponent?.Powered ?? true; public ParticleAcceleratorControlBoxComponent() { @@ -107,9 +108,9 @@ namespace Content.Server.ParticleAccelerator.Components UserInterface.OnReceiveMessage += UserInterfaceOnOnReceiveMessage; } - Owner.EnsureComponent(out _powerReceiverComponent); + Owner.EnsureComponent(out _apcPowerReceiverComponent); - _powerReceiverComponent!.Load = 250; + _apcPowerReceiverComponent!.Load = 250; } public override void HandleMessage(ComponentMessage message, IComponent? component) @@ -189,8 +190,8 @@ namespace Content.Server.ParticleAccelerator.Components public void UpdateUI() { - var draw = 0; - var receive = 0; + var draw = 0f; + var receive = 0f; if (_isEnabled) { @@ -202,8 +203,8 @@ namespace Content.Server.ParticleAccelerator.Components _isAssembled, _isEnabled, _selectedStrength, - draw, - receive, + (int) draw, + (int) receive, _partEmitterLeft != null, _partEmitterCenter != null, _partEmitterRight != null, @@ -577,7 +578,7 @@ namespace Content.Server.ParticleAccelerator.Components if (Owner.TryGetComponent(out AppearanceComponent? appearance)) { appearance.SetData(ParticleAcceleratorVisuals.VisualState, - _powerReceiverComponent!.Powered + _apcPowerReceiverComponent!.Powered ? (ParticleAcceleratorVisualState) _selectedStrength : ParticleAcceleratorVisualState.Unpowered); } @@ -645,7 +646,7 @@ namespace Content.Server.ParticleAccelerator.Components } * _powerDrawMult + _powerDrawBase; } - public void PowerBoxReceivedChanged(object? sender, ReceivedPowerChangedEventArgs eventArgs) + public void PowerBoxReceivedChanged(PowerConsumerReceivedChanged eventArgs) { DebugTools.Assert(_isAssembled); diff --git a/Content.Server/ParticleAccelerator/Components/ParticleAcceleratorPowerBoxComponent.cs b/Content.Server/ParticleAccelerator/Components/ParticleAcceleratorPowerBoxComponent.cs index c3f79a8be7..c37486bc81 100644 --- a/Content.Server/ParticleAccelerator/Components/ParticleAcceleratorPowerBoxComponent.cs +++ b/Content.Server/ParticleAccelerator/Components/ParticleAcceleratorPowerBoxComponent.cs @@ -17,12 +17,6 @@ namespace Content.Server.ParticleAccelerator.Components base.Initialize(); PowerConsumerComponent = Owner.EnsureComponentWarn(); - PowerConsumerComponent.OnReceivedPowerChanged += PowerReceivedChanged; - } - - private void PowerReceivedChanged(object? sender, ReceivedPowerChangedEventArgs e) - { - Master?.PowerBoxReceivedChanged(sender, e); } } } diff --git a/Content.Server/ParticleAccelerator/ParticleAcceleratorPartSystem.cs b/Content.Server/ParticleAccelerator/EntitySystems/ParticleAcceleratorPartSystem.cs similarity index 94% rename from Content.Server/ParticleAccelerator/ParticleAcceleratorPartSystem.cs rename to Content.Server/ParticleAccelerator/EntitySystems/ParticleAcceleratorPartSystem.cs index 10f386d959..79be10ebae 100644 --- a/Content.Server/ParticleAccelerator/ParticleAcceleratorPartSystem.cs +++ b/Content.Server/ParticleAccelerator/EntitySystems/ParticleAcceleratorPartSystem.cs @@ -3,7 +3,7 @@ using Content.Server.ParticleAccelerator.Components; using JetBrains.Annotations; using Robust.Shared.GameObjects; -namespace Content.Server.ParticleAccelerator +namespace Content.Server.ParticleAccelerator.EntitySystems { [UsedImplicitly] public class ParticleAcceleratorPartSystem : EntitySystem diff --git a/Content.Server/ParticleAccelerator/EntitySystems/ParticleAcceleratorPowerBoxSystem.cs b/Content.Server/ParticleAccelerator/EntitySystems/ParticleAcceleratorPowerBoxSystem.cs new file mode 100644 index 0000000000..92bef8bfeb --- /dev/null +++ b/Content.Server/ParticleAccelerator/EntitySystems/ParticleAcceleratorPowerBoxSystem.cs @@ -0,0 +1,27 @@ +using Content.Server.ParticleAccelerator.Components; +using Content.Server.Power.EntitySystems; +using JetBrains.Annotations; +using Robust.Shared.GameObjects; + +namespace Content.Server.ParticleAccelerator.EntitySystems +{ + [UsedImplicitly] + public class ParticleAcceleratorPowerBoxSystem : EntitySystem + { + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent( + PowerBoxReceivedChanged); + } + + private static void PowerBoxReceivedChanged( + EntityUid uid, + ParticleAcceleratorPowerBoxComponent component, + PowerConsumerReceivedChanged args) + { + component.Master!.PowerBoxReceivedChanged(args); + } + } +} diff --git a/Content.Server/Power/Commands/PowerStatCommand.cs b/Content.Server/Power/Commands/PowerStatCommand.cs new file mode 100644 index 0000000000..16be3b82a0 --- /dev/null +++ b/Content.Server/Power/Commands/PowerStatCommand.cs @@ -0,0 +1,26 @@ +using Content.Server.Administration; +using Content.Server.Power.EntitySystems; +using Content.Shared.Administration; +using Robust.Shared.Console; +using Robust.Shared.GameObjects; + +namespace Content.Server.Power.Commands +{ + [AdminCommand(AdminFlags.Debug)] + public sealed class PowerStatCommand : IConsoleCommand + { + public string Command => "powerstat"; + public string Description => "Shows statistics for pow3r"; + public string Help => "Usage: powerstat"; + + public void Execute(IConsoleShell shell, string argStr, string[] args) + { + var stats = EntitySystem.Get().GetStatistics(); + + shell.WriteLine($"networks: {stats.CountNetworks}"); + shell.WriteLine($"loads: {stats.CountLoads}"); + shell.WriteLine($"supplies: {stats.CountSupplies}"); + shell.WriteLine($"batteries: {stats.CountBatteries}"); + } + } +} diff --git a/Content.Server/APC/Components/ApcComponent.cs b/Content.Server/Power/Components/ApcComponent.cs similarity index 84% rename from Content.Server/APC/Components/ApcComponent.cs rename to Content.Server/Power/Components/ApcComponent.cs index 07df66a3fc..5182551775 100644 --- a/Content.Server/APC/Components/ApcComponent.cs +++ b/Content.Server/Power/Components/ApcComponent.cs @@ -1,23 +1,22 @@ #nullable enable using System; using Content.Server.Access.Components; -using Content.Server.Battery.Components; -using Content.Server.Power.Components; +using Content.Server.Power.NodeGroups; using Content.Server.UserInterface; using Content.Shared.APC; using Content.Shared.Interaction; -using Content.Shared.Notification; using Content.Shared.Notification.Managers; using Robust.Server.GameObjects; using Robust.Shared.Audio; using Robust.Shared.GameObjects; using Robust.Shared.IoC; using Robust.Shared.Localization; +using Robust.Shared.Maths; using Robust.Shared.Player; using Robust.Shared.Timing; using Robust.Shared.ViewVariables; -namespace Content.Server.APC.Components +namespace Content.Server.Power.Components { [RegisterComponent] [ComponentReference(typeof(IActivate))] @@ -57,7 +56,6 @@ namespace Content.Server.APC.Components { base.Initialize(); - Owner.EnsureComponent(); Owner.EnsureComponentWarn(); Owner.EnsureComponentWarn(); @@ -89,6 +87,8 @@ namespace Content.Server.APC.Components if (_accessReader == null || _accessReader.IsAllowed(user)) { MainBreakerEnabled = !MainBreakerEnabled; + Owner.GetComponent().CanDischarge = MainBreakerEnabled; + _uiDirty = true; SoundSystem.Play(Filter.Pvs(Owner), "/Audio/Machines/machine_switch.ogg", Owner, AudioParams.Default.WithVolume(-2f)); } @@ -153,44 +153,31 @@ namespace Content.Server.APC.Components return ApcChargeState.Full; } - if (!Owner.TryGetComponent(out PowerConsumerComponent? consumer)) - { - return ApcChargeState.Full; - } + var netBattery = Owner.GetComponent(); + var delta = netBattery.CurrentSupply - netBattery.CurrentReceiving; - if (consumer.DrawRate == consumer.ReceivedPower) - { - return ApcChargeState.Charging; - } - else - { - return ApcChargeState.Lack; - } + return delta < 0 ? ApcChargeState.Charging : ApcChargeState.Lack; } private ApcExternalPowerState CalcExtPowerState() { - if (!Owner.TryGetComponent(out BatteryStorageComponent? batteryStorage)) + var bat = Battery; + if (bat == null) + return ApcExternalPowerState.None; + + var netBat = Owner.GetComponent(); + if (netBat.CurrentReceiving == 0 && netBat.LoadingNetworkDemand != 0) { return ApcExternalPowerState.None; } - var consumer = batteryStorage.Consumer; - if (consumer == null) - return ApcExternalPowerState.None; - - if (consumer.ReceivedPower == 0 && consumer.DrawRate != 0) - { - return ApcExternalPowerState.None; - } - else if (consumer.ReceivedPower < consumer.DrawRate) + var delta = netBat.CurrentReceiving - netBat.LoadingNetworkDemand; + if (!MathHelper.CloseTo(delta, 0, 0.1f) && delta < 0) { return ApcExternalPowerState.Low; } - else - { - return ApcExternalPowerState.Good; - } + + return ApcExternalPowerState.Good; } void IActivate.Activate(ActivateEventArgs eventArgs) diff --git a/Content.Server/Power/Components/ApcPowerProviderComponent.cs b/Content.Server/Power/Components/ApcPowerProviderComponent.cs new file mode 100644 index 0000000000..c87e4b6c54 --- /dev/null +++ b/Content.Server/Power/Components/ApcPowerProviderComponent.cs @@ -0,0 +1,121 @@ +#nullable enable +using System; +using System.Collections.Generic; +using Content.Server.Power.NodeGroups; +using Robust.Shared.GameObjects; +using Robust.Shared.IoC; +using Robust.Shared.Serialization.Manager.Attributes; +using Robust.Shared.ViewVariables; + +namespace Content.Server.Power.Components +{ + [RegisterComponent] + public class ApcPowerProviderComponent : BaseApcNetComponent + { + public override string Name => "PowerProvider"; + + public IEntity ProviderOwner => Owner; + + /// + /// The max distance this can transmit power to s from. + /// + [ViewVariables(VVAccess.ReadWrite)] + public int PowerTransferRange { get => _powerTransferRange; set => SetPowerTransferRange(value); } + [DataField("powerTransferRange")] + private int _powerTransferRange = 3; + + [ViewVariables] public List LinkedReceivers { get; } = new(); + + /// + /// If s should consider connecting to this. + /// + [ViewVariables(VVAccess.ReadWrite)] + public bool Connectable { get; private set; } = true; + + public void AddReceiver(ApcPowerReceiverComponent receiver) + { + LinkedReceivers.Add(receiver); + receiver.NetworkLoad.LinkedNetwork = default; + + Net?.QueueNetworkReconnect(); + } + + public void RemoveReceiver(ApcPowerReceiverComponent receiver) + { + LinkedReceivers.Remove(receiver); + receiver.NetworkLoad.LinkedNetwork = default; + + Net?.QueueNetworkReconnect(); + } + + protected override void Startup() + { + base.Startup(); + + foreach (var receiver in FindAvailableReceivers()) + { + receiver.Provider = this; + } + } + + protected override void OnRemove() + { + Connectable = false; + var receivers = LinkedReceivers.ToArray(); + foreach (var receiver in receivers) + { + receiver.Provider = null; + } + foreach (var receiver in receivers) + { + receiver.TryFindAndSetProvider(); + } + base.OnRemove(); + } + + private IEnumerable FindAvailableReceivers() + { + var nearbyEntities = IoCManager.Resolve() + .GetEntitiesInRange(Owner, PowerTransferRange); + + foreach (var entity in nearbyEntities) + { + if (entity.TryGetComponent(out var receiver) && + receiver.Connectable && + receiver.NeedsProvider && + receiver.Owner.Transform.Coordinates.TryDistance(Owner.EntityManager, Owner.Transform.Coordinates, out var distance) && + distance < Math.Min(PowerTransferRange, receiver.PowerReceptionRange)) + { + yield return receiver; + } + } + } + + protected override void AddSelfToNet(IApcNet apcNet) + { + apcNet.AddPowerProvider(this); + } + + protected override void RemoveSelfFromNet(IApcNet apcNet) + { + apcNet.RemovePowerProvider(this); + } + + private void SetPowerTransferRange(int newPowerTransferRange) + { + var receivers = LinkedReceivers.ToArray(); + + foreach (var receiver in receivers) + { + receiver.Provider = null; + } + + _powerTransferRange = newPowerTransferRange; + + foreach (var receiver in receivers) + { + receiver.TryFindAndSetProvider(); + } + } + } +} diff --git a/Content.Server/Power/Components/PowerReceiverComponent.cs b/Content.Server/Power/Components/ApcPowerReceiverComponent.cs similarity index 65% rename from Content.Server/Power/Components/PowerReceiverComponent.cs rename to Content.Server/Power/Components/ApcPowerReceiverComponent.cs index 89d44c13a7..b95db5cc86 100644 --- a/Content.Server/Power/Components/PowerReceiverComponent.cs +++ b/Content.Server/Power/Components/ApcPowerReceiverComponent.cs @@ -1,12 +1,15 @@ #nullable enable using System; -using Content.Server.APC; +using System.Diagnostics.CodeAnalysis; +using Content.Server.Power.NodeGroups; +using Content.Server.Power.Pow3r; using Content.Shared.Examine; using Content.Shared.Power; using Robust.Server.GameObjects; using Robust.Shared.GameObjects; using Robust.Shared.IoC; using Robust.Shared.Localization; +using Robust.Shared.Maths; using Robust.Shared.Physics; using Robust.Shared.Serialization.Manager.Attributes; using Robust.Shared.Utility; @@ -15,26 +18,21 @@ using Robust.Shared.ViewVariables; namespace Content.Server.Power.Components { /// - /// Attempts to link with a nearby s so that it can receive power from a . + /// Attempts to link with a nearby s + /// so that it can receive power from a . /// [RegisterComponent] - public class PowerReceiverComponent : Component, IExamine + public class ApcPowerReceiverComponent : Component, IExamine { [ViewVariables] [ComponentDependency] private readonly IPhysBody? _physicsComponent = null; - public override string Name => "PowerReceiver"; + public override string Name => "ApcPowerReceiver"; [ViewVariables] - public bool Powered => (HasApcPower || !NeedsPower) && !PowerDisabled; + public bool Powered => (MathHelper.CloseTo(NetworkLoad.ReceivingPower, Load) || !NeedsPower) && !PowerDisabled; /// - /// If this is being powered by an Apc. - /// - [ViewVariables] - public bool HasApcPower { get; private set; } - - /// - /// The max distance from a that this can receive power from. + /// The max distance from a that this can receive power from. /// [ViewVariables(VVAccess.ReadWrite)] public int PowerReceptionRange { get => _powerReceptionRange; set => SetPowerReceptionRange(value); } @@ -42,32 +40,53 @@ namespace Content.Server.Power.Components private int _powerReceptionRange = 3; [ViewVariables] - public IPowerProvider Provider { get => _provider; set => SetProvider(value); } - private IPowerProvider _provider = PowerProviderComponent.NullProvider; + public ApcPowerProviderComponent? Provider + { + get => _provider; + set + { + // Will get updated before power networks process. + NetworkLoad.LinkedNetwork = default; + _provider?.RemoveReceiver(this); + _provider = value; + value?.AddReceiver(this); + ApcPowerChanged(); + } + } + + private ApcPowerProviderComponent? _provider; /// - /// If this should be considered for connection by s. + /// If this should be considered for connection by s. /// public bool Connectable => Anchored; private bool Anchored => _physicsComponent == null || _physicsComponent.BodyType == BodyType.Static; - [ViewVariables] - public bool NeedsProvider { get; private set; } = true; + [ViewVariables] public bool NeedsProvider => Provider == null; /// /// Amount of charge this needs from an APC per second to function. /// [ViewVariables(VVAccess.ReadWrite)] - public int Load { get => _load; set => SetLoad(value); } [DataField("powerLoad")] - private int _load = 5; + public float Load { get => NetworkLoad.DesiredPower; set => NetworkLoad.DesiredPower = value; } /// /// When false, causes this to appear powered even if not receiving power from an Apc. /// [ViewVariables(VVAccess.ReadWrite)] - public bool NeedsPower { get => _needsPower; set => SetNeedsPower(value); } + public bool NeedsPower + { + get => _needsPower; + set + { + _needsPower = value; + // Reset this so next tick will do a power update. + LastPowerReceived = float.NaN; + } + } + [DataField("needsPower")] private bool _needsPower = true; @@ -75,9 +94,16 @@ namespace Content.Server.Power.Components /// When true, causes this to never appear powered. /// [ViewVariables(VVAccess.ReadWrite)] - public bool PowerDisabled { get => _powerDisabled; set => SetPowerDisabled(value); } [DataField("powerDisabled")] - private bool _powerDisabled; + public bool PowerDisabled { get => !NetworkLoad.Enabled; set => NetworkLoad.Enabled = !value; } + + public float LastPowerReceived = float.NaN; + + [ViewVariables] + public PowerState.Load NetworkLoad { get; } = new PowerState.Load + { + DesiredPower = 5 + }; protected override void Startup() { @@ -94,7 +120,8 @@ namespace Content.Server.Power.Components protected override void OnRemove() { - _provider.RemoveReceiver(this); + _provider?.RemoveReceiver(this); + base.OnRemove(); } @@ -108,20 +135,17 @@ namespace Content.Server.Power.Components public void ApcPowerChanged() { - var oldPowered = Powered; - HasApcPower = Provider.HasApcPower; - if (Powered != oldPowered) - OnNewPowerState(); + OnNewPowerState(); } - private bool TryFindAvailableProvider(out IPowerProvider foundProvider) + private bool TryFindAvailableProvider([NotNullWhen(true)] out ApcPowerProviderComponent? foundProvider) { var nearbyEntities = IoCManager.Resolve() .GetEntitiesInRange(Owner, PowerReceptionRange); foreach (var entity in nearbyEntities) { - if (entity.TryGetComponent(out var provider)) + if (entity.TryGetComponent(out var provider)) { if (provider.Connectable) { @@ -136,60 +160,18 @@ namespace Content.Server.Power.Components } } } - foundProvider = default!; + + foundProvider = default; return false; } - public void ClearProvider() - { - _provider.RemoveReceiver(this); - _provider = PowerProviderComponent.NullProvider; - NeedsProvider = true; - ApcPowerChanged(); - } - - private void SetProvider(IPowerProvider newProvider) - { - _provider.RemoveReceiver(this); - _provider = newProvider; - newProvider.AddReceiver(this); - NeedsProvider = false; - ApcPowerChanged(); - } - private void SetPowerReceptionRange(int newPowerReceptionRange) { - ClearProvider(); + Provider = null; _powerReceptionRange = newPowerReceptionRange; TryFindAndSetProvider(); } - private void SetLoad(int newLoad) - { - Provider.UpdateReceiverLoad(Load, newLoad); - _load = newLoad; - } - - private void SetNeedsPower(bool newNeedsPower) - { - var oldPowered = Powered; - _needsPower = newNeedsPower; - if (oldPowered != Powered) - { - OnNewPowerState(); - } - } - - private void SetPowerDisabled(bool newPowerDisabled) - { - var oldPowered = Powered; - _powerDisabled = newPowerDisabled; - if (oldPowered != Powered) - { - OnNewPowerState(); - } - } - private void OnNewPowerState() { SendMessage(new PowerChangedMessage(Powered)); @@ -211,7 +193,7 @@ namespace Content.Server.Power.Components } else { - ClearProvider(); + Provider = null; } } diff --git a/Content.Server/Power/Components/BaseApcNetComponent.cs b/Content.Server/Power/Components/BaseApcNetComponent.cs new file mode 100644 index 0000000000..e004606107 --- /dev/null +++ b/Content.Server/Power/Components/BaseApcNetComponent.cs @@ -0,0 +1,9 @@ +#nullable enable +using Content.Server.Power.NodeGroups; + +namespace Content.Server.Power.Components +{ + public abstract class BaseApcNetComponent : BaseNetConnectorComponent + { + } +} diff --git a/Content.Server/Power/Components/BaseCharger.cs b/Content.Server/Power/Components/BaseCharger.cs index a438ad97cb..753e5d59e8 100644 --- a/Content.Server/Power/Components/BaseCharger.cs +++ b/Content.Server/Power/Components/BaseCharger.cs @@ -1,7 +1,6 @@ #nullable enable using System; using System.Threading.Tasks; -using Content.Server.Battery.Components; using Content.Server.Hands.Components; using Content.Server.Items; using Content.Server.Weapon.Ranged.Barrels.Components; @@ -45,7 +44,7 @@ namespace Content.Server.Power.Components { base.Initialize(); - Owner.EnsureComponent(); + Owner.EnsureComponent(); _container = ContainerHelpers.EnsureContainer(Owner, $"{Name}-powerCellContainer"); // Default state in the visualizer is OFF, so when this gets powered on during initialization it will generally show empty } @@ -191,7 +190,7 @@ namespace Content.Server.Power.Components private CellChargerStatus GetStatus() { - if (Owner.TryGetComponent(out PowerReceiverComponent? receiver) && + if (Owner.TryGetComponent(out ApcPowerReceiverComponent? receiver) && !receiver.Powered) { return CellChargerStatus.Off; @@ -234,7 +233,7 @@ namespace Content.Server.Power.Components // Not called UpdateAppearance just because it messes with the load var status = GetStatus(); if (_status == status || - !Owner.TryGetComponent(out PowerReceiverComponent? receiver)) + !Owner.TryGetComponent(out ApcPowerReceiverComponent? receiver)) { return; } @@ -279,7 +278,7 @@ namespace Content.Server.Power.Components private void TransferPower(float frameTime) { - if (Owner.TryGetComponent(out PowerReceiverComponent? receiver) && + if (Owner.TryGetComponent(out ApcPowerReceiverComponent? receiver) && !receiver.Powered) { return; diff --git a/Content.Server/Power/Components/BaseNetConnectorComponent.cs b/Content.Server/Power/Components/BaseNetConnectorComponent.cs index 017b80ca65..d24fb16191 100644 --- a/Content.Server/Power/Components/BaseNetConnectorComponent.cs +++ b/Content.Server/Power/Components/BaseNetConnectorComponent.cs @@ -17,23 +17,18 @@ namespace Content.Server.Power.Components private Voltage _voltage = Voltage.High; [ViewVariables] - public TNetType Net { get => _net; set => SetNet(value); } - private TNetType _net = default!; //set in OnAdd() - - protected abstract TNetType NullNet { get; } + public TNetType? Net { get => _net; set => SetNet(value); } + private TNetType? _net; [ViewVariables] - private bool _needsNet = true; + private bool _needsNet => _net != null; - protected override void OnAdd() - { - base.OnAdd(); - _net = NullNet; - } + [DataField("node")] [ViewVariables] public string? NodeId; protected override void Initialize() { base.Initialize(); + if (_needsNet) { TryFindAndSetNet(); @@ -56,9 +51,8 @@ namespace Content.Server.Power.Components public void ClearNet() { - RemoveSelfFromNet(_net); - _net = NullNet; - _needsNet = true; + if (_net != null) + RemoveSelfFromNet(_net); } protected abstract void AddSelfToNet(TNetType net); @@ -70,7 +64,7 @@ namespace Content.Server.Power.Components if (Owner.TryGetComponent(out var container)) { var compatibleNet = container.Nodes.Values - .Where(node => node.NodeGroupID == (NodeGroupID) Voltage) + .Where(node => (NodeId == null || NodeId == node.Name) && node.NodeGroupID == (NodeGroupID) Voltage) .Select(node => node.NodeGroup) .OfType() .FirstOrDefault(); @@ -85,12 +79,15 @@ namespace Content.Server.Power.Components return false; } - private void SetNet(TNetType newNet) + private void SetNet(TNetType? newNet) { - RemoveSelfFromNet(_net); - AddSelfToNet(newNet); + if (_net != null) + RemoveSelfFromNet(_net); + + if (newNet != null) + AddSelfToNet(newNet); + _net = newNet; - _needsNet = false; } private void SetVoltage(Voltage newVoltage) diff --git a/Content.Server/Power/Components/BasePowerNetComponent.cs b/Content.Server/Power/Components/BasePowerNetComponent.cs index 78e00cf9dd..c25715abb4 100644 --- a/Content.Server/Power/Components/BasePowerNetComponent.cs +++ b/Content.Server/Power/Components/BasePowerNetComponent.cs @@ -1,10 +1,10 @@ #nullable enable using Content.Server.NodeContainer.NodeGroups; +using Content.Server.Power.NodeGroups; namespace Content.Server.Power.Components { public abstract class BasePowerNetComponent : BaseNetConnectorComponent { - protected override IPowerNet NullNet => PowerNetNodeGroup.NullNet; } } diff --git a/Content.Server/Power/Components/BatteryChargerComponent.cs b/Content.Server/Power/Components/BatteryChargerComponent.cs new file mode 100644 index 0000000000..f6b472cdb4 --- /dev/null +++ b/Content.Server/Power/Components/BatteryChargerComponent.cs @@ -0,0 +1,24 @@ +using Content.Server.Power.NodeGroups; +using Robust.Shared.GameObjects; + +namespace Content.Server.Power.Components +{ + /// + /// Connects the loading side of a to a non-APC power network. + /// + [RegisterComponent] + public class BatteryChargerComponent : BasePowerNetComponent + { + public override string Name => "BatteryCharger"; + + protected override void AddSelfToNet(IPowerNet net) + { + net.AddCharger(this); + } + + protected override void RemoveSelfFromNet(IPowerNet net) + { + net.RemoveCharger(this); + } + } +} diff --git a/Content.Server/Battery/Components/BatteryComponent.cs b/Content.Server/Power/Components/BatteryComponent.cs similarity index 73% rename from Content.Server/Battery/Components/BatteryComponent.cs rename to Content.Server/Power/Components/BatteryComponent.cs index bc0ea33f65..480afbde0e 100644 --- a/Content.Server/Battery/Components/BatteryComponent.cs +++ b/Content.Server/Power/Components/BatteryComponent.cs @@ -5,8 +5,11 @@ using Robust.Shared.Maths; using Robust.Shared.Serialization.Manager.Attributes; using Robust.Shared.ViewVariables; -namespace Content.Server.Battery.Components +namespace Content.Server.Power.Components { + /// + /// Battery node on the pow3r network. Needs other components to connect to actual networks. + /// [RegisterComponent] public class BatteryComponent : Component { @@ -15,9 +18,9 @@ namespace Content.Server.Battery.Components /// /// Maximum charge of the battery in joules (ie. watt seconds) /// - [ViewVariables(VVAccess.ReadWrite)] public int MaxCharge { get => _maxCharge; set => SetMaxCharge(value); } + [ViewVariables(VVAccess.ReadWrite)] public float MaxCharge { get => _maxCharge; set => SetMaxCharge(value); } [DataField("maxCharge")] - private int _maxCharge = 1000; + private float _maxCharge; /// /// Current charge of the battery in joules (ie. watt seconds) @@ -25,7 +28,7 @@ namespace Content.Server.Battery.Components [ViewVariables(VVAccess.ReadWrite)] public float CurrentCharge { get => _currentCharge; set => SetCurrentCharge(value); } [DataField("startingCharge")] - private float _currentCharge = 500; + private float _currentCharge; /// /// True if the battery is fully charged. @@ -36,14 +39,6 @@ namespace Content.Server.Battery.Components [ViewVariables(VVAccess.ReadWrite)] [DataField("autoRechargeRate")] public float AutoRechargeRate { get; set; } - [ViewVariables] public BatteryState BatteryState { get; private set; } - - protected override void Initialize() - { - base.Initialize(); - UpdateStorageState(); - } - /// /// If sufficient charge is avaiable on the battery, use it. Otherwise, don't. /// @@ -83,34 +78,16 @@ namespace Content.Server.Battery.Components protected virtual void OnChargeChanged() { } - private void UpdateStorageState() - { - if (IsFullyCharged) - { - BatteryState = BatteryState.Full; - } - else if (CurrentCharge == 0) - { - BatteryState = BatteryState.Empty; - } - else - { - BatteryState = BatteryState.PartlyFull; - } - } - - private void SetMaxCharge(int newMax) + private void SetMaxCharge(float newMax) { _maxCharge = Math.Max(newMax, 0); _currentCharge = Math.Min(_currentCharge, MaxCharge); - UpdateStorageState(); OnChargeChanged(); } private void SetCurrentCharge(float newChargeAmount) { _currentCharge = MathHelper.Clamp(newChargeAmount, 0, MaxCharge); - UpdateStorageState(); OnChargeChanged(); } @@ -121,11 +98,4 @@ namespace Content.Server.Battery.Components CurrentCharge += AutoRechargeRate * frameTime; } } - - public enum BatteryState - { - Full, - PartlyFull, - Empty - } } diff --git a/Content.Server/Power/Components/BatteryDischargerComponent.cs b/Content.Server/Power/Components/BatteryDischargerComponent.cs index 62335e2727..37cb8dbe58 100644 --- a/Content.Server/Power/Components/BatteryDischargerComponent.cs +++ b/Content.Server/Power/Components/BatteryDischargerComponent.cs @@ -1,79 +1,21 @@ -#nullable enable -using Content.Server.Battery.Components; +using Content.Server.Power.NodeGroups; using Robust.Shared.GameObjects; -using Robust.Shared.Serialization.Manager.Attributes; -using Robust.Shared.ViewVariables; namespace Content.Server.Power.Components { - /// - /// Uses charge from a to supply power via a . - /// [RegisterComponent] - public class BatteryDischargerComponent : Component + public class BatteryDischargerComponent : BasePowerNetComponent { public override string Name => "BatteryDischarger"; - [ViewVariables] - [ComponentDependency] private BatteryComponent? _battery = default!; - - [ViewVariables] - [ComponentDependency] private PowerSupplierComponent? _supplier = default!; - - [ViewVariables(VVAccess.ReadWrite)] - public int ActiveSupplyRate { get => _activeSupplyRate; set => SetActiveSupplyRate(value); } - - [DataField("activeSupplyRate")] - private int _activeSupplyRate = 50; - - protected override void Initialize() + protected override void AddSelfToNet(IPowerNet net) { - base.Initialize(); - Owner.EnsureComponentWarn(); - UpdateSupplyRate(); + net.AddDischarger(this); } - public void Update(float frameTime) + protected override void RemoveSelfFromNet(IPowerNet net) { - if (_battery == null) - return; - - //Simplified implementation - if the battery is empty, and charge is being added to the battery - //at a lower rate that this is using it, the charge is used without creating power supply. - _battery.CurrentCharge -= ActiveSupplyRate * frameTime; - UpdateSupplyRate(); - } - - private void UpdateSupplyRate() - { - if (_battery == null) - return; - - if (_battery.BatteryState == BatteryState.Empty) - { - SetSupplierSupplyRate(0); - } - else - { - SetSupplierSupplyRate(ActiveSupplyRate); - } - } - - private void SetSupplierSupplyRate(int newSupplierSupplyRate) - { - if (_supplier == null) - return; - - if (_supplier.SupplyRate != newSupplierSupplyRate) - { - _supplier.SupplyRate = newSupplierSupplyRate; - } - } - - private void SetActiveSupplyRate(int newEnabledSupplyRate) - { - _activeSupplyRate = newEnabledSupplyRate; - UpdateSupplyRate(); + net.RemoveDischarger(this); } } } diff --git a/Content.Server/Power/Components/BatteryStorageComponent.cs b/Content.Server/Power/Components/BatteryStorageComponent.cs deleted file mode 100644 index daa1dba4d6..0000000000 --- a/Content.Server/Power/Components/BatteryStorageComponent.cs +++ /dev/null @@ -1,79 +0,0 @@ -#nullable enable -using Content.Server.Battery.Components; -using Robust.Shared.GameObjects; -using Robust.Shared.Serialization.Manager.Attributes; -using Robust.Shared.ViewVariables; - -namespace Content.Server.Power.Components -{ - /// - /// Takes power via a to charge a . - /// - [RegisterComponent] - public class BatteryStorageComponent : Component - { - public override string Name => "BatteryStorage"; - - [ViewVariables(VVAccess.ReadWrite)] - public int ActiveDrawRate { get => _activeDrawRate; set => SetActiveDrawRate(value); } - [DataField("activeDrawRate")] - private int _activeDrawRate = 100; - - [ViewVariables] - [ComponentDependency] private BatteryComponent? _battery = default!; - - [ViewVariables] - public PowerConsumerComponent? Consumer => _consumer; - - [ComponentDependency] private PowerConsumerComponent? _consumer = default!; - - protected override void Initialize() - { - base.Initialize(); - Owner.EnsureComponentWarn(); - UpdateDrawRate(); - } - - public void Update(float frameTime) - { - if (_consumer == null || _battery == null) - return; - - //Simplified implementation - If a frame adds more power to a partially full battery than it can hold, the power is lost. - _battery.CurrentCharge += _consumer.ReceivedPower * frameTime; - UpdateDrawRate(); - } - - private void UpdateDrawRate() - { - if (_battery == null) - return; - - if (_battery.BatteryState == BatteryState.Full) - { - SetConsumerDraw(0); - } - else - { - SetConsumerDraw(ActiveDrawRate); - } - } - - private void SetConsumerDraw(int newConsumerDrawRate) - { - if (_consumer == null) - return; - - if (_consumer.DrawRate != newConsumerDrawRate) - { - _consumer.DrawRate = newConsumerDrawRate; - } - } - - private void SetActiveDrawRate(int newEnabledDrawRate) - { - _activeDrawRate = newEnabledDrawRate; - UpdateDrawRate(); - } - } -} diff --git a/Content.Server/Wires/Components/WireComponent.cs b/Content.Server/Power/Components/CableComponent.cs similarity index 61% rename from Content.Server/Wires/Components/WireComponent.cs rename to Content.Server/Power/Components/CableComponent.cs index 473a6d8375..b95f790953 100644 --- a/Content.Server/Wires/Components/WireComponent.cs +++ b/Content.Server/Power/Components/CableComponent.cs @@ -3,45 +3,44 @@ using System.Threading.Tasks; using Content.Server.Stack; using Content.Server.Tools.Components; using Content.Shared.Interaction; -using Content.Shared.Stacks; using Content.Shared.Tool; using Robust.Shared.GameObjects; using Robust.Shared.Serialization.Manager.Attributes; using Robust.Shared.ViewVariables; -namespace Content.Server.Wires.Components +namespace Content.Server.Power.Components { /// - /// Allows the attached entity to be destroyed by a cutting tool, dropping a piece of wire. + /// Allows the attached entity to be destroyed by a cutting tool, dropping a piece of cable. /// [RegisterComponent] - public class WireComponent : Component, IInteractUsing + public class CableComponent : Component, IInteractUsing { - public override string Name => "Wire"; + public override string Name => "Cable"; [ViewVariables] - [DataField("wireDroppedOnCutPrototype")] - private string? _wireDroppedOnCutPrototype = "HVWireStack1"; + [DataField("cableDroppedOnCutPrototype")] + private string? _cableDroppedOnCutPrototype = "CableHVStack1"; /// - /// Checked by to determine if there is - /// already a wire of a type on a tile. + /// Checked by to determine if there is + /// already a cable of a type on a tile. /// [ViewVariables] - public WireType WireType => _wireType; - [DataField("wireType")] - private WireType _wireType = WireType.HighVoltage; + public CableType CableType => _cableType; + [DataField("cableType")] + private CableType _cableType = CableType.HighVoltage; async Task IInteractUsing.InteractUsing(InteractUsingEventArgs eventArgs) { - if (_wireDroppedOnCutPrototype == null) + if (_cableDroppedOnCutPrototype == null) return false; if (!eventArgs.Using.TryGetComponent(out var tool)) return false; if (!await tool.UseTool(eventArgs.User, Owner, 0.25f, ToolQuality.Cutting)) return false; Owner.Delete(); - var droppedEnt = Owner.EntityManager.SpawnEntity(_wireDroppedOnCutPrototype, eventArgs.ClickLocation); + var droppedEnt = Owner.EntityManager.SpawnEntity(_cableDroppedOnCutPrototype, eventArgs.ClickLocation); // TODO: Literally just use a prototype that has a single thing in the stack, it's not that complicated... if (droppedEnt.TryGetComponent(out var stack)) @@ -51,7 +50,7 @@ namespace Content.Server.Wires.Components } } - public enum WireType + public enum CableType { HighVoltage, MediumVoltage, diff --git a/Content.Server/Wires/Components/WirePlacerComponent.cs b/Content.Server/Power/Components/CablePlacerComponent.cs similarity index 73% rename from Content.Server/Wires/Components/WirePlacerComponent.cs rename to Content.Server/Power/Components/CablePlacerComponent.cs index 6b83e9de6c..a2eb805730 100644 --- a/Content.Server/Wires/Components/WirePlacerComponent.cs +++ b/Content.Server/Power/Components/CablePlacerComponent.cs @@ -9,28 +9,28 @@ using Robust.Shared.Map; using Robust.Shared.Serialization.Manager.Attributes; using Robust.Shared.ViewVariables; -namespace Content.Server.Wires.Components +namespace Content.Server.Power.Components { [RegisterComponent] - internal class WirePlacerComponent : Component, IAfterInteract + internal class CablePlacerComponent : Component, IAfterInteract { [Dependency] private readonly IMapManager _mapManager = default!; /// - public override string Name => "WirePlacer"; + public override string Name => "CablePlacer"; [ViewVariables] - [DataField("wirePrototypeID")] - private string? _wirePrototypeID = "HVWire"; + [DataField("cablePrototypeID")] + private string? _cablePrototypeID = "CableHV"; [ViewVariables] [DataField("blockingWireType")] - private WireType _blockingWireType = WireType.HighVoltage; + private CableType _blockingCableType = CableType.HighVoltage; /// async Task IAfterInteract.AfterInteract(AfterInteractEventArgs eventArgs) { - if (_wirePrototypeID == null) + if (_cablePrototypeID == null) return true; if (!eventArgs.InRangeUnobstructed(ignoreInsideBlocker: true, popup: true)) return true; @@ -41,7 +41,7 @@ namespace Content.Server.Wires.Components return true; foreach (var anchored in grid.GetAnchoredEntities(snapPos)) { - if (Owner.EntityManager.ComponentManager.TryGetComponent(anchored, out var wire) && wire.WireType == _blockingWireType) + if (Owner.EntityManager.ComponentManager.TryGetComponent(anchored, out var wire) && wire.CableType == _blockingCableType) { return true; } @@ -51,7 +51,7 @@ namespace Content.Server.Wires.Components && !EntitySystem.Get().Use(Owner.Uid, stack, 1)) return true; - Owner.EntityManager.SpawnEntity(_wirePrototypeID, grid.GridTileToLocal(snapPos)); + Owner.EntityManager.SpawnEntity(_cablePrototypeID, grid.GridTileToLocal(snapPos)); return true; } } diff --git a/Content.Server/Power/Components/CableVisComponent.cs b/Content.Server/Power/Components/CableVisComponent.cs new file mode 100644 index 0000000000..add61d7de5 --- /dev/null +++ b/Content.Server/Power/Components/CableVisComponent.cs @@ -0,0 +1,16 @@ +using Robust.Shared.GameObjects; +using Robust.Shared.Serialization.Manager.Attributes; +using Robust.Shared.ViewVariables; + +namespace Content.Server.Power.Components +{ + [RegisterComponent] + public sealed class CableVisComponent : Component + { + public override string Name => "CableVis"; + + [ViewVariables(VVAccess.ReadWrite)] + [DataField("node")] + public string? Node; + } +} diff --git a/Content.Server/Battery/Components/ExaminableBatteryComponent.cs b/Content.Server/Power/Components/ExaminableBatteryComponent.cs similarity index 96% rename from Content.Server/Battery/Components/ExaminableBatteryComponent.cs rename to Content.Server/Power/Components/ExaminableBatteryComponent.cs index 202572e568..e5da57a61c 100644 --- a/Content.Server/Battery/Components/ExaminableBatteryComponent.cs +++ b/Content.Server/Power/Components/ExaminableBatteryComponent.cs @@ -5,7 +5,7 @@ using Robust.Shared.Localization; using Robust.Shared.Utility; using Robust.Shared.ViewVariables; -namespace Content.Server.Battery.Components +namespace Content.Server.Power.Components { [RegisterComponent] public class ExaminableBatteryComponent : Component, IExamine diff --git a/Content.Server/Power/Components/IPowerNetManager.cs b/Content.Server/Power/Components/IPowerNetManager.cs deleted file mode 100644 index 51487f2297..0000000000 --- a/Content.Server/Power/Components/IPowerNetManager.cs +++ /dev/null @@ -1,39 +0,0 @@ -#nullable enable -using System.Collections.Generic; -using Content.Server.NodeContainer.NodeGroups; - -namespace Content.Server.Power.Components -{ - /// - /// Maintains a set of s that need to be updated with . - /// Defers updating to reduce recalculations when a group is altered multiple times in a frame. - /// - public interface IPowerNetManager - { - /// - /// Queue up an to be updated. - /// - void AddDirtyPowerNet(IPowerNet powerNet); - - void Update(float frameTime); - } - - public class PowerNetManager : IPowerNetManager - { - private readonly HashSet _dirtyPowerNets = new(); - - public void AddDirtyPowerNet(IPowerNet powerNet) - { - _dirtyPowerNets.Add(powerNet); - } - - public void Update(float frameTime) - { - foreach (var powerNet in _dirtyPowerNets) - { - powerNet.UpdateConsumerReceivedPower(); - } - _dirtyPowerNets.Clear(); - } - } -} diff --git a/Content.Server/Power/Components/PowerConsumerComponent.cs b/Content.Server/Power/Components/PowerConsumerComponent.cs index 94c3f2b064..a9c44434bd 100644 --- a/Content.Server/Power/Components/PowerConsumerComponent.cs +++ b/Content.Server/Power/Components/PowerConsumerComponent.cs @@ -1,13 +1,15 @@ #nullable enable -using System; -using System.Diagnostics; -using Content.Server.NodeContainer.NodeGroups; +using Content.Server.Power.NodeGroups; +using Content.Server.Power.Pow3r; using Robust.Shared.GameObjects; using Robust.Shared.Serialization.Manager.Attributes; using Robust.Shared.ViewVariables; namespace Content.Server.Power.Components { + /// + /// Draws power directly from an MV or HV wire it is on top of. + /// [RegisterComponent] public class PowerConsumerComponent : BasePowerNetComponent { @@ -16,28 +18,19 @@ namespace Content.Server.Power.Components /// /// How much power this needs to be fully powered. /// - [ViewVariables(VVAccess.ReadWrite)] - public int DrawRate { get => _drawRate; set => SetDrawRate(value); } [DataField("drawRate")] - private int _drawRate; - - /// - /// Determines which s receive power when there is not enough - /// power for each. - /// [ViewVariables(VVAccess.ReadWrite)] - public Priority Priority { get => _priority; set => SetPriority(value); } - [DataField("priority")] - private Priority _priority = Priority.First; + public float DrawRate { get => NetworkLoad.DesiredPower; set => NetworkLoad.DesiredPower = value; } /// /// How much power this is currently receiving from s. /// [ViewVariables] - public int ReceivedPower { get => _receivedPower; set => SetReceivedPower(value); } - private int _receivedPower; + public float ReceivedPower => NetworkLoad.ReceivingPower; - public event EventHandler? OnReceivedPowerChanged; + public float LastReceived = float.NaN; + + public PowerState.Load NetworkLoad { get; } = new(); protected override void AddSelfToNet(IPowerNet powerNet) { @@ -48,44 +41,5 @@ namespace Content.Server.Power.Components { powerNet.RemoveConsumer(this); } - - private void SetDrawRate(int newDrawRate) - { - var oldDrawRate = DrawRate; - _drawRate = newDrawRate; //must be set before updating powernet, as it checks the DrawRate of every consumer - Net.UpdateConsumerDraw(this, oldDrawRate, newDrawRate); - } - - private void SetReceivedPower(int newReceivedPower) - { - Debug.Assert(newReceivedPower >= 0 && newReceivedPower <= DrawRate); - if(_receivedPower == newReceivedPower) return; - _receivedPower = newReceivedPower; - OnReceivedPowerChanged?.Invoke(this, new ReceivedPowerChangedEventArgs(_drawRate, _receivedPower)); - } - - private void SetPriority(Priority newPriority) - { - Net.UpdateConsumerPriority(this, Priority, newPriority); - _priority = newPriority; - } - } - - public enum Priority - { - First, - Last, - } - - public class ReceivedPowerChangedEventArgs : EventArgs - { - public readonly int DrawRate; - public readonly int ReceivedPower; - - public ReceivedPowerChangedEventArgs(int drawRate, int receivedPower) - { - DrawRate = drawRate; - ReceivedPower = receivedPower; - } } } diff --git a/Content.Server/Power/Components/PowerNetworkBatteryComponent.cs b/Content.Server/Power/Components/PowerNetworkBatteryComponent.cs new file mode 100644 index 0000000000..5da505e03d --- /dev/null +++ b/Content.Server/Power/Components/PowerNetworkBatteryComponent.cs @@ -0,0 +1,119 @@ +using Content.Server.Power.Pow3r; +using Robust.Shared.GameObjects; +using Robust.Shared.Serialization.Manager.Attributes; +using Robust.Shared.ViewVariables; + +namespace Content.Server.Power.Components +{ + /// + /// Glue component that manages the pow3r network node for batteries that are connected to the power network. + /// + /// + /// This needs components like to work correctly, + /// and battery storage should be handed off to components like . + /// + [RegisterComponent] + public sealed class PowerNetworkBatteryComponent : Component + { + public override string Name => "PowerNetworkBattery"; + + [DataField("maxChargeRate")] + [ViewVariables(VVAccess.ReadWrite)] + public float MaxChargeRate + { + get => NetworkBattery.MaxChargeRate; + set => NetworkBattery.MaxChargeRate = value; + } + + [DataField("maxSupply")] + [ViewVariables(VVAccess.ReadWrite)] + public float MaxSupply + { + get => NetworkBattery.MaxSupply; + set => NetworkBattery.MaxSupply = value; + } + + [DataField("supplyRampTolerance")] + [ViewVariables(VVAccess.ReadWrite)] + public float SupplyRampTolerance + { + get => NetworkBattery.SupplyRampTolerance; + set => NetworkBattery.SupplyRampTolerance = value; + } + + [DataField("supplyRampRate")] + [ViewVariables(VVAccess.ReadWrite)] + public float SupplyRampRate + { + get => NetworkBattery.SupplyRampRate; + set => NetworkBattery.SupplyRampRate = value; + } + + [DataField("supplyRampPosition")] + [ViewVariables(VVAccess.ReadWrite)] + public float SupplyRampPosition + { + get => NetworkBattery.SupplyRampPosition; + set => NetworkBattery.SupplyRampPosition = value; + } + + [DataField("currentSupply")] + [ViewVariables(VVAccess.ReadWrite)] + public float CurrentSupply + { + get => NetworkBattery.CurrentSupply; + set => NetworkBattery.CurrentSupply = value; + } + + [DataField("currentReceiving")] + [ViewVariables(VVAccess.ReadWrite)] + public float CurrentReceiving + { + get => NetworkBattery.CurrentReceiving; + set => NetworkBattery.CurrentReceiving = value; + } + + [DataField("loadingNetworkDemand")] + [ViewVariables(VVAccess.ReadWrite)] + public float LoadingNetworkDemand + { + get => NetworkBattery.LoadingNetworkDemand; + set => NetworkBattery.LoadingNetworkDemand = value; + } + + [DataField("enabled")] + [ViewVariables(VVAccess.ReadWrite)] + public bool Enabled + { + get => NetworkBattery.Enabled; + set => NetworkBattery.Enabled = value; + } + + [DataField("canCharge")] + [ViewVariables(VVAccess.ReadWrite)] + public bool CanCharge + { + get => NetworkBattery.CanCharge; + set => NetworkBattery.CanCharge = value; + } + + [DataField("canDisharge")] + [ViewVariables(VVAccess.ReadWrite)] + public bool CanDischarge + { + get => NetworkBattery.CanDischarge; + set => NetworkBattery.CanDischarge = value; + } + + [DataField("efficiency")] + [ViewVariables(VVAccess.ReadWrite)] + public float Efficiency + { + get => NetworkBattery.Efficiency; + set => NetworkBattery.Efficiency = value; + } + + [ViewVariables] + public PowerState.Battery NetworkBattery { get; } = new(); + } +} diff --git a/Content.Server/Power/Components/PowerProviderComponent.cs b/Content.Server/Power/Components/PowerProviderComponent.cs deleted file mode 100644 index 1b8a35cbf2..0000000000 --- a/Content.Server/Power/Components/PowerProviderComponent.cs +++ /dev/null @@ -1,174 +0,0 @@ -#nullable enable -using System; -using System.Collections.Generic; -using Content.Server.APC; -using Content.Server.APC.Components; -using Robust.Shared.GameObjects; -using Robust.Shared.IoC; -using Robust.Shared.Serialization.Manager.Attributes; -using Robust.Shared.ViewVariables; - -namespace Content.Server.Power.Components -{ - /// - /// Relays s in an area to a so they can receive power. - /// - public interface IPowerProvider - { - void AddReceiver(PowerReceiverComponent receiver); - - void RemoveReceiver(PowerReceiverComponent receiver); - - void UpdateReceiverLoad(int oldLoad, int newLoad); - - public IEntity? ProviderOwner { get; } - - public bool HasApcPower { get; } - } - - [RegisterComponent] - public class PowerProviderComponent : BaseApcNetComponent, IPowerProvider - { - public override string Name => "PowerProvider"; - - public IEntity ProviderOwner => Owner; - - [ViewVariables] - public bool HasApcPower => Net.Powered; - - /// - /// The max distance this can transmit power to s from. - /// - [ViewVariables(VVAccess.ReadWrite)] - public int PowerTransferRange { get => _powerTransferRange; set => SetPowerTransferRange(value); } - [DataField("powerTransferRange")] - private int _powerTransferRange = 3; - - [ViewVariables] - public IReadOnlyList LinkedReceivers => _linkedReceivers; - private List _linkedReceivers = new(); - - /// - /// If s should consider connecting to this. - /// - [ViewVariables(VVAccess.ReadWrite)] - public bool Connectable { get; private set; } = true; - - public static readonly IPowerProvider NullProvider = new NullPowerProvider(); - - public void AddReceiver(PowerReceiverComponent receiver) - { - var oldLoad = GetTotalLoad(); - _linkedReceivers.Add(receiver); - var newLoad = oldLoad + receiver.Load; - Net.UpdatePowerProviderReceivers(this, oldLoad, newLoad); - } - - public void RemoveReceiver(PowerReceiverComponent receiver) - { - var oldLoad = GetTotalLoad(); - _linkedReceivers.Remove(receiver); - var newLoad = oldLoad - receiver.Load; - Net.UpdatePowerProviderReceivers(this, oldLoad, newLoad); - } - - public void UpdateReceiverLoad(int oldLoad, int newLoad) - { - Net.UpdatePowerProviderReceivers(this, oldLoad, newLoad); - } - - protected override void Startup() - { - base.Startup(); - foreach (var receiver in FindAvailableReceivers()) - { - receiver.Provider = this; - } - } - - protected override void OnRemove() - { - Connectable = false; - var receivers = _linkedReceivers.ToArray(); - foreach (var receiver in receivers) - { - receiver.ClearProvider(); - } - foreach (var receiver in receivers) - { - receiver.TryFindAndSetProvider(); - } - base.OnRemove(); - } - - private List FindAvailableReceivers() - { - var nearbyEntities = IoCManager.Resolve() - .GetEntitiesInRange(Owner, PowerTransferRange); - - var receivers = new List(); - - foreach (var entity in nearbyEntities) - { - if (entity.TryGetComponent(out var receiver) && - receiver.Connectable && - receiver.NeedsProvider && - receiver.Owner.Transform.Coordinates.TryDistance(Owner.EntityManager, Owner.Transform.Coordinates, out var distance) && - distance < Math.Min(PowerTransferRange, receiver.PowerReceptionRange)) - { - receivers.Add(receiver); - } - } - return receivers; - } - - protected override void AddSelfToNet(IApcNet apcNet) - { - apcNet.AddPowerProvider(this); - } - - protected override void RemoveSelfFromNet(IApcNet apcNet) - { - apcNet.RemovePowerProvider(this); - } - - private void SetPowerTransferRange(int newPowerTransferRange) - { - var receivers = _linkedReceivers.ToArray(); - - foreach (var receiver in receivers) - { - receiver.ClearProvider(); - } - _powerTransferRange = newPowerTransferRange; - - foreach (var receiver in receivers) - { - receiver.TryFindAndSetProvider(); - } - } - - private int GetTotalLoad() - { - var load = 0; - foreach (var receiver in _linkedReceivers) - { - load += receiver.Load; - } - return load; - } - - private class NullPowerProvider : IPowerProvider - { - /// - /// It is important that this returns false, so s with a have no power. - /// - public bool HasApcPower => false; - - public void AddReceiver(PowerReceiverComponent receiver) { } - public void RemoveReceiver(PowerReceiverComponent receiver) { } - public void UpdateReceiverLoad(int oldLoad, int newLoad) { } - public IEntity? ProviderOwner => default; - } - } -} diff --git a/Content.Server/Power/Components/PowerSupplierComponent.cs b/Content.Server/Power/Components/PowerSupplierComponent.cs index bbd8b658fd..c145cd6803 100644 --- a/Content.Server/Power/Components/PowerSupplierComponent.cs +++ b/Content.Server/Power/Components/PowerSupplierComponent.cs @@ -1,5 +1,6 @@ #nullable enable -using Content.Server.NodeContainer.NodeGroups; +using Content.Server.Power.NodeGroups; +using Content.Server.Power.Pow3r; using Robust.Shared.GameObjects; using Robust.Shared.Serialization.Manager.Attributes; using Robust.Shared.ViewVariables; @@ -12,9 +13,45 @@ namespace Content.Server.Power.Components public override string Name => "PowerSupplier"; [ViewVariables(VVAccess.ReadWrite)] - public int SupplyRate { get => _supplyRate; set => SetSupplyRate(value); } [DataField("supplyRate")] - private int _supplyRate; + public float MaxSupply { get => NetworkSupply.MaxSupply; set => NetworkSupply.MaxSupply = value; } + + [ViewVariables(VVAccess.ReadWrite)] + [DataField("supplyRampTolerance")] + public float SupplyRampTolerance + { + get => NetworkSupply.SupplyRampTolerance; + set => NetworkSupply.SupplyRampTolerance = value; + } + + [ViewVariables(VVAccess.ReadWrite)] + [DataField("supplyRampRate")] + public float SupplyRampRate + { + get => NetworkSupply.SupplyRampRate; + set => NetworkSupply.SupplyRampRate = value; + } + + [ViewVariables(VVAccess.ReadWrite)] + [DataField("supplyRampPosition")] + public float SupplyRampPosition + { + get => NetworkSupply.SupplyRampPosition; + set => NetworkSupply.SupplyRampPosition = value; + } + + [ViewVariables(VVAccess.ReadWrite)] + [DataField("enabled")] + public bool Enabled + { + get => NetworkSupply.Enabled; + set => NetworkSupply.Enabled = value; + } + + [ViewVariables] public float CurrentSupply => NetworkSupply.CurrentSupply; + + [ViewVariables] + public PowerState.Supply NetworkSupply { get; } = new(); protected override void AddSelfToNet(IPowerNet powerNet) { @@ -25,11 +62,5 @@ namespace Content.Server.Power.Components { powerNet.RemoveSupplier(this); } - - private void SetSupplyRate(int newSupplyRate) - { - Net.UpdateSupplierSupply(this, SupplyRate, newSupplyRate); - _supplyRate = newSupplyRate; - } } } diff --git a/Content.Server/Battery/DrainAllBatteriesCommand.cs b/Content.Server/Power/DrainAllBatteriesCommand.cs similarity index 78% rename from Content.Server/Battery/DrainAllBatteriesCommand.cs rename to Content.Server/Power/DrainAllBatteriesCommand.cs index 561d171d5b..431e68c4d8 100644 --- a/Content.Server/Battery/DrainAllBatteriesCommand.cs +++ b/Content.Server/Power/DrainAllBatteriesCommand.cs @@ -1,12 +1,12 @@ #nullable enable using Content.Server.Administration; -using Content.Server.Battery.Components; +using Content.Server.Power.Components; using Content.Shared.Administration; using Robust.Shared.Console; using Robust.Shared.GameObjects; using Robust.Shared.IoC; -namespace Content.Server.Battery +namespace Content.Server.Power { [AdminCommand(AdminFlags.Admin)] public class DrainAllBatteriesCommand : IConsoleCommand @@ -23,8 +23,8 @@ namespace Content.Server.Battery return; } - var entityManager = IoCManager.Resolve(); - foreach (var batteryComp in entityManager.ComponentManager.EntityQuery()) + var comp = IoCManager.Resolve(); + foreach (var batteryComp in comp.EntityQuery()) { batteryComp.CurrentCharge = 0; } diff --git a/Content.Server/Power/EntitySystems/BatterySystem.cs b/Content.Server/Power/EntitySystems/BatterySystem.cs new file mode 100644 index 0000000000..ce54a7e866 --- /dev/null +++ b/Content.Server/Power/EntitySystems/BatterySystem.cs @@ -0,0 +1,42 @@ +#nullable enable +using Content.Server.Power.Components; +using JetBrains.Annotations; +using Robust.Shared.GameObjects; + +namespace Content.Server.Power.EntitySystems +{ + [UsedImplicitly] + public class BatterySystem : EntitySystem + { + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(PreSync); + SubscribeLocalEvent(PostSync); + } + + private void PreSync(EntityUid uid, BatteryComponent component, NetworkBatteryPreSync args) + { + var networkBattery = ComponentManager.GetComponent(uid); + + networkBattery.NetworkBattery.Capacity = component.MaxCharge; + networkBattery.NetworkBattery.CurrentStorage = component.CurrentCharge; + } + + private void PostSync(EntityUid uid, BatteryComponent component, NetworkBatteryPostSync args) + { + var networkBattery = ComponentManager.GetComponent(uid); + + component.CurrentCharge = networkBattery.NetworkBattery.CurrentStorage; + } + + public override void Update(float frameTime) + { + foreach (var comp in ComponentManager.EntityQuery()) + { + comp.OnUpdate(frameTime); + } + } + } +} diff --git a/Content.Server/Power/EntitySystems/CableVisSystem.cs b/Content.Server/Power/EntitySystems/CableVisSystem.cs new file mode 100644 index 0000000000..d0425d63b5 --- /dev/null +++ b/Content.Server/Power/EntitySystems/CableVisSystem.cs @@ -0,0 +1,85 @@ +using System.Collections.Generic; +using Content.Server.NodeContainer; +using Content.Server.NodeContainer.EntitySystems; +using Content.Server.Power.Components; +using Content.Server.Power.Nodes; +using Content.Shared.Wires; +using JetBrains.Annotations; +using Robust.Server.GameObjects; +using Robust.Shared.GameObjects; +using Robust.Shared.IoC; +using Robust.Shared.Map; + +namespace Content.Server.Power.EntitySystems +{ + [UsedImplicitly] + public sealed class CableVisSystem : EntitySystem + { + [Dependency] private readonly IMapManager _mapManager = default!; + + private readonly HashSet _toUpdate = new(); + + public void QueueUpdate(EntityUid uid) + { + _toUpdate.Add(uid); + } + + public override void Initialize() + { + base.Initialize(); + + UpdatesAfter.Add(typeof(NodeGroupSystem)); + } + + public override void Update(float frameTime) + { + base.Update(frameTime); + + foreach (var uid in _toUpdate) + { + if (!ComponentManager.TryGetComponent(uid, out NodeContainerComponent? nodeContainer) + || !ComponentManager.TryGetComponent(uid, out CableVisComponent? cableVis) + || !ComponentManager.TryGetComponent(uid, out AppearanceComponent? appearance)) + { + continue; + } + + if (cableVis.Node == null) + continue; + + var mask = WireVisDirFlags.None; + + var transform = ComponentManager.GetComponent(uid); + var grid = _mapManager.GetGrid(transform.GridID); + var tile = grid.TileIndicesFor(transform.Coordinates); + var node = nodeContainer.GetNode(cableVis.Node); + + foreach (var reachable in node.ReachableNodes) + { + if (reachable is not CableNode) + continue; + + var otherTransform = reachable.Owner.Transform; + if (otherTransform.GridID != grid.Index) + continue; + + var otherTile = grid.TileIndicesFor(otherTransform.Coordinates); + var diff = otherTile - tile; + + mask |= diff switch + { + (0, 1) => WireVisDirFlags.North, + (0, -1) => WireVisDirFlags.South, + (1, 0) => WireVisDirFlags.East, + (-1, 0) => WireVisDirFlags.West, + _ => WireVisDirFlags.None + }; + } + + appearance.SetData(WireVisVisuals.ConnectedMask, mask); + } + + _toUpdate.Clear(); + } + } +} diff --git a/Content.Server/APC/PowerApcSystem.cs b/Content.Server/Power/EntitySystems/PowerApcSystem.cs similarity index 59% rename from Content.Server/APC/PowerApcSystem.cs rename to Content.Server/Power/EntitySystems/PowerApcSystem.cs index 1aefa669f4..e44b66f260 100644 --- a/Content.Server/APC/PowerApcSystem.cs +++ b/Content.Server/Power/EntitySystems/PowerApcSystem.cs @@ -1,16 +1,23 @@ #nullable enable -using Content.Server.APC.Components; +using Content.Server.Power.Components; using JetBrains.Annotations; using Robust.Shared.GameObjects; -namespace Content.Server.APC +namespace Content.Server.Power.EntitySystems { [UsedImplicitly] internal sealed class PowerApcSystem : EntitySystem { + public override void Initialize() + { + base.Initialize(); + + UpdatesAfter.Add(typeof(PowerNetSystem)); + } + public override void Update(float frameTime) { - foreach (var apc in ComponentManager.EntityQuery(false)) + foreach (var apc in ComponentManager.EntityQuery()) { apc.Update(); } diff --git a/Content.Server/Power/EntitySystems/PowerNetSystem.cs b/Content.Server/Power/EntitySystems/PowerNetSystem.cs index bcb8ec6926..e2b54ac769 100644 --- a/Content.Server/Power/EntitySystems/PowerNetSystem.cs +++ b/Content.Server/Power/EntitySystems/PowerNetSystem.cs @@ -1,20 +1,351 @@ #nullable enable +using System.Collections.Generic; +using Content.Server.NodeContainer.EntitySystems; using Content.Server.Power.Components; +using Content.Server.Power.NodeGroups; +using Content.Server.Power.Pow3r; using JetBrains.Annotations; using Robust.Shared.GameObjects; -using Robust.Shared.IoC; +using Robust.Shared.Maths; namespace Content.Server.Power.EntitySystems { + /// + /// Manages power networks, power state, and all power components. + /// [UsedImplicitly] public class PowerNetSystem : EntitySystem { - [Dependency] private readonly IPowerNetManager _powerNetManager = default!; + private readonly PowerState _powerState = new(); + private readonly HashSet _powerNetReconnectQueue = new(); + private readonly HashSet _apcNetReconnectQueue = new(); + + private int _nextId = 1; + private readonly BatteryRampPegSolver _solver = new(); + + public override void Initialize() + { + base.Initialize(); + + UpdatesAfter.Add(typeof(NodeGroupSystem)); + + SubscribeLocalEvent(ApcPowerReceiverInit); + SubscribeLocalEvent(ApcPowerReceiverShutdown); + SubscribeLocalEvent(ApcPowerReceiverPaused); + SubscribeLocalEvent(BatteryInit); + SubscribeLocalEvent(BatteryShutdown); + SubscribeLocalEvent(BatteryPaused); + SubscribeLocalEvent(PowerConsumerInit); + SubscribeLocalEvent(PowerConsumerShutdown); + SubscribeLocalEvent(PowerConsumerPaused); + SubscribeLocalEvent(PowerSupplierInit); + SubscribeLocalEvent(PowerSupplierShutdown); + SubscribeLocalEvent(PowerSupplierPaused); + } + + private void ApcPowerReceiverInit(EntityUid uid, ApcPowerReceiverComponent component, ComponentInit args) + { + AllocLoad(component.NetworkLoad); + } + + private void ApcPowerReceiverShutdown(EntityUid uid, ApcPowerReceiverComponent component, + ComponentShutdown args) + { + _powerState.Loads.Remove(component.NetworkLoad.Id); + } + + private static void ApcPowerReceiverPaused( + EntityUid uid, + ApcPowerReceiverComponent component, + EntityPausedEvent args) + { + component.NetworkLoad.Paused = args.Paused; + } + + private void BatteryInit(EntityUid uid, PowerNetworkBatteryComponent component, ComponentInit args) + { + AllocBattery(component.NetworkBattery); + } + + private void BatteryShutdown(EntityUid uid, PowerNetworkBatteryComponent component, ComponentShutdown args) + { + _powerState.Batteries.Remove(component.NetworkBattery.Id); + } + + private static void BatteryPaused(EntityUid uid, PowerNetworkBatteryComponent component, EntityPausedEvent args) + { + component.NetworkBattery.Paused = args.Paused; + } + + private void PowerConsumerInit(EntityUid uid, PowerConsumerComponent component, ComponentInit args) + { + AllocLoad(component.NetworkLoad); + } + + private void PowerConsumerShutdown(EntityUid uid, PowerConsumerComponent component, ComponentShutdown args) + { + _powerState.Loads.Remove(component.NetworkLoad.Id); + } + + private static void PowerConsumerPaused(EntityUid uid, PowerConsumerComponent component, EntityPausedEvent args) + { + component.NetworkLoad.Paused = args.Paused; + } + + private void PowerSupplierInit(EntityUid uid, PowerSupplierComponent component, ComponentInit args) + { + AllocSupply(component.NetworkSupply); + } + + private void PowerSupplierShutdown(EntityUid uid, PowerSupplierComponent component, ComponentShutdown args) + { + _powerState.Supplies.Remove(component.NetworkSupply.Id); + } + + private static void PowerSupplierPaused(EntityUid uid, PowerSupplierComponent component, EntityPausedEvent args) + { + component.NetworkSupply.Paused = args.Paused; + } + + public void InitPowerNet(PowerNet powerNet) + { + AllocNetwork(powerNet.NetworkNode); + } + + public void DestroyPowerNet(PowerNet powerNet) + { + _powerState.Networks.Remove(powerNet.NetworkNode.Id); + } + + public void QueueReconnectPowerNet(PowerNet powerNet) + { + _powerNetReconnectQueue.Add(powerNet); + } + + public void InitApcNet(ApcNet apcNet) + { + AllocNetwork(apcNet.NetworkNode); + } + + public void DestroyApcNet(ApcNet apcNet) + { + _powerState.Networks.Remove(apcNet.NetworkNode.Id); + } + + public void QueueReconnectApcNet(ApcNet apcNet) + { + _apcNetReconnectQueue.Add(apcNet); + } + + public PowerStatistics GetStatistics() + { + return new() + { + CountBatteries = _powerState.Batteries.Count, + CountLoads = _powerState.Loads.Count, + CountNetworks = _powerState.Networks.Count, + CountSupplies = _powerState.Supplies.Count + }; + } public override void Update(float frameTime) { base.Update(frameTime); - _powerNetManager.Update(frameTime); + + // Reconnect networks. + { + foreach (var apcNet in _apcNetReconnectQueue) + { + if (apcNet.Removed) + continue; + + DoReconnectApcNet(apcNet); + } + + _apcNetReconnectQueue.Clear(); + + foreach (var powerNet in _powerNetReconnectQueue) + { + if (powerNet.Removed) + continue; + + DoReconnectPowerNet(powerNet); + } + + _powerNetReconnectQueue.Clear(); + } + + // Synchronize batteries + foreach (var battery in ComponentManager.EntityQuery()) + { + RaiseLocalEvent(battery.Owner.Uid, new NetworkBatteryPreSync()); + } + + // Run power solver. + _solver.Tick(frameTime, _powerState); + + // Synchronize batteries, the other way around. + foreach (var battery in ComponentManager.EntityQuery()) + { + RaiseLocalEvent(battery.Owner.Uid, new NetworkBatteryPostSync()); + } + + // Send events where necessary. + { + foreach (var apcReceiver in ComponentManager.EntityQuery()) + { + var recv = apcReceiver.NetworkLoad.ReceivingPower; + ref var last = ref apcReceiver.LastPowerReceived; + + if (!MathHelper.CloseTo(recv, last)) + { + last = recv; + apcReceiver.ApcPowerChanged(); + } + } + + foreach (var consumer in ComponentManager.EntityQuery()) + { + var newRecv = consumer.NetworkLoad.ReceivingPower; + ref var lastRecv = ref consumer.LastReceived; + if (!MathHelper.CloseTo(lastRecv, newRecv)) + { + lastRecv = newRecv; + var msg = new PowerConsumerReceivedChanged(newRecv, consumer.DrawRate); + RaiseLocalEvent(consumer.Owner.Uid, msg); + } + } + } + } + + private void AllocLoad(PowerState.Load load) + { + load.Id = AllocId(); + _powerState.Loads.Add(load.Id, load); + } + + private void AllocSupply(PowerState.Supply supply) + { + supply.Id = AllocId(); + _powerState.Supplies.Add(supply.Id, supply); + } + + private void AllocBattery(PowerState.Battery battery) + { + battery.Id = AllocId(); + _powerState.Batteries.Add(battery.Id, battery); + } + + private void AllocNetwork(PowerState.Network network) + { + network.Id = AllocId(); + _powerState.Networks.Add(network.Id, network); + } + + private static void DoReconnectApcNet(ApcNet net) + { + var netNode = net.NetworkNode; + + netNode.Loads.Clear(); + netNode.BatteriesDischarging.Clear(); + netNode.BatteriesCharging.Clear(); + netNode.Supplies.Clear(); + + foreach (var provider in net.Providers) + { + foreach (var receiver in provider.LinkedReceivers) + { + netNode.Loads.Add(receiver.NetworkLoad.Id); + receiver.NetworkLoad.LinkedNetwork = netNode.Id; + } + } + + foreach (var apc in net.Apcs) + { + var netBattery = apc.Owner.GetComponent(); + netNode.BatteriesDischarging.Add(netBattery.NetworkBattery.Id); + netBattery.NetworkBattery.LinkedNetworkDischarging = netNode.Id; + } + } + + private static void DoReconnectPowerNet(PowerNet net) + { + var netNode = net.NetworkNode; + + netNode.Loads.Clear(); + netNode.Supplies.Clear(); + netNode.BatteriesCharging.Clear(); + netNode.BatteriesDischarging.Clear(); + + foreach (var consumer in net.Consumers) + { + netNode.Loads.Add(consumer.NetworkLoad.Id); + consumer.NetworkLoad.LinkedNetwork = netNode.Id; + } + + foreach (var supplier in net.Suppliers) + { + netNode.Supplies.Add(supplier.NetworkSupply.Id); + supplier.NetworkSupply.LinkedNetwork = netNode.Id; + } + + foreach (var charger in net.Chargers) + { + var battery = charger.Owner.GetComponent(); + netNode.BatteriesCharging.Add(battery.NetworkBattery.Id); + battery.NetworkBattery.LinkedNetworkCharging = netNode.Id; + } + + foreach (var discharger in net.Dischargers) + { + var battery = discharger.Owner.GetComponent(); + netNode.BatteriesDischarging.Add(battery.NetworkBattery.Id); + battery.NetworkBattery.LinkedNetworkDischarging = netNode.Id; + } + } + + private PowerState.NodeId AllocId() + { + return new(_nextId++); } } + + /// + /// Raised before power network simulation happens, to synchronize battery state from + /// components like into . + /// + public sealed class NetworkBatteryPreSync : EntityEventArgs + { + } + + /// + /// Raised after power network simulation happens, to synchronize battery charge changes from + /// to components like . + /// + public sealed class NetworkBatteryPostSync : EntityEventArgs + { + } + + /// + /// Raised when the amount of receiving power on a changes. + /// + public sealed class PowerConsumerReceivedChanged : EntityEventArgs + { + public float ReceivedPower { get; } + public float DrawRate { get; } + + public PowerConsumerReceivedChanged(float receivedPower, float drawRate) + { + ReceivedPower = receivedPower; + DrawRate = drawRate; + } + } + + public struct PowerStatistics + { + public int CountNetworks; + public int CountLoads; + public int CountSupplies; + public int CountBatteries; + } } diff --git a/Content.Server/Power/EntitySystems/PowerReceiverSystem.cs b/Content.Server/Power/EntitySystems/PowerReceiverSystem.cs index 54ed7847de..119e66195c 100644 --- a/Content.Server/Power/EntitySystems/PowerReceiverSystem.cs +++ b/Content.Server/Power/EntitySystems/PowerReceiverSystem.cs @@ -9,12 +9,12 @@ namespace Content.Server.Power.EntitySystems { base.Initialize(); - SubscribeLocalEvent(BodyTypeChanged); + SubscribeLocalEvent(BodyTypeChanged); } private static void BodyTypeChanged( EntityUid uid, - PowerReceiverComponent component, + ApcPowerReceiverComponent component, PhysicsBodyTypeChangedEvent args) { component.AnchorUpdate(); diff --git a/Content.Server/Power/NodeGroups/ApcNet.cs b/Content.Server/Power/NodeGroups/ApcNet.cs new file mode 100644 index 0000000000..a2f77eedb0 --- /dev/null +++ b/Content.Server/Power/NodeGroups/ApcNet.cs @@ -0,0 +1,112 @@ +#nullable enable +using System.Collections.Generic; +using System.Linq; +using Content.Server.NodeContainer.NodeGroups; +using Content.Server.NodeContainer.Nodes; +using Content.Server.Power.Components; +using Content.Server.Power.EntitySystems; +using Content.Server.Power.Pow3r; +using JetBrains.Annotations; +using Robust.Shared.GameObjects; +using Robust.Shared.Map; +using Robust.Shared.Maths; +using Robust.Shared.ViewVariables; + +namespace Content.Server.Power.NodeGroups +{ + public interface IApcNet + { + void AddApc(ApcComponent apc); + + void RemoveApc(ApcComponent apc); + + void AddPowerProvider(ApcPowerProviderComponent provider); + + void RemovePowerProvider(ApcPowerProviderComponent provider); + + void QueueNetworkReconnect(); + + PowerState.Network NetworkNode { get; } + + GridId? GridId { get; } + } + + [NodeGroup(NodeGroupID.Apc)] + [UsedImplicitly] + public class ApcNet : BaseNetConnectorNodeGroup, IApcNet + { + private readonly PowerNetSystem _powerNetSystem = EntitySystem.Get(); + + [ViewVariables] public readonly List Apcs = new(); + + [ViewVariables] public readonly List Providers = new(); + + //Debug property + [ViewVariables] private int TotalReceivers => Providers.Sum(provider => provider.LinkedReceivers.Count); + + [ViewVariables] + private IEnumerable AllReceivers => + Providers.SelectMany(provider => provider.LinkedReceivers); + + GridId? IApcNet.GridId => GridId; + + [ViewVariables] + public PowerState.Network NetworkNode { get; } = new(); + + public override void Initialize(Node sourceNode) + { + base.Initialize(sourceNode); + + _powerNetSystem.InitApcNet(this); + } + + public override void AfterRemake(IEnumerable> newGroups) + { + base.AfterRemake(newGroups); + + _powerNetSystem.DestroyApcNet(this); + } + + public void AddApc(ApcComponent apc) + { + if (apc.Owner.TryGetComponent(out PowerNetworkBatteryComponent? netBattery)) + netBattery.NetworkBattery.LinkedNetworkDischarging = default; + + _powerNetSystem.QueueReconnectApcNet(this); + Apcs.Add(apc); + } + + public void RemoveApc(ApcComponent apc) + { + if (apc.Owner.TryGetComponent(out PowerNetworkBatteryComponent? netBattery)) + netBattery.NetworkBattery.LinkedNetworkDischarging = default; + + _powerNetSystem.QueueReconnectApcNet(this); + Apcs.Remove(apc); + } + + public void AddPowerProvider(ApcPowerProviderComponent provider) + { + Providers.Add(provider); + + _powerNetSystem.QueueReconnectApcNet(this); + } + + public void RemovePowerProvider(ApcPowerProviderComponent provider) + { + Providers.Remove(provider); + + _powerNetSystem.QueueReconnectApcNet(this); + } + + public void QueueNetworkReconnect() + { + _powerNetSystem.QueueReconnectApcNet(this); + } + + protected override void SetNetConnectorNet(BaseApcNetComponent netConnectorComponent) + { + netConnectorComponent.Net = this; + } + } +} diff --git a/Content.Server/Power/NodeGroups/BaseNetConnectorNodeGroup.cs b/Content.Server/Power/NodeGroups/BaseNetConnectorNodeGroup.cs new file mode 100644 index 0000000000..17785078ef --- /dev/null +++ b/Content.Server/Power/NodeGroups/BaseNetConnectorNodeGroup.cs @@ -0,0 +1,34 @@ +#nullable enable +using System.Collections.Generic; +using System.Linq; +using Content.Server.NodeContainer.NodeGroups; +using Content.Server.NodeContainer.Nodes; +using Content.Server.Power.Components; + +namespace Content.Server.Power.NodeGroups +{ + public abstract class BaseNetConnectorNodeGroup : BaseNodeGroup + where TNetConnector : BaseNetConnectorComponent + { + public override void LoadNodes(List groupNodes) + { + base.LoadNodes(groupNodes); + + foreach (var node in groupNodes) + { + var newNetConnectorComponents = node.Owner + .GetAllComponents() + .Where(powerComp => (powerComp.NodeId == null || powerComp.NodeId == node.Name) && + (NodeGroupID) powerComp.Voltage == node.NodeGroupID) + .ToList(); + + foreach (var netConnector in newNetConnectorComponents) + { + SetNetConnectorNet(netConnector); + } + } + } + + protected abstract void SetNetConnectorNet(TNetConnector netConnectorComponent); + } +} diff --git a/Content.Server/Power/NodeGroups/PowerNet.cs b/Content.Server/Power/NodeGroups/PowerNet.cs new file mode 100644 index 0000000000..38df0af231 --- /dev/null +++ b/Content.Server/Power/NodeGroups/PowerNet.cs @@ -0,0 +1,132 @@ +#nullable enable +using System.Collections.Generic; +using System.Linq; +using Content.Server.NodeContainer.NodeGroups; +using Content.Server.NodeContainer.Nodes; +using Content.Server.Power.Components; +using Content.Server.Power.EntitySystems; +using Content.Server.Power.Pow3r; +using JetBrains.Annotations; +using Robust.Shared.GameObjects; +using Robust.Shared.Maths; +using Robust.Shared.ViewVariables; + +namespace Content.Server.Power.NodeGroups +{ + public interface IPowerNet + { + void AddSupplier(PowerSupplierComponent supplier); + + void RemoveSupplier(PowerSupplierComponent supplier); + + void AddConsumer(PowerConsumerComponent consumer); + + void RemoveConsumer(PowerConsumerComponent consumer); + + void AddDischarger(BatteryDischargerComponent discharger); + + void RemoveDischarger(BatteryDischargerComponent discharger); + + void AddCharger(BatteryChargerComponent charger); + + void RemoveCharger(BatteryChargerComponent charger); + } + + [NodeGroup(NodeGroupID.HVPower, NodeGroupID.MVPower)] + [UsedImplicitly] + public class PowerNet : BaseNetConnectorNodeGroup, IPowerNet + { + private readonly PowerNetSystem _powerNetSystem = EntitySystem.Get(); + + [ViewVariables] public readonly List Suppliers = new(); + [ViewVariables] public readonly List Consumers = new(); + [ViewVariables] public readonly List Chargers = new(); + [ViewVariables] public readonly List Dischargers = new(); + + [ViewVariables] + public PowerState.Network NetworkNode { get; } = new(); + + public override void Initialize(Node sourceNode) + { + base.Initialize(sourceNode); + + _powerNetSystem.InitPowerNet(this); + } + + public override void AfterRemake(IEnumerable> newGroups) + { + base.AfterRemake(newGroups); + + _powerNetSystem.DestroyPowerNet(this); + } + + protected override void SetNetConnectorNet(BasePowerNetComponent netConnectorComponent) + { + netConnectorComponent.Net = this; + } + + public void AddSupplier(PowerSupplierComponent supplier) + { + supplier.NetworkSupply.LinkedNetwork = default; + Suppliers.Add(supplier); + _powerNetSystem.QueueReconnectPowerNet(this); + } + + public void RemoveSupplier(PowerSupplierComponent supplier) + { + supplier.NetworkSupply.LinkedNetwork = default; + Suppliers.Remove(supplier); + _powerNetSystem.QueueReconnectPowerNet(this); + } + + public void AddConsumer(PowerConsumerComponent consumer) + { + consumer.NetworkLoad.LinkedNetwork = default; + Consumers.Add(consumer); + _powerNetSystem.QueueReconnectPowerNet(this); + } + + public void RemoveConsumer(PowerConsumerComponent consumer) + { + consumer.NetworkLoad.LinkedNetwork = default; + Consumers.Remove(consumer); + _powerNetSystem.QueueReconnectPowerNet(this); + } + + public void AddDischarger(BatteryDischargerComponent discharger) + { + var battery = discharger.Owner.GetComponent(); + battery.NetworkBattery.LinkedNetworkCharging = default; + Dischargers.Add(discharger); + _powerNetSystem.QueueReconnectPowerNet(this); + } + + public void RemoveDischarger(BatteryDischargerComponent discharger) + { + // Can be missing if the entity is being deleted, not a big deal. + if (discharger.Owner.TryGetComponent(out PowerNetworkBatteryComponent? battery)) + battery.NetworkBattery.LinkedNetworkCharging = default; + + Dischargers.Remove(discharger); + _powerNetSystem.QueueReconnectPowerNet(this); + } + + public void AddCharger(BatteryChargerComponent charger) + { + var battery = charger.Owner.GetComponent(); + battery.NetworkBattery.LinkedNetworkCharging = default; + Chargers.Add(charger); + _powerNetSystem.QueueReconnectPowerNet(this); + } + + public void RemoveCharger(BatteryChargerComponent charger) + { + // Can be missing if the entity is being deleted, not a big deal. + if (charger.Owner.TryGetComponent(out PowerNetworkBatteryComponent? battery)) + battery.NetworkBattery.LinkedNetworkCharging = default; + + Chargers.Remove(charger); + _powerNetSystem.QueueReconnectPowerNet(this); + } + } +} diff --git a/Content.Server/Power/Nodes/CableDeviceNode.cs b/Content.Server/Power/Nodes/CableDeviceNode.cs new file mode 100644 index 0000000000..48a7942728 --- /dev/null +++ b/Content.Server/Power/Nodes/CableDeviceNode.cs @@ -0,0 +1,29 @@ +using System.Collections.Generic; +using Content.Server.NodeContainer.Nodes; +using Robust.Shared.GameObjects; +using Robust.Shared.IoC; +using Robust.Shared.Map; +using Robust.Shared.Serialization.Manager.Attributes; + +namespace Content.Server.Power.Nodes +{ + /// + /// Type of node that connects to a below it. + /// + [DataDefinition] + public class CableDeviceNode : Node + { + public override IEnumerable GetReachableNodes() + { + var compMgr = IoCManager.Resolve(); + var grid = IoCManager.Resolve().GetGrid(Owner.Transform.GridID); + var gridIndex = grid.TileIndicesFor(Owner.Transform.Coordinates); + + foreach (var node in NodeHelpers.GetNodesInTile(compMgr, grid, gridIndex)) + { + if (node is CableNode) + yield return node; + } + } + } +} diff --git a/Content.Server/Power/Nodes/CableNode.cs b/Content.Server/Power/Nodes/CableNode.cs new file mode 100644 index 0000000000..07d519656d --- /dev/null +++ b/Content.Server/Power/Nodes/CableNode.cs @@ -0,0 +1,79 @@ +using System.Collections.Generic; +using Content.Server.NodeContainer.Nodes; +using Content.Server.Power.EntitySystems; +using Robust.Shared.GameObjects; +using Robust.Shared.IoC; +using Robust.Shared.Map; +using Robust.Shared.Maths; +using Robust.Shared.Serialization.Manager.Attributes; + +namespace Content.Server.Power.Nodes +{ + [DataDefinition] + public class CableNode : Node + { + public override IEnumerable GetReachableNodes() + { + if (!Anchored) + yield break; + + var compMgr = IoCManager.Resolve(); + var grid = IoCManager.Resolve().GetGrid(Owner.Transform.GridID); + var gridIndex = grid.TileIndicesFor(Owner.Transform.Coordinates); + + // While we go over adjacent nodes, we build a list of blocked directions due to + // incoming or outgoing wire terminals. + var terminalDirs = 0; + List<(Direction, Node)> nodeDirs = new(); + + foreach (var (dir, node) in NodeHelpers.GetCardinalNeighborNodes(compMgr, grid, gridIndex)) + { + if (node is CableNode && node != this) + { + nodeDirs.Add((dir, node)); + } + + if (node is CableDeviceNode && dir == Direction.Invalid) + { + // device on same tile + nodeDirs.Add((Direction.Invalid, node)); + } + + if (node is CableTerminalNode) + { + if (dir == Direction.Invalid) + { + // On own tile, block direction it faces + terminalDirs |= 1 << (int) node.Owner.Transform.LocalRotation.GetCardinalDir(); + } + else + { + var terminalDir = node.Owner.Transform.LocalRotation.GetCardinalDir(); + if (terminalDir.GetOpposite() == dir) + { + // Target tile has a terminal towards us, block the direction. + terminalDirs |= 1 << (int) dir; + break; + } + } + } + } + + foreach (var (dir, node) in nodeDirs) + { + // If there is a wire terminal connecting across this direction, skip the node. + if (dir != Direction.Invalid && (terminalDirs & (1 << (int) dir)) != 0) + continue; + + yield return node; + } + } + + public override void OnPostRebuild() + { + base.OnPostRebuild(); + + EntitySystem.Get().QueueUpdate(Owner.Uid); + } + } +} diff --git a/Content.Server/Power/Nodes/CableTerminalNode.cs b/Content.Server/Power/Nodes/CableTerminalNode.cs new file mode 100644 index 0000000000..7bcf0a323c --- /dev/null +++ b/Content.Server/Power/Nodes/CableTerminalNode.cs @@ -0,0 +1,34 @@ +using System.Collections.Generic; +using Content.Server.NodeContainer.Nodes; +using Robust.Shared.GameObjects; +using Robust.Shared.IoC; +using Robust.Shared.Map; +using Robust.Shared.Serialization.Manager.Attributes; + +namespace Content.Server.Power.Nodes +{ + [DataDefinition] + public class CableTerminalNode : CableDeviceNode + { + public override IEnumerable GetReachableNodes() + { + var compMgr = IoCManager.Resolve(); + var grid = IoCManager.Resolve().GetGrid(Owner.Transform.GridID); + var gridIndex = grid.TileIndicesFor(Owner.Transform.Coordinates); + + var dir = Owner.Transform.LocalRotation.GetDir(); + var targetIdx = gridIndex + NodeHelpers.TileOffsetForDir(dir); + + foreach (var node in NodeHelpers.GetNodesInTile(compMgr, grid, targetIdx)) + { + if (node is CableTerminalPortNode) + yield return node; + } + + foreach (var node in base.GetReachableNodes()) + { + yield return node; + } + } + } +} diff --git a/Content.Server/Power/Nodes/CableTerminalPortNode.cs b/Content.Server/Power/Nodes/CableTerminalPortNode.cs new file mode 100644 index 0000000000..aa703aefd8 --- /dev/null +++ b/Content.Server/Power/Nodes/CableTerminalPortNode.cs @@ -0,0 +1,27 @@ +using System.Collections.Generic; +using Content.Server.NodeContainer.Nodes; +using Robust.Shared.GameObjects; +using Robust.Shared.IoC; +using Robust.Shared.Map; +using Robust.Shared.Serialization.Manager.Attributes; + +namespace Content.Server.Power.Nodes +{ + [DataDefinition] + public class CableTerminalPortNode : Node + { + public override IEnumerable GetReachableNodes() + { + var compMgr = IoCManager.Resolve(); + var grid = IoCManager.Resolve().GetGrid(Owner.Transform.GridID); + var gridIndex = grid.TileIndicesFor(Owner.Transform.Coordinates); + + var nodes = NodeHelpers.GetCardinalNeighborNodes(compMgr, grid, gridIndex, includeSameTile: false); + foreach (var (_, node) in nodes) + { + if (node is CableTerminalNode) + yield return node; + } + } + } +} diff --git a/Content.Server/Power/Pow3r/BatteryRampPegSolver.cs b/Content.Server/Power/Pow3r/BatteryRampPegSolver.cs new file mode 100644 index 0000000000..591e4add55 --- /dev/null +++ b/Content.Server/Power/Pow3r/BatteryRampPegSolver.cs @@ -0,0 +1,305 @@ +using System; +using System.Collections.Generic; +using Robust.Shared.Utility; +using static Content.Server.Power.Pow3r.PowerState; + +namespace Content.Server.Power.Pow3r +{ + public sealed class BatteryRampPegSolver : IPowerSolver + { + private sealed class HeightComparer : IComparer + { + public static HeightComparer Instance { get; } = new(); + + public int Compare(Network? x, Network? y) + { + if (ReferenceEquals(x, y)) return 0; + if (ReferenceEquals(null, y)) return 1; + if (ReferenceEquals(null, x)) return -1; + return x.Height.CompareTo(y.Height); + } + } + + private Network[] _sortBuffer = Array.Empty(); + + public void Tick(float frameTime, PowerState state) + { + // Clear loads and supplies. + foreach (var load in state.Loads.Values) + { + if (load.Paused) + continue; + + load.ReceivingPower = 0; + } + + foreach (var supply in state.Supplies.Values) + { + if (supply.Paused) + continue; + + supply.CurrentSupply = 0; + supply.SupplyRampTarget = 0; + } + + // Run a pass to estimate network tree graph height. + // This is so that we can run networks before their children, + // to avoid draining batteries for a tick if their passing-supply gets cut off. + // It's not a big loss if this doesn't work (it won't, in some scenarios), but it's a nice-to-have. + foreach (var network in state.Networks.Values) + { + network.HeightTouched = false; + network.Height = -1; + } + + foreach (var network in state.Networks.Values) + { + if (network.BatteriesDischarging.Count != 0) + continue; + + EstimateNetworkDepth(state, network); + } + + if (_sortBuffer.Length != state.Networks.Count) + _sortBuffer = new Network[state.Networks.Count]; + + var i = 0; + foreach (var network in state.Networks.Values) + { + _sortBuffer[i++] = network; + } + + Array.Sort(_sortBuffer, HeightComparer.Instance); + + // Go over every network. + foreach (var network in _sortBuffer) + { + // Add up demand in network. + var demand = 0f; + foreach (var loadId in network.Loads) + { + var load = state.Loads[loadId]; + + if (!load.Enabled || load.Paused) + continue; + + DebugTools.Assert(load.DesiredPower >= 0); + demand += load.DesiredPower; + } + + // TODO: Consider having battery charge loads be processed "after" pass-through loads. + // This would mean that charge rate would have no impact on throughput rate like it does currently. + // Would require a second pass over the network, or something. Not sure. + + // Loading batteries. + foreach (var batteryId in network.BatteriesCharging) + { + var battery = state.Batteries[batteryId]; + if (!battery.Enabled || !battery.CanCharge || battery.Paused) + continue; + + var batterySpace = (battery.Capacity - battery.CurrentStorage) * (1 / battery.Efficiency); + batterySpace = Math.Max(0, batterySpace); + var scaledSpace = batterySpace / frameTime; + + var chargeRate = battery.MaxChargeRate + battery.LoadingNetworkDemand / battery.Efficiency; + + var batDemand = Math.Min(chargeRate, scaledSpace); + + DebugTools.Assert(batDemand >= 0); + + battery.DesiredPower = batDemand; + demand += batDemand; + } + + DebugTools.Assert(demand >= 0); + + // Add up supply in network. + var availableSupplySum = 0f; + var maxSupplySum = 0f; + foreach (var supplyId in network.Supplies) + { + var supply = state.Supplies[supplyId]; + if (!supply.Enabled || supply.Paused) + continue; + + var rampMax = supply.SupplyRampPosition + supply.SupplyRampTolerance; + var effectiveSupply = Math.Min(rampMax, supply.MaxSupply); + + DebugTools.Assert(effectiveSupply >= 0); + DebugTools.Assert(supply.MaxSupply >= 0); + + supply.EffectiveMaxSupply = effectiveSupply; + availableSupplySum += effectiveSupply; + maxSupplySum += supply.MaxSupply; + } + + var unmet = Math.Max(0, demand - availableSupplySum); + + DebugTools.Assert(availableSupplySum >= 0); + DebugTools.Assert(maxSupplySum >= 0); + + // Supplying batteries. + // Batteries need to go after local supplies so that local supplies are prioritized. + // Also, it makes demand-pulling of batteries + // Because all batteries will will desire the unmet demand of their loading network, + // there will be a "rush" of input current when a network powers on, + // before power stabilizes in the network. + // This is fine. + foreach (var batteryId in network.BatteriesDischarging) + { + var battery = state.Batteries[batteryId]; + if (!battery.Enabled || !battery.CanDischarge || battery.Paused) + continue; + + var scaledSpace = battery.CurrentStorage / frameTime; + var supplyCap = Math.Min(battery.MaxSupply, + battery.SupplyRampPosition + battery.SupplyRampTolerance); + var supplyAndPassthrough = supplyCap + battery.CurrentReceiving * battery.Efficiency; + var tempSupply = Math.Min(scaledSpace, supplyAndPassthrough); + // Clamp final supply to the unmet demand, so that batteries refrain from taking power away from supplies. + var clampedSupply = Math.Min(unmet, tempSupply); + + DebugTools.Assert(clampedSupply >= 0); + + battery.TempMaxSupply = clampedSupply; + availableSupplySum += clampedSupply; + // TODO: Calculate this properly. + maxSupplySum += clampedSupply; + + battery.LoadingNetworkDemand = unmet; + battery.LoadingDemandMarked = true; + } + + var met = Math.Min(demand, availableSupplySum); + + if (met != 0) + { + // Distribute supply to loads. + foreach (var loadId in network.Loads) + { + var load = state.Loads[loadId]; + if (!load.Enabled || load.DesiredPower == 0 || load.Paused) + continue; + + var ratio = load.DesiredPower / demand; + load.ReceivingPower = ratio * met; + } + + // Loading batteries + foreach (var batteryId in network.BatteriesCharging) + { + var battery = state.Batteries[batteryId]; + + if (!battery.Enabled || battery.DesiredPower == 0 || battery.Paused) + continue; + + var ratio = battery.DesiredPower / demand; + battery.CurrentReceiving = ratio * met; + var receivedPower = frameTime * battery.CurrentReceiving; + receivedPower *= battery.Efficiency; + battery.CurrentStorage = Math.Min( + battery.Capacity, + battery.CurrentStorage + receivedPower); + battery.LoadingMarked = true; + } + + // Load to supplies + foreach (var supplyId in network.Supplies) + { + var supply = state.Supplies[supplyId]; + if (!supply.Enabled || supply.EffectiveMaxSupply == 0 || supply.Paused) + continue; + + var ratio = supply.EffectiveMaxSupply / availableSupplySum; + supply.CurrentSupply = ratio * met; + + if (supply.MaxSupply != 0) + { + var maxSupplyRatio = supply.MaxSupply / maxSupplySum; + + supply.SupplyRampTarget = maxSupplyRatio * demand; + } + else + { + supply.SupplyRampTarget = 0; + } + } + + // Supplying batteries + foreach (var batteryId in network.BatteriesDischarging) + { + var battery = state.Batteries[batteryId]; + if (!battery.Enabled || battery.TempMaxSupply == 0 || battery.Paused) + continue; + + var ratio = battery.TempMaxSupply / availableSupplySum; + battery.CurrentSupply = ratio * met; + + battery.CurrentStorage = Math.Max( + 0, + battery.CurrentStorage - frameTime * battery.CurrentSupply); + + battery.SupplyRampTarget = battery.CurrentSupply - battery.CurrentReceiving * battery.Efficiency; + + /*var maxSupplyRatio = supply.MaxSupply / maxSupplySum; + + supply.SupplyRampTarget = maxSupplyRatio * demand;*/ + battery.SupplyingMarked = true; + } + } + } + + // Clear supplying/loading on any batteries that haven't been marked by usage. + // Because we need this data while processing ramp-pegging, we can't clear it at the start. + foreach (var battery in state.Batteries.Values) + { + if (battery.Paused) + continue; + + if (!battery.SupplyingMarked) + battery.CurrentSupply = 0; + + if (!battery.LoadingMarked) + battery.CurrentReceiving = 0; + + if (!battery.LoadingDemandMarked) + battery.LoadingNetworkDemand = 0; + + battery.SupplyingMarked = false; + battery.LoadingMarked = false; + battery.LoadingDemandMarked = false; + } + + PowerSolverShared.UpdateRampPositions(frameTime, state); + } + + private static void EstimateNetworkDepth(PowerState state, Network network) + { + network.HeightTouched = true; + + if (network.BatteriesCharging.Count == 0) + { + network.Height = 1; + return; + } + + var max = 0; + foreach (var batteryId in network.BatteriesCharging) + { + var battery = state.Batteries[batteryId]; + + if (battery.LinkedNetworkDischarging == default) + continue; + + var subNet = state.Networks[battery.LinkedNetworkDischarging]; + if (!subNet.HeightTouched) + EstimateNetworkDepth(state, subNet); + + max = Math.Max(subNet.Height, max); + } + + network.Height = 1 + max; + } + } +} diff --git a/Content.Server/Power/Pow3r/GraphWalkSolver.cs b/Content.Server/Power/Pow3r/GraphWalkSolver.cs new file mode 100644 index 0000000000..981aad8120 --- /dev/null +++ b/Content.Server/Power/Pow3r/GraphWalkSolver.cs @@ -0,0 +1,181 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using static Content.Server.Power.Pow3r.PowerState; + +namespace Content.Server.Power.Pow3r +{ + /// + /// Partial implementation of full-graph-walking power solving under pow3r. + /// Concept described at https://hackmd.io/@ss14/lowpower + /// + /// + /// Many features like batteries, cycle detection, join handling, etc... are not implemented at all. + /// Seriously, this implementation barely works. Ah well. + /// is better. + /// + public class GraphWalkSolver : IPowerSolver + { + public void Tick(float frameTime, PowerState state) + { + foreach (var load in state.Loads.Values) + { + load.ReceivingPower = 0; + } + + foreach (var supply in state.Supplies.Values) + { + supply.CurrentSupply = 0; + } + + foreach (var network in state.Networks.Values) + { + // Clear some stuff. + network.LocalDemandMet = 0; + + // Add up demands in network. + network.LocalDemandTotal = network.Loads + .Select(l => state.Loads[l]) + .Where(c => c.Enabled) + .Sum(c => c.DesiredPower); + + // Add up supplies in network. + var availableSupplySum = 0f; + var maxSupplySum = 0f; + foreach (var supplyId in network.Supplies) + { + var supply = state.Supplies[supplyId]; + if (!supply.Enabled) + continue; + + var rampMax = supply.SupplyRampPosition + supply.SupplyRampTolerance; + var effectiveSupply = Math.Min(rampMax, supply.MaxSupply); + supply.EffectiveMaxSupply = effectiveSupply; + availableSupplySum += effectiveSupply; + maxSupplySum += supply.MaxSupply; + } + + network.AvailableSupplyTotal = availableSupplySum; + network.TheoreticalSupplyTotal = maxSupplySum; + } + + // Sort networks by tree height so that suppliers that have less possible loads go FIRST. + // Idea being that a backup generator on a small subnet should do more work + // so that a larger generator that covers more networks can put its power elsewhere. + var sortedByHeight = state.Networks.Values.OrderBy(v => TotalSubLoadCount(state, v)).ToArray(); + + // Go over every network with supply to send power. + foreach (var network in sortedByHeight) + { + // Find all loads recursively, and sum them up. + var subNets = new List(); + var totalDemand = 0f; + GetLoadingNetworksRecursively(state, network, subNets, ref totalDemand); + + if (totalDemand == 0) + continue; + + // Calculate power delivered. + var power = Math.Min(totalDemand, network.AvailableSupplyTotal); + + // Distribute load across supplies in network. + foreach (var supplyId in network.Supplies) + { + var supply = state.Supplies[supplyId]; + if (!supply.Enabled) + continue; + + if (supply.EffectiveMaxSupply != 0) + { + var ratio = supply.EffectiveMaxSupply / network.AvailableSupplyTotal; + + supply.CurrentSupply = ratio * power; + } + else + { + supply.CurrentSupply = 0; + } + + if (supply.MaxSupply != 0) + { + var ratio = supply.MaxSupply / network.TheoreticalSupplyTotal; + + supply.SupplyRampTarget = ratio * totalDemand; + } + else + { + supply.SupplyRampTarget = 0; + } + } + + // Distribute supply across subnet loads. + foreach (var subNet in subNets) + { + var rem = subNet.RemainingDemand; + var ratio = rem / totalDemand; + + subNet.LocalDemandMet += ratio * power; + } + } + + // Distribute power across loads in networks. + foreach (var network in state.Networks.Values) + { + if (network.LocalDemandMet == 0) + continue; + + foreach (var loadId in network.Loads) + { + var load = state.Loads[loadId]; + if (!load.Enabled) + continue; + + var ratio = load.DesiredPower / network.LocalDemandTotal; + load.ReceivingPower = ratio * network.LocalDemandMet; + } + } + + PowerSolverShared.UpdateRampPositions(frameTime, state); + } + + private int TotalSubLoadCount(PowerState state, Network network) + { + // TODO: Cycle detection. + var height = network.Loads.Count; + + foreach (var batteryId in network.BatteriesCharging) + { + var battery = state.Batteries[batteryId]; + if (battery.LinkedNetworkDischarging != default) + { + height += TotalSubLoadCount(state, state.Networks[battery.LinkedNetworkDischarging]); + } + } + + return height; + } + + private void GetLoadingNetworksRecursively( + PowerState state, + Network network, + List networks, + ref float totalDemand) + { + networks.Add(network); + totalDemand += network.LocalDemandTotal - network.LocalDemandMet; + + foreach (var batteryId in network.BatteriesCharging) + { + var battery = state.Batteries[batteryId]; + if (battery.LinkedNetworkDischarging != default) + { + GetLoadingNetworksRecursively( + state, + state.Networks[battery.LinkedNetworkDischarging], + networks, + ref totalDemand); + } + } + } + } +} diff --git a/Content.Server/Power/Pow3r/IPowerSolver.cs b/Content.Server/Power/Pow3r/IPowerSolver.cs new file mode 100644 index 0000000000..af1fe2d035 --- /dev/null +++ b/Content.Server/Power/Pow3r/IPowerSolver.cs @@ -0,0 +1,7 @@ +namespace Content.Server.Power.Pow3r +{ + public interface IPowerSolver + { + void Tick(float frameTime, PowerState state); + } +} diff --git a/Content.Server/Power/Pow3r/NoOpSolver.cs b/Content.Server/Power/Pow3r/NoOpSolver.cs new file mode 100644 index 0000000000..fa54a8b80d --- /dev/null +++ b/Content.Server/Power/Pow3r/NoOpSolver.cs @@ -0,0 +1,10 @@ +namespace Content.Server.Power.Pow3r +{ + public sealed class NoOpSolver : IPowerSolver + { + public void Tick(float frameTime, PowerState state) + { + // Literally nothing. + } + } +} diff --git a/Content.Server/Power/Pow3r/PowerSolverShared.cs b/Content.Server/Power/Pow3r/PowerSolverShared.cs new file mode 100644 index 0000000000..f9ef3cead5 --- /dev/null +++ b/Content.Server/Power/Pow3r/PowerSolverShared.cs @@ -0,0 +1,90 @@ +using System; + +namespace Content.Server.Power.Pow3r +{ + public static class PowerSolverShared + { + public static void UpdateRampPositions(float frameTime, PowerState state) + { + // Update supplies to move their ramp position towards target, if necessary. + foreach (var supply in state.Supplies.Values) + { + if (supply.Paused) + continue; + + if (!supply.Enabled) + { + // If disabled, set ramp to 0. + supply.SupplyRampPosition = 0; + continue; + } + + var rampDev = supply.SupplyRampTarget - supply.SupplyRampPosition; + if (Math.Abs(rampDev) > 0.001f) + { + float newPos; + if (rampDev > 0) + { + // Position below target, go up. + newPos = Math.Min( + supply.SupplyRampTarget, + supply.SupplyRampPosition + supply.SupplyRampRate * frameTime); + } + else + { + // Other way around, go down + newPos = Math.Max( + supply.SupplyRampTarget, + supply.SupplyRampPosition - supply.SupplyRampRate * frameTime); + } + + supply.SupplyRampPosition = Math.Clamp(newPos, 0, supply.MaxSupply); + } + else + { + supply.SupplyRampPosition = supply.SupplyRampTarget; + } + } + + // Batteries too. + foreach (var battery in state.Batteries.Values) + { + if (battery.Paused) + continue; + + if (!battery.Enabled) + { + // If disabled, set ramp to 0. + battery.SupplyRampPosition = 0; + continue; + } + + var rampDev = battery.SupplyRampTarget - battery.SupplyRampPosition; + if (Math.Abs(rampDev) > 0.001f) + { + float newPos; + if (rampDev > 0) + { + // Position below target, go up. + newPos = Math.Min( + battery.SupplyRampTarget, + battery.SupplyRampPosition + battery.SupplyRampRate * frameTime); + } + else + { + // Other way around, go down + newPos = Math.Max( + battery.SupplyRampTarget, + battery.SupplyRampPosition - battery.SupplyRampRate * frameTime); + } + + battery.SupplyRampPosition = Math.Clamp(newPos, 0, battery.MaxSupply); + } + else + { + battery.SupplyRampPosition = battery.SupplyRampTarget; + } + } + } + } +} diff --git a/Content.Server/Power/Pow3r/PowerState.cs b/Content.Server/Power/Pow3r/PowerState.cs new file mode 100644 index 0000000000..276fc785a9 --- /dev/null +++ b/Content.Server/Power/Pow3r/PowerState.cs @@ -0,0 +1,207 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Numerics; +using System.Text.Json; +using System.Text.Json.Serialization; +using Robust.Shared.ViewVariables; + +namespace Content.Server.Power.Pow3r +{ + public sealed class PowerState + { + public const int MaxTickData = 180; + + public static readonly JsonSerializerOptions SerializerOptions = new() + { + IncludeFields = true, + Converters = {new NodeIdJsonConverter()} + }; + + public Dictionary Supplies = new(); + public Dictionary Networks = new(); + public Dictionary Loads = new(); + public Dictionary Batteries = new(); + + public readonly struct NodeId : IEquatable + { + public readonly int Id; + + public NodeId(int id) + { + Id = id; + } + + public bool Equals(NodeId other) + { + return Id == other.Id; + } + + public override bool Equals(object? obj) + { + return obj is NodeId other && Equals(other); + } + + public override int GetHashCode() + { + return Id; + } + + public static bool operator ==(NodeId left, NodeId right) + { + return left.Equals(right); + } + + public static bool operator !=(NodeId left, NodeId right) + { + return !left.Equals(right); + } + + public override string ToString() + { + return Id.ToString(); + } + } + + public sealed class NodeIdJsonConverter : JsonConverter + { + public override NodeId Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + return new(reader.GetInt32()); + } + + public override void Write(Utf8JsonWriter writer, NodeId value, JsonSerializerOptions options) + { + writer.WriteNumberValue(value.Id); + } + } + + public sealed class Supply + { + [ViewVariables] public NodeId Id; + + // == Static parameters == + [ViewVariables(VVAccess.ReadWrite)] public bool Enabled = true; + [ViewVariables(VVAccess.ReadWrite)] public bool Paused; + [ViewVariables(VVAccess.ReadWrite)] public float MaxSupply; + + [ViewVariables(VVAccess.ReadWrite)] public float SupplyRampRate; + [ViewVariables(VVAccess.ReadWrite)] public float SupplyRampTolerance; + + // == Runtime parameters == + + // Actual power supplied last network update. + [ViewVariables(VVAccess.ReadWrite)] public float CurrentSupply; + + // The amount of power we WANT to be supplying to match grid load. + [ViewVariables(VVAccess.ReadWrite)] [JsonIgnore] + public float SupplyRampTarget; + + // Position of the supply ramp. + [ViewVariables(VVAccess.ReadWrite)] public float SupplyRampPosition; + + [ViewVariables] [JsonIgnore] public NodeId LinkedNetwork; + + // In-tick max supply thanks to ramp. Used during calculations. + [JsonIgnore] public float EffectiveMaxSupply; + } + + public sealed class Load + { + [ViewVariables] public NodeId Id; + + // == Static parameters == + [ViewVariables(VVAccess.ReadWrite)] public bool Enabled = true; + [ViewVariables(VVAccess.ReadWrite)] public bool Paused; + [ViewVariables(VVAccess.ReadWrite)] public float DesiredPower; + + // == Runtime parameters == + [ViewVariables(VVAccess.ReadWrite)] public float ReceivingPower; + + [ViewVariables] [JsonIgnore] public NodeId LinkedNetwork; + } + + public sealed class Battery + { + [ViewVariables] public NodeId Id; + + // == Static parameters == + [ViewVariables(VVAccess.ReadWrite)] public bool Enabled = true; + [ViewVariables(VVAccess.ReadWrite)] public bool Paused; + [ViewVariables(VVAccess.ReadWrite)] public bool CanDischarge = true; + [ViewVariables(VVAccess.ReadWrite)] public bool CanCharge = true; + [ViewVariables(VVAccess.ReadWrite)] public float Capacity; + [ViewVariables(VVAccess.ReadWrite)] public float MaxChargeRate; + [ViewVariables(VVAccess.ReadWrite)] public float MaxThroughput; // 0 = infinite cuz imgui + [ViewVariables(VVAccess.ReadWrite)] public float MaxSupply; + [ViewVariables(VVAccess.ReadWrite)] public float SupplyRampTolerance; + [ViewVariables(VVAccess.ReadWrite)] public float SupplyRampRate; + [ViewVariables(VVAccess.ReadWrite)] public float Efficiency = 1; + + // == Runtime parameters == + [ViewVariables(VVAccess.ReadWrite)] public float SupplyRampPosition; + [ViewVariables(VVAccess.ReadWrite)] public float CurrentSupply; + [ViewVariables(VVAccess.ReadWrite)] public float CurrentStorage; + [ViewVariables(VVAccess.ReadWrite)] public float CurrentReceiving; + [ViewVariables(VVAccess.ReadWrite)] public float LoadingNetworkDemand; + + [ViewVariables(VVAccess.ReadWrite)] [JsonIgnore] + public bool SupplyingMarked; + + [ViewVariables(VVAccess.ReadWrite)] [JsonIgnore] + public bool LoadingMarked; + + [ViewVariables(VVAccess.ReadWrite)] [JsonIgnore] + public bool LoadingDemandMarked; + + [ViewVariables(VVAccess.ReadWrite)] [JsonIgnore] + public float TempMaxSupply; + + [ViewVariables(VVAccess.ReadWrite)] [JsonIgnore] + public float DesiredPower; + + [ViewVariables(VVAccess.ReadWrite)] [JsonIgnore] + public float SupplyRampTarget; + + [ViewVariables(VVAccess.ReadWrite)] [JsonIgnore] + public NodeId LinkedNetworkCharging; + + [ViewVariables(VVAccess.ReadWrite)] [JsonIgnore] + public NodeId LinkedNetworkDischarging; + } + + // Readonly breaks json serialization. + [SuppressMessage("ReSharper", "FieldCanBeMadeReadOnly.Local")] + public sealed class Network + { + [ViewVariables] public NodeId Id; + + [ViewVariables] public List Supplies = new(); + + [ViewVariables] public List Loads = new(); + + // "Loading" means the network is connected to the INPUT port of the battery. + [ViewVariables] public List BatteriesCharging = new(); + + // "Supplying" means the network is connected to the OUTPUT port of the battery. + [ViewVariables] public List BatteriesDischarging = new(); + + // Calculation parameters used by GraphWalkSolver. + // Unused by BatteryRampPegSolver. + [JsonIgnore] public float LocalDemandTotal; + [JsonIgnore] public float LocalDemandMet; + [JsonIgnore] public float GroupDemandTotal; + [JsonIgnore] public float GroupDemandMet; + + [ViewVariables] [JsonIgnore] public int Height; + [JsonIgnore] public bool HeightTouched; + + // Supply available this tick. + [JsonIgnore] public float AvailableSupplyTotal; + + // Max theoretical supply assuming max ramp. + [JsonIgnore] public float TheoreticalSupplyTotal; + public float RemainingDemand => LocalDemandTotal - LocalDemandMet; + } + } +} diff --git a/Content.Server/SMES/PowerSmesSystem.cs b/Content.Server/Power/SMES/PowerSmesSystem.cs similarity index 91% rename from Content.Server/SMES/PowerSmesSystem.cs rename to Content.Server/Power/SMES/PowerSmesSystem.cs index 1bccbecbcf..bf66d9daa0 100644 --- a/Content.Server/SMES/PowerSmesSystem.cs +++ b/Content.Server/Power/SMES/PowerSmesSystem.cs @@ -2,7 +2,7 @@ using JetBrains.Annotations; using Robust.Shared.GameObjects; -namespace Content.Server.SMES +namespace Content.Server.Power.SMES { [UsedImplicitly] internal class PowerSmesSystem : EntitySystem diff --git a/Content.Server/SMES/SmesComponent.cs b/Content.Server/Power/SMES/SmesComponent.cs similarity index 81% rename from Content.Server/SMES/SmesComponent.cs rename to Content.Server/Power/SMES/SmesComponent.cs index c511f5bf11..903d616011 100644 --- a/Content.Server/SMES/SmesComponent.cs +++ b/Content.Server/Power/SMES/SmesComponent.cs @@ -1,6 +1,5 @@ #nullable enable using System; -using Content.Server.Battery.Components; using Content.Server.Power.Components; using Content.Shared.Power; using Content.Shared.Rounding; @@ -10,7 +9,7 @@ using Robust.Shared.GameObjects; using Robust.Shared.IoC; using Robust.Shared.Timing; -namespace Content.Server.SMES +namespace Content.Server.Power.SMES { /// /// Handles the "user-facing" side of the actual SMES object. @@ -80,20 +79,13 @@ namespace Content.Server.SMES private ChargeState GetNewChargeState() { - var supplier = Owner.GetComponent(); - var consumer = Owner.GetComponent(); - if (supplier.SupplyRate > 0 && consumer.DrawRate != consumer.ReceivedPower) + var battery = Owner.GetComponent(); + return (battery.CurrentSupply - battery.CurrentReceiving) switch { - return ChargeState.Discharging; - } - else if (supplier.SupplyRate == 0 && consumer.DrawRate > 0) - { - return ChargeState.Charging; - } - else - { - return ChargeState.Still; - } + > 0 => ChargeState.Discharging, + < 0 => ChargeState.Charging, + _ => ChargeState.Still + }; } } } diff --git a/Content.Server/PowerCell/Components/PowerCellChargerComponent.cs b/Content.Server/PowerCell/Components/PowerCellChargerComponent.cs index 8548ff020b..80cfa844ac 100644 --- a/Content.Server/PowerCell/Components/PowerCellChargerComponent.cs +++ b/Content.Server/PowerCell/Components/PowerCellChargerComponent.cs @@ -1,5 +1,4 @@ #nullable enable -using Content.Server.Battery.Components; using Content.Server.Power.Components; using Content.Shared.Interaction; using Robust.Shared.GameObjects; diff --git a/Content.Server/PowerCell/Components/PowerCellComponent.cs b/Content.Server/PowerCell/Components/PowerCellComponent.cs index 05b951913a..2ba23bf120 100644 --- a/Content.Server/PowerCell/Components/PowerCellComponent.cs +++ b/Content.Server/PowerCell/Components/PowerCellComponent.cs @@ -1,8 +1,8 @@ #nullable enable using System; -using Content.Server.Battery.Components; using Content.Server.Chemistry.Components; using Content.Server.Explosion; +using Content.Server.Power.Components; using Content.Shared.Chemistry; using Content.Shared.Examine; using Content.Shared.PowerCell; diff --git a/Content.Server/Recycling/Components/RecyclerComponent.cs b/Content.Server/Recycling/Components/RecyclerComponent.cs index 1c1073b0a1..bf0b04b219 100644 --- a/Content.Server/Recycling/Components/RecyclerComponent.cs +++ b/Content.Server/Recycling/Components/RecyclerComponent.cs @@ -47,7 +47,7 @@ namespace Content.Server.Recycling.Components private float _efficiency = 0.25f; private bool Powered => - !Owner.TryGetComponent(out PowerReceiverComponent? receiver) || + !Owner.TryGetComponent(out ApcPowerReceiverComponent? receiver) || receiver.Powered; private void Bloodstain() @@ -97,7 +97,7 @@ namespace Content.Server.Recycling.Components public bool CanRun() { - if (Owner.TryGetComponent(out PowerReceiverComponent? receiver) && + if (Owner.TryGetComponent(out ApcPowerReceiverComponent? receiver) && !receiver.Powered) { return false; diff --git a/Content.Server/Research/Components/ResearchConsoleComponent.cs b/Content.Server/Research/Components/ResearchConsoleComponent.cs index b6cdea4c1a..da1dea4ff9 100644 --- a/Content.Server/Research/Components/ResearchConsoleComponent.cs +++ b/Content.Server/Research/Components/ResearchConsoleComponent.cs @@ -26,7 +26,7 @@ namespace Content.Server.Research.Components private const string SoundCollectionName = "keyboard"; - [ViewVariables] private bool Powered => !Owner.TryGetComponent(out PowerReceiverComponent? receiver) || receiver.Powered; + [ViewVariables] private bool Powered => !Owner.TryGetComponent(out ApcPowerReceiverComponent? receiver) || receiver.Powered; [ViewVariables] private BoundUserInterface? UserInterface => Owner.GetUIOrNull(ResearchConsoleUiKey.Key); diff --git a/Content.Server/Research/Components/ResearchPointSourceComponent.cs b/Content.Server/Research/Components/ResearchPointSourceComponent.cs index 4eaeeff0b8..39d95fe36d 100644 --- a/Content.Server/Research/Components/ResearchPointSourceComponent.cs +++ b/Content.Server/Research/Components/ResearchPointSourceComponent.cs @@ -16,7 +16,7 @@ namespace Content.Server.Research.Components private int _pointsPerSecond; [DataField("active")] private bool _active; - private PowerReceiverComponent? _powerReceiver; + private ApcPowerReceiverComponent? _powerReceiver; [ViewVariables(VVAccess.ReadWrite)] public int PointsPerSecond @@ -35,7 +35,7 @@ namespace Content.Server.Research.Components /// /// Whether this can be used to produce research points. /// - /// If no is found, it's assumed power is not required. + /// If no is found, it's assumed power is not required. [ViewVariables] public bool CanProduce => Active && (_powerReceiver is null || _powerReceiver.Powered); diff --git a/Content.Server/Research/Components/ResearchServerComponent.cs b/Content.Server/Research/Components/ResearchServerComponent.cs index f8e8368afb..fada87fc84 100644 --- a/Content.Server/Research/Components/ResearchServerComponent.cs +++ b/Content.Server/Research/Components/ResearchServerComponent.cs @@ -61,11 +61,11 @@ namespace Content.Server.Research.Components } } - /// If no is found, it's assumed power is not required. + /// If no is found, it's assumed power is not required. [ViewVariables] public bool CanRun => _powerReceiver is null || _powerReceiver.Powered; - private PowerReceiverComponent? _powerReceiver; + private ApcPowerReceiverComponent? _powerReceiver; protected override void Initialize() { diff --git a/Content.Server/Singularity/Components/EmitterComponent.cs b/Content.Server/Singularity/Components/EmitterComponent.cs index 6571234b1d..cf87e7955c 100644 --- a/Content.Server/Singularity/Components/EmitterComponent.cs +++ b/Content.Server/Singularity/Components/EmitterComponent.cs @@ -44,7 +44,7 @@ namespace Content.Server.Singularity.Components private PowerConsumerComponent _powerConsumer = default!; // whether the power switch is in "on" - [ViewVariables] private bool _isOn; + [ViewVariables] public bool IsOn { get; private set; } // Whether the power switch is on AND the machine has enough power (so is actively firing) [ViewVariables] private bool _isPowered; [ViewVariables] private bool _isLocked; @@ -64,32 +64,6 @@ namespace Content.Server.Singularity.Components [ViewVariables(VVAccess.ReadWrite)] [DataField("fireBurstDelayMin")] private TimeSpan _fireBurstDelayMin = TimeSpan.FromSeconds(2); [ViewVariables(VVAccess.ReadWrite)] [DataField("fireBurstDelayMax")] private TimeSpan _fireBurstDelayMax = TimeSpan.FromSeconds(10); - protected override void Initialize() - { - base.Initialize(); - - Owner.EnsureComponent(out _powerConsumer); - - _powerConsumer.OnReceivedPowerChanged += OnReceivedPowerChanged; - } - - private void OnReceivedPowerChanged(object? sender, ReceivedPowerChangedEventArgs e) - { - if (!_isOn) - { - return; - } - - if (e.ReceivedPower < e.DrawRate) - { - PowerOff(); - } - else - { - PowerOn(); - } - } - void IActivate.Activate(ActivateEventArgs eventArgs) { if (_isLocked) @@ -100,7 +74,7 @@ namespace Content.Server.Singularity.Components if (Owner.TryGetComponent(out PhysicsComponent? phys) && phys.BodyType == BodyType.Static) { - if (!_isOn) + if (!IsOn) { SwitchOn(); Owner.PopupMessage(eventArgs.User, Loc.GetString("comp-emitter-turned-on", ("target", Owner))); @@ -149,7 +123,7 @@ namespace Content.Server.Singularity.Components public void SwitchOff() { - _isOn = false; + IsOn = false; _powerConsumer.DrawRate = 0; PowerOff(); UpdateAppearance(); @@ -157,14 +131,14 @@ namespace Content.Server.Singularity.Components public void SwitchOn() { - _isOn = true; + IsOn = true; _powerConsumer.DrawRate = _powerUseActive; // Do not directly PowerOn(). // OnReceivedPowerChanged will get fired due to DrawRate change which will turn it on. UpdateAppearance(); } - private void PowerOff() + public void PowerOff() { if (!_isPowered) { @@ -180,7 +154,7 @@ namespace Content.Server.Singularity.Components UpdateAppearance(); } - private void PowerOn() + public void PowerOn() { if (_isPowered) { @@ -202,7 +176,7 @@ namespace Content.Server.Singularity.Components // Any power-off condition should result in the timer for this method being cancelled // and thus not firing DebugTools.Assert(_isPowered); - DebugTools.Assert(_isOn); + DebugTools.Assert(IsOn); DebugTools.Assert(_powerConsumer.DrawRate <= _powerConsumer.ReceivedPower); Fire(); @@ -269,7 +243,7 @@ namespace Content.Server.Singularity.Components { state = EmitterVisualState.On; } - else if (_isOn) + else if (IsOn) { state = EmitterVisualState.Underpowered; } diff --git a/Content.Server/Singularity/Components/RadiationCollectorComponent.cs b/Content.Server/Singularity/Components/RadiationCollectorComponent.cs index 31c4413f58..84a05b155b 100644 --- a/Content.Server/Singularity/Components/RadiationCollectorComponent.cs +++ b/Content.Server/Singularity/Components/RadiationCollectorComponent.cs @@ -1,9 +1,7 @@ #nullable enable using System; -using Content.Server.Battery.Components; using Content.Server.Power.Components; using Content.Shared.Interaction; -using Content.Shared.Notification; using Content.Shared.Notification.Managers; using Content.Shared.Radiation; using Content.Shared.Singularity.Components; @@ -37,7 +35,6 @@ namespace Content.Server.Singularity.Components } [ComponentDependency] private readonly BatteryComponent? _batteryComponent = default!; - [ComponentDependency] private readonly BatteryDischargerComponent? _batteryDischargerComponent = default!; bool IInteractHand.InteractHand(InteractHandEventArgs eventArgs) { @@ -74,12 +71,6 @@ namespace Content.Server.Singularity.Components if (_batteryComponent != null) { _batteryComponent!.CurrentCharge += frameTime * radiation.RadsPerSecond * 3000f; - if (_batteryDischargerComponent != null) - { - // The battery discharger is controlled like this to ensure it won't drain the entire battery in a single tick. - // If that occurs then the battery discharger ends up shutting down. - _batteryDischargerComponent!.ActiveSupplyRate = (int) Math.Max(1, _batteryComponent!.CurrentCharge); - } } } diff --git a/Content.Server/Singularity/EntitySystems/EmitterSystem.cs b/Content.Server/Singularity/EntitySystems/EmitterSystem.cs new file mode 100644 index 0000000000..5f3fc0c83d --- /dev/null +++ b/Content.Server/Singularity/EntitySystems/EmitterSystem.cs @@ -0,0 +1,38 @@ +using Content.Server.Power.EntitySystems; +using Content.Server.Singularity.Components; +using JetBrains.Annotations; +using Robust.Shared.GameObjects; + +namespace Content.Server.Singularity.EntitySystems +{ + [UsedImplicitly] + public class EmitterSystem : EntitySystem + { + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(ReceivedChanged); + } + + private static void ReceivedChanged( + EntityUid uid, + EmitterComponent component, + PowerConsumerReceivedChanged args) + { + if (!component.IsOn) + { + return; + } + + if (args.ReceivedPower < args.DrawRate) + { + component.PowerOff(); + } + else + { + component.PowerOn(); + } + } + } +} diff --git a/Content.Server/Solar/Components/SolarPanelComponent.cs b/Content.Server/Solar/Components/SolarPanelComponent.cs index 1c82915ed0..d4f918beb6 100644 --- a/Content.Server/Solar/Components/SolarPanelComponent.cs +++ b/Content.Server/Solar/Components/SolarPanelComponent.cs @@ -67,7 +67,7 @@ namespace Content.Server.Solar.Components { if (Owner.TryGetComponent(out var supplier)) { - supplier.SupplyRate = (int) (_maxSupply * _coverage); + supplier.MaxSupply = (int) (_maxSupply * _coverage); } } diff --git a/Content.Server/StationEvents/Events/PowerGridCheck.cs b/Content.Server/StationEvents/Events/PowerGridCheck.cs index 0d44829a18..6ff0b78e1a 100644 --- a/Content.Server/StationEvents/Events/PowerGridCheck.cs +++ b/Content.Server/StationEvents/Events/PowerGridCheck.cs @@ -41,7 +41,7 @@ namespace Content.Server.StationEvents.Events { var componentManager = IoCManager.Resolve(); - foreach (var component in componentManager.EntityQuery(true)) + foreach (var component in componentManager.EntityQuery(true)) { component.PowerDisabled = true; _powered.Add(component.Owner); @@ -56,7 +56,7 @@ namespace Content.Server.StationEvents.Events { if (entity.Deleted) continue; - if (entity.TryGetComponent(out PowerReceiverComponent? powerReceiverComponent)) + if (entity.TryGetComponent(out ApcPowerReceiverComponent? powerReceiverComponent)) { powerReceiverComponent.PowerDisabled = false; } diff --git a/Content.Server/VendingMachines/VendingMachineComponent.cs b/Content.Server/VendingMachines/VendingMachineComponent.cs index f0a6ce7000..4b4bd3bca6 100644 --- a/Content.Server/VendingMachines/VendingMachineComponent.cs +++ b/Content.Server/VendingMachines/VendingMachineComponent.cs @@ -7,7 +7,7 @@ using Content.Server.Advertise; using Content.Server.Notification; using Content.Server.Power.Components; using Content.Server.UserInterface; -using Content.Server.Wires.Components; +using Content.Server.WireHacking; using Content.Shared.Acts; using Content.Shared.Examine; using Content.Shared.Interaction; @@ -41,7 +41,7 @@ namespace Content.Server.VendingMachines private string? _description; private string _spriteName = ""; - private bool Powered => !Owner.TryGetComponent(out PowerReceiverComponent? receiver) || receiver.Powered; + private bool Powered => !Owner.TryGetComponent(out ApcPowerReceiverComponent? receiver) || receiver.Powered; private bool _broken; [DataField("soundVend")] @@ -108,7 +108,7 @@ namespace Content.Server.VendingMachines UserInterface.OnReceiveMessage += UserInterfaceOnOnReceiveMessage; } - if (Owner.TryGetComponent(out PowerReceiverComponent? receiver)) + if (Owner.TryGetComponent(out ApcPowerReceiverComponent? receiver)) { TrySetVisualState(receiver.Powered ? VendingMachineVisualState.Normal : VendingMachineVisualState.Off); } diff --git a/Content.Server/Weapon/Ranged/Barrels/Components/ServerBatteryBarrelComponent.cs b/Content.Server/Weapon/Ranged/Barrels/Components/ServerBatteryBarrelComponent.cs index 95b4aff527..9909470dac 100644 --- a/Content.Server/Weapon/Ranged/Barrels/Components/ServerBatteryBarrelComponent.cs +++ b/Content.Server/Weapon/Ranged/Barrels/Components/ServerBatteryBarrelComponent.cs @@ -1,9 +1,9 @@ using System; using System.Collections.Generic; using System.Threading.Tasks; -using Content.Server.Battery.Components; using Content.Server.Hands.Components; using Content.Server.Items; +using Content.Server.Power.Components; using Content.Server.Projectiles.Components; using Content.Shared.ActionBlocker; using Content.Shared.Damage; diff --git a/Content.Server/Weapon/WeaponCapacitorChargerComponent.cs b/Content.Server/Weapon/WeaponCapacitorChargerComponent.cs index adcfdf029a..956bfcb5c4 100644 --- a/Content.Server/Weapon/WeaponCapacitorChargerComponent.cs +++ b/Content.Server/Weapon/WeaponCapacitorChargerComponent.cs @@ -1,5 +1,4 @@ #nullable enable -using Content.Server.Battery.Components; using Content.Server.Power.Components; using Content.Server.PowerCell.Components; using Content.Server.Weapon.Ranged.Barrels.Components; diff --git a/Content.Server/Wires/WireHackingSystem.cs b/Content.Server/WireHacking/WireHackingSystem.cs similarity index 97% rename from Content.Server/Wires/WireHackingSystem.cs rename to Content.Server/WireHacking/WireHackingSystem.cs index 526db3ced7..99ed63bfb6 100644 --- a/Content.Server/Wires/WireHackingSystem.cs +++ b/Content.Server/WireHacking/WireHackingSystem.cs @@ -5,7 +5,7 @@ using Robust.Shared.GameObjects; using Robust.Shared.ViewVariables; using static Content.Shared.Wires.SharedWiresComponent; -namespace Content.Server.Wires +namespace Content.Server.WireHacking { public class WireHackingSystem : EntitySystem { diff --git a/Content.Server/Wires/Components/WiresComponent.cs b/Content.Server/WireHacking/WiresComponent.cs similarity index 99% rename from Content.Server/Wires/Components/WiresComponent.cs rename to Content.Server/WireHacking/WiresComponent.cs index 60d19b0e1f..e48b1959dc 100644 --- a/Content.Server/Wires/Components/WiresComponent.cs +++ b/Content.Server/WireHacking/WiresComponent.cs @@ -10,7 +10,6 @@ using Content.Server.VendingMachines; using Content.Shared.Examine; using Content.Shared.Interaction; using Content.Shared.Interaction.Helpers; -using Content.Shared.Notification; using Content.Shared.Notification.Managers; using Content.Shared.Tool; using Content.Shared.Wires; @@ -27,7 +26,7 @@ using Robust.Shared.Serialization.Manager.Attributes; using Robust.Shared.Utility; using Robust.Shared.ViewVariables; -namespace Content.Server.Wires.Components +namespace Content.Server.WireHacking { [RegisterComponent] public class WiresComponent : SharedWiresComponent, IInteractUsing, IExamine, IMapInit diff --git a/Content.Shared/Light/Component/SharedEmergencyLightComponent.cs b/Content.Shared/Light/Component/SharedEmergencyLightComponent.cs new file mode 100644 index 0000000000..b7f1e9a95a --- /dev/null +++ b/Content.Shared/Light/Component/SharedEmergencyLightComponent.cs @@ -0,0 +1,11 @@ +using System; +using Robust.Shared.Serialization; + +namespace Content.Shared.Light.Component +{ + [Serializable, NetSerializable] + public enum EmergencyLightVisuals + { + On, + } +} diff --git a/Content.Shared/NodeContainer/NodeVis.cs b/Content.Shared/NodeContainer/NodeVis.cs new file mode 100644 index 0000000000..d3f9ceb93a --- /dev/null +++ b/Content.Shared/NodeContainer/NodeVis.cs @@ -0,0 +1,48 @@ +using System; +using System.Collections.Generic; +using Robust.Shared.GameObjects; +using Robust.Shared.Maths; +using Robust.Shared.Serialization; + +namespace Content.Shared.NodeContainer +{ + public static class NodeVis + { + [Serializable, NetSerializable] + public sealed class MsgEnable : EntityEventArgs + { + public MsgEnable(bool enabled) + { + Enabled = enabled; + } + + public bool Enabled { get; } + } + + [Serializable, NetSerializable] + public sealed class MsgData : EntityEventArgs + { + public List Groups = new(); + public List GroupDeletions = new(); + } + + [Serializable, NetSerializable] + public sealed class GroupData + { + public int NetId; + public string GroupId = ""; + public Color Color; + public NodeDatum[] Nodes = Array.Empty(); + } + + [Serializable, NetSerializable] + public sealed class NodeDatum + { + public EntityUid Entity; + public int NetId; + public int[] Reachable = Array.Empty(); + public string Name = ""; + public string Type = ""; + } + } +} diff --git a/Content.Shared/Wires/SharedWireVisComponent.cs b/Content.Shared/Wires/SharedWireVisComponent.cs new file mode 100644 index 0000000000..df9f0837c2 --- /dev/null +++ b/Content.Shared/Wires/SharedWireVisComponent.cs @@ -0,0 +1,22 @@ +using System; +using Robust.Shared.Serialization; + +namespace Content.Shared.Wires +{ + [Serializable, NetSerializable] + public enum WireVisVisuals + { + ConnectedMask + } + + [Flags] + [Serializable, NetSerializable] + public enum WireVisDirFlags : byte + { + None = 0, + North = 1, + South = 2, + East = 4, + West = 8 + } +} diff --git a/Pow3r/LinqHelper.cs b/Pow3r/LinqHelper.cs new file mode 100644 index 0000000000..25ae91b090 --- /dev/null +++ b/Pow3r/LinqHelper.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; + +namespace Pow3r +{ + public static class LinqHelper + { + public static void ForEach(this IEnumerable enumerable, Action action) + { + foreach (var item in enumerable) + { + action(item); + } + } + } +} diff --git a/Pow3r/Pow3r.csproj b/Pow3r/Pow3r.csproj new file mode 100644 index 0000000000..d86f41e139 --- /dev/null +++ b/Pow3r/Pow3r.csproj @@ -0,0 +1,21 @@ + + + + Exe + net5.0 + true + + + + + + + + + + + + + + + diff --git a/Pow3r/Program.OpenGL.cs b/Pow3r/Program.OpenGL.cs new file mode 100644 index 0000000000..5ad123feed --- /dev/null +++ b/Pow3r/Program.OpenGL.cs @@ -0,0 +1,127 @@ +using System; +using System.Numerics; +using System.Text; +using System.Linq; +using ImGuiNET; +using OpenTK.Graphics.OpenGL; +using OpenTK.Windowing.GraphicsLibraryFramework; + +namespace Pow3r +{ + internal sealed unsafe partial class Program + { + private int _glFontTexture; + + private void InitOpenGL() + { + if (GL.GetString(StringName.Extensions).Split(' ').Contains("GL_ARB_debug_output")) + GL.Arb.DebugMessageCallback(GLDebugCallbackDelegate, (nint) 0x0105); + + GL.Enable(EnableCap.ScissorTest); + GL.Enable(EnableCap.Blend); + GL.BlendEquation(BlendEquationMode.FuncAdd); + GL.BlendFuncSeparate( + BlendingFactorSrc.SrcAlpha, + BlendingFactorDest.OneMinusSrcAlpha, + BlendingFactorSrc.One, + BlendingFactorDest.OneMinusSrcAlpha); + + var io = ImGui.GetIO(); + + io.Fonts.GetTexDataAsRGBA32(out byte* pixels, out var width, out var height, out _); + + _glFontTexture = GL.GenTexture(); + GL.BindTexture(TextureTarget.Texture2D, _glFontTexture); + GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, width, height, 0, PixelFormat.Bgra, PixelType.UnsignedByte, (nint) pixels); + GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int) TextureMagFilter.Nearest); + GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int) TextureMinFilter.Nearest); + GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int) TextureWrapMode.ClampToEdge); + GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int) TextureWrapMode.ClampToEdge); + + /* + GL.TextureParameter(_fontTexture, TextureParameterName.TextureSwizzleR, 1); + GL.TextureParameter(_fontTexture, TextureParameterName.TextureSwizzleG, 1); + GL.TextureParameter(_fontTexture, TextureParameterName.TextureSwizzleB, 1); + GL.TextureParameter(_fontTexture, TextureParameterName.TextureSwizzleA, (int) All.Red);*/ + + io.Fonts.SetTexID((nint) _glFontTexture); + io.Fonts.ClearTexData(); + } + + private void RenderOpenGL() + { + GLFW.GetFramebufferSize(_window.WindowPtr, out var fbW, out var fbH); + GL.Viewport(0, 0, fbW, fbH); + GL.Disable(EnableCap.ScissorTest); + GL.ClearColor(0, 0, 0, 1); + GL.Clear(ClearBufferMask.ColorBufferBit); + GL.Enable(EnableCap.ScissorTest); + GL.Enable(EnableCap.Texture2D); + + var drawData = ImGui.GetDrawData(); + + var l = drawData.DisplayPos.X; + var r = drawData.DisplayPos.X + drawData.DisplaySize.X; + var t = drawData.DisplayPos.Y; + var b = drawData.DisplayPos.Y + drawData.DisplaySize.Y; + + var matrix = Matrix4x4.CreateOrthographicOffCenter(l, r, b, t, -1, 1); + + GL.MatrixMode(MatrixMode.Projection); + GL.LoadMatrix((float*) &matrix); + + var clipOff = drawData.DisplayPos; + var clipScale = drawData.FramebufferScale; + + GL.EnableClientState(ArrayCap.VertexArray); + GL.EnableClientState(ArrayCap.TextureCoordArray); + GL.EnableClientState(ArrayCap.ColorArray); + + for (var n = 0; n < drawData.CmdListsCount; n++) + { + var drawList = drawData.CmdListsRange[n]; + + for (var cmdI = 0; cmdI < drawList.CmdBuffer.Size; cmdI++) + { + var cmd = drawList.CmdBuffer[cmdI]; + + GL.BindTexture(TextureTarget.Texture2D, (uint) cmd.TextureId); + + Vector4 clipRect = default; + clipRect.X = (cmd.ClipRect.X - clipOff.X) * clipScale.X; + clipRect.Y = (cmd.ClipRect.Y - clipOff.Y) * clipScale.Y; + clipRect.Z = (cmd.ClipRect.Z - clipOff.X) * clipScale.X; + clipRect.W = (cmd.ClipRect.W - clipOff.Y) * clipScale.Y; + + GL.Scissor((int) clipRect.X, (int) (fbH - clipRect.W), (int) (clipRect.Z - clipRect.X), + (int) (clipRect.W - clipRect.Y)); + + IntPtr adjustedVB = drawList.VtxBuffer.Data + (nint) (sizeof(ImDrawVert) * cmd.VtxOffset); + + GL.VertexPointer(2, VertexPointerType.Float, sizeof(ImDrawVert), adjustedVB); + GL.TexCoordPointer(2, TexCoordPointerType.Float, sizeof(ImDrawVert), adjustedVB + 8); + GL.ColorPointer(4, ColorPointerType.UnsignedByte, sizeof(ImDrawVert), adjustedVB + 16); + + GL.DrawElements(PrimitiveType.Triangles, (int) cmd.ElemCount, + DrawElementsType.UnsignedShort, + drawList.IdxBuffer.Data + (nint) (cmd.IdxOffset * 2)); + } + } + + _window.SwapBuffers(); + } + + private static readonly DebugProcArb GLDebugCallbackDelegate = GLDebugCallback; + + private static void GLDebugCallback(DebugSource source, DebugType type, int id, DebugSeverity severity, + int length, IntPtr message, IntPtr userParam) + { + var msg = Encoding.UTF8.GetString((byte*) message, length); + + if (severity == DebugSeverity.DebugSeverityNotification) + return; + + Console.WriteLine($"[{type}][{severity}] {source}: {msg}"); + } + } +} diff --git a/Pow3r/Program.SaveLoad.cs b/Pow3r/Program.SaveLoad.cs new file mode 100644 index 0000000000..2ffdc8eb4e --- /dev/null +++ b/Pow3r/Program.SaveLoad.cs @@ -0,0 +1,71 @@ +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text.Json; +using Content.Server.Power.Pow3r; +using static Content.Server.Power.Pow3r.PowerState; + +namespace Pow3r +{ + internal sealed partial class Program + { + private void LoadFromDisk() + { + if (!File.Exists("data.json")) + return; + + var dat = JsonSerializer.Deserialize(File.ReadAllBytes("data.json"), SerializerOptions); + + if (dat == null) + return; + + _paused = dat.Paused; + _nextId = dat.NextId; + _currentSolver = dat.Solver; + + _state = new PowerState + { + Networks = dat.Networks.ToDictionary(n => n.Id, n => n), + Supplies = dat.Supplies.ToDictionary(s => s.Id, s => s), + Loads = dat.Loads.ToDictionary(l => l.Id, l => l), + Batteries = dat.Batteries.ToDictionary(b => b.Id, b => b) + }; + + _displayLoads = dat.Loads.ToDictionary(n => n.Id, _ => new DisplayLoad()); + _displaySupplies = dat.Supplies.ToDictionary(n => n.Id, _ => new DisplaySupply()); + _displayBatteries = dat.Batteries.ToDictionary(n => n.Id, _ => new DisplayBattery()); + _displayNetworks = dat.Networks.ToDictionary(n => n.Id, _ => new DisplayNetwork()); + + RefreshLinks(); + } + + private void SaveToDisk() + { + var data = new DiskDat + { + Paused = _paused, + NextId = _nextId, + Solver = _currentSolver, + + Loads = _state.Loads.Values.ToList(), + Batteries = _state.Batteries.Values.ToList(), + Networks = _state.Networks.Values.ToList(), + Supplies = _state.Supplies.Values.ToList() + }; + + File.WriteAllBytes("data.json", JsonSerializer.SerializeToUtf8Bytes(data, SerializerOptions)); + } + + private sealed class DiskDat + { + public bool Paused; + public int NextId; + public int Solver; + + public List Loads; + public List Networks; + public List Supplies; + public List Batteries; + } + } +} diff --git a/Pow3r/Program.Simulation.cs b/Pow3r/Program.Simulation.cs new file mode 100644 index 0000000000..440e262f83 --- /dev/null +++ b/Pow3r/Program.Simulation.cs @@ -0,0 +1,137 @@ +using System.Collections.Generic; +using System.Diagnostics; +using Content.Server.Power.Pow3r; +using static Content.Server.Power.Pow3r.PowerState; + + +namespace Pow3r +{ + internal sealed partial class Program + { + private const int MaxTickData = 180; + + private int _nextId = 1; + private PowerState _state = new(); + private Network _linking; + private int _tickDataIdx; + private bool _paused; + + private readonly string[] _solverNames = + { + nameof(GraphWalkSolver), + nameof(BatteryRampPegSolver), + nameof(NoOpSolver) + }; + + private readonly IPowerSolver[] _solvers = { + new GraphWalkSolver(), + new BatteryRampPegSolver(), + new NoOpSolver() + }; + + private int _currentSolver; + + private readonly float[] _simTickTimes = new float[MaxTickData]; + private readonly Queue _remQueue = new(); + private readonly Stopwatch _simStopwatch = new Stopwatch(); + + private NodeId AllocId() + { + return new(_nextId++); + } + + private void Tick(float frameTime) + { + if (_paused) + return; + + RunSingleStep(frameTime); + } + + private void RunSingleStep(float frameTime) + { + _simStopwatch.Restart(); + _tickDataIdx = (_tickDataIdx + 1) % MaxTickData; + + _solvers[_currentSolver].Tick(frameTime, _state); + + // Update tick history. + foreach (var load in _state.Loads.Values) + { + var displayLoad = _displayLoads[load.Id]; + displayLoad.ReceivedPowerData[_tickDataIdx] = load.ReceivingPower; + } + + foreach (var supply in _state.Supplies.Values) + { + var displaySupply = _displaySupplies[supply.Id]; + displaySupply.SuppliedPowerData[_tickDataIdx] = supply.CurrentSupply; + } + + foreach (var battery in _state.Batteries.Values) + { + var displayBattery = _displayBatteries[battery.Id]; + displayBattery.StoredPowerData[_tickDataIdx] = battery.CurrentStorage; + displayBattery.ReceivingPowerData[_tickDataIdx] = battery.CurrentReceiving; + displayBattery.SuppliedPowerData[_tickDataIdx] = battery.CurrentSupply; + } + + _simTickTimes[_tickDataIdx] = (float) _simStopwatch.Elapsed.TotalMilliseconds; + } + + private void RunSingleStep() + { + RunSingleStep(1f/_tps); + } + + // Link data is stored authoritatively on networks, + // but for easy access it is replicated into the linked components. + // This is updated here. + private void RefreshLinks() + { + foreach (var battery in _state.Batteries.Values) + { + battery.LinkedNetworkCharging = default; + battery.LinkedNetworkDischarging = default; + } + + foreach (var load in _state.Loads.Values) + { + load.LinkedNetwork = default; + } + + foreach (var supply in _state.Supplies.Values) + { + supply.LinkedNetwork = default; + } + + foreach (var network in _state.Networks.Values) + { + foreach (var loadId in network.Loads) + { + var load = _state.Loads[loadId]; + load.LinkedNetwork = network.Id; + } + + foreach (var supplyId in network.Supplies) + { + var supply = _state.Supplies[supplyId]; + supply.LinkedNetwork = network.Id; + } + + foreach (var batteryId in network.BatteriesCharging) + { + var battery = _state.Batteries[batteryId]; + battery.LinkedNetworkCharging = network.Id; + } + + foreach (var batteryId in network.BatteriesDischarging) + { + var battery = _state.Batteries[batteryId]; + battery.LinkedNetworkDischarging = network.Id; + } + } + } + + } +} diff --git a/Pow3r/Program.UI.cs b/Pow3r/Program.UI.cs new file mode 100644 index 0000000000..96f7b90cf8 --- /dev/null +++ b/Pow3r/Program.UI.cs @@ -0,0 +1,459 @@ +using System; +using System.Collections.Generic; +using ImGuiNET; +using Robust.Shared.Maths; +using static ImGuiNET.ImGui; +using Color = System.Drawing.Color; +using Vector2 = System.Numerics.Vector2; +using RobustVec2 = Robust.Shared.Maths.Vector2; +using static Content.Server.Power.Pow3r.PowerState; + +namespace Pow3r +{ + internal sealed partial class Program + { + private bool _showDemo; + + private Dictionary _displayLoads = new(); + private Dictionary _displayBatteries = new(); + private Dictionary _displayNetworks = new(); + private Dictionary _displaySupplies = new(); + + private void DoUI(float frameTime) + { + if (BeginMainMenuBar()) + { + _showDemo ^= MenuItem("Demo"); + EndMainMenuBar(); + } + + SetNextWindowSize(new Vector2(150, 200)); + + Begin("CreateButtons", + ImGuiWindowFlags.NoTitleBar | + ImGuiWindowFlags.NoCollapse | + ImGuiWindowFlags.NoResize); + + if (Button("Generator")) + { + var id = AllocId(); + _state.Supplies.Add(id, new Supply { Id = id }); + _displaySupplies.Add(id, new DisplaySupply()); + } + + if (Button("Load")) + { + var id = AllocId(); + _state.Loads.Add(id, new Load { Id = id }); + _displayLoads.Add(id, new DisplayLoad()); + } + + if (Button("Network")) + { + var id = AllocId(); + _state.Networks.Add(id, new Network { Id = id }); + _displayNetworks.Add(id, new DisplayNetwork()); + } + + if (Button("Battery")) + { + var id = AllocId(); + _state.Batteries.Add(id, new Battery { Id = id }); + _displayBatteries.Add(id, new DisplayBattery()); + } + + Checkbox("Paused", ref _paused); + SliderInt("TPS", ref _tps, 1, 120); + SetNextItemWidth(-1); + Combo("", ref _currentSolver, _solverNames, _solverNames.Length); + + if (Button("Single step")) + RunSingleStep(); + + End(); + + Begin("Simulating timing"); + + PlotLines("Tick time (ms)", ref _simTickTimes[0], MaxTickData, _tickDataIdx + 1, + $"{_simTickTimes[_tickDataIdx]:N2}", + 0, + 0.1f, new Vector2(250, 150)); + + End(); + + Begin("Frame timings"); + + PlotLines("Frame (ms)", ref _frameTimings[0], _frameTimings.Length, _frameTimeIdx + 1, + $"{_frameTimings[_frameTimeIdx]:N2}", + 0, + 33.333f, new Vector2(250, 150)); + + End(); + + { + Begin("Memory"); + + var heap = GC.GetTotalMemory(false); + Text($"Managed heap: {heap>>20} MiB"); + + End(); + } + + foreach (var network in _state.Networks.Values) + { + var displayNetwork = _displayNetworks[network.Id]; + Begin($"Network {network.Id}##Gen{network.Id}"); + + Text($"Height: {network.Height}"); + + displayNetwork.CurrentWindowPos = CalcWindowCenter(); + + if (Button("Delete")) + { + _remQueue.Enqueue(network); + + if (_linking == network) + { + _linking = null; + } + } + + SameLine(); + + if (_linking != null) + { + if (_linking == network && Button("Cancel")) + { + _linking = null; + } + } + else + { + if (Button("Link...")) + { + _linking = network; + } + } + + End(); + } + + foreach (var load in _state.Loads.Values) + { + var displayLoad = _displayLoads[load.Id]; + + Begin($"Load {load.Id}##Load{load.Id}"); + + Checkbox("Enabled", ref load.Enabled); + SliderFloat("Desired", ref load.DesiredPower, 0, 1000, "%.0f W"); + + displayLoad.CurrentWindowPos = CalcWindowCenter(); + + PlotLines("", ref displayLoad.ReceivedPowerData[0], MaxTickData, _tickDataIdx + 1, + $"Receiving: {load.ReceivingPower:N1} W", + 0, + load.DesiredPower, new Vector2(250, 150)); + + if (Button("Delete")) + { + _remQueue.Enqueue(load); + } + + SameLine(); + if (_linking != null) + { + if (Button("Link")) + { + _linking.Loads.Add(load.Id); + _linking = null; + RefreshLinks(); + } + } + else + { + if (load.LinkedNetwork != default && Button("Unlink")) + { + var net = _state.Networks[load.LinkedNetwork]; + net.Loads.Remove(load.Id); + load.LinkedNetwork = default; + } + } + + End(); + } + + foreach (var supply in _state.Supplies.Values) + { + var displaySupply = _displaySupplies[supply.Id]; + Begin($"Generator {supply.Id}##Gen{supply.Id}"); + + Checkbox("Enabled", ref supply.Enabled); + SliderFloat("Available", ref supply.MaxSupply, 0, 1000, "%.0f W"); + SliderFloat("Ramp", ref supply.SupplyRampRate, 0, 100, "%.0f W/s"); + SliderFloat("Tolerance", ref supply.SupplyRampTolerance, 0, 100, "%.0f W"); + + displaySupply.CurrentWindowPos = CalcWindowCenter(); + + Text($"Ramp Position: {supply.SupplyRampPosition:N1}"); + + PlotLines("", ref displaySupply.SuppliedPowerData[0], MaxTickData, _tickDataIdx + 1, + $"Supply: {supply.CurrentSupply:N1} W", + 0, supply.MaxSupply, new Vector2(250, 150)); + + if (Button("Delete")) + { + _remQueue.Enqueue(supply); + } + + SameLine(); + if (_linking != null) + { + if (Button("Link")) + { + _linking.Supplies.Add(supply.Id); + _linking = null; + RefreshLinks(); + } + } + else + { + if (supply.LinkedNetwork != default && Button("Unlink")) + { + var net = _state.Networks[supply.LinkedNetwork]; + net.Supplies.Remove(supply.Id); + supply.LinkedNetwork = default; + } + } + + End(); + } + + foreach (var battery in _state.Batteries.Values) + { + var displayBattery = _displayBatteries[battery.Id]; + + Begin($"Battery {battery.Id}##Bat{battery.Id}"); + + Checkbox("Enabled", ref battery.Enabled); + SliderFloat("Capacity", ref battery.Capacity, 0, 100000, "%.0f J"); + SliderFloat("Max charge rate", ref battery.MaxChargeRate, 0, 1000, "%.0f W"); + SliderFloat("Max supply", ref battery.MaxSupply, 0, 1000, "%.0f W"); + SliderFloat("Ramp", ref battery.SupplyRampRate, 0, 100, "%.0f W/s"); + SliderFloat("Tolerance", ref battery.SupplyRampTolerance, 0, 100, "%.0f W"); + var percent = 100 * battery.Efficiency; + SliderFloat("Efficiency", ref percent, 0, 100, "%.0f %%"); + battery.Efficiency = percent / 100; + + displayBattery.CurrentWindowPos = CalcWindowCenter(); + + SliderFloat("Ramp position", ref battery.SupplyRampPosition, 0, battery.MaxSupply, "%.0f W"); + + PlotLines("", ref displayBattery.SuppliedPowerData[0], MaxTickData, _tickDataIdx + 1, + $"OUT: {battery.CurrentSupply:N1} W", + 0, battery.MaxSupply + 1000, new Vector2(250, 75)); + + PlotLines("", ref displayBattery.ReceivingPowerData[0], MaxTickData, _tickDataIdx + 1, + $"IN: {battery.CurrentReceiving:N1} W", + 0, battery.MaxChargeRate + 1000, new Vector2(250, 75)); + + PlotLines("", ref displayBattery.StoredPowerData[0], MaxTickData, _tickDataIdx + 1, + $"Charge: {battery.CurrentStorage:N1} J", + 0, battery.Capacity, new Vector2(250, 75)); + + if (Button("Delete")) + { + _remQueue.Enqueue(battery); + } + + SameLine(); + if (_linking != null) + { + if (battery.LinkedNetworkCharging == default && Button("Link as load")) + { + _linking.BatteriesCharging.Add(battery.Id); + _linking = null; + RefreshLinks(); + } + else + { + SameLine(); + if (battery.LinkedNetworkDischarging == default && Button("Link as supply")) + { + _linking.BatteriesDischarging.Add(battery.Id); + _linking = null; + RefreshLinks(); + } + } + } + else + { + if (battery.LinkedNetworkCharging != default && Button("Unlink loading")) + { + var net = _state.Networks[battery.LinkedNetworkCharging]; + net.BatteriesCharging.Remove(battery.Id); + battery.LinkedNetworkCharging = default; + } + else + { + SameLine(); + if (battery.LinkedNetworkDischarging != default && Button("Unlink supplying")) + { + var net = _state.Networks[battery.LinkedNetworkDischarging]; + net.BatteriesDischarging.Remove(battery.Id); + battery.LinkedNetworkDischarging = default; + } + } + } + + if (Button("Empty")) + battery.CurrentStorage = 0; + SameLine(); + if (Button("Fill")) + battery.CurrentStorage = battery.Capacity; + + End(); + } + + var bgDrawList = GetBackgroundDrawList(); + + foreach (var network in _state.Networks.Values) + { + var displayNet = _displayNetworks[network.Id]; + foreach (var supplyId in network.Supplies) + { + var supply = _displaySupplies[supplyId]; + DrawArrowLine(bgDrawList, displayNet.CurrentWindowPos, supply.CurrentWindowPos, Color.LawnGreen); + } + + foreach (var loadId in network.Loads) + { + var load = _displayLoads[loadId]; + DrawArrowLine(bgDrawList, load.CurrentWindowPos, displayNet.CurrentWindowPos, Color.Red); + } + + foreach (var batteryId in network.BatteriesCharging) + { + var battery = _displayBatteries[batteryId]; + DrawArrowLine(bgDrawList, battery.CurrentWindowPos, displayNet.CurrentWindowPos, Color.Purple); + } + + foreach (var batteryId in network.BatteriesDischarging) + { + var battery = _displayBatteries[batteryId]; + DrawArrowLine(bgDrawList, displayNet.CurrentWindowPos, battery.CurrentWindowPos, Color.Cyan); + } + } + + if (_showDemo) + { + ShowDemoWindow(); + } + + var reLink = false; + while (_remQueue.TryDequeue(out var item)) + { + switch (item) + { + case Network n: + _state.Networks.Remove(n.Id); + _displayNetworks.Remove(n.Id); + reLink = true; + break; + + case Supply s: + _state.Supplies.Remove(s.Id); + _state.Networks.Values.ForEach(n => n.Supplies.Remove(s.Id)); + _displaySupplies.Remove(s.Id); + break; + + case Load l: + _state.Loads.Remove(l.Id); + _state.Networks.Values.ForEach(n => n.Loads.Remove(l.Id)); + _displayLoads.Remove(l.Id); + break; + + case Battery b: + _state.Batteries.Remove(b.Id); + _state.Networks.Values.ForEach(n => n.BatteriesCharging.Remove(b.Id)); + _state.Networks.Values.ForEach(n => n.BatteriesDischarging.Remove(b.Id)); + _displayBatteries.Remove(b.Id); + break; + } + } + + if (reLink) + RefreshLinks(); + } + + + private void DrawArrowLine(ImDrawListPtr ptr, Vector2 a, Vector2 b, Color color) + { + // A: to + // B: from + + const float wingLength = 15; + const float thickness = 3; + + var cvtColor = CvtColor(color); + + ptr.AddLine(a, b, cvtColor, thickness); + + var angleA = Angle.FromDegrees(45); + var angleB = Angle.FromDegrees(-45); + + var mid = (a + b) / 2; + var dir = -Vector2.Normalize(a - b); + + var rVec = new RobustVec2(dir.X, dir.Y); + + var wingADir = CvtVec(angleA.RotateVec(rVec)); + var wingBDir = CvtVec(angleB.RotateVec(rVec)); + + var wingA = wingADir * wingLength + mid; + var wingB = wingBDir * wingLength + mid; + + ptr.AddLine(mid, wingA, cvtColor, thickness); + ptr.AddLine(mid, wingB, cvtColor, thickness); + } + + private static uint CvtColor(Color color) + { + return color.R | ((uint) color.G << 8) | ((uint) color.B << 16) | ((uint) color.A << 24); + } + + private static Vector2 CalcWindowCenter() + { + return GetWindowPos() + GetWindowSize() / 2; + } + + private static Vector2 CvtVec(RobustVec2 vec) + { + return new Vector2(vec.X, vec.Y); + } + + private sealed class DisplayNetwork + { + public Vector2 CurrentWindowPos; + } + + private sealed class DisplayBattery + { + public Vector2 CurrentWindowPos; + public readonly float[] ReceivingPowerData = new float[MaxTickData]; + public readonly float[] SuppliedPowerData = new float[MaxTickData]; + public readonly float[] StoredPowerData = new float[MaxTickData]; + } + + private sealed class DisplayLoad + { + public Vector2 CurrentWindowPos; + public readonly float[] ReceivedPowerData = new float[MaxTickData]; + } + + private sealed class DisplaySupply + { + public Vector2 CurrentWindowPos; + public readonly float[] SuppliedPowerData = new float[MaxTickData]; + } + } +} diff --git a/Pow3r/Program.Veldrid.cs b/Pow3r/Program.Veldrid.cs new file mode 100644 index 0000000000..0ebc62b8de --- /dev/null +++ b/Pow3r/Program.Veldrid.cs @@ -0,0 +1,409 @@ +using System; +using System.Numerics; +using System.Runtime.InteropServices; +using System.Text; +using ImGuiNET; +using OpenTK.Windowing.GraphicsLibraryFramework; +using Veldrid; +using Veldrid.OpenGL; +using Veldrid.SPIRV; +using Veldrid.Vk; + +namespace Pow3r +{ + internal sealed unsafe partial class Program + { + private const string VDVertexShader = @" +#version 460 + +layout (location = 0) in vec2 Position; +layout (location = 1) in vec2 UV; +layout (location = 2) in vec4 Color; + +layout (set = 0, binding = 0) uniform ProjMtx { + mat4 _ProjMtx; +}; + +layout (location = 0) out vec2 Frag_UV; +layout (location = 1) out vec4 Frag_Color; + +// Converts a color from sRGB gamma to linear light gamma +vec4 toLinear(vec4 sRGB) +{ + bvec3 cutoff = lessThan(sRGB.rgb, vec3(0.04045)); + vec3 higher = pow((sRGB.rgb + vec3(0.055))/vec3(1.055), vec3(2.4)); + vec3 lower = sRGB.rgb/vec3(12.92); + + return vec4(mix(higher, lower, cutoff), sRGB.a); +} + +void main() +{ + Frag_UV = UV; + Frag_Color = toLinear(Color); + gl_Position = _ProjMtx * vec4(Position.xy,0,1); +}"; + + private const string VDFragmentShader = @" +#version 460 + +layout (location = 0) in vec2 Frag_UV; +layout (location = 1) in vec4 Frag_Color; + +layout (set = 1, binding = 0) uniform texture2D Texture; +layout (set = 1, binding = 1) uniform sampler TextureSampler; + +layout (location = 0) out vec4 Out_Color; + +void main() +{ + Out_Color = Frag_Color * texture(sampler2D(Texture, TextureSampler), Frag_UV.st); +}"; + + private VeldridRenderer _vdRenderer = VeldridRenderer.Vulkan; + + private GraphicsDevice _vdGfxDevice; + private CommandList _vdCommandList; + private Pipeline _vdPipeline; + private Shader[] _vdShaders; + private ResourceSet _vdSetTexture; + private ResourceSet _vdSetProjMatrix; + private Texture _vdTexture; + private Sampler _vdSampler; + private DeviceBuffer _vdProjMatrixUniformBuffer; + private int _vdLastWidth; + private int _vdLastHeight; + private VdFencedDatum[] _fencedData = Array.Empty(); + + private void InitVeldrid() + { + var options = new GraphicsDeviceOptions + { +#if DEBUG + Debug = true, +#endif + HasMainSwapchain = true, + SyncToVerticalBlank = _vsync, + PreferStandardClipSpaceYDirection = true, + SwapchainSrgbFormat = true + }; + + GLFW.GetFramebufferSize(_window.WindowPtr, out var w, out var h); + + var hwnd = GLFW.GetWin32Window(_window.WindowPtr); + var hinstance = GetModuleHandleA(null); + + switch (_vdRenderer) + { + case VeldridRenderer.Vulkan: + _vdGfxDevice = GraphicsDevice.CreateVulkan( + options, + VkSurfaceSource.CreateWin32((nint) hinstance, hwnd), + (uint) w, (uint) h); + break; + case VeldridRenderer.D3D11: + _vdGfxDevice = GraphicsDevice.CreateD3D11(options, hwnd, (uint) w, (uint) h); + break; + case VeldridRenderer.OpenGL: + { + var platInfo = new OpenGLPlatformInfo( + (nint) _window.WindowPtr, + GLFW.GetProcAddress, + ptr => GLFW.MakeContextCurrent((Window*) ptr), + () => (nint) GLFW.GetCurrentContext(), + () => GLFW.MakeContextCurrent(null), + ptr => GLFW.DestroyWindow((Window*) ptr), + () => GLFW.SwapBuffers(_window.WindowPtr), + vsync => GLFW.SwapInterval(vsync ? 1 : 0)); + + _vdGfxDevice = GraphicsDevice.CreateOpenGL(options, platInfo, (uint) w, (uint) h); + break; + } + } + + + var factory = _vdGfxDevice.ResourceFactory; + + _vdCommandList = factory.CreateCommandList(); + _vdCommandList.Name = "Honk"; + + var vtxLayout = new VertexLayoutDescription( + new VertexElementDescription("Position", VertexElementFormat.Float2, + VertexElementSemantic.TextureCoordinate), + new VertexElementDescription("UV", VertexElementFormat.Float2, VertexElementSemantic.TextureCoordinate), + new VertexElementDescription("Color", VertexElementFormat.Byte4_Norm, + VertexElementSemantic.TextureCoordinate)); + + var vtxShaderDesc = new ShaderDescription( + ShaderStages.Vertex, + Encoding.UTF8.GetBytes(VDVertexShader), + "main"); + + var fragShaderDesc = new ShaderDescription( + ShaderStages.Fragment, + Encoding.UTF8.GetBytes(VDFragmentShader), + "main"); + + _vdShaders = factory.CreateFromSpirv(vtxShaderDesc, fragShaderDesc); + + _vdShaders[0].Name = "VertexShader"; + _vdShaders[1].Name = "FragmentShader"; + + var layoutTexture = factory.CreateResourceLayout(new ResourceLayoutDescription( + new ResourceLayoutElementDescription( + "Texture", + ResourceKind.TextureReadOnly, + ShaderStages.Fragment), + new ResourceLayoutElementDescription( + "TextureSampler", + ResourceKind.Sampler, + ShaderStages.Fragment))); + + layoutTexture.Name = "LayoutTexture"; + + var layoutProjMatrix = factory.CreateResourceLayout(new ResourceLayoutDescription( + new ResourceLayoutElementDescription( + "ProjMtx", + ResourceKind.UniformBuffer, + ShaderStages.Vertex))); + + layoutProjMatrix.Name = "LayoutProjMatrix"; + + var pipelineDesc = new GraphicsPipelineDescription( + new BlendStateDescription( + RgbaFloat.White, + new BlendAttachmentDescription( + true, + BlendFactor.SourceAlpha, + BlendFactor.InverseSourceAlpha, + BlendFunction.Add, + BlendFactor.One, + BlendFactor.InverseSourceAlpha, + BlendFunction.Add) + ), + DepthStencilStateDescription.Disabled, + new RasterizerStateDescription( + FaceCullMode.None, + PolygonFillMode.Solid, + FrontFace.Clockwise, + depthClipEnabled: false, + scissorTestEnabled: true), + PrimitiveTopology.TriangleList, + new ShaderSetDescription(new[] {vtxLayout}, _vdShaders), + new[] {layoutProjMatrix, layoutTexture}, + new OutputDescription( + null, + new OutputAttachmentDescription(PixelFormat.B8_G8_R8_A8_UNorm_SRgb)) + ); + + _vdPipeline = factory.CreateGraphicsPipeline(pipelineDesc); + _vdPipeline.Name = "MainPipeline"; + + _vdProjMatrixUniformBuffer = factory.CreateBuffer(new BufferDescription( + (uint) sizeof(Matrix4x4), + BufferUsage.Dynamic | BufferUsage.UniformBuffer)); + _vdProjMatrixUniformBuffer.Name = "_vdProjMatrixUniformBuffer"; + + _vdSetProjMatrix = factory.CreateResourceSet(new ResourceSetDescription( + layoutProjMatrix, + _vdProjMatrixUniformBuffer)); + _vdSetProjMatrix.Name = "_vdSetProjMatrix"; + var io = ImGui.GetIO(); + + io.Fonts.GetTexDataAsRGBA32(out byte* pixels, out var width, out var height, out _); + + _vdTexture = factory.CreateTexture(TextureDescription.Texture2D( + (uint) width, (uint) height, + mipLevels: 1, + arrayLayers: 1, + PixelFormat.R8_G8_B8_A8_UNorm_SRgb, + TextureUsage.Sampled)); + + _vdTexture.Name = "MainTexture"; + + _vdSampler = factory.CreateSampler(SamplerDescription.Linear); + + _vdSampler.Name = "MainSampler"; + + _vdGfxDevice.UpdateTexture( + _vdTexture, + (IntPtr) pixels, + (uint) (width * height * 4), + x: 0, y: 0, z: 0, + (uint) width, (uint) height, depth: 1, + mipLevel: 0, + arrayLayer: 0); + + _vdSetTexture = factory.CreateResourceSet(new ResourceSetDescription( + layoutTexture, + _vdTexture, + _vdSampler)); + + _vdSetTexture.Name = "SetTexture"; + + io.Fonts.SetTexID((nint) 0); + io.Fonts.ClearTexData(); + + _vdGfxDevice.ResizeMainWindow((uint) w, (uint) h); + _vdGfxDevice.SwapBuffers(); + } + + private void RenderVeldrid() + { + GLFW.GetFramebufferSize(_window.WindowPtr, out var fbW, out var fbH); + + if (_vdLastWidth != fbW && _vdLastHeight != fbH) + { + _vdGfxDevice.ResizeMainWindow((uint) fbW, (uint) fbH); + _vdLastWidth = fbW; + _vdLastHeight = fbH; + } + + _vdCommandList.Begin(); + _vdCommandList.SetFramebuffer(_vdGfxDevice.SwapchainFramebuffer); + + _vdCommandList.SetViewport(0, new Viewport(0, 0, fbW, fbH, 0, 1)); + _vdCommandList.ClearColorTarget(0, RgbaFloat.Black); + + var factory = _vdGfxDevice.ResourceFactory; + + var drawData = ImGui.GetDrawData(); + + ref var fencedData = ref GetFreeFencedData(); + ref var vtxBuf = ref fencedData.VertexBuffer; + ref var idxBuf = ref fencedData.IndexBuffer; + + var byteLenVtx = (uint) (sizeof(ImDrawVert) * drawData.TotalVtxCount); + if (fencedData.VertexBuffer == null || vtxBuf.SizeInBytes < byteLenVtx) + { + vtxBuf?.Dispose(); + vtxBuf = factory.CreateBuffer(new BufferDescription( + byteLenVtx, + BufferUsage.VertexBuffer | BufferUsage.Dynamic)); + vtxBuf.Name = "_vdVtxBuffer"; + } + + var byteLenIdx = (uint) (sizeof(ushort) * drawData.TotalIdxCount); + if (idxBuf == null || idxBuf.SizeInBytes < byteLenIdx) + { + idxBuf?.Dispose(); + idxBuf = factory.CreateBuffer(new BufferDescription( + byteLenIdx, + BufferUsage.IndexBuffer | BufferUsage.Dynamic)); + idxBuf.Name = "_vdIdxBuffer"; + } + + var vtxOffset = 0; + var idxOffset = 0; + var mappedVtxBuf = MappedToSpan(_vdGfxDevice.Map(vtxBuf, MapMode.Write)); + var mappedIdxBuf = MappedToSpan(_vdGfxDevice.Map(idxBuf, MapMode.Write)); + + var l = drawData.DisplayPos.X; + var r = drawData.DisplayPos.X + drawData.DisplaySize.X; + var t = drawData.DisplayPos.Y; + var b = drawData.DisplayPos.Y + drawData.DisplaySize.Y; + + var matrix = Matrix4x4.CreateOrthographicOffCenter(l, r, b, t, -1, 1); + + var clipOff = drawData.DisplayPos; + var clipScale = drawData.FramebufferScale; + + _vdCommandList.UpdateBuffer(_vdProjMatrixUniformBuffer, 0, ref matrix); + + _vdCommandList.SetPipeline(_vdPipeline); + _vdCommandList.SetGraphicsResourceSet(0, _vdSetProjMatrix); + _vdCommandList.SetGraphicsResourceSet(1, _vdSetTexture); + _vdCommandList.SetVertexBuffer(0, vtxBuf); + _vdCommandList.SetIndexBuffer(idxBuf, IndexFormat.UInt16); + + for (var n = 0; n < drawData.CmdListsCount; n++) + { + var drawList = drawData.CmdListsRange[n]; + + var drawVtx = new Span((void*) drawList.VtxBuffer.Data, drawList.VtxBuffer.Size); + var drawIdx = new Span((void*) drawList.IdxBuffer.Data, drawList.IdxBuffer.Size); + + drawVtx.CopyTo(mappedVtxBuf[vtxOffset..]); + drawIdx.CopyTo(mappedIdxBuf[idxOffset..]); + + for (var cmdI = 0; cmdI < drawList.CmdBuffer.Size; cmdI++) + { + var cmd = drawList.CmdBuffer[cmdI]; + + Vector4 clipRect = default; + clipRect.X = (cmd.ClipRect.X - clipOff.X) * clipScale.X; + clipRect.Y = (cmd.ClipRect.Y - clipOff.Y) * clipScale.Y; + clipRect.Z = (cmd.ClipRect.Z - clipOff.X) * clipScale.X; + clipRect.W = (cmd.ClipRect.W - clipOff.Y) * clipScale.Y; + + _vdCommandList.SetScissorRect( + 0, + (uint) clipRect.X, + (uint) clipRect.Y, + (uint) (clipRect.Z - clipRect.X), + (uint) (clipRect.W - clipRect.Y)); + + _vdCommandList.DrawIndexed( + cmd.ElemCount, + 1, + (uint) (cmd.IdxOffset + idxOffset), + (int) (cmd.VtxOffset + vtxOffset), + 0); + } + + vtxOffset += drawVtx.Length; + idxOffset += drawIdx.Length; + } + + _vdGfxDevice.Unmap(vtxBuf); + _vdGfxDevice.Unmap(idxBuf); + + _vdCommandList.End(); + + _vdGfxDevice.SubmitCommands(_vdCommandList, fencedData.Fence); + _vdGfxDevice.SwapBuffers(); + } + + private ref VdFencedDatum GetFreeFencedData() + { + for (var i = 0; i < _fencedData.Length; i++) + { + ref var fenced = ref _fencedData[i]; + + if (fenced.Fence.Signaled) + { + fenced.Fence.Reset(); + return ref fenced; + } + } + + Array.Resize(ref _fencedData, _fencedData.Length + 1); + ref var slot = ref _fencedData[^1]; + slot = new VdFencedDatum {Fence = _vdGfxDevice.ResourceFactory.CreateFence(false)}; + return ref slot; + } + + private static Span MappedToSpan(MappedResourceView mapped) where T : struct + { + return MemoryMarshal.CreateSpan(ref mapped[0], mapped.Count); + } + + [DllImport("kernel32.dll")] + private static extern void* GetModuleHandleA(byte* lpModuleName); + + private struct VdFencedDatum + { + public Fence Fence; + + public DeviceBuffer IndexBuffer; + public DeviceBuffer VertexBuffer; + } + + private enum VeldridRenderer + { + Vulkan, + D3D11, + OpenGL + } + } +} diff --git a/Pow3r/Program.cs b/Pow3r/Program.cs new file mode 100644 index 0000000000..349fb6bcd7 --- /dev/null +++ b/Pow3r/Program.cs @@ -0,0 +1,389 @@ +using System; +using System.Diagnostics; +using System.Runtime.InteropServices; +using ImGuiNET; +using OpenTK.Windowing.Common; +using OpenTK.Windowing.Desktop; +using OpenTK.Windowing.GraphicsLibraryFramework; +using ErrorCode = OpenTK.Windowing.GraphicsLibraryFramework.ErrorCode; +using Vector2 = System.Numerics.Vector2; + +// ReSharper disable PossibleNullReferenceException + +namespace Pow3r +{ + internal sealed unsafe partial class Program + { + private Renderer _renderer = Renderer.Veldrid; + + [UnmanagedCallersOnly] + private static byte* GetClipboardTextCallback(void* userData) + { + return GLFW.GetClipboardStringRaw((Window*) userData); + } + + [UnmanagedCallersOnly] + private static void SetClipboardTextCallback(void* userData, byte* text) + { + GLFW.SetClipboardStringRaw((Window*) userData, text); + } + + private static readonly GLFWCallbacks.ErrorCallback ErrorCallback = GlfwErrorCallback; + + private static void GlfwErrorCallback(ErrorCode error, string description) + { + Console.WriteLine($"{error}: {description}"); + } + + private bool[] _mouseJustPressed = new bool[5]; + + private bool _fullscreen; + private int _monitorIdx; + private bool _vsync = true; + private GameWindow _window; + private readonly Stopwatch _stopwatch = new(); + private readonly Cursor*[] _cursors = new Cursor*[9]; + private readonly float[] _frameTimings = new float[180]; + private int _frameTimeIdx = 0; + private int _tps = 60; + + private void Run(string[] args) + { + for (var i = 0; i < args.Length; i++) + { + if (args[i] == "--renderer") + { + _renderer = Enum.Parse(args[++i]); + } + else if (args[i] == "--veldrid") + { + _vdRenderer = Enum.Parse(args[++i]); + } + else if (args[i] == "--fullscreen") + { + _fullscreen = true; + } + else if (args[i] == "--monitor-idx") + { + _monitorIdx = int.Parse(args[++i]); + } + else if (args[i] == "--no-vsync") + { + _vsync = false; + } + else if (args[i] == "--help") + { + Console.WriteLine("--renderer "); + Console.WriteLine("--veldrid "); + Console.WriteLine("--no-vsync"); + Console.WriteLine("--fullscreen"); + Console.WriteLine("--monitor-idx"); + Console.WriteLine("--help"); + return; + } + else + { + Console.WriteLine($"unknown arg \"{args[i]}\""); + return; + } + } + + Console.WriteLine($"Renderer: {_renderer}"); + if (_renderer == Renderer.Veldrid) + Console.WriteLine($"Veldrid API: {_vdRenderer}"); + + Console.WriteLine($"Fullscreen: {_fullscreen}"); + Console.WriteLine($"VSync: {_vsync}"); + + //NativeLibrary.Load("nvapi64.dll"); + GLFW.Init(); + GLFW.SetErrorCallback(ErrorCallback); + + // var sw = Stopwatch.StartNew(); + GLFW.WindowHint(WindowHintBool.SrgbCapable, true); + var windowSettings = new NativeWindowSettings + { + Size = (1280, 720), + WindowState = WindowState.Maximized, + StartVisible = false, + + Title = "Pow3r" + }; + + + var openGLBased = _renderer == Renderer.OpenGL || + (_renderer == Renderer.Veldrid && _vdRenderer == VeldridRenderer.OpenGL); + + if (openGLBased) + { + windowSettings.API = ContextAPI.OpenGL; + if (_renderer == Renderer.Veldrid) + { + windowSettings.Profile = ContextProfile.Core; + windowSettings.APIVersion = new Version(4, 6); + windowSettings.Flags = ContextFlags.ForwardCompatible; + } + else + { + windowSettings.Profile = ContextProfile.Any; + windowSettings.APIVersion = new Version(1, 5); + } +#if DEBUG + windowSettings.Flags |= ContextFlags.Debug; +#endif + } + else + { + windowSettings.API = ContextAPI.NoAPI; + } + + _window = new GameWindow(GameWindowSettings.Default, windowSettings); + + // Console.WriteLine(sw.ElapsedMilliseconds); + + if (_fullscreen) + { + var monitors = GLFW.GetMonitors(); + var monitor = monitors[_monitorIdx]; + var monitorMode = GLFW.GetVideoMode(monitor); + + GLFW.SetWindowMonitor( + _window.WindowPtr, + monitor, + 0, 0, + monitorMode->Width, + monitorMode->Height, + monitorMode->RefreshRate); + } + + if (openGLBased) + { + _window.VSync = _vsync ? VSyncMode.On : VSyncMode.Off; + } + + var context = ImGui.CreateContext(); + ImGui.SetCurrentContext(context); + ImGui.StyleColorsDark(); + + var io = ImGui.GetIO(); + io.Fonts.AddFontDefault(); + + delegate* unmanaged getClipboardCallback = &GetClipboardTextCallback; + io.GetClipboardTextFn = (IntPtr) getClipboardCallback; + delegate* unmanaged setClipboardCallback = &SetClipboardTextCallback; + io.GetClipboardTextFn = (IntPtr) setClipboardCallback; + io.ClipboardUserData = (IntPtr) _window.WindowPtr; + io.BackendFlags |= ImGuiBackendFlags.RendererHasVtxOffset; + io.BackendFlags |= ImGuiBackendFlags.HasSetMousePos; + io.BackendFlags |= ImGuiBackendFlags.HasMouseCursors; + + io.KeyMap[(int) ImGuiKey.Tab] = (int) Keys.Tab; + io.KeyMap[(int) ImGuiKey.LeftArrow] = (int) Keys.Left; + io.KeyMap[(int) ImGuiKey.RightArrow] = (int) Keys.Right; + io.KeyMap[(int) ImGuiKey.UpArrow] = (int) Keys.Up; + io.KeyMap[(int) ImGuiKey.DownArrow] = (int) Keys.Down; + io.KeyMap[(int) ImGuiKey.PageUp] = (int) Keys.PageUp; + io.KeyMap[(int) ImGuiKey.PageDown] = (int) Keys.PageDown; + io.KeyMap[(int) ImGuiKey.Home] = (int) Keys.Home; + io.KeyMap[(int) ImGuiKey.End] = (int) Keys.End; + io.KeyMap[(int) ImGuiKey.Delete] = (int) Keys.Delete; + io.KeyMap[(int) ImGuiKey.Backspace] = (int) Keys.Backspace; + io.KeyMap[(int) ImGuiKey.Enter] = (int) Keys.Enter; + io.KeyMap[(int) ImGuiKey.Escape] = (int) Keys.Escape; + io.KeyMap[(int) ImGuiKey.A] = (int) Keys.A; + io.KeyMap[(int) ImGuiKey.C] = (int) Keys.C; + io.KeyMap[(int) ImGuiKey.V] = (int) Keys.V; + io.KeyMap[(int) ImGuiKey.X] = (int) Keys.X; + io.KeyMap[(int) ImGuiKey.Y] = (int) Keys.Y; + io.KeyMap[(int) ImGuiKey.Z] = (int) Keys.Z; + + _cursors[(int) ImGuiMouseCursor.Arrow] = GLFW.CreateStandardCursor(CursorShape.Arrow); + _cursors[(int) ImGuiMouseCursor.TextInput] = GLFW.CreateStandardCursor(CursorShape.IBeam); + _cursors[(int) ImGuiMouseCursor.ResizeNS] = GLFW.CreateStandardCursor(CursorShape.VResize); + _cursors[(int) ImGuiMouseCursor.ResizeEW] = GLFW.CreateStandardCursor(CursorShape.HResize); + _cursors[(int) ImGuiMouseCursor.Hand] = GLFW.CreateStandardCursor(CursorShape.Hand); + _cursors[(int) ImGuiMouseCursor.ResizeAll] = GLFW.CreateStandardCursor(CursorShape.Arrow); + _cursors[(int) ImGuiMouseCursor.ResizeNESW] = GLFW.CreateStandardCursor(CursorShape.Arrow); + _cursors[(int) ImGuiMouseCursor.ResizeNWSE] = GLFW.CreateStandardCursor(CursorShape.Arrow); + _cursors[(int) ImGuiMouseCursor.NotAllowed] = GLFW.CreateStandardCursor(CursorShape.Arrow); + + InitRenderer(); + + _window.MouseDown += OnMouseDown; + _window.TextInput += WindowOnTextInput; + _window.MouseWheel += WindowOnMouseWheel; + _window.KeyDown += args => KeyCallback(args, true); + _window.KeyUp += args => KeyCallback(args, false); + + _stopwatch.Start(); + + LoadFromDisk(); + + _window.IsVisible = true; + + var lastTick = TimeSpan.Zero; + var lastFrame = TimeSpan.Zero; + var curTime = TimeSpan.Zero; + + while (!GLFW.WindowShouldClose(_window.WindowPtr)) + { + _window.ProcessEvents(); + + var tickSpan = TimeSpan.FromSeconds(1f / _tps); + while (curTime - lastTick > tickSpan) + { + lastTick += tickSpan; + + Tick((float) tickSpan.TotalSeconds); + } + + _frameTimeIdx = (_frameTimeIdx + 1) % _frameTimings.Length; + + var dt = curTime - lastFrame; + lastFrame = curTime; + _frameTimings[_frameTimeIdx] = (float) dt.TotalMilliseconds; + + FrameUpdate((float) dt.TotalSeconds); + Render(); + curTime = _stopwatch.Elapsed; + } + + SaveToDisk(); + } + + private static void KeyCallback(KeyboardKeyEventArgs obj, bool down) + { + var io = ImGui.GetIO(); + if (obj.Key ==Keys.Unknown) + return; + + var keyInt = (int) obj.Key; + io.KeysDown[keyInt] = down; + io.KeyCtrl = io.KeysDown[(int) Keys.LeftControl] || io.KeysDown[(int) Keys.RightControl]; + io.KeyShift = io.KeysDown[(int) Keys.LeftShift] || io.KeysDown[(int) Keys.RightShift]; + io.KeyAlt = io.KeysDown[(int) Keys.LeftAlt] || io.KeysDown[(int) Keys.RightAlt]; + } + + private static void WindowOnMouseWheel(MouseWheelEventArgs obj) + { + var io = ImGui.GetIO(); + io.MouseWheelH += obj.OffsetX; + io.MouseWheel += obj.OffsetY; + } + + private static void WindowOnTextInput(TextInputEventArgs obj) + { + var io = ImGui.GetIO(); + io.AddInputCharacter((uint) obj.Unicode); + } + + private void OnMouseDown(MouseButtonEventArgs obj) + { + var button = (int) obj.Button; + if (obj.IsPressed && button < _mouseJustPressed.Length) + _mouseJustPressed[button] = true; + } + + private void FrameUpdate(float dt) + { + //var sw = Stopwatch.StartNew(); + var io = ImGui.GetIO(); + GLFW.GetFramebufferSize(_window.WindowPtr, out var fbW, out var fbH); + GLFW.GetWindowSize(_window.WindowPtr, out var wW, out var wH); + io.DisplaySize = new Vector2(wW, wH); + io.DisplayFramebufferScale = new Vector2(fbW / (float) wW, fbH / (float) wH); + io.DeltaTime = dt; + + UpdateMouseState(io); + UpdateCursorState(io); + + //Console.WriteLine($"INPUT: {sw.Elapsed.TotalMilliseconds}"); + + ImGui.NewFrame(); + + DoUI(dt); + } + + private void UpdateCursorState(ImGuiIOPtr io) + { + var cursor = ImGui.GetMouseCursor(); + if (cursor == ImGuiMouseCursor.None) + { + GLFW.SetInputMode(_window.WindowPtr, CursorStateAttribute.Cursor, CursorModeValue.CursorHidden); + } + else + { + GLFW.SetCursor(_window.WindowPtr, _cursors[(int) cursor]); + GLFW.SetInputMode(_window.WindowPtr, CursorStateAttribute.Cursor, CursorModeValue.CursorNormal); + } + } + + private void UpdateMouseState(ImGuiIOPtr io) + { + for (var i = 0; i < io.MouseDown.Count; i++) + { + io.MouseDown[i] = _mouseJustPressed[i] || + GLFW.GetMouseButton(_window.WindowPtr, (MouseButton) i) == InputAction.Press; + _mouseJustPressed[i] = false; + } + + var oldMousePos = io.MousePos; + io.MousePos = new Vector2(float.PositiveInfinity, float.PositiveInfinity); + + var focused = _window.IsFocused; + if (focused) + { + if (io.WantSetMousePos) + { + GLFW.SetCursorPos(_window.WindowPtr, oldMousePos.X, oldMousePos.Y); + } + else + { + GLFW.GetCursorPos(_window.WindowPtr, out var x, out var y); + io.MousePos = new Vector2((float) x, (float) y); + } + } + } + + private void InitRenderer() + { + switch (_renderer) + { + case Renderer.OpenGL: + InitOpenGL(); + break; + + case Renderer.Veldrid: + InitVeldrid(); + break; + } + } + + private void Render() + { + ImGui.Render(); + + switch (_renderer) + { + case Renderer.OpenGL: + RenderOpenGL(); + break; + + case Renderer.Veldrid: + RenderVeldrid(); + break; + } + } + + private static void Main(string[] args) + { + new Program().Run(args); + } + + public enum Renderer + { + OpenGL, + Veldrid + } + } +} diff --git a/Resources/Maps/Test/singularity.yml b/Resources/Maps/Test/singularity.yml index 337431e707..ceb80b4927 100644 --- a/Resources/Maps/Test/singularity.yml +++ b/Resources/Maps/Test/singularity.yml @@ -576,361 +576,361 @@ entities: pos: -4.5,-0.5 type: Transform - uid: 21 - type: MVWire + type: CableMV components: - parent: 0 pos: -4.5,-0.5 type: Transform - uid: 22 - type: MVWire + type: CableMV components: - parent: 0 pos: -5.5,-0.5 type: Transform - uid: 23 - type: MVWire + type: CableMV components: - parent: 0 pos: -6.5,-0.5 type: Transform - uid: 24 - type: MVWire + type: CableMV components: - parent: 0 pos: -6.5,-1.5 type: Transform - uid: 25 - type: MVWire + type: CableMV components: - parent: 0 pos: -6.5,-2.5 type: Transform - uid: 26 - type: MVWire + type: CableMV components: - parent: 0 pos: -6.5,-3.5 type: Transform - uid: 27 - type: MVWire + type: CableMV components: - parent: 0 pos: -6.5,-4.5 type: Transform - uid: 28 - type: MVWire + type: CableMV components: - parent: 0 pos: -5.5,-4.5 type: Transform - uid: 29 - type: MVWire + type: CableMV components: - parent: 0 pos: -4.5,-4.5 type: Transform - uid: 30 - type: MVWire + type: CableMV components: - parent: 0 pos: -6.5,-5.5 type: Transform - uid: 31 - type: MVWire + type: CableMV components: - parent: 0 pos: -6.5,-6.5 type: Transform - uid: 32 - type: MVWire + type: CableMV components: - parent: 0 pos: -6.5,-7.5 type: Transform - uid: 33 - type: MVWire + type: CableMV components: - parent: 0 pos: -6.5,-8.5 type: Transform - uid: 34 - type: MVWire + type: CableMV components: - parent: 0 pos: -5.5,-8.5 type: Transform - uid: 35 - type: MVWire + type: CableMV components: - parent: 0 pos: -4.5,-8.5 type: Transform - uid: 36 - type: MVWire + type: CableMV components: - parent: 0 pos: -0.5,3.5 type: Transform - uid: 37 - type: MVWire + type: CableMV components: - parent: 0 pos: -0.5,4.5 type: Transform - uid: 38 - type: MVWire + type: CableMV components: - parent: 0 pos: -0.5,5.5 type: Transform - uid: 39 - type: MVWire + type: CableMV components: - parent: 0 pos: 0.5,5.5 type: Transform - uid: 40 - type: MVWire + type: CableMV components: - parent: 0 pos: 1.5,5.5 type: Transform - uid: 41 - type: MVWire + type: CableMV components: - parent: 0 pos: 2.5,5.5 type: Transform - uid: 42 - type: MVWire + type: CableMV components: - parent: 0 pos: 3.5,5.5 type: Transform - uid: 43 - type: MVWire + type: CableMV components: - parent: 0 pos: 3.5,4.5 type: Transform - uid: 44 - type: MVWire + type: CableMV components: - parent: 0 pos: 3.5,3.5 type: Transform - uid: 45 - type: MVWire + type: CableMV components: - parent: 0 pos: 4.5,5.5 type: Transform - uid: 46 - type: MVWire + type: CableMV components: - parent: 0 pos: 5.5,5.5 type: Transform - uid: 47 - type: MVWire + type: CableMV components: - parent: 0 pos: 6.5,5.5 type: Transform - uid: 48 - type: MVWire + type: CableMV components: - parent: 0 pos: 7.5,5.5 type: Transform - uid: 49 - type: MVWire + type: CableMV components: - parent: 0 pos: 7.5,4.5 type: Transform - uid: 50 - type: MVWire + type: CableMV components: - parent: 0 pos: 7.5,3.5 type: Transform - uid: 51 - type: MVWire + type: CableMV components: - parent: 0 pos: 11.5,-0.5 type: Transform - uid: 52 - type: MVWire + type: CableMV components: - parent: 0 pos: 12.5,-0.5 type: Transform - uid: 53 - type: MVWire + type: CableMV components: - parent: 0 pos: 13.5,-0.5 type: Transform - uid: 54 - type: MVWire + type: CableMV components: - parent: 0 pos: 13.5,-1.5 type: Transform - uid: 55 - type: MVWire + type: CableMV components: - parent: 0 pos: 13.5,-2.5 type: Transform - uid: 56 - type: MVWire + type: CableMV components: - parent: 0 pos: 13.5,-3.5 type: Transform - uid: 57 - type: MVWire + type: CableMV components: - parent: 0 pos: 13.5,-4.5 type: Transform - uid: 58 - type: MVWire + type: CableMV components: - parent: 0 pos: 12.5,-4.5 type: Transform - uid: 59 - type: MVWire + type: CableMV components: - parent: 0 pos: 11.5,-4.5 type: Transform - uid: 60 - type: MVWire + type: CableMV components: - parent: 0 pos: 13.5,-5.5 type: Transform - uid: 61 - type: MVWire + type: CableMV components: - parent: 0 pos: 13.5,-6.5 type: Transform - uid: 62 - type: MVWire + type: CableMV components: - parent: 0 pos: 13.5,-7.5 type: Transform - uid: 63 - type: MVWire + type: CableMV components: - parent: 0 pos: 13.5,-8.5 type: Transform - uid: 64 - type: MVWire + type: CableMV components: - parent: 0 pos: 12.5,-8.5 type: Transform - uid: 65 - type: MVWire + type: CableMV components: - parent: 0 pos: 11.5,-8.5 type: Transform - uid: 66 - type: MVWire + type: CableMV components: - parent: 0 pos: 7.5,-12.5 type: Transform - uid: 67 - type: MVWire + type: CableMV components: - parent: 0 pos: 7.5,-13.5 type: Transform - uid: 68 - type: MVWire + type: CableMV components: - parent: 0 pos: 7.5,-14.5 type: Transform - uid: 69 - type: MVWire + type: CableMV components: - parent: 0 pos: 3.5,-12.5 type: Transform - uid: 70 - type: MVWire + type: CableMV components: - parent: 0 pos: 3.5,-13.5 type: Transform - uid: 71 - type: MVWire + type: CableMV components: - parent: 0 pos: 3.5,-14.5 type: Transform - uid: 72 - type: MVWire + type: CableMV components: - parent: 0 pos: -0.5,-12.5 type: Transform - uid: 73 - type: MVWire + type: CableMV components: - parent: 0 pos: -0.5,-13.5 type: Transform - uid: 74 - type: MVWire + type: CableMV components: - parent: 0 pos: -0.5,-14.5 type: Transform - uid: 75 - type: MVWire + type: CableMV components: - parent: 0 pos: 0.5,-14.5 type: Transform - uid: 76 - type: MVWire + type: CableMV components: - parent: 0 pos: 1.5,-14.5 type: Transform - uid: 77 - type: MVWire + type: CableMV components: - parent: 0 pos: 2.5,-14.5 type: Transform - uid: 78 - type: MVWire + type: CableMV components: - parent: 0 pos: 4.5,-14.5 type: Transform - uid: 79 - type: MVWire + type: CableMV components: - parent: 0 pos: 5.5,-14.5 type: Transform - uid: 80 - type: MVWire + type: CableMV components: - parent: 0 pos: 6.5,-14.5 @@ -942,265 +942,265 @@ entities: pos: 3.5,-4.5 type: Transform - uid: 82 - type: MVWire + type: CableMV components: - parent: 0 pos: -6.5,0.5 type: Transform - uid: 83 - type: MVWire + type: CableMV components: - parent: 0 pos: -6.5,1.5 type: Transform - uid: 84 - type: MVWire + type: CableMV components: - parent: 0 pos: -6.5,2.5 type: Transform - uid: 85 - type: MVWire + type: CableMV components: - parent: 0 pos: -6.5,3.5 type: Transform - uid: 86 - type: MVWire + type: CableMV components: - parent: 0 pos: -6.5,4.5 type: Transform - uid: 87 - type: MVWire + type: CableMV components: - parent: 0 pos: -6.5,5.5 type: Transform - uid: 88 - type: MVWire + type: CableMV components: - parent: 0 pos: -5.5,5.5 type: Transform - uid: 89 - type: MVWire + type: CableMV components: - parent: 0 pos: -4.5,5.5 type: Transform - uid: 90 - type: MVWire + type: CableMV components: - parent: 0 pos: -3.5,5.5 type: Transform - uid: 91 - type: MVWire + type: CableMV components: - parent: 0 pos: -2.5,5.5 type: Transform - uid: 92 - type: MVWire + type: CableMV components: - parent: 0 pos: -1.5,5.5 type: Transform - uid: 93 - type: MVWire + type: CableMV components: - parent: 0 pos: -6.5,-9.5 type: Transform - uid: 94 - type: MVWire + type: CableMV components: - parent: 0 pos: -6.5,-10.5 type: Transform - uid: 95 - type: MVWire + type: CableMV components: - parent: 0 pos: -6.5,-11.5 type: Transform - uid: 96 - type: MVWire + type: CableMV components: - parent: 0 pos: -6.5,-12.5 type: Transform - uid: 97 - type: MVWire + type: CableMV components: - parent: 0 pos: -6.5,-13.5 type: Transform - uid: 98 - type: MVWire + type: CableMV components: - parent: 0 pos: -6.5,-14.5 type: Transform - uid: 99 - type: MVWire + type: CableMV components: - parent: 0 pos: -5.5,-14.5 type: Transform - uid: 100 - type: MVWire + type: CableMV components: - parent: 0 pos: -4.5,-14.5 type: Transform - uid: 101 - type: MVWire + type: CableMV components: - parent: 0 pos: -3.5,-14.5 type: Transform - uid: 102 - type: MVWire + type: CableMV components: - parent: 0 pos: -2.5,-14.5 type: Transform - uid: 103 - type: MVWire + type: CableMV components: - parent: 0 pos: -1.5,-14.5 type: Transform - uid: 104 - type: MVWire + type: CableMV components: - parent: 0 pos: 8.5,-14.5 type: Transform - uid: 105 - type: MVWire + type: CableMV components: - parent: 0 pos: 9.5,-14.5 type: Transform - uid: 106 - type: MVWire + type: CableMV components: - parent: 0 pos: 10.5,-14.5 type: Transform - uid: 107 - type: MVWire + type: CableMV components: - parent: 0 pos: 11.5,-14.5 type: Transform - uid: 108 - type: MVWire + type: CableMV components: - parent: 0 pos: 12.5,-14.5 type: Transform - uid: 109 - type: MVWire + type: CableMV components: - parent: 0 pos: 13.5,-14.5 type: Transform - uid: 110 - type: MVWire + type: CableMV components: - parent: 0 pos: 13.5,-13.5 type: Transform - uid: 111 - type: MVWire + type: CableMV components: - parent: 0 pos: 13.5,-12.5 type: Transform - uid: 112 - type: MVWire + type: CableMV components: - parent: 0 pos: 13.5,-11.5 type: Transform - uid: 113 - type: MVWire + type: CableMV components: - parent: 0 pos: 13.5,-10.5 type: Transform - uid: 114 - type: MVWire + type: CableMV components: - parent: 0 pos: 13.5,-9.5 type: Transform - uid: 115 - type: MVWire + type: CableMV components: - parent: 0 pos: 13.5,0.5 type: Transform - uid: 116 - type: MVWire + type: CableMV components: - parent: 0 pos: 13.5,1.5 type: Transform - uid: 117 - type: MVWire + type: CableMV components: - parent: 0 pos: 13.5,2.5 type: Transform - uid: 118 - type: MVWire + type: CableMV components: - parent: 0 pos: 13.5,3.5 type: Transform - uid: 119 - type: MVWire + type: CableMV components: - parent: 0 pos: 13.5,4.5 type: Transform - uid: 120 - type: MVWire + type: CableMV components: - parent: 0 pos: 13.5,5.5 type: Transform - uid: 121 - type: MVWire + type: CableMV components: - parent: 0 pos: 12.5,5.5 type: Transform - uid: 122 - type: MVWire + type: CableMV components: - parent: 0 pos: 11.5,5.5 type: Transform - uid: 123 - type: MVWire + type: CableMV components: - parent: 0 pos: 10.5,5.5 type: Transform - uid: 124 - type: MVWire + type: CableMV components: - parent: 0 pos: 9.5,5.5 type: Transform - uid: 125 - type: MVWire + type: CableMV components: - parent: 0 pos: 8.5,5.5 @@ -1248,7 +1248,7 @@ entities: rot: -1.5707963267948966 rad type: Transform - powerLoad: 250 - type: PowerReceiver + type: ApcPowerReceiver - uid: 132 type: ParticleAcceleratorEndCap components: @@ -1257,105 +1257,105 @@ entities: rot: -1.5707963267948966 rad type: Transform - uid: 133 - type: HVWire + type: CableHV components: - parent: 0 pos: 2.5,12.5 rot: -1.5707963267948966 rad type: Transform - uid: 134 - type: HVWire + type: CableHV components: - parent: 0 pos: 3.5,12.5 rot: -1.5707963267948966 rad type: Transform - uid: 135 - type: HVWire + type: CableHV components: - parent: 0 pos: 4.5,12.5 rot: -1.5707963267948966 rad type: Transform - uid: 136 - type: HVWire + type: CableHV components: - parent: 0 pos: 3.5,13.5 rot: -1.5707963267948966 rad type: Transform - uid: 137 - type: HVWire + type: CableHV components: - parent: 0 pos: 3.5,14.5 rot: -1.5707963267948966 rad type: Transform - uid: 138 - type: HVWire + type: CableHV components: - parent: 0 pos: 2.5,14.5 rot: -1.5707963267948966 rad type: Transform - uid: 139 - type: HVWire + type: CableHV components: - parent: 0 pos: 3.5,15.5 rot: -1.5707963267948966 rad type: Transform - uid: 140 - type: HVWire + type: CableHV components: - parent: 0 pos: 4.5,14.5 rot: -1.5707963267948966 rad type: Transform - uid: 141 - type: HVWire + type: CableHV components: - parent: 0 pos: 3.5,16.5 rot: -1.5707963267948966 rad type: Transform - uid: 142 - type: HVWire + type: CableHV components: - parent: 0 pos: 0.5,16.5 rot: -1.5707963267948966 rad type: Transform - uid: 143 - type: HVWire + type: CableHV components: - parent: 0 pos: 1.5,16.5 rot: -1.5707963267948966 rad type: Transform - uid: 144 - type: HVWire + type: CableHV components: - parent: 0 pos: 2.5,16.5 rot: -1.5707963267948966 rad type: Transform - uid: 145 - type: HVWire + type: CableHV components: - parent: 0 pos: 4.5,16.5 rot: -1.5707963267948966 rad type: Transform - uid: 146 - type: HVWire + type: CableHV components: - parent: 0 pos: 5.5,16.5 rot: -1.5707963267948966 rad type: Transform - uid: 147 - type: HVWire + type: CableHV components: - parent: 0 pos: 6.5,16.5 @@ -1376,35 +1376,35 @@ entities: rot: -1.5707963267948966 rad type: Transform - uid: 150 - type: ApcExtensionCable + type: CableApcExtension components: - parent: 0 pos: 3.5,16.5 rot: -1.5707963267948966 rad type: Transform - uid: 151 - type: ApcExtensionCable + type: CableApcExtension components: - parent: 0 pos: 3.5,17.5 rot: -1.5707963267948966 rad type: Transform - uid: 152 - type: ApcExtensionCable + type: CableApcExtension components: - parent: 0 pos: 2.5,16.5 rot: -1.5707963267948966 rad type: Transform - uid: 153 - type: ApcExtensionCable + type: CableApcExtension components: - parent: 0 pos: 2.5,15.5 rot: -1.5707963267948966 rad type: Transform - uid: 154 - type: ApcExtensionCable + type: CableApcExtension components: - parent: 0 pos: 2.5,14.5 @@ -1439,70 +1439,70 @@ entities: rot: -1.5707963267948966 rad type: Transform - uid: 159 - type: HVWire + type: CableHV components: - parent: 0 pos: 0.5,13.5 rot: -1.5707963267948966 rad type: Transform - uid: 160 - type: HVWire + type: CableHV components: - parent: 0 pos: 0.5,12.5 rot: -1.5707963267948966 rad type: Transform - uid: 161 - type: HVWire + type: CableHV components: - parent: 0 pos: 6.5,13.5 rot: -1.5707963267948966 rad type: Transform - uid: 162 - type: HVWire + type: CableHV components: - parent: 0 pos: 6.5,12.5 rot: -1.5707963267948966 rad type: Transform - uid: 163 - type: HVWire + type: CableHV components: - parent: 0 pos: 6.5,11.5 rot: -1.5707963267948966 rad type: Transform - uid: 164 - type: HVWire + type: CableHV components: - parent: 0 pos: 0.5,11.5 rot: -1.5707963267948966 rad type: Transform - uid: 165 - type: HVWire + type: CableHV components: - parent: 0 pos: 0.5,10.5 rot: -1.5707963267948966 rad type: Transform - uid: 166 - type: HVWire + type: CableHV components: - parent: 0 pos: 1.5,10.5 rot: -1.5707963267948966 rad type: Transform - uid: 167 - type: HVWire + type: CableHV components: - parent: 0 pos: 6.5,10.5 rot: -1.5707963267948966 rad type: Transform - uid: 168 - type: HVWire + type: CableHV components: - parent: 0 pos: 5.5,10.5 @@ -1579,77 +1579,77 @@ entities: rot: -1.5707963267948966 rad type: Transform - uid: 179 - type: MVWire + type: CableMV components: - parent: 0 pos: 3.5,6.5 rot: -1.5707963267948966 rad type: Transform - uid: 180 - type: MVWire + type: CableMV components: - parent: 0 pos: 3.5,7.5 rot: -1.5707963267948966 rad type: Transform - uid: 181 - type: MVWire + type: CableMV components: - parent: 0 pos: 3.5,8.5 rot: -1.5707963267948966 rad type: Transform - uid: 182 - type: MVWire + type: CableMV components: - parent: 0 pos: 3.5,9.5 rot: -1.5707963267948966 rad type: Transform - uid: 183 - type: MVWire + type: CableMV components: - parent: 0 pos: 3.5,10.5 rot: -1.5707963267948966 rad type: Transform - uid: 184 - type: MVWire + type: CableMV components: - parent: 0 pos: 2.5,10.5 rot: -1.5707963267948966 rad type: Transform - uid: 185 - type: MVWire + type: CableMV components: - parent: 0 pos: 4.5,10.5 rot: -1.5707963267948966 rad type: Transform - uid: 186 - type: MVWire + type: CableMV components: - parent: 0 pos: 5.5,10.5 rot: -1.5707963267948966 rad type: Transform - uid: 187 - type: MVWire + type: CableMV components: - parent: 0 pos: 6.5,10.5 rot: -1.5707963267948966 rad type: Transform - uid: 188 - type: MVWire + type: CableMV components: - parent: 0 pos: 1.5,10.5 rot: -1.5707963267948966 rad type: Transform - uid: 189 - type: MVWire + type: CableMV components: - parent: 0 pos: 0.5,10.5 @@ -1992,7 +1992,7 @@ entities: rot: -1.5707963267948966 rad type: Transform - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: light_bulb: !type:ContainerSlot {} type: ContainerContainer @@ -2004,26 +2004,26 @@ entities: rot: -1.5707963267948966 rad type: Transform - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: light_bulb: !type:ContainerSlot {} type: ContainerContainer - uid: 239 - type: ApcExtensionCable + type: CableApcExtension components: - parent: 0 pos: 4.5,16.5 rot: -1.5707963267948966 rad type: Transform - uid: 240 - type: ApcExtensionCable + type: CableApcExtension components: - parent: 0 pos: 5.5,16.5 rot: -1.5707963267948966 rad type: Transform - uid: 241 - type: ApcExtensionCable + type: CableApcExtension components: - parent: 0 pos: 1.5,16.5 diff --git a/Resources/Maps/saltern.yml b/Resources/Maps/saltern.yml index 58f9423ef6..cea7e3fb9d 100644 --- a/Resources/Maps/saltern.yml +++ b/Resources/Maps/saltern.yml @@ -1155,7 +1155,7 @@ entities: parent: 853 type: Transform - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: light_bulb: !type:ContainerSlot {} type: ContainerContainer @@ -1248,7 +1248,7 @@ entities: CloningPod-bodyContainer: !type:ContainerSlot {} type: ContainerContainer - uid: 152 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 58.5,-31.5 @@ -1257,7 +1257,7 @@ entities: - canCollide: False type: Physics - uid: 153 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 58.5,-29.5 @@ -1316,7 +1316,7 @@ entities: - canCollide: False type: Physics - uid: 161 - type: ApcExtensionCable + type: CableApcExtension components: - rot: -1.5707963267948966 rad pos: 16.5,-1.5 @@ -1355,7 +1355,7 @@ entities: ents: [] type: ContainerContainer - uid: 165 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 3.141592653589793 rad pos: 13.5,1.5 @@ -2676,7 +2676,7 @@ entities: ents: [] type: ContainerContainer - uid: 287 - type: HVWire + type: CableHV components: - rot: 3.141592653589793 rad pos: 3.5,-20.5 @@ -4650,7 +4650,7 @@ entities: parent: 853 type: Transform - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: light_bulb: !type:ContainerSlot {} type: ContainerContainer @@ -4749,7 +4749,7 @@ entities: parent: 853 type: Transform - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: light_bulb: !type:ContainerSlot {} type: ContainerContainer @@ -5095,7 +5095,7 @@ entities: - color: '#FFFFFFFF' type: PointLight - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: light_bulb: !type:ContainerSlot {} type: ContainerContainer @@ -5619,7 +5619,7 @@ entities: ents: [] type: ContainerContainer - uid: 608 - type: ApcExtensionCable + type: CableApcExtension components: - pos: -4.5,4.5 parent: 853 @@ -5971,7 +5971,7 @@ entities: ents: [] type: ContainerContainer - uid: 638 - type: HVWire + type: CableHV components: - rot: 3.141592653589793 rad pos: 3.5,-23.5 @@ -6536,7 +6536,7 @@ entities: ents: [] type: ContainerContainer - uid: 701 - type: HVWire + type: CableHV components: - rot: 3.141592653589793 rad pos: 3.5,-22.5 @@ -6554,7 +6554,7 @@ entities: parent: 853 type: Transform - uid: 703 - type: HVWire + type: CableHV components: - rot: 3.141592653589793 rad pos: 3.5,-21.5 @@ -6950,7 +6950,7 @@ entities: parent: 853 type: Transform - uid: 757 - type: HVWire + type: CableHV components: - pos: 14.5,11.5 parent: 853 @@ -12249,7 +12249,7 @@ entities: parent: 853 type: Transform - uid: 879 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 43.5,1.5 @@ -12346,7 +12346,7 @@ entities: - color: '#FFFFFFFF' type: PointLight - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: light_bulb: !type:ContainerSlot {} type: ContainerContainer @@ -12369,7 +12369,7 @@ entities: - color: '#FFFFFFFF' type: PointLight - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: light_bulb: !type:ContainerSlot {} type: ContainerContainer @@ -13083,7 +13083,7 @@ entities: parent: 853 type: Transform - uid: 994 - type: ApcExtensionCable + type: CableApcExtension components: - pos: 1.5,1.5 parent: 853 @@ -13107,7 +13107,7 @@ entities: - bodyType: Dynamic type: Physics - uid: 997 - type: ApcExtensionCable + type: CableApcExtension components: - pos: 0.5,2.5 parent: 853 @@ -13115,7 +13115,7 @@ entities: - canCollide: False type: Physics - uid: 998 - type: ApcExtensionCable + type: CableApcExtension components: - pos: 1.5,2.5 parent: 853 @@ -13130,7 +13130,7 @@ entities: parent: 853 type: Transform - uid: 1000 - type: ApcExtensionCable + type: CableApcExtension components: - pos: 3.5,30.5 parent: 853 @@ -13140,7 +13140,7 @@ entities: - canCollide: False type: Physics - uid: 1001 - type: ApcExtensionCable + type: CableApcExtension components: - pos: 3.5,28.5 parent: 853 @@ -13150,7 +13150,7 @@ entities: - canCollide: False type: Physics - uid: 1002 - type: ApcExtensionCable + type: CableApcExtension components: - pos: 26.5,4.5 parent: 853 @@ -13160,7 +13160,7 @@ entities: - canCollide: False type: Physics - uid: 1003 - type: ApcExtensionCable + type: CableApcExtension components: - pos: 25.5,4.5 parent: 853 @@ -13184,7 +13184,7 @@ entities: parent: 853 type: Transform - uid: 1006 - type: ApcExtensionCable + type: CableApcExtension components: - pos: 27.5,4.5 parent: 853 @@ -13194,7 +13194,7 @@ entities: - canCollide: False type: Physics - uid: 1007 - type: ApcExtensionCable + type: CableApcExtension components: - pos: 27.5,6.5 parent: 853 @@ -13204,7 +13204,7 @@ entities: - canCollide: False type: Physics - uid: 1008 - type: ApcExtensionCable + type: CableApcExtension components: - pos: 27.5,5.5 parent: 853 @@ -13214,7 +13214,7 @@ entities: - canCollide: False type: Physics - uid: 1009 - type: ApcExtensionCable + type: CableApcExtension components: - pos: 3.5,29.5 parent: 853 @@ -13224,7 +13224,7 @@ entities: - canCollide: False type: Physics - uid: 1010 - type: ApcExtensionCable + type: CableApcExtension components: - pos: 16.5,-2.5 parent: 853 @@ -13241,7 +13241,7 @@ entities: parent: 853 type: Transform - uid: 1012 - type: ApcExtensionCable + type: CableApcExtension components: - pos: 22.5,-18.5 parent: 853 @@ -13299,7 +13299,7 @@ entities: parent: 853 type: Transform - uid: 1019 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -6.5,-26.5 @@ -13594,7 +13594,7 @@ entities: - color: '#FFFFFFFF' type: PointLight - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: light_bulb: !type:ContainerSlot {} type: ContainerContainer @@ -13675,7 +13675,7 @@ entities: - color: '#FFFFFFFF' type: PointLight - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: light_bulb: !type:ContainerSlot {} type: ContainerContainer @@ -13699,7 +13699,7 @@ entities: - color: '#FFFFFFFF' type: PointLight - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: light_bulb: !type:ContainerSlot {} type: ContainerContainer @@ -13723,7 +13723,7 @@ entities: - color: '#FFFFFFFF' type: PointLight - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: light_bulb: !type:ContainerSlot {} type: ContainerContainer @@ -13757,7 +13757,7 @@ entities: - color: '#FFFFFFFF' type: PointLight - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: light_bulb: !type:ContainerSlot {} type: ContainerContainer @@ -14071,7 +14071,7 @@ entities: parent: 853 type: Transform - uid: 1117 - type: HVWire + type: CableHV components: - pos: -6.5,-26.5 parent: 853 @@ -14079,7 +14079,7 @@ entities: - canCollide: False type: Physics - uid: 1118 - type: HVWire + type: CableHV components: - pos: -4.5,-26.5 parent: 853 @@ -14124,7 +14124,7 @@ entities: - color: '#FFFFFFFF' type: PointLight - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: light_bulb: !type:ContainerSlot {} type: ContainerContainer @@ -14660,7 +14660,7 @@ entities: parent: 853 type: Transform - powerLoad: 1 - type: PowerReceiver + type: ApcPowerReceiver - startingCharge: 30000 type: Battery - uid: 1191 @@ -14727,7 +14727,7 @@ entities: - color: '#FFFFFFFF' type: PointLight - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: light_bulb: !type:ContainerSlot {} type: ContainerContainer @@ -14755,7 +14755,7 @@ entities: - color: '#FFFFFFFF' type: PointLight - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: light_bulb: !type:ContainerSlot {} type: ContainerContainer @@ -14769,7 +14769,7 @@ entities: - color: '#FFFFFFFF' type: PointLight - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: light_bulb: !type:ContainerSlot {} type: ContainerContainer @@ -14841,7 +14841,7 @@ entities: - color: '#FFFFFFFF' type: PointLight - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: light_bulb: !type:ContainerSlot {} type: ContainerContainer @@ -14885,7 +14885,7 @@ entities: - color: '#FFFFFFFF' type: PointLight - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: light_bulb: !type:ContainerSlot {} type: ContainerContainer @@ -14899,7 +14899,7 @@ entities: - color: '#FFFFFFFF' type: PointLight - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: light_bulb: !type:ContainerSlot {} type: ContainerContainer @@ -15006,7 +15006,7 @@ entities: - color: '#FFFFFFFF' type: PointLight - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: light_bulb: !type:ContainerSlot {} type: ContainerContainer @@ -15034,7 +15034,7 @@ entities: - color: '#FFFFFFFF' type: PointLight - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: light_bulb: !type:ContainerSlot {} type: ContainerContainer @@ -15048,7 +15048,7 @@ entities: - color: '#FFFFFFFF' type: PointLight - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: light_bulb: !type:ContainerSlot {} type: ContainerContainer @@ -15062,7 +15062,7 @@ entities: - color: '#FFFFFFFF' type: PointLight - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: light_bulb: !type:ContainerSlot {} type: ContainerContainer @@ -15126,8 +15126,7 @@ entities: type: Transform - startingCharge: 11999.417 type: Battery - - drawRate: 2000 - type: PowerConsumer + - uid: 1240 type: Poweredlight components: @@ -15174,7 +15173,7 @@ entities: parent: 853 type: Transform - uid: 1246 - type: ApcExtensionCable + type: CableApcExtension components: - pos: -2.5,-15.5 parent: 853 @@ -15184,7 +15183,7 @@ entities: - canCollide: False type: Physics - uid: 1247 - type: ApcExtensionCable + type: CableApcExtension components: - pos: 6.5,-0.5 parent: 853 @@ -15201,7 +15200,7 @@ entities: parent: 853 type: Transform - uid: 1249 - type: ApcExtensionCable + type: CableApcExtension components: - pos: 6.5,0.5 parent: 853 @@ -15234,7 +15233,7 @@ entities: - color: '#FFFFFFFF' type: PointLight - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: light_bulb: !type:ContainerSlot {} type: ContainerContainer @@ -15248,7 +15247,7 @@ entities: - color: '#FFFFFFFF' type: PointLight - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: light_bulb: !type:ContainerSlot {} type: ContainerContainer @@ -15262,7 +15261,7 @@ entities: - color: '#FFFFFFFF' type: PointLight - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: light_bulb: !type:ContainerSlot {} type: ContainerContainer @@ -15276,7 +15275,7 @@ entities: - color: '#FFFFFFFF' type: PointLight - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: light_bulb: !type:ContainerSlot {} type: ContainerContainer @@ -15290,7 +15289,7 @@ entities: - color: '#FFFFFFFF' type: PointLight - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: light_bulb: !type:ContainerSlot {} type: ContainerContainer @@ -15310,7 +15309,7 @@ entities: - color: '#FFFFFFFF' type: PointLight - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: light_bulb: !type:ContainerSlot {} type: ContainerContainer @@ -15343,7 +15342,7 @@ entities: - color: '#FFFFFFFF' type: PointLight - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: light_bulb: !type:ContainerSlot {} type: ContainerContainer @@ -15395,7 +15394,7 @@ entities: - color: '#FFFFFFFF' type: PointLight - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: light_bulb: !type:ContainerSlot {} type: ContainerContainer @@ -15454,7 +15453,7 @@ entities: - color: '#FFFFFFFF' type: PointLight - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: light_bulb: !type:ContainerSlot {} type: ContainerContainer @@ -15468,7 +15467,7 @@ entities: - color: '#FFFFFFFF' type: PointLight - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: light_bulb: !type:ContainerSlot {} type: ContainerContainer @@ -15482,7 +15481,7 @@ entities: - color: '#FFFFFFFF' type: PointLight - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: light_bulb: !type:ContainerSlot {} type: ContainerContainer @@ -15496,7 +15495,7 @@ entities: - color: '#FFFFFFFF' type: PointLight - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: light_bulb: !type:ContainerSlot {} type: ContainerContainer @@ -15510,7 +15509,7 @@ entities: - color: '#FFFFFFFF' type: PointLight - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: light_bulb: !type:ContainerSlot {} type: ContainerContainer @@ -15522,7 +15521,7 @@ entities: parent: 853 type: Transform - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: light_bulb: !type:ContainerSlot {} type: ContainerContainer @@ -15536,7 +15535,7 @@ entities: - color: '#FFFFFFFF' type: PointLight - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: light_bulb: !type:ContainerSlot {} type: ContainerContainer @@ -15598,7 +15597,7 @@ entities: - color: '#FFFFFFFF' type: PointLight - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: light_bulb: !type:ContainerSlot {} type: ContainerContainer @@ -15623,7 +15622,7 @@ entities: - color: '#FFFFFFFF' type: PointLight - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: light_bulb: !type:ContainerSlot {} type: ContainerContainer @@ -15666,7 +15665,7 @@ entities: - color: '#FFFFFFFF' type: PointLight - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: light_bulb: !type:ContainerSlot {} type: ContainerContainer @@ -15680,7 +15679,7 @@ entities: - color: '#FFFFFFFF' type: PointLight - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: light_bulb: !type:ContainerSlot {} type: ContainerContainer @@ -15694,7 +15693,7 @@ entities: - color: '#FFFFFFFF' type: PointLight - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: light_bulb: !type:ContainerSlot {} type: ContainerContainer @@ -15727,7 +15726,7 @@ entities: - color: '#FFFFFFFF' type: PointLight - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: light_bulb: !type:ContainerSlot {} type: ContainerContainer @@ -15741,7 +15740,7 @@ entities: - color: '#FFFFFFFF' type: PointLight - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: light_bulb: !type:ContainerSlot {} type: ContainerContainer @@ -15755,7 +15754,7 @@ entities: - color: '#FFFFFFFF' type: PointLight - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: light_bulb: !type:ContainerSlot {} type: ContainerContainer @@ -15820,7 +15819,7 @@ entities: - color: '#FFFFFFFF' type: PointLight - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: light_bulb: !type:ContainerSlot {} type: ContainerContainer @@ -15834,7 +15833,7 @@ entities: - color: '#FFFFFFFF' type: PointLight - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: light_bulb: !type:ContainerSlot {} type: ContainerContainer @@ -15848,7 +15847,7 @@ entities: - color: '#FFFFFFFF' type: PointLight - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: light_bulb: !type:ContainerSlot {} type: ContainerContainer @@ -15881,7 +15880,7 @@ entities: - color: '#FFFFFFFF' type: PointLight - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: light_bulb: !type:ContainerSlot {} type: ContainerContainer @@ -15895,7 +15894,7 @@ entities: - color: '#FFFFFFFF' type: PointLight - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: light_bulb: !type:ContainerSlot {} type: ContainerContainer @@ -15909,7 +15908,7 @@ entities: - color: '#FFFFFFFF' type: PointLight - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: light_bulb: !type:ContainerSlot {} type: ContainerContainer @@ -15933,7 +15932,7 @@ entities: - color: '#FFFFFFFF' type: PointLight - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: light_bulb: !type:ContainerSlot {} type: ContainerContainer @@ -15989,7 +15988,7 @@ entities: - color: '#FFFFFFFF' type: PointLight - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: light_bulb: !type:ContainerSlot {} type: ContainerContainer @@ -16003,7 +16002,7 @@ entities: - color: '#FFFFFFFF' type: PointLight - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: light_bulb: !type:ContainerSlot {} type: ContainerContainer @@ -16093,7 +16092,7 @@ entities: - color: '#FFFFFFFF' type: PointLight - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: light_bulb: !type:ContainerSlot {} type: ContainerContainer @@ -16107,7 +16106,7 @@ entities: - color: '#FFFFFFFF' type: PointLight - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: light_bulb: !type:ContainerSlot {} type: ContainerContainer @@ -16181,7 +16180,7 @@ entities: parent: 853 type: Transform - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: light_bulb: !type:ContainerSlot {} type: ContainerContainer @@ -16231,7 +16230,7 @@ entities: - color: '#FFFFFFFF' type: PointLight - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: light_bulb: !type:ContainerSlot {} type: ContainerContainer @@ -16250,7 +16249,7 @@ entities: parent: 853 type: Transform - uid: 1351 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -32.5,1.5 @@ -16275,7 +16274,7 @@ entities: - color: '#FFFFFFFF' type: PointLight - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: light_bulb: !type:ContainerSlot {} type: ContainerContainer @@ -16296,7 +16295,7 @@ entities: - color: '#FFFFFFFF' type: PointLight - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: light_bulb: !type:ContainerSlot {} type: ContainerContainer @@ -16310,7 +16309,7 @@ entities: - color: '#FFFFFFFF' type: PointLight - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: light_bulb: !type:ContainerSlot {} type: ContainerContainer @@ -16359,7 +16358,7 @@ entities: - color: '#FFFFFFFF' type: PointLight - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: light_bulb: !type:ContainerSlot {} type: ContainerContainer @@ -16380,7 +16379,7 @@ entities: - color: '#FFFFFFFF' type: PointLight - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: light_bulb: !type:ContainerSlot {} type: ContainerContainer @@ -16394,7 +16393,7 @@ entities: - color: '#FFFFFFFF' type: PointLight - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: light_bulb: !type:ContainerSlot {} type: ContainerContainer @@ -16427,7 +16426,7 @@ entities: - color: '#FFFFFFFF' type: PointLight - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: light_bulb: !type:ContainerSlot {} type: ContainerContainer @@ -16486,7 +16485,7 @@ entities: - color: '#FFFFFFFF' type: PointLight - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: light_bulb: !type:ContainerSlot {} type: ContainerContainer @@ -16500,7 +16499,7 @@ entities: - color: '#FFFFFFFF' type: PointLight - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: light_bulb: !type:ContainerSlot {} type: ContainerContainer @@ -16514,7 +16513,7 @@ entities: - color: '#FFFFFFFF' type: PointLight - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: light_bulb: !type:ContainerSlot {} type: ContainerContainer @@ -16571,7 +16570,7 @@ entities: - color: '#FFFFFFFF' type: PointLight - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: light_bulb: !type:ContainerSlot {} type: ContainerContainer @@ -16585,12 +16584,12 @@ entities: - color: '#FFFFFFFF' type: PointLight - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: light_bulb: !type:ContainerSlot {} type: ContainerContainer - uid: 1384 - type: ApcExtensionCable + type: CableApcExtension components: - pos: -4.5,5.5 parent: 853 @@ -16616,7 +16615,7 @@ entities: - color: '#FFFFFFFF' type: PointLight - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: light_bulb: !type:ContainerSlot {} type: ContainerContainer @@ -16630,7 +16629,7 @@ entities: - color: '#FFFFFFFF' type: PointLight - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: light_bulb: !type:ContainerSlot {} type: ContainerContainer @@ -17290,7 +17289,7 @@ entities: parent: 853 type: Transform - uid: 1482 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -7.5,-25.5 @@ -17301,7 +17300,7 @@ entities: - canCollide: False type: Physics - uid: 1483 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -7.5,-26.5 @@ -17702,7 +17701,7 @@ entities: parent: 853 type: Transform - uid: 1539 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 58.5,-28.5 @@ -17760,7 +17759,7 @@ entities: ents: [] type: ContainerContainer - uid: 1546 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 58.5,-32.5 @@ -17769,7 +17768,7 @@ entities: - canCollide: False type: Physics - uid: 1547 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 57.5,-33.5 @@ -18310,7 +18309,7 @@ entities: - color: '#FFFFFFFF' type: PointLight - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: light_bulb: !type:ContainerSlot {} type: ContainerContainer @@ -18324,7 +18323,7 @@ entities: - color: '#FFFFFFFF' type: PointLight - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: light_bulb: !type:ContainerSlot {} type: ContainerContainer @@ -19173,7 +19172,7 @@ entities: parent: 853 type: Transform - uid: 1753 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 54.5,-33.5 @@ -19209,7 +19208,7 @@ entities: parent: 853 type: Transform - uid: 1758 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 58.5,-30.5 @@ -19365,7 +19364,7 @@ entities: parent: 853 type: Transform - uid: 1780 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 56.5,-33.5 @@ -19374,7 +19373,7 @@ entities: - canCollide: False type: Physics - uid: 1781 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 58.5,-33.5 @@ -19397,7 +19396,7 @@ entities: parent: 853 type: Transform - uid: 1784 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 52.5,-33.5 @@ -19678,7 +19677,7 @@ entities: parent: 853 type: Transform - uid: 1825 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 53.5,-33.5 @@ -19687,7 +19686,7 @@ entities: - canCollide: False type: Physics - uid: 1826 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 55.5,-33.5 @@ -19788,7 +19787,7 @@ entities: - color: '#FFFFFFFF' type: PointLight - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: light_bulb: !type:ContainerSlot {} type: ContainerContainer @@ -21511,7 +21510,7 @@ entities: parent: 853 type: Transform - uid: 2085 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -7.5,-24.5 @@ -21534,7 +21533,7 @@ entities: parent: 853 type: Transform - uid: 2088 - type: ApcExtensionCable + type: CableApcExtension components: - pos: 1.5,6.5 parent: 853 @@ -23809,7 +23808,7 @@ entities: parent: 853 type: Transform - uid: 2410 - type: ApcExtensionCable + type: CableApcExtension components: - pos: -1.5,6.5 parent: 853 @@ -23855,7 +23854,7 @@ entities: ents: [] type: ContainerContainer - uid: 2415 - type: ApcExtensionCable + type: CableApcExtension components: - pos: -3.5,6.5 parent: 853 @@ -23863,7 +23862,7 @@ entities: - canCollide: False type: Physics - uid: 2416 - type: ApcExtensionCable + type: CableApcExtension components: - pos: -2.5,6.5 parent: 853 @@ -23885,7 +23884,7 @@ entities: parent: 853 type: Transform - uid: 2419 - type: ApcExtensionCable + type: CableApcExtension components: - pos: -4.5,6.5 parent: 853 @@ -23914,7 +23913,7 @@ entities: parent: 853 type: Transform - uid: 2423 - type: ApcExtensionCable + type: CableApcExtension components: - pos: -13.5,-9.5 parent: 853 @@ -24509,8 +24508,7 @@ entities: type: Transform - startingCharge: 11999.634 type: Battery - - drawRate: 2000 - type: PowerConsumer + - uid: 2505 type: SalternApc components: @@ -24520,8 +24518,7 @@ entities: type: Transform - startingCharge: 11999.3 type: Battery - - drawRate: 2000 - type: PowerConsumer + - uid: 2506 type: SalternApc components: @@ -24531,8 +24528,7 @@ entities: type: Transform - startingCharge: 11999.066 type: Battery - - drawRate: 2000 - type: PowerConsumer + - uid: 2507 type: SalternApc components: @@ -24542,8 +24538,7 @@ entities: type: Transform - startingCharge: 11999.733 type: Battery - - drawRate: 2000 - type: PowerConsumer + - uid: 2508 type: SalternApc components: @@ -24553,8 +24548,7 @@ entities: type: Transform - startingCharge: 11999.483 type: Battery - - drawRate: 2000 - type: PowerConsumer + - uid: 2509 type: SalternApc components: @@ -24564,8 +24558,7 @@ entities: type: Transform - startingCharge: 11991.15 type: Battery - - drawRate: 2000 - type: PowerConsumer + - uid: 2510 type: SalternApc components: @@ -24575,8 +24568,7 @@ entities: type: Transform - startingCharge: 11999.15 type: Battery - - drawRate: 2000 - type: PowerConsumer + - uid: 2511 type: SalternApc components: @@ -24586,8 +24578,7 @@ entities: type: Transform - startingCharge: 11999.384 type: Battery - - drawRate: 2000 - type: PowerConsumer + - uid: 2512 type: SalternApc components: @@ -24597,8 +24588,7 @@ entities: type: Transform - startingCharge: 11999.116 type: Battery - - drawRate: 2000 - type: PowerConsumer + - uid: 2513 type: SalternApc components: @@ -24608,8 +24598,7 @@ entities: type: Transform - startingCharge: 11999.2 type: Battery - - drawRate: 2000 - type: PowerConsumer + - uid: 2514 type: SalternApc components: @@ -24619,8 +24608,7 @@ entities: type: Transform - startingCharge: 11999.066 type: Battery - - drawRate: 2000 - type: PowerConsumer + - uid: 2515 type: SalternApc components: @@ -24630,8 +24618,7 @@ entities: type: Transform - startingCharge: 11999.467 type: Battery - - drawRate: 2000 - type: PowerConsumer + - uid: 2516 type: CrateServiceReplacementLights components: @@ -24653,8 +24640,7 @@ entities: type: Transform - startingCharge: 11999.483 type: Battery - - drawRate: 2000 - type: PowerConsumer + - uid: 2518 type: SalternApc components: @@ -24664,8 +24650,7 @@ entities: type: Transform - startingCharge: 11999.4 type: Battery - - drawRate: 2000 - type: PowerConsumer + - uid: 2519 type: SalternApc components: @@ -24675,8 +24660,7 @@ entities: type: Transform - startingCharge: 11999.4 type: Battery - - drawRate: 2000 - type: PowerConsumer + - uid: 2520 type: SalternApc components: @@ -24686,8 +24670,7 @@ entities: type: Transform - startingCharge: 11998.483 type: Battery - - drawRate: 2000 - type: PowerConsumer + - uid: 2521 type: ShellShotgunSlug components: @@ -24705,10 +24688,9 @@ entities: type: Transform - startingCharge: 11999.75 type: Battery - - drawRate: 2000 - type: PowerConsumer + - uid: 2523 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -14.5,0.5 @@ -24734,8 +24716,7 @@ entities: type: Transform - startingCharge: 11999.083 type: Battery - - drawRate: 2000 - type: PowerConsumer + - uid: 2526 type: SalternApc components: @@ -24745,8 +24726,7 @@ entities: type: Transform - startingCharge: 11996.233 type: Battery - - drawRate: 2000 - type: PowerConsumer + - uid: 2527 type: SalternApc components: @@ -24756,10 +24736,9 @@ entities: type: Transform - startingCharge: 11999.65 type: Battery - - drawRate: 2000 - type: PowerConsumer + - uid: 2528 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -28.5,12.5 @@ -24768,7 +24747,7 @@ entities: - canCollide: False type: Physics - uid: 2529 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -28.5,11.5 @@ -24779,7 +24758,7 @@ entities: - canCollide: False type: Physics - uid: 2530 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -28.5,10.5 @@ -24790,7 +24769,7 @@ entities: - canCollide: False type: Physics - uid: 2531 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -28.5,9.5 @@ -24801,7 +24780,7 @@ entities: - canCollide: False type: Physics - uid: 2532 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -28.5,8.5 @@ -24812,7 +24791,7 @@ entities: - canCollide: False type: Physics - uid: 2533 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -27.5,9.5 @@ -24823,7 +24802,7 @@ entities: - canCollide: False type: Physics - uid: 2534 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -26.5,9.5 @@ -24834,7 +24813,7 @@ entities: - canCollide: False type: Physics - uid: 2535 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -25.5,9.5 @@ -24843,7 +24822,7 @@ entities: - canCollide: False type: Physics - uid: 2536 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -26.5,8.5 @@ -24854,7 +24833,7 @@ entities: - canCollide: False type: Physics - uid: 2537 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -26.5,7.5 @@ -24863,7 +24842,7 @@ entities: - canCollide: False type: Physics - uid: 2538 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -24.5,9.5 @@ -24874,7 +24853,7 @@ entities: - canCollide: False type: Physics - uid: 2539 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -23.5,9.5 @@ -24885,7 +24864,7 @@ entities: - canCollide: False type: Physics - uid: 2540 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -22.5,9.5 @@ -24896,7 +24875,7 @@ entities: - canCollide: False type: Physics - uid: 2541 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -21.5,9.5 @@ -24907,7 +24886,7 @@ entities: - canCollide: False type: Physics - uid: 2542 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -20.5,9.5 @@ -24918,7 +24897,7 @@ entities: - canCollide: False type: Physics - uid: 2543 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -19.5,9.5 @@ -24929,7 +24908,7 @@ entities: - canCollide: False type: Physics - uid: 2544 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -23.5,8.5 @@ -24940,7 +24919,7 @@ entities: - canCollide: False type: Physics - uid: 2545 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -23.5,7.5 @@ -24951,7 +24930,7 @@ entities: - canCollide: False type: Physics - uid: 2546 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -23.5,7.5 @@ -24962,7 +24941,7 @@ entities: - canCollide: False type: Physics - uid: 2547 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -23.5,6.5 @@ -24973,7 +24952,7 @@ entities: - canCollide: False type: Physics - uid: 2548 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -28.5,13.5 @@ -24984,7 +24963,7 @@ entities: - canCollide: False type: Physics - uid: 2549 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -28.5,14.5 @@ -24993,7 +24972,7 @@ entities: - canCollide: False type: Physics - uid: 2550 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -17.5,9.5 @@ -25002,7 +24981,7 @@ entities: - canCollide: False type: Physics - uid: 2551 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -16.5,9.5 @@ -25013,7 +24992,7 @@ entities: - canCollide: False type: Physics - uid: 2552 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -16.5,8.5 @@ -25024,7 +25003,7 @@ entities: - canCollide: False type: Physics - uid: 2553 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -16.5,7.5 @@ -25041,10 +25020,9 @@ entities: type: Transform - startingCharge: 11999.833 type: Battery - - drawRate: 2000 - type: PowerConsumer + - uid: 2555 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -16.5,15.5 @@ -25055,7 +25033,7 @@ entities: - canCollide: False type: Physics - uid: 2556 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -17.5,15.5 @@ -25064,7 +25042,7 @@ entities: - canCollide: False type: Physics - uid: 2557 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -17.5,16.5 @@ -25075,7 +25053,7 @@ entities: - canCollide: False type: Physics - uid: 2558 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -17.5,17.5 @@ -25086,7 +25064,7 @@ entities: - canCollide: False type: Physics - uid: 2559 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -17.5,18.5 @@ -25097,7 +25075,7 @@ entities: - canCollide: False type: Physics - uid: 2560 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -17.5,19.5 @@ -25108,7 +25086,7 @@ entities: - canCollide: False type: Physics - uid: 2561 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -17.5,20.5 @@ -25119,7 +25097,7 @@ entities: - canCollide: False type: Physics - uid: 2562 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -17.5,21.5 @@ -25130,7 +25108,7 @@ entities: - canCollide: False type: Physics - uid: 2563 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -17.5,22.5 @@ -25141,7 +25119,7 @@ entities: - canCollide: False type: Physics - uid: 2564 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -17.5,23.5 @@ -25152,7 +25130,7 @@ entities: - canCollide: False type: Physics - uid: 2565 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -17.5,24.5 @@ -25163,7 +25141,7 @@ entities: - canCollide: False type: Physics - uid: 2566 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -16.5,24.5 @@ -25174,7 +25152,7 @@ entities: - canCollide: False type: Physics - uid: 2567 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -15.5,24.5 @@ -25185,7 +25163,7 @@ entities: - canCollide: False type: Physics - uid: 2568 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -14.5,24.5 @@ -25196,7 +25174,7 @@ entities: - canCollide: False type: Physics - uid: 2569 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -13.5,24.5 @@ -25207,7 +25185,7 @@ entities: - canCollide: False type: Physics - uid: 2570 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -12.5,24.5 @@ -25218,7 +25196,7 @@ entities: - canCollide: False type: Physics - uid: 2571 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -11.5,24.5 @@ -25229,7 +25207,7 @@ entities: - canCollide: False type: Physics - uid: 2572 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -10.5,24.5 @@ -25240,7 +25218,7 @@ entities: - canCollide: False type: Physics - uid: 2573 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -9.5,24.5 @@ -25251,7 +25229,7 @@ entities: - canCollide: False type: Physics - uid: 2574 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -8.5,24.5 @@ -25262,7 +25240,7 @@ entities: - canCollide: False type: Physics - uid: 2575 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -7.5,24.5 @@ -25271,7 +25249,7 @@ entities: - canCollide: False type: Physics - uid: 2576 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -12.5,12.5 @@ -25280,7 +25258,7 @@ entities: - canCollide: False type: Physics - uid: 2577 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -12.5,11.5 @@ -25291,7 +25269,7 @@ entities: - canCollide: False type: Physics - uid: 2578 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -13.5,11.5 @@ -25302,7 +25280,7 @@ entities: - canCollide: False type: Physics - uid: 2579 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -12.5,10.5 @@ -25313,7 +25291,7 @@ entities: - canCollide: False type: Physics - uid: 2580 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -12.5,9.5 @@ -25324,7 +25302,7 @@ entities: - canCollide: False type: Physics - uid: 2581 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -12.5,7.5 @@ -25335,7 +25313,7 @@ entities: - canCollide: False type: Physics - uid: 2582 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -12.5,8.5 @@ -25346,7 +25324,7 @@ entities: - canCollide: False type: Physics - uid: 2583 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -11.5,7.5 @@ -25357,7 +25335,7 @@ entities: - canCollide: False type: Physics - uid: 2584 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -11.5,10.5 @@ -25368,7 +25346,7 @@ entities: - canCollide: False type: Physics - uid: 2585 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -9.5,10.5 @@ -25379,7 +25357,7 @@ entities: - canCollide: False type: Physics - uid: 2586 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -10.5,10.5 @@ -25390,7 +25368,7 @@ entities: - canCollide: False type: Physics - uid: 2587 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -8.5,10.5 @@ -25401,7 +25379,7 @@ entities: - canCollide: False type: Physics - uid: 2588 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -7.5,10.5 @@ -25412,7 +25390,7 @@ entities: - canCollide: False type: Physics - uid: 2589 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -6.5,10.5 @@ -25423,7 +25401,7 @@ entities: - canCollide: False type: Physics - uid: 2590 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -5.5,10.5 @@ -25434,7 +25412,7 @@ entities: - canCollide: False type: Physics - uid: 2591 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -4.5,10.5 @@ -25445,7 +25423,7 @@ entities: - canCollide: False type: Physics - uid: 2592 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -3.5,10.5 @@ -25456,7 +25434,7 @@ entities: - canCollide: False type: Physics - uid: 2593 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -2.5,10.5 @@ -25467,7 +25445,7 @@ entities: - canCollide: False type: Physics - uid: 2594 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -1.5,10.5 @@ -25478,7 +25456,7 @@ entities: - canCollide: False type: Physics - uid: 2595 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -0.5,10.5 @@ -25489,7 +25467,7 @@ entities: - canCollide: False type: Physics - uid: 2596 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 0.5,10.5 @@ -25500,7 +25478,7 @@ entities: - canCollide: False type: Physics - uid: 2597 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -5.5,9.5 @@ -25511,7 +25489,7 @@ entities: - canCollide: False type: Physics - uid: 2598 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -5.5,8.5 @@ -25522,7 +25500,7 @@ entities: - canCollide: False type: Physics - uid: 2599 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -5.5,7.5 @@ -25533,7 +25511,7 @@ entities: - canCollide: False type: Physics - uid: 2600 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 0.5,9.5 @@ -25544,7 +25522,7 @@ entities: - canCollide: False type: Physics - uid: 2601 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 0.5,8.5 @@ -25555,7 +25533,7 @@ entities: - canCollide: False type: Physics - uid: 2602 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 0.5,7.5 @@ -25566,7 +25544,7 @@ entities: - canCollide: False type: Physics - uid: 2603 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 0.5,6.5 @@ -25575,7 +25553,7 @@ entities: - canCollide: False type: Physics - uid: 2604 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 0.5,6.5 @@ -25584,7 +25562,7 @@ entities: - canCollide: False type: Physics - uid: 2605 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -0.5,6.5 @@ -25593,7 +25571,7 @@ entities: - canCollide: False type: Physics - uid: 2606 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -3.5,15.5 @@ -25602,7 +25580,7 @@ entities: - canCollide: False type: Physics - uid: 2607 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -3.5,16.5 @@ -25613,7 +25591,7 @@ entities: - canCollide: False type: Physics - uid: 2608 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -3.5,17.5 @@ -25624,7 +25602,7 @@ entities: - canCollide: False type: Physics - uid: 2609 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -3.5,18.5 @@ -25635,7 +25613,7 @@ entities: - canCollide: False type: Physics - uid: 2610 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -2.5,18.5 @@ -25646,7 +25624,7 @@ entities: - canCollide: False type: Physics - uid: 2611 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -1.5,18.5 @@ -25657,7 +25635,7 @@ entities: - canCollide: False type: Physics - uid: 2612 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -0.5,18.5 @@ -25668,7 +25646,7 @@ entities: - canCollide: False type: Physics - uid: 2613 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -3.5,15.5 @@ -25677,7 +25655,7 @@ entities: - canCollide: False type: Physics - uid: 2614 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -3.5,14.5 @@ -25688,7 +25666,7 @@ entities: - canCollide: False type: Physics - uid: 2615 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -4.5,14.5 @@ -25699,7 +25677,7 @@ entities: - canCollide: False type: Physics - uid: 2616 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -5.5,14.5 @@ -25710,7 +25688,7 @@ entities: - canCollide: False type: Physics - uid: 2617 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -6.5,14.5 @@ -25721,7 +25699,7 @@ entities: - canCollide: False type: Physics - uid: 2618 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -7.5,14.5 @@ -25732,7 +25710,7 @@ entities: - canCollide: False type: Physics - uid: 2619 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -8.5,14.5 @@ -25743,7 +25721,7 @@ entities: - canCollide: False type: Physics - uid: 2620 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -9.5,14.5 @@ -25754,7 +25732,7 @@ entities: - canCollide: False type: Physics - uid: 2621 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -10.5,14.5 @@ -25763,7 +25741,7 @@ entities: - canCollide: False type: Physics - uid: 2622 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -11.5,14.5 @@ -25774,7 +25752,7 @@ entities: - canCollide: False type: Physics - uid: 2623 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -12.5,14.5 @@ -25785,7 +25763,7 @@ entities: - canCollide: False type: Physics - uid: 2624 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -12.5,15.5 @@ -25796,7 +25774,7 @@ entities: - canCollide: False type: Physics - uid: 2625 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -12.5,16.5 @@ -25807,7 +25785,7 @@ entities: - canCollide: False type: Physics - uid: 2626 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -7.5,15.5 @@ -25818,7 +25796,7 @@ entities: - canCollide: False type: Physics - uid: 2627 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -7.5,16.5 @@ -25829,7 +25807,7 @@ entities: - canCollide: False type: Physics - uid: 2628 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -7.5,17.5 @@ -25840,7 +25818,7 @@ entities: - canCollide: False type: Physics - uid: 2629 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -6.5,17.5 @@ -25851,7 +25829,7 @@ entities: - canCollide: False type: Physics - uid: 2630 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -8.5,17.5 @@ -25862,7 +25840,7 @@ entities: - canCollide: False type: Physics - uid: 2631 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -8.5,18.5 @@ -25873,7 +25851,7 @@ entities: - canCollide: False type: Physics - uid: 2632 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -8.5,19.5 @@ -25884,7 +25862,7 @@ entities: - canCollide: False type: Physics - uid: 2633 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -8.5,20.5 @@ -25895,7 +25873,7 @@ entities: - canCollide: False type: Physics - uid: 2634 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -9.5,20.5 @@ -25906,7 +25884,7 @@ entities: - canCollide: False type: Physics - uid: 2635 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -8.5,21.5 @@ -25917,7 +25895,7 @@ entities: - canCollide: False type: Physics - uid: 2636 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -7.5,21.5 @@ -25928,7 +25906,7 @@ entities: - canCollide: False type: Physics - uid: 2637 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -12.5,17.5 @@ -25939,7 +25917,7 @@ entities: - canCollide: False type: Physics - uid: 2638 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -12.5,18.5 @@ -25950,7 +25928,7 @@ entities: - canCollide: False type: Physics - uid: 2639 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -12.5,19.5 @@ -25961,7 +25939,7 @@ entities: - canCollide: False type: Physics - uid: 2640 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -12.5,20.5 @@ -25972,7 +25950,7 @@ entities: - canCollide: False type: Physics - uid: 2641 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -13.5,20.5 @@ -25983,7 +25961,7 @@ entities: - canCollide: False type: Physics - uid: 2642 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -14.5,20.5 @@ -25994,7 +25972,7 @@ entities: - canCollide: False type: Physics - uid: 2643 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -3.5,14.5 @@ -26005,7 +25983,7 @@ entities: - canCollide: False type: Physics - uid: 2644 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -2.5,14.5 @@ -26016,7 +25994,7 @@ entities: - canCollide: False type: Physics - uid: 2645 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -1.5,14.5 @@ -26027,7 +26005,7 @@ entities: - canCollide: False type: Physics - uid: 2646 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -0.5,14.5 @@ -26038,7 +26016,7 @@ entities: - canCollide: False type: Physics - uid: 2647 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 0.5,14.5 @@ -26049,7 +26027,7 @@ entities: - canCollide: False type: Physics - uid: 2648 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 1.5,14.5 @@ -26058,7 +26036,7 @@ entities: - canCollide: False type: Physics - uid: 2649 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 0.5,13.5 @@ -26069,7 +26047,7 @@ entities: - canCollide: False type: Physics - uid: 2650 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 0.5,12.5 @@ -26080,7 +26058,7 @@ entities: - canCollide: False type: Physics - uid: 2651 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -39.5,11.5 @@ -26089,7 +26067,7 @@ entities: - canCollide: False type: Physics - uid: 2652 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -39.5,10.5 @@ -26100,7 +26078,7 @@ entities: - canCollide: False type: Physics - uid: 2653 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -38.5,10.5 @@ -26111,7 +26089,7 @@ entities: - canCollide: False type: Physics - uid: 2654 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -37.5,10.5 @@ -26122,7 +26100,7 @@ entities: - canCollide: False type: Physics - uid: 2655 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -36.5,10.5 @@ -26133,7 +26111,7 @@ entities: - canCollide: False type: Physics - uid: 2656 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -36.5,9.5 @@ -26144,7 +26122,7 @@ entities: - canCollide: False type: Physics - uid: 2657 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -36.5,8.5 @@ -26155,7 +26133,7 @@ entities: - canCollide: False type: Physics - uid: 2658 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -36.5,7.5 @@ -26166,7 +26144,7 @@ entities: - canCollide: False type: Physics - uid: 2659 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -36.5,6.5 @@ -26177,7 +26155,7 @@ entities: - canCollide: False type: Physics - uid: 2660 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -36.5,5.5 @@ -26188,7 +26166,7 @@ entities: - canCollide: False type: Physics - uid: 2661 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -36.5,4.5 @@ -26199,7 +26177,7 @@ entities: - canCollide: False type: Physics - uid: 2662 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -36.5,3.5 @@ -26210,7 +26188,7 @@ entities: - canCollide: False type: Physics - uid: 2663 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -36.5,2.5 @@ -26221,7 +26199,7 @@ entities: - canCollide: False type: Physics - uid: 2664 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -36.5,1.5 @@ -26232,7 +26210,7 @@ entities: - canCollide: False type: Physics - uid: 2665 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -36.5,0.5 @@ -26243,7 +26221,7 @@ entities: - canCollide: False type: Physics - uid: 2666 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -36.5,-0.5 @@ -26254,7 +26232,7 @@ entities: - canCollide: False type: Physics - uid: 2667 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -36.5,-1.5 @@ -26265,7 +26243,7 @@ entities: - canCollide: False type: Physics - uid: 2668 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -36.5,-2.5 @@ -26276,7 +26254,7 @@ entities: - canCollide: False type: Physics - uid: 2669 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -36.5,-3.5 @@ -26287,7 +26265,7 @@ entities: - canCollide: False type: Physics - uid: 2670 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -36.5,-4.5 @@ -26298,7 +26276,7 @@ entities: - canCollide: False type: Physics - uid: 2671 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -36.5,-5.5 @@ -26309,7 +26287,7 @@ entities: - canCollide: False type: Physics - uid: 2672 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -36.5,-6.5 @@ -26320,7 +26298,7 @@ entities: - canCollide: False type: Physics - uid: 2673 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -35.5,-6.5 @@ -26331,7 +26309,7 @@ entities: - canCollide: False type: Physics - uid: 2674 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -35.5,2.5 @@ -26342,7 +26320,7 @@ entities: - canCollide: False type: Physics - uid: 2675 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -35.5,5.5 @@ -26353,7 +26331,7 @@ entities: - canCollide: False type: Physics - uid: 2676 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -34.5,5.5 @@ -26364,7 +26342,7 @@ entities: - canCollide: False type: Physics - uid: 2677 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -33.5,5.5 @@ -26375,7 +26353,7 @@ entities: - canCollide: False type: Physics - uid: 2678 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -32.5,5.5 @@ -26386,7 +26364,7 @@ entities: - canCollide: False type: Physics - uid: 2679 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -35.5,8.5 @@ -26397,7 +26375,7 @@ entities: - canCollide: False type: Physics - uid: 2680 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -34.5,8.5 @@ -26408,7 +26386,7 @@ entities: - canCollide: False type: Physics - uid: 2681 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -37.5,8.5 @@ -26419,7 +26397,7 @@ entities: - canCollide: False type: Physics - uid: 2682 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -38.5,8.5 @@ -26430,7 +26408,7 @@ entities: - canCollide: False type: Physics - uid: 2683 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -39.5,8.5 @@ -26441,7 +26419,7 @@ entities: - canCollide: False type: Physics - uid: 2684 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -40.5,8.5 @@ -26452,7 +26430,7 @@ entities: - canCollide: False type: Physics - uid: 2685 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -37.5,4.5 @@ -26463,7 +26441,7 @@ entities: - canCollide: False type: Physics - uid: 2686 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -38.5,4.5 @@ -26474,7 +26452,7 @@ entities: - canCollide: False type: Physics - uid: 2687 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -39.5,4.5 @@ -26485,7 +26463,7 @@ entities: - canCollide: False type: Physics - uid: 2688 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -40.5,4.5 @@ -26496,7 +26474,7 @@ entities: - canCollide: False type: Physics - uid: 2689 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -37.5,-3.5 @@ -26507,7 +26485,7 @@ entities: - canCollide: False type: Physics - uid: 2690 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -38.5,-3.5 @@ -26518,7 +26496,7 @@ entities: - canCollide: False type: Physics - uid: 2691 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -18.5,9.5 @@ -26527,7 +26505,7 @@ entities: - canCollide: False type: Physics - uid: 2692 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -17.5,7.5 @@ -26536,7 +26514,7 @@ entities: - canCollide: False type: Physics - uid: 2693 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -18.5,7.5 @@ -26545,7 +26523,7 @@ entities: - canCollide: False type: Physics - uid: 2694 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -30.5,-3.5 @@ -26554,7 +26532,7 @@ entities: - canCollide: False type: Physics - uid: 2695 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -30.5,-4.5 @@ -26565,7 +26543,7 @@ entities: - canCollide: False type: Physics - uid: 2696 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -30.5,-5.5 @@ -26576,7 +26554,7 @@ entities: - canCollide: False type: Physics - uid: 2697 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -30.5,-6.5 @@ -26585,7 +26563,7 @@ entities: - canCollide: False type: Physics - uid: 2698 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -30.5,-7.5 @@ -26596,7 +26574,7 @@ entities: - canCollide: False type: Physics - uid: 2699 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -29.5,-7.5 @@ -26607,7 +26585,7 @@ entities: - canCollide: False type: Physics - uid: 2700 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -28.5,-7.5 @@ -26618,7 +26596,7 @@ entities: - canCollide: False type: Physics - uid: 2701 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -27.5,-7.5 @@ -26629,7 +26607,7 @@ entities: - canCollide: False type: Physics - uid: 2702 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -26.5,-7.5 @@ -26640,7 +26618,7 @@ entities: - canCollide: False type: Physics - uid: 2703 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -25.5,-7.5 @@ -26651,7 +26629,7 @@ entities: - canCollide: False type: Physics - uid: 2704 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -25.5,-8.5 @@ -26662,7 +26640,7 @@ entities: - canCollide: False type: Physics - uid: 2705 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -24.5,-7.5 @@ -26673,7 +26651,7 @@ entities: - canCollide: False type: Physics - uid: 2706 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -23.5,-7.5 @@ -26684,7 +26662,7 @@ entities: - canCollide: False type: Physics - uid: 2707 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -23.5,-8.5 @@ -26695,7 +26673,7 @@ entities: - canCollide: False type: Physics - uid: 2708 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -20.5,-7.5 @@ -26706,7 +26684,7 @@ entities: - canCollide: False type: Physics - uid: 2709 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -30.5,-2.5 @@ -26717,7 +26695,7 @@ entities: - canCollide: False type: Physics - uid: 2710 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -30.5,-1.5 @@ -26728,7 +26706,7 @@ entities: - canCollide: False type: Physics - uid: 2711 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -30.5,-0.5 @@ -26737,7 +26715,7 @@ entities: - canCollide: False type: Physics - uid: 2712 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -30.5,0.5 @@ -26748,7 +26726,7 @@ entities: - canCollide: False type: Physics - uid: 2713 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -30.5,1.5 @@ -26759,7 +26737,7 @@ entities: - canCollide: False type: Physics - uid: 2714 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -29.5,0.5 @@ -26770,7 +26748,7 @@ entities: - canCollide: False type: Physics - uid: 2715 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -28.5,0.5 @@ -26781,7 +26759,7 @@ entities: - canCollide: False type: Physics - uid: 2716 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -27.5,0.5 @@ -26792,7 +26770,7 @@ entities: - canCollide: False type: Physics - uid: 2717 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -27.5,-0.5 @@ -26801,7 +26779,7 @@ entities: - canCollide: False type: Physics - uid: 2718 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -27.5,-1.5 @@ -26819,7 +26797,7 @@ entities: parent: 853 type: Transform - uid: 2720 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -31.5,-6.5 @@ -26830,7 +26808,7 @@ entities: - canCollide: False type: Physics - uid: 2721 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -32.5,-6.5 @@ -26839,7 +26817,7 @@ entities: - canCollide: False type: Physics - uid: 2722 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -32.5,-5.5 @@ -26850,7 +26828,7 @@ entities: - canCollide: False type: Physics - uid: 2723 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -32.5,-4.5 @@ -26861,7 +26839,7 @@ entities: - canCollide: False type: Physics - uid: 2724 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -32.5,-3.5 @@ -26872,7 +26850,7 @@ entities: - canCollide: False type: Physics - uid: 2725 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -32.5,-2.5 @@ -26883,7 +26861,7 @@ entities: - canCollide: False type: Physics - uid: 2726 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -32.5,-1.5 @@ -26894,7 +26872,7 @@ entities: - canCollide: False type: Physics - uid: 2727 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -32.5,-0.5 @@ -26905,7 +26883,7 @@ entities: - canCollide: False type: Physics - uid: 2728 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -32.5,0.5 @@ -26914,7 +26892,7 @@ entities: - canCollide: False type: Physics - uid: 2729 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -32.5,1.5 @@ -26923,7 +26901,7 @@ entities: - canCollide: False type: Physics - uid: 2730 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -20.5,-12.5 @@ -26932,7 +26910,7 @@ entities: - canCollide: False type: Physics - uid: 2731 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -20.5,-13.5 @@ -26943,7 +26921,7 @@ entities: - canCollide: False type: Physics - uid: 2732 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -20.5,-14.5 @@ -26954,7 +26932,7 @@ entities: - canCollide: False type: Physics - uid: 2733 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -21.5,-14.5 @@ -26965,7 +26943,7 @@ entities: - canCollide: False type: Physics - uid: 2734 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -22.5,-14.5 @@ -26976,7 +26954,7 @@ entities: - canCollide: False type: Physics - uid: 2735 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -22.5,-14.5 @@ -26987,7 +26965,7 @@ entities: - canCollide: False type: Physics - uid: 2736 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -23.5,-14.5 @@ -26998,7 +26976,7 @@ entities: - canCollide: False type: Physics - uid: 2737 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -24.5,-14.5 @@ -27009,7 +26987,7 @@ entities: - canCollide: False type: Physics - uid: 2738 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -24.5,-13.5 @@ -27020,7 +26998,7 @@ entities: - canCollide: False type: Physics - uid: 2739 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -14.5,-8.5 @@ -27031,7 +27009,7 @@ entities: - canCollide: False type: Physics - uid: 2740 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -14.5,-9.5 @@ -27042,7 +27020,7 @@ entities: - canCollide: False type: Physics - uid: 2741 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -14.5,-10.5 @@ -27053,7 +27031,7 @@ entities: - canCollide: False type: Physics - uid: 2742 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -14.5,-10.5 @@ -27064,7 +27042,7 @@ entities: - canCollide: False type: Physics - uid: 2743 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -14.5,-11.5 @@ -27075,7 +27053,7 @@ entities: - canCollide: False type: Physics - uid: 2744 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -13.5,-11.5 @@ -27086,7 +27064,7 @@ entities: - canCollide: False type: Physics - uid: 2745 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -12.5,-11.5 @@ -27097,7 +27075,7 @@ entities: - canCollide: False type: Physics - uid: 2746 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -11.5,-11.5 @@ -27108,7 +27086,7 @@ entities: - canCollide: False type: Physics - uid: 2747 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -12.5,-10.5 @@ -27119,7 +27097,7 @@ entities: - canCollide: False type: Physics - uid: 2748 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -12.5,-9.5 @@ -27130,7 +27108,7 @@ entities: - canCollide: False type: Physics - uid: 2749 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -13.5,-12.5 @@ -27141,7 +27119,7 @@ entities: - canCollide: False type: Physics - uid: 2750 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -12.5,-8.5 @@ -27152,7 +27130,7 @@ entities: - canCollide: False type: Physics - uid: 2751 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -16.5,-7.5 @@ -27163,7 +27141,7 @@ entities: - canCollide: False type: Physics - uid: 2752 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -15.5,-7.5 @@ -27174,7 +27152,7 @@ entities: - canCollide: False type: Physics - uid: 2753 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -14.5,-7.5 @@ -27185,7 +27163,7 @@ entities: - canCollide: False type: Physics - uid: 2754 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -17.5,-7.5 @@ -27196,7 +27174,7 @@ entities: - canCollide: False type: Physics - uid: 2755 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -18.5,-7.5 @@ -27207,7 +27185,7 @@ entities: - canCollide: False type: Physics - uid: 2756 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -19.5,-7.5 @@ -27218,7 +27196,7 @@ entities: - canCollide: False type: Physics - uid: 2757 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -20.5,-7.5 @@ -27229,7 +27207,7 @@ entities: - canCollide: False type: Physics - uid: 2758 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -18.5,-6.5 @@ -27238,7 +27216,7 @@ entities: - canCollide: False type: Physics - uid: 2759 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -18.5,-5.5 @@ -27249,7 +27227,7 @@ entities: - canCollide: False type: Physics - uid: 2760 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -18.5,-4.5 @@ -27260,7 +27238,7 @@ entities: - canCollide: False type: Physics - uid: 2761 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -19.5,-4.5 @@ -27271,7 +27249,7 @@ entities: - canCollide: False type: Physics - uid: 2762 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -20.5,-4.5 @@ -27282,7 +27260,7 @@ entities: - canCollide: False type: Physics - uid: 2763 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -21.5,-4.5 @@ -27293,7 +27271,7 @@ entities: - canCollide: False type: Physics - uid: 2764 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -22.5,-4.5 @@ -27304,7 +27282,7 @@ entities: - canCollide: False type: Physics - uid: 2765 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -22.5,-3.5 @@ -27315,7 +27293,7 @@ entities: - canCollide: False type: Physics - uid: 2766 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -22.5,-2.5 @@ -27326,7 +27304,7 @@ entities: - canCollide: False type: Physics - uid: 2767 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -22.5,-2.5 @@ -27337,7 +27315,7 @@ entities: - canCollide: False type: Physics - uid: 2768 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -22.5,-1.5 @@ -27348,7 +27326,7 @@ entities: - canCollide: False type: Physics - uid: 2769 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -22.5,-0.5 @@ -27359,7 +27337,7 @@ entities: - canCollide: False type: Physics - uid: 2770 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -22.5,0.5 @@ -27370,7 +27348,7 @@ entities: - canCollide: False type: Physics - uid: 2771 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -22.5,1.5 @@ -27379,7 +27357,7 @@ entities: - canCollide: False type: Physics - uid: 2772 - type: ApcExtensionCable + type: CableApcExtension components: - pos: -23.5,0.5 parent: 853 @@ -27389,7 +27367,7 @@ entities: - canCollide: False type: Physics - uid: 2773 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -15.5,-6.5 @@ -27398,7 +27376,7 @@ entities: - canCollide: False type: Physics - uid: 2774 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -15.5,-5.5 @@ -27407,7 +27385,7 @@ entities: - canCollide: False type: Physics - uid: 2775 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -15.5,-4.5 @@ -27416,7 +27394,7 @@ entities: - canCollide: False type: Physics - uid: 2776 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -11.5,2.5 @@ -27425,7 +27403,7 @@ entities: - canCollide: False type: Physics - uid: 2777 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -11.5,1.5 @@ -27436,7 +27414,7 @@ entities: - canCollide: False type: Physics - uid: 2778 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -11.5,0.5 @@ -27447,7 +27425,7 @@ entities: - canCollide: False type: Physics - uid: 2779 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -11.5,-0.5 @@ -27458,7 +27436,7 @@ entities: - canCollide: False type: Physics - uid: 2780 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -11.5,-1.5 @@ -27469,7 +27447,7 @@ entities: - canCollide: False type: Physics - uid: 2781 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -11.5,-2.5 @@ -27478,7 +27456,7 @@ entities: - canCollide: False type: Physics - uid: 2782 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -11.5,-3.5 @@ -27489,7 +27467,7 @@ entities: - canCollide: False type: Physics - uid: 2783 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -11.5,-4.5 @@ -27500,7 +27478,7 @@ entities: - canCollide: False type: Physics - uid: 2784 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -12.5,-4.5 @@ -27511,7 +27489,7 @@ entities: - canCollide: False type: Physics - uid: 2785 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -12.5,0.5 @@ -27522,7 +27500,7 @@ entities: - canCollide: False type: Physics - uid: 2786 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -13.5,0.5 @@ -27533,7 +27511,7 @@ entities: - canCollide: False type: Physics - uid: 2787 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -14.5,0.5 @@ -27544,7 +27522,7 @@ entities: - canCollide: False type: Physics - uid: 2788 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -14.5,0.5 @@ -27563,10 +27541,9 @@ entities: type: Transform - startingCharge: 11999.45 type: Battery - - drawRate: 2000 - type: PowerConsumer + - uid: 2790 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -15.5,0.5 @@ -27577,7 +27554,7 @@ entities: - canCollide: False type: Physics - uid: 2791 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -16.5,0.5 @@ -27588,7 +27565,7 @@ entities: - canCollide: False type: Physics - uid: 2792 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -17.5,0.5 @@ -27599,7 +27576,7 @@ entities: - canCollide: False type: Physics - uid: 2793 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -18.5,0.5 @@ -27610,7 +27587,7 @@ entities: - canCollide: False type: Physics - uid: 2794 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -19.5,0.5 @@ -27621,7 +27598,7 @@ entities: - canCollide: False type: Physics - uid: 2795 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -20.5,0.5 @@ -27632,7 +27609,7 @@ entities: - canCollide: False type: Physics - uid: 2796 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -20.5,1.5 @@ -27643,7 +27620,7 @@ entities: - canCollide: False type: Physics - uid: 2797 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -16.5,-0.5 @@ -27654,7 +27631,7 @@ entities: - canCollide: False type: Physics - uid: 2798 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -16.5,-1.5 @@ -27665,7 +27642,7 @@ entities: - canCollide: False type: Physics - uid: 2799 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -12.5,-1.5 @@ -27676,7 +27653,7 @@ entities: - canCollide: False type: Physics - uid: 2800 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -12.5,-1.5 @@ -27687,7 +27664,7 @@ entities: - canCollide: False type: Physics - uid: 2801 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -13.5,-1.5 @@ -27698,7 +27675,7 @@ entities: - canCollide: False type: Physics - uid: 2802 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -20.5,-0.5 @@ -27709,7 +27686,7 @@ entities: - canCollide: False type: Physics - uid: 2803 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -20.5,-0.5 @@ -27720,7 +27697,7 @@ entities: - canCollide: False type: Physics - uid: 2804 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -20.5,-1.5 @@ -27731,7 +27708,7 @@ entities: - canCollide: False type: Physics - uid: 2805 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -20.5,-2.5 @@ -27742,7 +27719,7 @@ entities: - canCollide: False type: Physics - uid: 2806 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -10.5,0.5 @@ -27753,7 +27730,7 @@ entities: - canCollide: False type: Physics - uid: 2807 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -9.5,0.5 @@ -27764,7 +27741,7 @@ entities: - canCollide: False type: Physics - uid: 2808 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -8.5,0.5 @@ -27775,7 +27752,7 @@ entities: - canCollide: False type: Physics - uid: 2809 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -7.5,0.5 @@ -27786,7 +27763,7 @@ entities: - canCollide: False type: Physics - uid: 2810 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -6.5,0.5 @@ -27797,7 +27774,7 @@ entities: - canCollide: False type: Physics - uid: 2811 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -5.5,0.5 @@ -27808,7 +27785,7 @@ entities: - canCollide: False type: Physics - uid: 2812 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -4.5,0.5 @@ -27819,7 +27796,7 @@ entities: - canCollide: False type: Physics - uid: 2813 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -3.5,0.5 @@ -27830,7 +27807,7 @@ entities: - canCollide: False type: Physics - uid: 2814 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -2.5,0.5 @@ -27841,7 +27818,7 @@ entities: - canCollide: False type: Physics - uid: 2815 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -1.5,0.5 @@ -27852,7 +27829,7 @@ entities: - canCollide: False type: Physics - uid: 2816 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -0.5,0.5 @@ -27863,7 +27840,7 @@ entities: - canCollide: False type: Physics - uid: 2817 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 0.5,0.5 @@ -27874,7 +27851,7 @@ entities: - canCollide: False type: Physics - uid: 2818 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -0.5,0.5 @@ -27885,7 +27862,7 @@ entities: - canCollide: False type: Physics - uid: 2819 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -0.5,-0.5 @@ -27896,7 +27873,7 @@ entities: - canCollide: False type: Physics - uid: 2820 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -0.5,-1.5 @@ -27907,7 +27884,7 @@ entities: - canCollide: False type: Physics - uid: 2821 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -0.5,-2.5 @@ -27918,7 +27895,7 @@ entities: - canCollide: False type: Physics - uid: 2822 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -0.5,-3.5 @@ -27929,7 +27906,7 @@ entities: - canCollide: False type: Physics - uid: 2823 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -0.5,-4.5 @@ -27940,7 +27917,7 @@ entities: - canCollide: False type: Physics - uid: 2824 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 0.5,-4.5 @@ -27951,7 +27928,7 @@ entities: - canCollide: False type: Physics - uid: 2825 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -5.5,-8.5 @@ -27960,7 +27937,7 @@ entities: - canCollide: False type: Physics - uid: 2826 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -5.5,-7.5 @@ -27971,7 +27948,7 @@ entities: - canCollide: False type: Physics - uid: 2827 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -4.5,-7.5 @@ -27982,7 +27959,7 @@ entities: - canCollide: False type: Physics - uid: 2828 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -3.5,-7.5 @@ -27993,7 +27970,7 @@ entities: - canCollide: False type: Physics - uid: 2829 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -6.5,-7.5 @@ -28004,7 +27981,7 @@ entities: - canCollide: False type: Physics - uid: 2830 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -6.5,-7.5 @@ -28015,7 +27992,7 @@ entities: - canCollide: False type: Physics - uid: 2831 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -7.5,-7.5 @@ -28026,7 +28003,7 @@ entities: - canCollide: False type: Physics - uid: 2832 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -6.5,-6.5 @@ -28037,7 +28014,7 @@ entities: - canCollide: False type: Physics - uid: 2833 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -6.5,-5.5 @@ -28048,7 +28025,7 @@ entities: - canCollide: False type: Physics - uid: 2834 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -6.5,-4.5 @@ -28059,7 +28036,7 @@ entities: - canCollide: False type: Physics - uid: 2835 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -5.5,-9.5 @@ -28070,7 +28047,7 @@ entities: - canCollide: False type: Physics - uid: 2836 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -5.5,-10.5 @@ -28079,7 +28056,7 @@ entities: - canCollide: False type: Physics - uid: 2837 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -4.5,-10.5 @@ -28088,7 +28065,7 @@ entities: - canCollide: False type: Physics - uid: 2838 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -4.5,-10.5 @@ -28097,7 +28074,7 @@ entities: - canCollide: False type: Physics - uid: 2839 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -3.5,-10.5 @@ -28106,7 +28083,7 @@ entities: - canCollide: False type: Physics - uid: 2840 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -2.5,-10.5 @@ -28115,7 +28092,7 @@ entities: - canCollide: False type: Physics - uid: 2841 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -1.5,-10.5 @@ -28124,7 +28101,7 @@ entities: - canCollide: False type: Physics - uid: 2842 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -0.5,-10.5 @@ -28133,7 +28110,7 @@ entities: - canCollide: False type: Physics - uid: 2843 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 0.5,-10.5 @@ -28142,7 +28119,7 @@ entities: - canCollide: False type: Physics - uid: 2844 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 0.5,-9.5 @@ -28151,7 +28128,7 @@ entities: - canCollide: False type: Physics - uid: 2845 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 0.5,-8.5 @@ -28160,7 +28137,7 @@ entities: - canCollide: False type: Physics - uid: 2846 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 0.5,-7.5 @@ -28169,7 +28146,7 @@ entities: - canCollide: False type: Physics - uid: 2847 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -0.5,-11.5 @@ -28178,7 +28155,7 @@ entities: - canCollide: False type: Physics - uid: 2848 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -1.5,-18.5 @@ -28187,7 +28164,7 @@ entities: - canCollide: False type: Physics - uid: 2849 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -1.5,-19.5 @@ -28198,7 +28175,7 @@ entities: - canCollide: False type: Physics - uid: 2850 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -1.5,-20.5 @@ -28209,7 +28186,7 @@ entities: - canCollide: False type: Physics - uid: 2851 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -0.5,-19.5 @@ -28220,7 +28197,7 @@ entities: - canCollide: False type: Physics - uid: 2852 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -2.5,-19.5 @@ -28231,7 +28208,7 @@ entities: - canCollide: False type: Physics - uid: 2853 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -3.5,-19.5 @@ -28242,7 +28219,7 @@ entities: - canCollide: False type: Physics - uid: 2854 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -4.5,-19.5 @@ -28253,7 +28230,7 @@ entities: - canCollide: False type: Physics - uid: 2855 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -3.5,-20.5 @@ -28264,7 +28241,7 @@ entities: - canCollide: False type: Physics - uid: 2856 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -3.5,-21.5 @@ -28275,7 +28252,7 @@ entities: - canCollide: False type: Physics - uid: 2857 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -3.5,-23.5 @@ -28286,7 +28263,7 @@ entities: - canCollide: False type: Physics - uid: 2858 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -3.5,-22.5 @@ -28297,7 +28274,7 @@ entities: - canCollide: False type: Physics - uid: 2859 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -2.5,-23.5 @@ -28308,7 +28285,7 @@ entities: - canCollide: False type: Physics - uid: 2860 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -9.5,-21.5 @@ -28317,7 +28294,7 @@ entities: - canCollide: False type: Physics - uid: 2861 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -9.5,-22.5 @@ -28328,7 +28305,7 @@ entities: - canCollide: False type: Physics - uid: 2862 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -9.5,-23.5 @@ -28339,7 +28316,7 @@ entities: - canCollide: False type: Physics - uid: 2863 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -8.5,-23.5 @@ -28350,7 +28327,7 @@ entities: - canCollide: False type: Physics - uid: 2864 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -7.5,-23.5 @@ -28361,7 +28338,7 @@ entities: - canCollide: False type: Physics - uid: 2865 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -7.5,-24.5 @@ -28370,7 +28347,7 @@ entities: - canCollide: False type: Physics - uid: 2866 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -7.5,-25.5 @@ -28381,7 +28358,7 @@ entities: - canCollide: False type: Physics - uid: 2867 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -9.5,-20.5 @@ -28392,7 +28369,7 @@ entities: - canCollide: False type: Physics - uid: 2868 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -10.5,-20.5 @@ -28403,7 +28380,7 @@ entities: - canCollide: False type: Physics - uid: 2869 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -11.5,-20.5 @@ -28414,7 +28391,7 @@ entities: - canCollide: False type: Physics - uid: 2870 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -11.5,-19.5 @@ -28425,7 +28402,7 @@ entities: - canCollide: False type: Physics - uid: 2871 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -9.5,-19.5 @@ -28436,7 +28413,7 @@ entities: - canCollide: False type: Physics - uid: 2872 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -9.5,-18.5 @@ -28447,7 +28424,7 @@ entities: - canCollide: False type: Physics - uid: 2873 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -9.5,-17.5 @@ -28458,7 +28435,7 @@ entities: - canCollide: False type: Physics - uid: 2874 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -8.5,-17.5 @@ -28469,7 +28446,7 @@ entities: - canCollide: False type: Physics - uid: 2875 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -3.5,-18.5 @@ -28480,7 +28457,7 @@ entities: - canCollide: False type: Physics - uid: 2876 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -3.5,-17.5 @@ -28491,7 +28468,7 @@ entities: - canCollide: False type: Physics - uid: 2877 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -3.5,-17.5 @@ -28502,7 +28479,7 @@ entities: - canCollide: False type: Physics - uid: 2878 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -3.5,-16.5 @@ -28513,7 +28490,7 @@ entities: - canCollide: False type: Physics - uid: 2879 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -3.5,-15.5 @@ -28524,7 +28501,7 @@ entities: - canCollide: False type: Physics - uid: 2880 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -3.5,-14.5 @@ -28535,7 +28512,7 @@ entities: - canCollide: False type: Physics - uid: 2881 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -3.5,-13.5 @@ -28546,7 +28523,7 @@ entities: - canCollide: False type: Physics - uid: 2882 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -3.5,-12.5 @@ -28557,7 +28534,7 @@ entities: - canCollide: False type: Physics - uid: 2883 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -2.5,-13.5 @@ -28568,7 +28545,7 @@ entities: - canCollide: False type: Physics - uid: 2884 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -1.5,-13.5 @@ -28579,7 +28556,7 @@ entities: - canCollide: False type: Physics - uid: 2885 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -1.5,-17.5 @@ -28590,7 +28567,7 @@ entities: - canCollide: False type: Physics - uid: 2886 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -0.5,-17.5 @@ -28601,7 +28578,7 @@ entities: - canCollide: False type: Physics - uid: 2887 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 0.5,-17.5 @@ -28610,7 +28587,7 @@ entities: - canCollide: False type: Physics - uid: 2888 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -4.5,-14.5 @@ -28621,7 +28598,7 @@ entities: - canCollide: False type: Physics - uid: 2889 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -4.5,-12.5 @@ -28632,7 +28609,7 @@ entities: - canCollide: False type: Physics - uid: 2890 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -4.5,-17.5 @@ -28643,7 +28620,7 @@ entities: - canCollide: False type: Physics - uid: 2891 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -5.5,-12.5 @@ -28654,7 +28631,7 @@ entities: - canCollide: False type: Physics - uid: 2892 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -6.5,-12.5 @@ -28663,7 +28640,7 @@ entities: - canCollide: False type: Physics - uid: 2893 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -5.5,-14.5 @@ -28674,7 +28651,7 @@ entities: - canCollide: False type: Physics - uid: 2894 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -14.5,-16.5 @@ -28683,7 +28660,7 @@ entities: - canCollide: False type: Physics - uid: 2895 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -14.5,-17.5 @@ -28694,7 +28671,7 @@ entities: - canCollide: False type: Physics - uid: 2896 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -14.5,-18.5 @@ -28705,7 +28682,7 @@ entities: - canCollide: False type: Physics - uid: 2897 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -14.5,-19.5 @@ -28716,7 +28693,7 @@ entities: - canCollide: False type: Physics - uid: 2898 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -14.5,-20.5 @@ -28727,7 +28704,7 @@ entities: - canCollide: False type: Physics - uid: 2899 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -14.5,-21.5 @@ -28738,7 +28715,7 @@ entities: - canCollide: False type: Physics - uid: 2900 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -14.5,-22.5 @@ -28749,7 +28726,7 @@ entities: - canCollide: False type: Physics - uid: 2901 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -14.5,-23.5 @@ -28760,7 +28737,7 @@ entities: - canCollide: False type: Physics - uid: 2902 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -14.5,-24.5 @@ -28771,7 +28748,7 @@ entities: - canCollide: False type: Physics - uid: 2903 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -14.5,-25.5 @@ -28782,7 +28759,7 @@ entities: - canCollide: False type: Physics - uid: 2904 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -15.5,-25.5 @@ -28793,7 +28770,7 @@ entities: - canCollide: False type: Physics - uid: 2905 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -16.5,-25.5 @@ -28804,7 +28781,7 @@ entities: - canCollide: False type: Physics - uid: 2906 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -15.5,-22.5 @@ -28815,7 +28792,7 @@ entities: - canCollide: False type: Physics - uid: 2907 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -16.5,-22.5 @@ -28826,7 +28803,7 @@ entities: - canCollide: False type: Physics - uid: 2908 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -17.5,-22.5 @@ -28837,7 +28814,7 @@ entities: - canCollide: False type: Physics - uid: 2909 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -1.5,-23.5 @@ -28846,7 +28823,7 @@ entities: - canCollide: False type: Physics - uid: 2910 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -0.5,-23.5 @@ -28855,7 +28832,7 @@ entities: - canCollide: False type: Physics - uid: 2911 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 0.5,-23.5 @@ -28864,7 +28841,7 @@ entities: - canCollide: False type: Physics - uid: 2912 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 7.5,-17.5 @@ -28873,7 +28850,7 @@ entities: - canCollide: False type: Physics - uid: 2913 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 7.5,-18.5 @@ -28884,7 +28861,7 @@ entities: - canCollide: False type: Physics - uid: 2914 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 7.5,-19.5 @@ -28893,7 +28870,7 @@ entities: - canCollide: False type: Physics - uid: 2915 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 8.5,-18.5 @@ -28904,7 +28881,7 @@ entities: - canCollide: False type: Physics - uid: 2916 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 9.5,-18.5 @@ -28915,7 +28892,7 @@ entities: - canCollide: False type: Physics - uid: 2917 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 10.5,-18.5 @@ -28926,7 +28903,7 @@ entities: - canCollide: False type: Physics - uid: 2918 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 10.5,-19.5 @@ -28937,7 +28914,7 @@ entities: - canCollide: False type: Physics - uid: 2919 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 11.5,-19.5 @@ -28948,7 +28925,7 @@ entities: - canCollide: False type: Physics - uid: 2920 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 12.5,-19.5 @@ -28959,7 +28936,7 @@ entities: - canCollide: False type: Physics - uid: 2921 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 13.5,-19.5 @@ -28970,7 +28947,7 @@ entities: - canCollide: False type: Physics - uid: 2922 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 14.5,-19.5 @@ -28979,7 +28956,7 @@ entities: - canCollide: False type: Physics - uid: 2923 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 15.5,-19.5 @@ -28990,7 +28967,7 @@ entities: - canCollide: False type: Physics - uid: 2924 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 7.5,-16.5 @@ -29001,7 +28978,7 @@ entities: - canCollide: False type: Physics - uid: 2925 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 7.5,-15.5 @@ -29012,7 +28989,7 @@ entities: - canCollide: False type: Physics - uid: 2926 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 7.5,-14.5 @@ -29023,7 +29000,7 @@ entities: - canCollide: False type: Physics - uid: 2927 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 7.5,-13.5 @@ -29034,7 +29011,7 @@ entities: - canCollide: False type: Physics - uid: 2928 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 6.5,-13.5 @@ -29043,7 +29020,7 @@ entities: - canCollide: False type: Physics - uid: 2929 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 5.5,-13.5 @@ -29054,7 +29031,7 @@ entities: - canCollide: False type: Physics - uid: 2930 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 8.5,-13.5 @@ -29065,7 +29042,7 @@ entities: - canCollide: False type: Physics - uid: 2931 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 9.5,-13.5 @@ -29076,7 +29053,7 @@ entities: - canCollide: False type: Physics - uid: 2932 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 10.5,-13.5 @@ -29087,7 +29064,7 @@ entities: - canCollide: False type: Physics - uid: 2933 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 11.5,-13.5 @@ -29096,7 +29073,7 @@ entities: - canCollide: False type: Physics - uid: 2934 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 22.5,-4.5 @@ -29107,7 +29084,7 @@ entities: - canCollide: False type: Physics - uid: 2935 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 22.5,-5.5 @@ -29118,7 +29095,7 @@ entities: - canCollide: False type: Physics - uid: 2936 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 23.5,-4.5 @@ -29129,7 +29106,7 @@ entities: - canCollide: False type: Physics - uid: 2937 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 24.5,-4.5 @@ -29140,7 +29117,7 @@ entities: - canCollide: False type: Physics - uid: 2938 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 25.5,-4.5 @@ -29149,7 +29126,7 @@ entities: - canCollide: False type: Physics - uid: 2939 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 22.5,-2.5 @@ -29158,7 +29135,7 @@ entities: - canCollide: False type: Physics - uid: 2940 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 22.5,-1.5 @@ -29169,7 +29146,7 @@ entities: - canCollide: False type: Physics - uid: 2941 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 22.5,-0.5 @@ -29180,7 +29157,7 @@ entities: - canCollide: False type: Physics - uid: 2942 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 22.5,0.5 @@ -29191,7 +29168,7 @@ entities: - canCollide: False type: Physics - uid: 2943 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 22.5,1.5 @@ -29202,7 +29179,7 @@ entities: - canCollide: False type: Physics - uid: 2944 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 21.5,1.5 @@ -29211,7 +29188,7 @@ entities: - canCollide: False type: Physics - uid: 2945 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 23.5,0.5 @@ -29222,7 +29199,7 @@ entities: - canCollide: False type: Physics - uid: 2946 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 23.5,-1.5 @@ -29233,7 +29210,7 @@ entities: - canCollide: False type: Physics - uid: 2947 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 24.5,-1.5 @@ -29244,7 +29221,7 @@ entities: - canCollide: False type: Physics - uid: 2948 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 25.5,-1.5 @@ -29255,7 +29232,7 @@ entities: - canCollide: False type: Physics - uid: 2949 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 22.5,-6.5 @@ -29266,7 +29243,7 @@ entities: - canCollide: False type: Physics - uid: 2950 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 21.5,-6.5 @@ -29277,7 +29254,7 @@ entities: - canCollide: False type: Physics - uid: 2951 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 20.5,-6.5 @@ -29288,7 +29265,7 @@ entities: - canCollide: False type: Physics - uid: 2952 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 19.5,-6.5 @@ -29299,7 +29276,7 @@ entities: - canCollide: False type: Physics - uid: 2953 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 18.5,-6.5 @@ -29310,7 +29287,7 @@ entities: - canCollide: False type: Physics - uid: 2954 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 18.5,-5.5 @@ -29321,7 +29298,7 @@ entities: - canCollide: False type: Physics - uid: 2955 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 18.5,-4.5 @@ -29332,7 +29309,7 @@ entities: - canCollide: False type: Physics - uid: 2956 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 18.5,-7.5 @@ -29343,7 +29320,7 @@ entities: - canCollide: False type: Physics - uid: 2957 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 18.5,-8.5 @@ -29354,7 +29331,7 @@ entities: - canCollide: False type: Physics - uid: 2958 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 18.5,-9.5 @@ -29365,7 +29342,7 @@ entities: - canCollide: False type: Physics - uid: 2959 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 18.5,-10.5 @@ -29376,7 +29353,7 @@ entities: - canCollide: False type: Physics - uid: 2960 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 18.5,-11.5 @@ -29387,7 +29364,7 @@ entities: - canCollide: False type: Physics - uid: 2961 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 18.5,-12.5 @@ -29398,7 +29375,7 @@ entities: - canCollide: False type: Physics - uid: 2962 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 18.5,-13.5 @@ -29409,7 +29386,7 @@ entities: - canCollide: False type: Physics - uid: 2963 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 18.5,-14.5 @@ -29420,7 +29397,7 @@ entities: - canCollide: False type: Physics - uid: 2964 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 18.5,-15.5 @@ -29431,7 +29408,7 @@ entities: - canCollide: False type: Physics - uid: 2965 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 18.5,-16.5 @@ -29442,7 +29419,7 @@ entities: - canCollide: False type: Physics - uid: 2966 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 18.5,-17.5 @@ -29453,7 +29430,7 @@ entities: - canCollide: False type: Physics - uid: 2967 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 18.5,-18.5 @@ -29462,7 +29439,7 @@ entities: - canCollide: False type: Physics - uid: 2968 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 18.5,-19.5 @@ -29473,7 +29450,7 @@ entities: - canCollide: False type: Physics - uid: 2969 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 18.5,-20.5 @@ -29484,7 +29461,7 @@ entities: - canCollide: False type: Physics - uid: 2970 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 19.5,-13.5 @@ -29495,7 +29472,7 @@ entities: - canCollide: False type: Physics - uid: 2971 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 20.5,-13.5 @@ -29506,7 +29483,7 @@ entities: - canCollide: False type: Physics - uid: 2972 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 21.5,-13.5 @@ -29517,7 +29494,7 @@ entities: - canCollide: False type: Physics - uid: 2973 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 22.5,-13.5 @@ -29528,7 +29505,7 @@ entities: - canCollide: False type: Physics - uid: 2974 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 22.5,-13.5 @@ -29539,7 +29516,7 @@ entities: - canCollide: False type: Physics - uid: 2975 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 23.5,-13.5 @@ -29550,7 +29527,7 @@ entities: - canCollide: False type: Physics - uid: 2976 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 23.5,-14.5 @@ -29561,7 +29538,7 @@ entities: - canCollide: False type: Physics - uid: 2977 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 8.5,-12.5 @@ -29572,7 +29549,7 @@ entities: - canCollide: False type: Physics - uid: 2978 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 8.5,-11.5 @@ -29583,7 +29560,7 @@ entities: - canCollide: False type: Physics - uid: 2979 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 7.5,-11.5 @@ -29594,7 +29571,7 @@ entities: - canCollide: False type: Physics - uid: 2980 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 9.5,-11.5 @@ -29605,7 +29582,7 @@ entities: - canCollide: False type: Physics - uid: 2981 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 10.5,-11.5 @@ -29616,7 +29593,7 @@ entities: - canCollide: False type: Physics - uid: 2982 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 7.5,-7.5 @@ -29627,7 +29604,7 @@ entities: - canCollide: False type: Physics - uid: 2983 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 8.5,-7.5 @@ -29638,7 +29615,7 @@ entities: - canCollide: False type: Physics - uid: 2984 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 9.5,-7.5 @@ -29649,7 +29626,7 @@ entities: - canCollide: False type: Physics - uid: 2985 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 10.5,-7.5 @@ -29660,7 +29637,7 @@ entities: - canCollide: False type: Physics - uid: 2986 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 11.5,-7.5 @@ -29671,7 +29648,7 @@ entities: - canCollide: False type: Physics - uid: 2987 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 12.5,-7.5 @@ -29682,7 +29659,7 @@ entities: - canCollide: False type: Physics - uid: 2988 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 13.5,-7.5 @@ -29693,7 +29670,7 @@ entities: - canCollide: False type: Physics - uid: 2989 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 14.5,-7.5 @@ -29704,7 +29681,7 @@ entities: - canCollide: False type: Physics - uid: 2990 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 15.5,-7.5 @@ -29715,7 +29692,7 @@ entities: - canCollide: False type: Physics - uid: 2991 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 16.5,-7.5 @@ -29726,7 +29703,7 @@ entities: - canCollide: False type: Physics - uid: 2992 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 17.5,-7.5 @@ -29737,7 +29714,7 @@ entities: - canCollide: False type: Physics - uid: 2993 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 18.5,-7.5 @@ -29748,7 +29725,7 @@ entities: - canCollide: False type: Physics - uid: 2994 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 17.5,-17.5 @@ -29759,7 +29736,7 @@ entities: - canCollide: False type: Physics - uid: 2995 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 16.5,-17.5 @@ -29770,7 +29747,7 @@ entities: - canCollide: False type: Physics - uid: 2996 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 15.5,-17.5 @@ -29781,7 +29758,7 @@ entities: - canCollide: False type: Physics - uid: 2997 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 16.5,2.5 @@ -29790,7 +29767,7 @@ entities: - canCollide: False type: Physics - uid: 2998 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 16.5,1.5 @@ -29801,7 +29778,7 @@ entities: - canCollide: False type: Physics - uid: 2999 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 17.5,1.5 @@ -29812,7 +29789,7 @@ entities: - canCollide: False type: Physics - uid: 3000 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 18.5,1.5 @@ -29823,7 +29800,7 @@ entities: - canCollide: False type: Physics - uid: 3001 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 15.5,1.5 @@ -29834,7 +29811,7 @@ entities: - canCollide: False type: Physics - uid: 3002 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 14.5,1.5 @@ -29853,7 +29830,7 @@ entities: - canCollide: False type: Physics - uid: 3004 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 12.5,1.5 @@ -29864,7 +29841,7 @@ entities: - canCollide: False type: Physics - uid: 3005 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 11.5,1.5 @@ -29875,7 +29852,7 @@ entities: - canCollide: False type: Physics - uid: 3006 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 10.5,1.5 @@ -29886,7 +29863,7 @@ entities: - canCollide: False type: Physics - uid: 3007 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 9.5,1.5 @@ -29897,7 +29874,7 @@ entities: - canCollide: False type: Physics - uid: 3008 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 8.5,1.5 @@ -29908,7 +29885,7 @@ entities: - canCollide: False type: Physics - uid: 3009 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 7.5,1.5 @@ -29919,7 +29896,7 @@ entities: - canCollide: False type: Physics - uid: 3010 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 6.5,1.5 @@ -29930,7 +29907,7 @@ entities: - canCollide: False type: Physics - uid: 3011 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 16.5,0.5 @@ -29941,7 +29918,7 @@ entities: - canCollide: False type: Physics - uid: 3012 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 16.5,-0.5 @@ -29952,7 +29929,7 @@ entities: - canCollide: False type: Physics - uid: 3013 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 17.5,-0.5 @@ -29963,7 +29940,7 @@ entities: - canCollide: False type: Physics - uid: 3014 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 18.5,-0.5 @@ -29974,7 +29951,7 @@ entities: - canCollide: False type: Physics - uid: 3015 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 9.5,0.5 @@ -29985,7 +29962,7 @@ entities: - canCollide: False type: Physics - uid: 3016 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 9.5,-0.5 @@ -29996,7 +29973,7 @@ entities: - canCollide: False type: Physics - uid: 3017 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 9.5,-1.5 @@ -30007,7 +29984,7 @@ entities: - canCollide: False type: Physics - uid: 3018 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 9.5,-2.5 @@ -30018,7 +29995,7 @@ entities: - canCollide: False type: Physics - uid: 3019 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 9.5,-3.5 @@ -30029,7 +30006,7 @@ entities: - canCollide: False type: Physics - uid: 3020 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 9.5,-4.5 @@ -30040,7 +30017,7 @@ entities: - canCollide: False type: Physics - uid: 3021 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 8.5,-4.5 @@ -30051,7 +30028,7 @@ entities: - canCollide: False type: Physics - uid: 3022 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 7.5,-4.5 @@ -30062,7 +30039,7 @@ entities: - canCollide: False type: Physics - uid: 3023 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 6.5,-4.5 @@ -30073,7 +30050,7 @@ entities: - canCollide: False type: Physics - uid: 3024 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 10.5,-2.5 @@ -30084,7 +30061,7 @@ entities: - canCollide: False type: Physics - uid: 3025 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 11.5,-2.5 @@ -30095,7 +30072,7 @@ entities: - canCollide: False type: Physics - uid: 3026 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 6.5,-17.5 @@ -30104,7 +30081,7 @@ entities: - canCollide: False type: Physics - uid: 3027 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 1.5,-23.5 @@ -30115,7 +30092,7 @@ entities: - canCollide: False type: Physics - uid: 3028 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 2.5,-23.5 @@ -30126,7 +30103,7 @@ entities: - canCollide: False type: Physics - uid: 3029 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 3.5,-23.5 @@ -30137,7 +30114,7 @@ entities: - canCollide: False type: Physics - uid: 3030 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 3.5,-22.5 @@ -30148,7 +30125,7 @@ entities: - canCollide: False type: Physics - uid: 3031 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 3.5,-21.5 @@ -30159,7 +30136,7 @@ entities: - canCollide: False type: Physics - uid: 3032 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 2.5,-21.5 @@ -30170,7 +30147,7 @@ entities: - canCollide: False type: Physics - uid: 3033 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 4.5,-21.5 @@ -30181,7 +30158,7 @@ entities: - canCollide: False type: Physics - uid: 3034 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 22.5,-3.5 @@ -30190,7 +30167,7 @@ entities: - canCollide: False type: Physics - uid: 3035 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 31.5,1.5 @@ -30199,7 +30176,7 @@ entities: - canCollide: False type: Physics - uid: 3036 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 31.5,0.5 @@ -30210,7 +30187,7 @@ entities: - canCollide: False type: Physics - uid: 3037 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 31.5,-0.5 @@ -30221,7 +30198,7 @@ entities: - canCollide: False type: Physics - uid: 3038 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 31.5,-1.5 @@ -30232,7 +30209,7 @@ entities: - canCollide: False type: Physics - uid: 3039 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 31.5,-3.5 @@ -30243,7 +30220,7 @@ entities: - canCollide: False type: Physics - uid: 3040 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 31.5,-2.5 @@ -30254,7 +30231,7 @@ entities: - canCollide: False type: Physics - uid: 3041 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 30.5,-2.5 @@ -30265,7 +30242,7 @@ entities: - canCollide: False type: Physics - uid: 3042 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 29.5,-2.5 @@ -30276,7 +30253,7 @@ entities: - canCollide: False type: Physics - uid: 3043 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 32.5,-2.5 @@ -30287,7 +30264,7 @@ entities: - canCollide: False type: Physics - uid: 3044 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 33.5,-2.5 @@ -30298,7 +30275,7 @@ entities: - canCollide: False type: Physics - uid: 3045 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 34.5,-2.5 @@ -30309,7 +30286,7 @@ entities: - canCollide: False type: Physics - uid: 3046 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 35.5,-2.5 @@ -30320,7 +30297,7 @@ entities: - canCollide: False type: Physics - uid: 3047 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 31.5,1.5 @@ -30329,7 +30306,7 @@ entities: - canCollide: False type: Physics - uid: 3048 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 31.5,2.5 @@ -30340,7 +30317,7 @@ entities: - canCollide: False type: Physics - uid: 3049 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 31.5,3.5 @@ -30351,7 +30328,7 @@ entities: - canCollide: False type: Physics - uid: 3050 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 31.5,4.5 @@ -30362,7 +30339,7 @@ entities: - canCollide: False type: Physics - uid: 3051 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 32.5,4.5 @@ -30373,7 +30350,7 @@ entities: - canCollide: False type: Physics - uid: 3052 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 33.5,4.5 @@ -30384,7 +30361,7 @@ entities: - canCollide: False type: Physics - uid: 3053 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 34.5,4.5 @@ -30395,7 +30372,7 @@ entities: - canCollide: False type: Physics - uid: 3054 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 35.5,4.5 @@ -30406,7 +30383,7 @@ entities: - canCollide: False type: Physics - uid: 3055 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 36.5,4.5 @@ -30417,7 +30394,7 @@ entities: - canCollide: False type: Physics - uid: 3056 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 37.5,4.5 @@ -30428,7 +30405,7 @@ entities: - canCollide: False type: Physics - uid: 3057 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 38.5,4.5 @@ -30439,7 +30416,7 @@ entities: - canCollide: False type: Physics - uid: 3058 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 38.5,3.5 @@ -30450,7 +30427,7 @@ entities: - canCollide: False type: Physics - uid: 3059 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 38.5,2.5 @@ -30461,7 +30438,7 @@ entities: - canCollide: False type: Physics - uid: 3060 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 38.5,1.5 @@ -30472,7 +30449,7 @@ entities: - canCollide: False type: Physics - uid: 3061 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 38.5,0.5 @@ -30483,7 +30460,7 @@ entities: - canCollide: False type: Physics - uid: 3062 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 38.5,-0.5 @@ -30494,7 +30471,7 @@ entities: - canCollide: False type: Physics - uid: 3063 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 38.5,-1.5 @@ -30505,7 +30482,7 @@ entities: - canCollide: False type: Physics - uid: 3064 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 43.5,10.5 @@ -30514,7 +30491,7 @@ entities: - canCollide: False type: Physics - uid: 3065 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 43.5,9.5 @@ -30525,7 +30502,7 @@ entities: - canCollide: False type: Physics - uid: 3066 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 42.5,9.5 @@ -30536,7 +30513,7 @@ entities: - canCollide: False type: Physics - uid: 3067 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 41.5,9.5 @@ -30547,7 +30524,7 @@ entities: - canCollide: False type: Physics - uid: 3068 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 39.5,9.5 @@ -30558,7 +30535,7 @@ entities: - canCollide: False type: Physics - uid: 3069 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 38.5,9.5 @@ -30569,7 +30546,7 @@ entities: - canCollide: False type: Physics - uid: 3070 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 40.5,9.5 @@ -30580,7 +30557,7 @@ entities: - canCollide: False type: Physics - uid: 3071 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 38.5,8.5 @@ -30591,7 +30568,7 @@ entities: - canCollide: False type: Physics - uid: 3072 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 38.5,7.5 @@ -30602,7 +30579,7 @@ entities: - canCollide: False type: Physics - uid: 3073 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 38.5,6.5 @@ -30613,7 +30590,7 @@ entities: - canCollide: False type: Physics - uid: 3074 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 44.5,9.5 @@ -30624,7 +30601,7 @@ entities: - canCollide: False type: Physics - uid: 3075 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 44.5,8.5 @@ -30635,7 +30612,7 @@ entities: - canCollide: False type: Physics - uid: 3076 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 44.5,7.5 @@ -30646,7 +30623,7 @@ entities: - canCollide: False type: Physics - uid: 3077 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 44.5,6.5 @@ -30657,7 +30634,7 @@ entities: - canCollide: False type: Physics - uid: 3078 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 44.5,5.5 @@ -30668,7 +30645,7 @@ entities: - canCollide: False type: Physics - uid: 3079 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 44.5,4.5 @@ -30679,7 +30656,7 @@ entities: - canCollide: False type: Physics - uid: 3080 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 45.5,4.5 @@ -30690,7 +30667,7 @@ entities: - canCollide: False type: Physics - uid: 3081 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 46.5,4.5 @@ -30701,7 +30678,7 @@ entities: - canCollide: False type: Physics - uid: 3082 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 47.5,4.5 @@ -30712,7 +30689,7 @@ entities: - canCollide: False type: Physics - uid: 3083 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 48.5,4.5 @@ -30723,7 +30700,7 @@ entities: - canCollide: False type: Physics - uid: 3084 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 49.5,4.5 @@ -30734,7 +30711,7 @@ entities: - canCollide: False type: Physics - uid: 3085 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 33.5,-3.5 @@ -30745,7 +30722,7 @@ entities: - canCollide: False type: Physics - uid: 3086 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 33.5,-4.5 @@ -30756,7 +30733,7 @@ entities: - canCollide: False type: Physics - uid: 3087 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 43.5,4.5 @@ -30767,7 +30744,7 @@ entities: - canCollide: False type: Physics - uid: 3088 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 43.5,3.5 @@ -30778,7 +30755,7 @@ entities: - canCollide: False type: Physics - uid: 3089 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 43.5,2.5 @@ -30789,7 +30766,7 @@ entities: - canCollide: False type: Physics - uid: 3090 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 43.5,1.5 @@ -30800,7 +30777,7 @@ entities: - canCollide: False type: Physics - uid: 3091 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 43.5,0.5 @@ -30811,7 +30788,7 @@ entities: - canCollide: False type: Physics - uid: 3092 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 43.5,-0.5 @@ -30822,7 +30799,7 @@ entities: - canCollide: False type: Physics - uid: 3093 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 43.5,-1.5 @@ -30833,7 +30810,7 @@ entities: - canCollide: False type: Physics - uid: 3094 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 43.5,-2.5 @@ -30844,7 +30821,7 @@ entities: - canCollide: False type: Physics - uid: 3095 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 43.5,-3.5 @@ -30855,7 +30832,7 @@ entities: - canCollide: False type: Physics - uid: 3096 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 42.5,-3.5 @@ -30866,7 +30843,7 @@ entities: - canCollide: False type: Physics - uid: 3097 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 41.5,-3.5 @@ -30877,7 +30854,7 @@ entities: - canCollide: False type: Physics - uid: 3098 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 40.5,-3.5 @@ -30888,7 +30865,7 @@ entities: - canCollide: False type: Physics - uid: 3099 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 39.5,-3.5 @@ -30899,7 +30876,7 @@ entities: - canCollide: False type: Physics - uid: 3100 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 38.5,-3.5 @@ -30910,7 +30887,7 @@ entities: - canCollide: False type: Physics - uid: 3101 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 37.5,-3.5 @@ -30921,7 +30898,7 @@ entities: - canCollide: False type: Physics - uid: 3102 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 37.5,-4.5 @@ -30932,7 +30909,7 @@ entities: - canCollide: False type: Physics - uid: 3103 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 37.5,-5.5 @@ -30943,7 +30920,7 @@ entities: - canCollide: False type: Physics - uid: 3104 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 37.5,-6.5 @@ -30954,7 +30931,7 @@ entities: - canCollide: False type: Physics - uid: 3105 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 36.5,-6.5 @@ -30965,7 +30942,7 @@ entities: - canCollide: False type: Physics - uid: 3106 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 35.5,-6.5 @@ -30976,7 +30953,7 @@ entities: - canCollide: False type: Physics - uid: 3107 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 34.5,-6.5 @@ -30987,7 +30964,7 @@ entities: - canCollide: False type: Physics - uid: 3108 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 33.5,-6.5 @@ -30996,7 +30973,7 @@ entities: - canCollide: False type: Physics - uid: 3109 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 32.5,-6.5 @@ -31007,7 +30984,7 @@ entities: - canCollide: False type: Physics - uid: 3110 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 31.5,-6.5 @@ -31018,7 +30995,7 @@ entities: - canCollide: False type: Physics - uid: 3111 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 30.5,-6.5 @@ -31029,7 +31006,7 @@ entities: - canCollide: False type: Physics - uid: 3112 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 29.5,-6.5 @@ -31038,7 +31015,7 @@ entities: - canCollide: False type: Physics - uid: 3113 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 28.5,-6.5 @@ -31047,7 +31024,7 @@ entities: - canCollide: False type: Physics - uid: 3114 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 27.5,-6.5 @@ -31056,7 +31033,7 @@ entities: - canCollide: False type: Physics - uid: 3115 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 27.5,-7.5 @@ -31067,7 +31044,7 @@ entities: - canCollide: False type: Physics - uid: 3116 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 27.5,-8.5 @@ -31078,7 +31055,7 @@ entities: - canCollide: False type: Physics - uid: 3117 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 27.5,-9.5 @@ -31089,7 +31066,7 @@ entities: - canCollide: False type: Physics - uid: 3118 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 27.5,-10.5 @@ -31100,7 +31077,7 @@ entities: - canCollide: False type: Physics - uid: 3119 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 27.5,-11.5 @@ -31111,7 +31088,7 @@ entities: - canCollide: False type: Physics - uid: 3120 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 27.5,-12.5 @@ -31122,7 +31099,7 @@ entities: - canCollide: False type: Physics - uid: 3121 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 27.5,-13.5 @@ -31133,7 +31110,7 @@ entities: - canCollide: False type: Physics - uid: 3122 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 27.5,-14.5 @@ -31144,7 +31121,7 @@ entities: - canCollide: False type: Physics - uid: 3123 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 27.5,-15.5 @@ -31155,7 +31132,7 @@ entities: - canCollide: False type: Physics - uid: 3124 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 27.5,-16.5 @@ -31166,7 +31143,7 @@ entities: - canCollide: False type: Physics - uid: 3125 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 27.5,-17.5 @@ -31177,7 +31154,7 @@ entities: - canCollide: False type: Physics - uid: 3126 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 27.5,-18.5 @@ -31188,7 +31165,7 @@ entities: - canCollide: False type: Physics - uid: 3127 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 26.5,-18.5 @@ -31199,7 +31176,7 @@ entities: - canCollide: False type: Physics - uid: 3128 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 25.5,-18.5 @@ -31210,7 +31187,7 @@ entities: - canCollide: False type: Physics - uid: 3129 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 24.5,-18.5 @@ -31221,7 +31198,7 @@ entities: - canCollide: False type: Physics - uid: 3130 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 47.5,-1.5 @@ -31230,7 +31207,7 @@ entities: - canCollide: False type: Physics - uid: 3131 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 47.5,-2.5 @@ -31239,7 +31216,7 @@ entities: - canCollide: False type: Physics - uid: 3132 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 47.5,-3.5 @@ -31248,7 +31225,7 @@ entities: - canCollide: False type: Physics - uid: 3133 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 48.5,-2.5 @@ -31257,7 +31234,7 @@ entities: - canCollide: False type: Physics - uid: 3134 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 49.5,-2.5 @@ -31266,7 +31243,7 @@ entities: - canCollide: False type: Physics - uid: 3135 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 50.5,-2.5 @@ -31275,7 +31252,7 @@ entities: - canCollide: False type: Physics - uid: 3136 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 51.5,-2.5 @@ -31284,7 +31261,7 @@ entities: - canCollide: False type: Physics - uid: 3137 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 51.5,-3.5 @@ -31293,7 +31270,7 @@ entities: - canCollide: False type: Physics - uid: 3138 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 51.5,-4.5 @@ -31302,7 +31279,7 @@ entities: - canCollide: False type: Physics - uid: 3139 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 41.5,10.5 @@ -31313,7 +31290,7 @@ entities: - canCollide: False type: Physics - uid: 3140 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 41.5,11.5 @@ -31324,7 +31301,7 @@ entities: - canCollide: False type: Physics - uid: 3141 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 41.5,12.5 @@ -31335,7 +31312,7 @@ entities: - canCollide: False type: Physics - uid: 3142 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 41.5,13.5 @@ -31346,7 +31323,7 @@ entities: - canCollide: False type: Physics - uid: 3143 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 28.5,14.5 @@ -31355,7 +31332,7 @@ entities: - canCollide: False type: Physics - uid: 3144 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 28.5,13.5 @@ -31364,7 +31341,7 @@ entities: - canCollide: False type: Physics - uid: 3145 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 28.5,12.5 @@ -31375,7 +31352,7 @@ entities: - canCollide: False type: Physics - uid: 3146 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 28.5,11.5 @@ -31386,7 +31363,7 @@ entities: - canCollide: False type: Physics - uid: 3147 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 28.5,10.5 @@ -31397,7 +31374,7 @@ entities: - canCollide: False type: Physics - uid: 3148 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 29.5,10.5 @@ -31408,7 +31385,7 @@ entities: - canCollide: False type: Physics - uid: 3149 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 28.5,9.5 @@ -31417,7 +31394,7 @@ entities: - canCollide: False type: Physics - uid: 3150 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 27.5,9.5 @@ -31428,7 +31405,7 @@ entities: - canCollide: False type: Physics - uid: 3151 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 26.5,9.5 @@ -31437,7 +31414,7 @@ entities: - canCollide: False type: Physics - uid: 3152 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 25.5,9.5 @@ -31448,7 +31425,7 @@ entities: - canCollide: False type: Physics - uid: 3153 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 26.5,10.5 @@ -31459,7 +31436,7 @@ entities: - canCollide: False type: Physics - uid: 3154 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 26.5,11.5 @@ -31470,7 +31447,7 @@ entities: - canCollide: False type: Physics - uid: 3155 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 27.5,8.5 @@ -31479,7 +31456,7 @@ entities: - canCollide: False type: Physics - uid: 3156 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 27.5,7.5 @@ -31490,7 +31467,7 @@ entities: - canCollide: False type: Physics - uid: 3157 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 30.5,10.5 @@ -31501,7 +31478,7 @@ entities: - canCollide: False type: Physics - uid: 3158 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 31.5,10.5 @@ -31512,7 +31489,7 @@ entities: - canCollide: False type: Physics - uid: 3159 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 32.5,10.5 @@ -31523,7 +31500,7 @@ entities: - canCollide: False type: Physics - uid: 3160 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 33.5,10.5 @@ -31534,7 +31511,7 @@ entities: - canCollide: False type: Physics - uid: 3161 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 34.5,10.5 @@ -31545,7 +31522,7 @@ entities: - canCollide: False type: Physics - uid: 3162 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 35.5,10.5 @@ -31556,7 +31533,7 @@ entities: - canCollide: False type: Physics - uid: 3163 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 36.5,10.5 @@ -31567,7 +31544,7 @@ entities: - canCollide: False type: Physics - uid: 3164 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 30.5,9.5 @@ -31578,7 +31555,7 @@ entities: - canCollide: False type: Physics - uid: 3165 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 33.5,9.5 @@ -31589,7 +31566,7 @@ entities: - canCollide: False type: Physics - uid: 3166 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 35.5,9.5 @@ -31600,7 +31577,7 @@ entities: - canCollide: False type: Physics - uid: 3167 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 35.5,8.5 @@ -31611,7 +31588,7 @@ entities: - canCollide: False type: Physics - uid: 3168 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 35.5,7.5 @@ -31620,7 +31597,7 @@ entities: - canCollide: False type: Physics - uid: 3169 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 36.5,11.5 @@ -31631,7 +31608,7 @@ entities: - canCollide: False type: Physics - uid: 3170 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 36.5,12.5 @@ -31642,7 +31619,7 @@ entities: - canCollide: False type: Physics - uid: 3171 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 30.5,11.5 @@ -31653,7 +31630,7 @@ entities: - canCollide: False type: Physics - uid: 3172 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 30.5,12.5 @@ -31664,7 +31641,7 @@ entities: - canCollide: False type: Physics - uid: 3173 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 24.5,14.5 @@ -31673,7 +31650,7 @@ entities: - canCollide: False type: Physics - uid: 3174 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 24.5,13.5 @@ -31684,7 +31661,7 @@ entities: - canCollide: False type: Physics - uid: 3175 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 23.5,13.5 @@ -31695,7 +31672,7 @@ entities: - canCollide: False type: Physics - uid: 3176 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 22.5,13.5 @@ -31706,7 +31683,7 @@ entities: - canCollide: False type: Physics - uid: 3177 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 58.5,-27.5 @@ -31732,7 +31709,7 @@ entities: ents: [] type: ContainerContainer - uid: 3180 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 21.5,13.5 @@ -31743,7 +31720,7 @@ entities: - canCollide: False type: Physics - uid: 3181 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 20.5,13.5 @@ -31754,7 +31731,7 @@ entities: - canCollide: False type: Physics - uid: 3182 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 58.5,-26.5 @@ -31763,7 +31740,7 @@ entities: - canCollide: False type: Physics - uid: 3183 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 58.5,-25.5 @@ -31772,7 +31749,7 @@ entities: - canCollide: False type: Physics - uid: 3184 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 19.5,13.5 @@ -31783,7 +31760,7 @@ entities: - canCollide: False type: Physics - uid: 3185 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 18.5,13.5 @@ -31794,7 +31771,7 @@ entities: - canCollide: False type: Physics - uid: 3186 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 21.5,12.5 @@ -31805,7 +31782,7 @@ entities: - canCollide: False type: Physics - uid: 3187 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 21.5,11.5 @@ -31816,7 +31793,7 @@ entities: - canCollide: False type: Physics - uid: 3188 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 21.5,10.5 @@ -31827,7 +31804,7 @@ entities: - canCollide: False type: Physics - uid: 3189 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 21.5,9.5 @@ -31838,7 +31815,7 @@ entities: - canCollide: False type: Physics - uid: 3190 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 21.5,8.5 @@ -31849,7 +31826,7 @@ entities: - canCollide: False type: Physics - uid: 3191 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 22.5,8.5 @@ -31860,7 +31837,7 @@ entities: - canCollide: False type: Physics - uid: 3192 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 23.5,8.5 @@ -31871,7 +31848,7 @@ entities: - canCollide: False type: Physics - uid: 3193 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 20.5,8.5 @@ -31882,7 +31859,7 @@ entities: - canCollide: False type: Physics - uid: 3194 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 19.5,8.5 @@ -31893,7 +31870,7 @@ entities: - canCollide: False type: Physics - uid: 3195 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 18.5,8.5 @@ -31904,7 +31881,7 @@ entities: - canCollide: False type: Physics - uid: 3196 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 17.5,8.5 @@ -31913,7 +31890,7 @@ entities: - canCollide: False type: Physics - uid: 3197 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 18.5,12.5 @@ -31924,7 +31901,7 @@ entities: - canCollide: False type: Physics - uid: 3198 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 18.5,11.5 @@ -31935,7 +31912,7 @@ entities: - canCollide: False type: Physics - uid: 3199 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 12.5,13.5 @@ -31944,7 +31921,7 @@ entities: - canCollide: False type: Physics - uid: 3200 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 12.5,12.5 @@ -31955,7 +31932,7 @@ entities: - canCollide: False type: Physics - uid: 3201 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 12.5,11.5 @@ -31966,7 +31943,7 @@ entities: - canCollide: False type: Physics - uid: 3202 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 12.5,10.5 @@ -31977,7 +31954,7 @@ entities: - canCollide: False type: Physics - uid: 3203 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 13.5,10.5 @@ -31988,7 +31965,7 @@ entities: - canCollide: False type: Physics - uid: 3204 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 14.5,10.5 @@ -31999,7 +31976,7 @@ entities: - canCollide: False type: Physics - uid: 3205 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 15.5,10.5 @@ -32010,7 +31987,7 @@ entities: - canCollide: False type: Physics - uid: 3206 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 16.5,10.5 @@ -32021,7 +31998,7 @@ entities: - canCollide: False type: Physics - uid: 3207 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 15.5,11.5 @@ -32032,7 +32009,7 @@ entities: - canCollide: False type: Physics - uid: 3208 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 13.5,9.5 @@ -32043,7 +32020,7 @@ entities: - canCollide: False type: Physics - uid: 3209 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 11.5,10.5 @@ -32052,7 +32029,7 @@ entities: - canCollide: False type: Physics - uid: 3210 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 10.5,10.5 @@ -32063,7 +32040,7 @@ entities: - canCollide: False type: Physics - uid: 3211 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 9.5,10.5 @@ -32074,7 +32051,7 @@ entities: - canCollide: False type: Physics - uid: 3212 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 8.5,10.5 @@ -32085,7 +32062,7 @@ entities: - canCollide: False type: Physics - uid: 3213 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 7.5,10.5 @@ -32096,7 +32073,7 @@ entities: - canCollide: False type: Physics - uid: 3214 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 6.5,10.5 @@ -32107,7 +32084,7 @@ entities: - canCollide: False type: Physics - uid: 3215 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 8.5,11.5 @@ -32118,7 +32095,7 @@ entities: - canCollide: False type: Physics - uid: 3216 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 8.5,9.5 @@ -32129,7 +32106,7 @@ entities: - canCollide: False type: Physics - uid: 3217 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 8.5,8.5 @@ -32140,7 +32117,7 @@ entities: - canCollide: False type: Physics - uid: 3218 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 8.5,7.5 @@ -32151,7 +32128,7 @@ entities: - canCollide: False type: Physics - uid: 3219 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 8.5,6.5 @@ -32160,7 +32137,7 @@ entities: - canCollide: False type: Physics - uid: 3220 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 12.5,13.5 @@ -32169,7 +32146,7 @@ entities: - canCollide: False type: Physics - uid: 3221 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 12.5,14.5 @@ -32178,7 +32155,7 @@ entities: - canCollide: False type: Physics - uid: 3222 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 11.5,14.5 @@ -32187,7 +32164,7 @@ entities: - canCollide: False type: Physics - uid: 3223 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 10.5,14.5 @@ -32196,7 +32173,7 @@ entities: - canCollide: False type: Physics - uid: 3224 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 9.5,14.5 @@ -32207,7 +32184,7 @@ entities: - canCollide: False type: Physics - uid: 3225 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 8.5,14.5 @@ -32218,7 +32195,7 @@ entities: - canCollide: False type: Physics - uid: 3226 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 7.5,14.5 @@ -32229,7 +32206,7 @@ entities: - canCollide: False type: Physics - uid: 3227 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 6.5,14.5 @@ -32238,7 +32215,7 @@ entities: - canCollide: False type: Physics - uid: 3228 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 12.5,14.5 @@ -32247,7 +32224,7 @@ entities: - canCollide: False type: Physics - uid: 3229 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 13.5,14.5 @@ -32258,7 +32235,7 @@ entities: - canCollide: False type: Physics - uid: 3230 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 14.5,14.5 @@ -32269,7 +32246,7 @@ entities: - canCollide: False type: Physics - uid: 3231 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 15.5,14.5 @@ -32280,7 +32257,7 @@ entities: - canCollide: False type: Physics - uid: 3232 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 15.5,15.5 @@ -32291,7 +32268,7 @@ entities: - canCollide: False type: Physics - uid: 3233 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 13.5,16.5 @@ -32302,7 +32279,7 @@ entities: - canCollide: False type: Physics - uid: 3234 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 13.5,15.5 @@ -32313,7 +32290,7 @@ entities: - canCollide: False type: Physics - uid: 3235 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 9.5,22.5 @@ -32322,7 +32299,7 @@ entities: - canCollide: False type: Physics - uid: 3236 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 9.5,21.5 @@ -32333,7 +32310,7 @@ entities: - canCollide: False type: Physics - uid: 3237 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 9.5,20.5 @@ -32344,7 +32321,7 @@ entities: - canCollide: False type: Physics - uid: 3238 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 9.5,19.5 @@ -32355,7 +32332,7 @@ entities: - canCollide: False type: Physics - uid: 3239 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 9.5,18.5 @@ -32366,7 +32343,7 @@ entities: - canCollide: False type: Physics - uid: 3240 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 9.5,17.5 @@ -32377,7 +32354,7 @@ entities: - canCollide: False type: Physics - uid: 3241 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 9.5,16.5 @@ -32388,7 +32365,7 @@ entities: - canCollide: False type: Physics - uid: 3242 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 10.5,20.5 @@ -32399,7 +32376,7 @@ entities: - canCollide: False type: Physics - uid: 3243 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 8.5,17.5 @@ -32410,7 +32387,7 @@ entities: - canCollide: False type: Physics - uid: 3244 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 8.5,17.5 @@ -32421,7 +32398,7 @@ entities: - canCollide: False type: Physics - uid: 3245 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 7.5,17.5 @@ -32432,7 +32409,7 @@ entities: - canCollide: False type: Physics - uid: 3246 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 8.5,20.5 @@ -32443,7 +32420,7 @@ entities: - canCollide: False type: Physics - uid: 3247 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 6.5,17.5 @@ -32454,7 +32431,7 @@ entities: - canCollide: False type: Physics - uid: 3248 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 5.5,17.5 @@ -32465,7 +32442,7 @@ entities: - canCollide: False type: Physics - uid: 3249 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 5.5,16.5 @@ -32476,7 +32453,7 @@ entities: - canCollide: False type: Physics - uid: 3250 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 4.5,17.5 @@ -32487,7 +32464,7 @@ entities: - canCollide: False type: Physics - uid: 3251 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 3.5,17.5 @@ -32498,7 +32475,7 @@ entities: - canCollide: False type: Physics - uid: 3252 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 3.5,18.5 @@ -32509,7 +32486,7 @@ entities: - canCollide: False type: Physics - uid: 3253 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 3.5,19.5 @@ -32520,7 +32497,7 @@ entities: - canCollide: False type: Physics - uid: 3254 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 3.5,20.5 @@ -32531,7 +32508,7 @@ entities: - canCollide: False type: Physics - uid: 3255 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 3.5,20.5 @@ -32542,7 +32519,7 @@ entities: - canCollide: False type: Physics - uid: 3256 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 3.5,21.5 @@ -32553,7 +32530,7 @@ entities: - canCollide: False type: Physics - uid: 3257 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 3.5,22.5 @@ -32562,7 +32539,7 @@ entities: - canCollide: False type: Physics - uid: 3258 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 2.5,20.5 @@ -32573,7 +32550,7 @@ entities: - canCollide: False type: Physics - uid: 3259 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 1.5,20.5 @@ -32584,7 +32561,7 @@ entities: - canCollide: False type: Physics - uid: 3260 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 9.5,27.5 @@ -32593,7 +32570,7 @@ entities: - canCollide: False type: Physics - uid: 3261 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 9.5,26.5 @@ -32604,7 +32581,7 @@ entities: - canCollide: False type: Physics - uid: 3262 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 9.5,25.5 @@ -32615,7 +32592,7 @@ entities: - canCollide: False type: Physics - uid: 3263 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 9.5,24.5 @@ -32626,7 +32603,7 @@ entities: - canCollide: False type: Physics - uid: 3264 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 8.5,24.5 @@ -32637,7 +32614,7 @@ entities: - canCollide: False type: Physics - uid: 3265 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 7.5,24.5 @@ -32648,7 +32625,7 @@ entities: - canCollide: False type: Physics - uid: 3266 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 6.5,24.5 @@ -32659,7 +32636,7 @@ entities: - canCollide: False type: Physics - uid: 3267 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 9.5,28.5 @@ -32670,7 +32647,7 @@ entities: - canCollide: False type: Physics - uid: 3268 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 9.5,29.5 @@ -32681,7 +32658,7 @@ entities: - canCollide: False type: Physics - uid: 3269 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 9.5,30.5 @@ -32692,7 +32669,7 @@ entities: - canCollide: False type: Physics - uid: 3270 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 8.5,30.5 @@ -32703,7 +32680,7 @@ entities: - canCollide: False type: Physics - uid: 3271 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 7.5,30.5 @@ -32714,7 +32691,7 @@ entities: - canCollide: False type: Physics - uid: 3272 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 6.5,30.5 @@ -32725,7 +32702,7 @@ entities: - canCollide: False type: Physics - uid: 3273 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 6.5,31.5 @@ -32736,7 +32713,7 @@ entities: - canCollide: False type: Physics - uid: 3274 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -2.5,27.5 @@ -32745,7 +32722,7 @@ entities: - canCollide: False type: Physics - uid: 3275 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -2.5,28.5 @@ -32756,7 +32733,7 @@ entities: - canCollide: False type: Physics - uid: 3276 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -2.5,29.5 @@ -32767,7 +32744,7 @@ entities: - canCollide: False type: Physics - uid: 3277 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -2.5,30.5 @@ -32778,7 +32755,7 @@ entities: - canCollide: False type: Physics - uid: 3278 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -1.5,30.5 @@ -32789,7 +32766,7 @@ entities: - canCollide: False type: Physics - uid: 3279 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -0.5,30.5 @@ -32800,7 +32777,7 @@ entities: - canCollide: False type: Physics - uid: 3280 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 0.5,30.5 @@ -32811,7 +32788,7 @@ entities: - canCollide: False type: Physics - uid: 3281 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 1.5,30.5 @@ -32822,7 +32799,7 @@ entities: - canCollide: False type: Physics - uid: 3282 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 2.5,30.5 @@ -32833,7 +32810,7 @@ entities: - canCollide: False type: Physics - uid: 3283 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 3.5,30.5 @@ -32844,7 +32821,7 @@ entities: - canCollide: False type: Physics - uid: 3284 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 0.5,31.5 @@ -32855,7 +32832,7 @@ entities: - canCollide: False type: Physics - uid: 3285 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 3.5,31.5 @@ -32866,7 +32843,7 @@ entities: - canCollide: False type: Physics - uid: 3286 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -2.5,26.5 @@ -32877,7 +32854,7 @@ entities: - canCollide: False type: Physics - uid: 3287 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -2.5,25.5 @@ -32888,7 +32865,7 @@ entities: - canCollide: False type: Physics - uid: 3288 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -1.5,25.5 @@ -32899,7 +32876,7 @@ entities: - canCollide: False type: Physics - uid: 3289 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -0.5,25.5 @@ -32910,7 +32887,7 @@ entities: - canCollide: False type: Physics - uid: 3290 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 0.5,25.5 @@ -32921,7 +32898,7 @@ entities: - canCollide: False type: Physics - uid: 3291 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 0.5,24.5 @@ -32932,7 +32909,7 @@ entities: - canCollide: False type: Physics - uid: 3292 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -2.5,24.5 @@ -32943,7 +32920,7 @@ entities: - canCollide: False type: Physics - uid: 3293 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -2.5,23.5 @@ -32954,7 +32931,7 @@ entities: - canCollide: False type: Physics - uid: 3294 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -1.5,23.5 @@ -32979,7 +32956,7 @@ entities: parent: 853 type: Transform - uid: 3297 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 41.5,6.5 @@ -32990,7 +32967,7 @@ entities: - canCollide: False type: Physics - uid: 3298 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 41.5,5.5 @@ -33001,7 +32978,7 @@ entities: - canCollide: False type: Physics - uid: 3299 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 42.5,4.5 @@ -33012,7 +32989,7 @@ entities: - canCollide: False type: Physics - uid: 3300 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 42.5,3.5 @@ -33023,7 +33000,7 @@ entities: - canCollide: False type: Physics - uid: 3301 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 42.5,2.5 @@ -33034,7 +33011,7 @@ entities: - canCollide: False type: Physics - uid: 3302 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 42.5,1.5 @@ -33045,7 +33022,7 @@ entities: - canCollide: False type: Physics - uid: 3303 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 42.5,0.5 @@ -33054,7 +33031,7 @@ entities: - canCollide: False type: Physics - uid: 3304 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 42.5,-0.5 @@ -33063,7 +33040,7 @@ entities: - canCollide: False type: Physics - uid: 3305 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 42.5,-1.5 @@ -33072,7 +33049,7 @@ entities: - canCollide: False type: Physics - uid: 3306 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 42.5,-2.5 @@ -33081,7 +33058,7 @@ entities: - canCollide: False type: Physics - uid: 3307 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 42.5,-3.5 @@ -33092,7 +33069,7 @@ entities: - canCollide: False type: Physics - uid: 3308 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 42.5,-4.5 @@ -33101,7 +33078,7 @@ entities: - canCollide: False type: Physics - uid: 3309 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 42.5,-4.5 @@ -33110,7 +33087,7 @@ entities: - canCollide: False type: Physics - uid: 3310 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 41.5,-4.5 @@ -33119,7 +33096,7 @@ entities: - canCollide: False type: Physics - uid: 3311 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 40.5,-4.5 @@ -33128,7 +33105,7 @@ entities: - canCollide: False type: Physics - uid: 3312 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 39.5,-4.5 @@ -33137,7 +33114,7 @@ entities: - canCollide: False type: Physics - uid: 3313 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 38.5,-4.5 @@ -33146,7 +33123,7 @@ entities: - canCollide: False type: Physics - uid: 3314 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 38.5,-5.5 @@ -33155,7 +33132,7 @@ entities: - canCollide: False type: Physics - uid: 3315 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 38.5,-6.5 @@ -33164,7 +33141,7 @@ entities: - canCollide: False type: Physics - uid: 3316 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 38.5,-7.5 @@ -33173,7 +33150,7 @@ entities: - canCollide: False type: Physics - uid: 3317 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 37.5,-7.5 @@ -33182,7 +33159,7 @@ entities: - canCollide: False type: Physics - uid: 3318 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 36.5,-7.5 @@ -33191,7 +33168,7 @@ entities: - canCollide: False type: Physics - uid: 3319 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 35.5,-7.5 @@ -33200,7 +33177,7 @@ entities: - canCollide: False type: Physics - uid: 3320 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 34.5,-7.5 @@ -33209,7 +33186,7 @@ entities: - canCollide: False type: Physics - uid: 3321 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 33.5,-7.5 @@ -33218,7 +33195,7 @@ entities: - canCollide: False type: Physics - uid: 3322 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 32.5,-7.5 @@ -33227,7 +33204,7 @@ entities: - canCollide: False type: Physics - uid: 3323 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 31.5,-7.5 @@ -33236,7 +33213,7 @@ entities: - canCollide: False type: Physics - uid: 3324 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 30.5,-7.5 @@ -33245,7 +33222,7 @@ entities: - canCollide: False type: Physics - uid: 3325 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 29.5,-7.5 @@ -33254,7 +33231,7 @@ entities: - canCollide: False type: Physics - uid: 3326 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 28.5,-7.5 @@ -33263,7 +33240,7 @@ entities: - canCollide: False type: Physics - uid: 3327 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 27.5,-7.5 @@ -33274,7 +33251,7 @@ entities: - canCollide: False type: Physics - uid: 3328 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 26.5,-7.5 @@ -33283,7 +33260,7 @@ entities: - canCollide: False type: Physics - uid: 3329 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 26.5,-8.5 @@ -33292,7 +33269,7 @@ entities: - canCollide: False type: Physics - uid: 3330 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 26.5,-9.5 @@ -33301,7 +33278,7 @@ entities: - canCollide: False type: Physics - uid: 3331 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 26.5,-10.5 @@ -33310,7 +33287,7 @@ entities: - canCollide: False type: Physics - uid: 3332 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 26.5,-11.5 @@ -33319,7 +33296,7 @@ entities: - canCollide: False type: Physics - uid: 3333 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 26.5,-12.5 @@ -33328,7 +33305,7 @@ entities: - canCollide: False type: Physics - uid: 3334 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 26.5,-13.5 @@ -33337,7 +33314,7 @@ entities: - canCollide: False type: Physics - uid: 3335 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 26.5,-14.5 @@ -33346,7 +33323,7 @@ entities: - canCollide: False type: Physics - uid: 3336 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 26.5,-15.5 @@ -33355,7 +33332,7 @@ entities: - canCollide: False type: Physics - uid: 3337 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 26.5,-16.5 @@ -33364,7 +33341,7 @@ entities: - canCollide: False type: Physics - uid: 3338 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 26.5,-17.5 @@ -33373,7 +33350,7 @@ entities: - canCollide: False type: Physics - uid: 3339 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 25.5,-9.5 @@ -33382,7 +33359,7 @@ entities: - canCollide: False type: Physics - uid: 3340 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 24.5,-9.5 @@ -33391,7 +33368,7 @@ entities: - canCollide: False type: Physics - uid: 3341 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 23.5,-9.5 @@ -33400,7 +33377,7 @@ entities: - canCollide: False type: Physics - uid: 3342 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 22.5,-9.5 @@ -33409,7 +33386,7 @@ entities: - canCollide: False type: Physics - uid: 3343 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 21.5,-9.5 @@ -33418,7 +33395,7 @@ entities: - canCollide: False type: Physics - uid: 3344 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 25.5,-17.5 @@ -33427,7 +33404,7 @@ entities: - canCollide: False type: Physics - uid: 3345 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 24.5,-17.5 @@ -33436,7 +33413,7 @@ entities: - canCollide: False type: Physics - uid: 3346 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 23.5,-17.5 @@ -33445,7 +33422,7 @@ entities: - canCollide: False type: Physics - uid: 3347 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 22.5,-17.5 @@ -33454,7 +33431,7 @@ entities: - canCollide: False type: Physics - uid: 3348 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 22.5,-18.5 @@ -33463,7 +33440,7 @@ entities: - canCollide: False type: Physics - uid: 3349 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 22.5,-19.5 @@ -33472,7 +33449,7 @@ entities: - canCollide: False type: Physics - uid: 3350 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 22.5,-20.5 @@ -33481,7 +33458,7 @@ entities: - canCollide: False type: Physics - uid: 3351 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 22.5,-21.5 @@ -33490,7 +33467,7 @@ entities: - canCollide: False type: Physics - uid: 3352 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 22.5,-22.5 @@ -33499,7 +33476,7 @@ entities: - canCollide: False type: Physics - uid: 3353 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 22.5,-23.5 @@ -33508,7 +33485,7 @@ entities: - canCollide: False type: Physics - uid: 3354 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 22.5,-24.5 @@ -33517,7 +33494,7 @@ entities: - canCollide: False type: Physics - uid: 3355 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 22.5,-25.5 @@ -33526,7 +33503,7 @@ entities: - canCollide: False type: Physics - uid: 3356 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 21.5,-25.5 @@ -33535,7 +33512,7 @@ entities: - canCollide: False type: Physics - uid: 3357 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 20.5,-25.5 @@ -33544,7 +33521,7 @@ entities: - canCollide: False type: Physics - uid: 3358 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 19.5,-25.5 @@ -33553,7 +33530,7 @@ entities: - canCollide: False type: Physics - uid: 3359 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 18.5,-25.5 @@ -33562,7 +33539,7 @@ entities: - canCollide: False type: Physics - uid: 3360 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 17.5,-25.5 @@ -33571,7 +33548,7 @@ entities: - canCollide: False type: Physics - uid: 3361 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 16.5,-25.5 @@ -33580,7 +33557,7 @@ entities: - canCollide: False type: Physics - uid: 3362 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 15.5,-25.5 @@ -33589,7 +33566,7 @@ entities: - canCollide: False type: Physics - uid: 3363 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 14.5,-25.5 @@ -33598,7 +33575,7 @@ entities: - canCollide: False type: Physics - uid: 3364 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 14.5,-24.5 @@ -33607,7 +33584,7 @@ entities: - canCollide: False type: Physics - uid: 3365 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 14.5,-23.5 @@ -33616,7 +33593,7 @@ entities: - canCollide: False type: Physics - uid: 3366 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 14.5,-22.5 @@ -33625,7 +33602,7 @@ entities: - canCollide: False type: Physics - uid: 3367 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 14.5,-21.5 @@ -33634,7 +33611,7 @@ entities: - canCollide: False type: Physics - uid: 3368 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 14.5,-20.5 @@ -33643,7 +33620,7 @@ entities: - canCollide: False type: Physics - uid: 3369 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 13.5,-20.5 @@ -33652,7 +33629,7 @@ entities: - canCollide: False type: Physics - uid: 3370 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 12.5,-20.5 @@ -33661,7 +33638,7 @@ entities: - canCollide: False type: Physics - uid: 3371 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 11.5,-20.5 @@ -33670,7 +33647,7 @@ entities: - canCollide: False type: Physics - uid: 3372 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 10.5,-20.5 @@ -33679,7 +33656,7 @@ entities: - canCollide: False type: Physics - uid: 3373 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 9.5,-20.5 @@ -33688,7 +33665,7 @@ entities: - canCollide: False type: Physics - uid: 3374 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 8.5,-20.5 @@ -33697,7 +33674,7 @@ entities: - canCollide: False type: Physics - uid: 3375 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 7.5,-20.5 @@ -33706,7 +33683,7 @@ entities: - canCollide: False type: Physics - uid: 3376 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 6.5,-20.5 @@ -33715,7 +33692,7 @@ entities: - canCollide: False type: Physics - uid: 3377 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 5.5,-20.5 @@ -33726,7 +33703,7 @@ entities: - canCollide: False type: Physics - uid: 3378 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 4.5,-20.5 @@ -33744,10 +33721,6 @@ entities: type: Transform - startingCharge: 2366791.8 type: Battery - - drawRate: 8000 - type: PowerConsumer - - supplyRate: 6000 - type: PowerSupplier - uid: 3380 type: SalternApc components: @@ -33757,7 +33730,7 @@ entities: - startingCharge: 11999.918 type: Battery - uid: 3381 - type: MVWire + type: CableMV components: - pos: 14.5,-25.5 parent: 853 @@ -33765,7 +33738,7 @@ entities: - canCollide: False type: Physics - uid: 3382 - type: MVWire + type: CableMV components: - pos: 13.5,-25.5 parent: 853 @@ -33773,7 +33746,7 @@ entities: - canCollide: False type: Physics - uid: 3383 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 2.5,-23.5 @@ -33784,7 +33757,7 @@ entities: - canCollide: False type: Physics - uid: 3384 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 1.5,-23.5 @@ -33795,7 +33768,7 @@ entities: - canCollide: False type: Physics - uid: 3385 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -0.5,-23.5 @@ -33804,7 +33777,7 @@ entities: - canCollide: False type: Physics - uid: 3386 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 0.5,-23.5 @@ -33813,7 +33786,7 @@ entities: - canCollide: False type: Physics - uid: 3387 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -0.5,-24.5 @@ -33822,7 +33795,7 @@ entities: - canCollide: False type: Physics - uid: 3388 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -0.5,-25.5 @@ -33831,7 +33804,7 @@ entities: - canCollide: False type: Physics - uid: 3389 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -0.5,-26.5 @@ -33840,7 +33813,7 @@ entities: - canCollide: False type: Physics - uid: 3390 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -1.5,-26.5 @@ -33849,7 +33822,7 @@ entities: - canCollide: False type: Physics - uid: 3391 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -2.5,-26.5 @@ -33858,7 +33831,7 @@ entities: - canCollide: False type: Physics - uid: 3392 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -3.5,-26.5 @@ -33867,7 +33840,7 @@ entities: - canCollide: False type: Physics - uid: 3393 - type: ApcExtensionCable + type: CableApcExtension components: - pos: -0.5,-15.5 parent: 853 @@ -33877,7 +33850,7 @@ entities: - canCollide: False type: Physics - uid: 3394 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -4.5,-26.5 @@ -33886,7 +33859,7 @@ entities: - canCollide: False type: Physics - uid: 3395 - type: ApcExtensionCable + type: CableApcExtension components: - pos: -1.5,-15.5 parent: 853 @@ -33896,7 +33869,7 @@ entities: - canCollide: False type: Physics - uid: 3396 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -7.5,-26.5 @@ -33905,7 +33878,7 @@ entities: - canCollide: False type: Physics - uid: 3397 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -8.5,-26.5 @@ -33914,7 +33887,7 @@ entities: - canCollide: False type: Physics - uid: 3398 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -9.5,-26.5 @@ -33923,7 +33896,7 @@ entities: - canCollide: False type: Physics - uid: 3399 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -10.5,-26.5 @@ -33932,7 +33905,7 @@ entities: - canCollide: False type: Physics - uid: 3400 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -11.5,-26.5 @@ -33941,7 +33914,7 @@ entities: - canCollide: False type: Physics - uid: 3401 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -11.5,-26.5 @@ -33950,7 +33923,7 @@ entities: - canCollide: False type: Physics - uid: 3402 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -11.5,-25.5 @@ -33959,7 +33932,7 @@ entities: - canCollide: False type: Physics - uid: 3403 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -11.5,-24.5 @@ -33968,7 +33941,7 @@ entities: - canCollide: False type: Physics - uid: 3404 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -11.5,-23.5 @@ -33977,7 +33950,7 @@ entities: - canCollide: False type: Physics - uid: 3405 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -11.5,-22.5 @@ -33986,7 +33959,7 @@ entities: - canCollide: False type: Physics - uid: 3406 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -11.5,-21.5 @@ -33997,7 +33970,7 @@ entities: - canCollide: False type: Physics - uid: 3407 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -11.5,-20.5 @@ -34008,7 +33981,7 @@ entities: - canCollide: False type: Physics - uid: 3408 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -11.5,-19.5 @@ -34019,7 +33992,7 @@ entities: - canCollide: False type: Physics - uid: 3409 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -11.5,-18.5 @@ -34030,7 +34003,7 @@ entities: - canCollide: False type: Physics - uid: 3410 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -11.5,-17.5 @@ -34041,7 +34014,7 @@ entities: - canCollide: False type: Physics - uid: 3411 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -11.5,-16.5 @@ -34050,7 +34023,7 @@ entities: - canCollide: False type: Physics - uid: 3412 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -11.5,-15.5 @@ -34061,7 +34034,7 @@ entities: - canCollide: False type: Physics - uid: 3413 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -11.5,-14.5 @@ -34070,7 +34043,7 @@ entities: - canCollide: False type: Physics - uid: 3414 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -10.5,-14.5 @@ -34079,7 +34052,7 @@ entities: - canCollide: False type: Physics - uid: 3415 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -9.5,-14.5 @@ -34088,7 +34061,7 @@ entities: - canCollide: False type: Physics - uid: 3416 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -9.5,-13.5 @@ -34097,7 +34070,7 @@ entities: - canCollide: False type: Physics - uid: 3417 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -9.5,-12.5 @@ -34106,7 +34079,7 @@ entities: - canCollide: False type: Physics - uid: 3418 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -9.5,-11.5 @@ -34115,7 +34088,7 @@ entities: - canCollide: False type: Physics - uid: 3419 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -9.5,-10.5 @@ -34124,7 +34097,7 @@ entities: - canCollide: False type: Physics - uid: 3420 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -8.5,-10.5 @@ -34133,7 +34106,7 @@ entities: - canCollide: False type: Physics - uid: 3421 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -7.5,-10.5 @@ -34142,7 +34115,7 @@ entities: - canCollide: False type: Physics - uid: 3422 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -6.5,-10.5 @@ -34151,7 +34124,7 @@ entities: - canCollide: False type: Physics - uid: 3423 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -5.5,-10.5 @@ -34160,7 +34133,7 @@ entities: - canCollide: False type: Physics - uid: 3424 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -4.5,-10.5 @@ -34169,7 +34142,7 @@ entities: - canCollide: False type: Physics - uid: 3425 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -3.5,-10.5 @@ -34178,7 +34151,7 @@ entities: - canCollide: False type: Physics - uid: 3426 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -2.5,-10.5 @@ -34187,7 +34160,7 @@ entities: - canCollide: False type: Physics - uid: 3427 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -1.5,-10.5 @@ -34196,7 +34169,7 @@ entities: - canCollide: False type: Physics - uid: 3428 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -0.5,-10.5 @@ -34205,7 +34178,7 @@ entities: - canCollide: False type: Physics - uid: 3429 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 0.5,-10.5 @@ -34214,7 +34187,7 @@ entities: - canCollide: False type: Physics - uid: 3430 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 0.5,-9.5 @@ -34223,7 +34196,7 @@ entities: - canCollide: False type: Physics - uid: 3431 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 0.5,-8.5 @@ -34232,7 +34205,7 @@ entities: - canCollide: False type: Physics - uid: 3432 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 0.5,-7.5 @@ -34241,7 +34214,7 @@ entities: - canCollide: False type: Physics - uid: 3433 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 0.5,-6.5 @@ -34252,7 +34225,7 @@ entities: - canCollide: False type: Physics - uid: 3434 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -12.5,-14.5 @@ -34261,7 +34234,7 @@ entities: - canCollide: False type: Physics - uid: 3435 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -13.5,-14.5 @@ -34270,7 +34243,7 @@ entities: - canCollide: False type: Physics - uid: 3436 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -14.5,-14.5 @@ -34279,7 +34252,7 @@ entities: - canCollide: False type: Physics - uid: 3437 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -15.5,-14.5 @@ -34288,7 +34261,7 @@ entities: - canCollide: False type: Physics - uid: 3438 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -16.5,-14.5 @@ -34297,7 +34270,7 @@ entities: - canCollide: False type: Physics - uid: 3439 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -17.5,-14.5 @@ -34306,7 +34279,7 @@ entities: - canCollide: False type: Physics - uid: 3440 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -18.5,-14.5 @@ -34315,7 +34288,7 @@ entities: - canCollide: False type: Physics - uid: 3441 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -18.5,-13.5 @@ -34324,7 +34297,7 @@ entities: - canCollide: False type: Physics - uid: 3442 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -18.5,-12.5 @@ -34333,7 +34306,7 @@ entities: - canCollide: False type: Physics - uid: 3443 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -18.5,-11.5 @@ -34342,7 +34315,7 @@ entities: - canCollide: False type: Physics - uid: 3444 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -18.5,-11.5 @@ -34351,7 +34324,7 @@ entities: - canCollide: False type: Physics - uid: 3445 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -19.5,-11.5 @@ -34360,7 +34333,7 @@ entities: - canCollide: False type: Physics - uid: 3446 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -20.5,-11.5 @@ -34369,7 +34342,7 @@ entities: - canCollide: False type: Physics - uid: 3447 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -21.5,-11.5 @@ -34378,7 +34351,7 @@ entities: - canCollide: False type: Physics - uid: 3448 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -22.5,-11.5 @@ -34387,7 +34360,7 @@ entities: - canCollide: False type: Physics - uid: 3449 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -23.5,-11.5 @@ -34396,7 +34369,7 @@ entities: - canCollide: False type: Physics - uid: 3450 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -24.5,-11.5 @@ -34405,7 +34378,7 @@ entities: - canCollide: False type: Physics - uid: 3451 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -25.5,-11.5 @@ -34414,7 +34387,7 @@ entities: - canCollide: False type: Physics - uid: 3452 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -26.5,-11.5 @@ -34423,7 +34396,7 @@ entities: - canCollide: False type: Physics - uid: 3453 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -27.5,-11.5 @@ -34432,7 +34405,7 @@ entities: - canCollide: False type: Physics - uid: 3454 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -21.5,-10.5 @@ -34443,7 +34416,7 @@ entities: - canCollide: False type: Physics - uid: 3455 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -28.5,-11.5 @@ -34452,7 +34425,7 @@ entities: - canCollide: False type: Physics - uid: 3456 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -29.5,-11.5 @@ -34461,7 +34434,7 @@ entities: - canCollide: False type: Physics - uid: 3457 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -30.5,-11.5 @@ -34470,7 +34443,7 @@ entities: - canCollide: False type: Physics - uid: 3458 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -31.5,-11.5 @@ -34479,7 +34452,7 @@ entities: - canCollide: False type: Physics - uid: 3459 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -32.5,-11.5 @@ -34488,7 +34461,7 @@ entities: - canCollide: False type: Physics - uid: 3460 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -33.5,-11.5 @@ -34497,7 +34470,7 @@ entities: - canCollide: False type: Physics - uid: 3461 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -33.5,-10.5 @@ -34506,7 +34479,7 @@ entities: - canCollide: False type: Physics - uid: 3462 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -33.5,-9.5 @@ -34515,7 +34488,7 @@ entities: - canCollide: False type: Physics - uid: 3463 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -33.5,-8.5 @@ -34524,7 +34497,7 @@ entities: - canCollide: False type: Physics - uid: 3464 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -33.5,-7.5 @@ -34533,7 +34506,7 @@ entities: - canCollide: False type: Physics - uid: 3465 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -33.5,-6.5 @@ -34542,7 +34515,7 @@ entities: - canCollide: False type: Physics - uid: 3466 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -33.5,-5.5 @@ -34551,7 +34524,7 @@ entities: - canCollide: False type: Physics - uid: 3467 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -33.5,-4.5 @@ -34560,7 +34533,7 @@ entities: - canCollide: False type: Physics - uid: 3468 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -33.5,-3.5 @@ -34569,7 +34542,7 @@ entities: - canCollide: False type: Physics - uid: 3469 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -33.5,-2.5 @@ -34578,7 +34551,7 @@ entities: - canCollide: False type: Physics - uid: 3470 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -33.5,-1.5 @@ -34587,7 +34560,7 @@ entities: - canCollide: False type: Physics - uid: 3471 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -33.5,-0.5 @@ -34596,7 +34569,7 @@ entities: - canCollide: False type: Physics - uid: 3472 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -33.5,0.5 @@ -34605,7 +34578,7 @@ entities: - canCollide: False type: Physics - uid: 3473 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -32.5,0.5 @@ -34614,7 +34587,7 @@ entities: - canCollide: False type: Physics - uid: 3474 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -32.5,1.5 @@ -34623,7 +34596,7 @@ entities: - canCollide: False type: Physics - uid: 3475 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -32.5,2.5 @@ -34634,7 +34607,7 @@ entities: - canCollide: False type: Physics - uid: 3476 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -32.5,3.5 @@ -34645,7 +34618,7 @@ entities: - canCollide: False type: Physics - uid: 3477 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -32.5,4.5 @@ -34656,7 +34629,7 @@ entities: - canCollide: False type: Physics - uid: 3478 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -32.5,5.5 @@ -34667,7 +34640,7 @@ entities: - canCollide: False type: Physics - uid: 3479 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -32.5,6.5 @@ -34676,7 +34649,7 @@ entities: - canCollide: False type: Physics - uid: 3480 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -32.5,7.5 @@ -34685,7 +34658,7 @@ entities: - canCollide: False type: Physics - uid: 3481 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -32.5,8.5 @@ -34694,7 +34667,7 @@ entities: - canCollide: False type: Physics - uid: 3482 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -32.5,9.5 @@ -34703,7 +34676,7 @@ entities: - canCollide: False type: Physics - uid: 3483 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -32.5,10.5 @@ -34712,7 +34685,7 @@ entities: - canCollide: False type: Physics - uid: 3484 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -32.5,11.5 @@ -34721,7 +34694,7 @@ entities: - canCollide: False type: Physics - uid: 3485 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -32.5,12.5 @@ -34730,7 +34703,7 @@ entities: - canCollide: False type: Physics - uid: 3486 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -32.5,13.5 @@ -34739,7 +34712,7 @@ entities: - canCollide: False type: Physics - uid: 3487 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -32.5,14.5 @@ -34748,7 +34721,7 @@ entities: - canCollide: False type: Physics - uid: 3488 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -32.5,14.5 @@ -34757,7 +34730,7 @@ entities: - canCollide: False type: Physics - uid: 3489 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -31.5,14.5 @@ -34766,7 +34739,7 @@ entities: - canCollide: False type: Physics - uid: 3490 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -30.5,14.5 @@ -34775,7 +34748,7 @@ entities: - canCollide: False type: Physics - uid: 3491 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -29.5,14.5 @@ -34784,7 +34757,7 @@ entities: - canCollide: False type: Physics - uid: 3492 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -28.5,14.5 @@ -34793,7 +34766,7 @@ entities: - canCollide: False type: Physics - uid: 3493 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -27.5,14.5 @@ -34802,7 +34775,7 @@ entities: - canCollide: False type: Physics - uid: 3494 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -26.5,14.5 @@ -34811,7 +34784,7 @@ entities: - canCollide: False type: Physics - uid: 3495 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -25.5,14.5 @@ -34820,7 +34793,7 @@ entities: - canCollide: False type: Physics - uid: 3496 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -24.5,14.5 @@ -34829,7 +34802,7 @@ entities: - canCollide: False type: Physics - uid: 3497 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -23.5,14.5 @@ -34838,7 +34811,7 @@ entities: - canCollide: False type: Physics - uid: 3498 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -22.5,14.5 @@ -34847,7 +34820,7 @@ entities: - canCollide: False type: Physics - uid: 3499 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -21.5,14.5 @@ -34856,7 +34829,7 @@ entities: - canCollide: False type: Physics - uid: 3500 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -20.5,14.5 @@ -34865,7 +34838,7 @@ entities: - canCollide: False type: Physics - uid: 3501 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -20.5,13.5 @@ -34874,7 +34847,7 @@ entities: - canCollide: False type: Physics - uid: 3502 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -19.5,13.5 @@ -34883,7 +34856,7 @@ entities: - canCollide: False type: Physics - uid: 3503 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -18.5,13.5 @@ -34892,7 +34865,7 @@ entities: - canCollide: False type: Physics - uid: 3504 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -18.5,13.5 @@ -34901,7 +34874,7 @@ entities: - canCollide: False type: Physics - uid: 3505 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -17.5,13.5 @@ -34910,7 +34883,7 @@ entities: - canCollide: False type: Physics - uid: 3506 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -17.5,14.5 @@ -34919,7 +34892,7 @@ entities: - canCollide: False type: Physics - uid: 3507 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -17.5,15.5 @@ -34928,7 +34901,7 @@ entities: - canCollide: False type: Physics - uid: 3508 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -18.5,16.5 @@ -34937,7 +34910,7 @@ entities: - canCollide: False type: Physics - uid: 3509 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -17.5,16.5 @@ -34948,7 +34921,7 @@ entities: - canCollide: False type: Physics - uid: 3510 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -16.5,16.5 @@ -34959,7 +34932,7 @@ entities: - canCollide: False type: Physics - uid: 3511 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -15.5,16.5 @@ -34968,7 +34941,7 @@ entities: - canCollide: False type: Physics - uid: 3512 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -18.5,17.5 @@ -34977,7 +34950,7 @@ entities: - canCollide: False type: Physics - uid: 3513 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -18.5,18.5 @@ -34986,7 +34959,7 @@ entities: - canCollide: False type: Physics - uid: 3514 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -18.5,19.5 @@ -34995,7 +34968,7 @@ entities: - canCollide: False type: Physics - uid: 3515 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -18.5,20.5 @@ -35004,7 +34977,7 @@ entities: - canCollide: False type: Physics - uid: 3516 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -18.5,21.5 @@ -35013,7 +34986,7 @@ entities: - canCollide: False type: Physics - uid: 3517 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -18.5,22.5 @@ -35022,7 +34995,7 @@ entities: - canCollide: False type: Physics - uid: 3518 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -18.5,23.5 @@ -35031,7 +35004,7 @@ entities: - canCollide: False type: Physics - uid: 3519 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -18.5,24.5 @@ -35040,7 +35013,7 @@ entities: - canCollide: False type: Physics - uid: 3520 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -18.5,25.5 @@ -35049,7 +35022,7 @@ entities: - canCollide: False type: Physics - uid: 3521 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -17.5,25.5 @@ -35058,7 +35031,7 @@ entities: - canCollide: False type: Physics - uid: 3522 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -16.5,25.5 @@ -35067,7 +35040,7 @@ entities: - canCollide: False type: Physics - uid: 3523 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -15.5,25.5 @@ -35076,7 +35049,7 @@ entities: - canCollide: False type: Physics - uid: 3524 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -14.5,25.5 @@ -35085,7 +35058,7 @@ entities: - canCollide: False type: Physics - uid: 3525 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -13.5,25.5 @@ -35094,7 +35067,7 @@ entities: - canCollide: False type: Physics - uid: 3526 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -12.5,25.5 @@ -35103,7 +35076,7 @@ entities: - canCollide: False type: Physics - uid: 3527 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -11.5,25.5 @@ -35112,7 +35085,7 @@ entities: - canCollide: False type: Physics - uid: 3528 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -10.5,25.5 @@ -35121,7 +35094,7 @@ entities: - canCollide: False type: Physics - uid: 3529 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -9.5,25.5 @@ -35130,7 +35103,7 @@ entities: - canCollide: False type: Physics - uid: 3530 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -8.5,25.5 @@ -35139,7 +35112,7 @@ entities: - canCollide: False type: Physics - uid: 3531 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -7.5,25.5 @@ -35148,7 +35121,7 @@ entities: - canCollide: False type: Physics - uid: 3532 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -7.5,24.5 @@ -35157,7 +35130,7 @@ entities: - canCollide: False type: Physics - uid: 3533 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -6.5,24.5 @@ -35166,7 +35139,7 @@ entities: - canCollide: False type: Physics - uid: 3534 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -5.5,24.5 @@ -35175,7 +35148,7 @@ entities: - canCollide: False type: Physics - uid: 3535 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -4.5,24.5 @@ -35184,7 +35157,7 @@ entities: - canCollide: False type: Physics - uid: 3536 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -4.5,24.5 @@ -35193,7 +35166,7 @@ entities: - canCollide: False type: Physics - uid: 3537 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -4.5,23.5 @@ -35202,7 +35175,7 @@ entities: - canCollide: False type: Physics - uid: 3538 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -4.5,22.5 @@ -35211,7 +35184,7 @@ entities: - canCollide: False type: Physics - uid: 3539 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -4.5,21.5 @@ -35220,7 +35193,7 @@ entities: - canCollide: False type: Physics - uid: 3540 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -4.5,21.5 @@ -35229,7 +35202,7 @@ entities: - canCollide: False type: Physics - uid: 3541 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -3.5,21.5 @@ -35238,7 +35211,7 @@ entities: - canCollide: False type: Physics - uid: 3542 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -2.5,21.5 @@ -35247,7 +35220,7 @@ entities: - canCollide: False type: Physics - uid: 3543 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -1.5,21.5 @@ -35256,7 +35229,7 @@ entities: - canCollide: False type: Physics - uid: 3544 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -0.5,21.5 @@ -35265,7 +35238,7 @@ entities: - canCollide: False type: Physics - uid: 3545 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -0.5,20.5 @@ -35274,7 +35247,7 @@ entities: - canCollide: False type: Physics - uid: 3546 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 0.5,20.5 @@ -35285,7 +35258,7 @@ entities: - canCollide: False type: Physics - uid: 3547 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 1.5,20.5 @@ -35296,7 +35269,7 @@ entities: - canCollide: False type: Physics - uid: 3548 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 2.5,20.5 @@ -35307,7 +35280,7 @@ entities: - canCollide: False type: Physics - uid: 3549 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 3.5,20.5 @@ -35318,7 +35291,7 @@ entities: - canCollide: False type: Physics - uid: 3550 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 4.5,20.5 @@ -35329,7 +35302,7 @@ entities: - canCollide: False type: Physics - uid: 3551 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 5.5,20.5 @@ -35340,7 +35313,7 @@ entities: - canCollide: False type: Physics - uid: 3552 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 6.5,20.5 @@ -35351,7 +35324,7 @@ entities: - canCollide: False type: Physics - uid: 3553 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 7.5,20.5 @@ -35362,7 +35335,7 @@ entities: - canCollide: False type: Physics - uid: 3554 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 8.5,20.5 @@ -35373,7 +35346,7 @@ entities: - canCollide: False type: Physics - uid: 3555 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 9.5,20.5 @@ -35384,7 +35357,7 @@ entities: - canCollide: False type: Physics - uid: 3556 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 10.5,20.5 @@ -35395,7 +35368,7 @@ entities: - canCollide: False type: Physics - uid: 3557 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 11.5,20.5 @@ -35406,7 +35379,7 @@ entities: - canCollide: False type: Physics - uid: 3558 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 12.5,20.5 @@ -35415,7 +35388,7 @@ entities: - canCollide: False type: Physics - uid: 3559 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 12.5,21.5 @@ -35426,7 +35399,7 @@ entities: - canCollide: False type: Physics - uid: 3560 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 12.5,22.5 @@ -35437,7 +35410,7 @@ entities: - canCollide: False type: Physics - uid: 3561 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 12.5,23.5 @@ -35448,7 +35421,7 @@ entities: - canCollide: False type: Physics - uid: 3562 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 12.5,24.5 @@ -35457,7 +35430,7 @@ entities: - canCollide: False type: Physics - uid: 3563 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 11.5,24.5 @@ -35466,7 +35439,7 @@ entities: - canCollide: False type: Physics - uid: 3564 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 12.5,20.5 @@ -35475,7 +35448,7 @@ entities: - canCollide: False type: Physics - uid: 3565 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 12.5,19.5 @@ -35484,7 +35457,7 @@ entities: - canCollide: False type: Physics - uid: 3566 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 12.5,18.5 @@ -35493,7 +35466,7 @@ entities: - canCollide: False type: Physics - uid: 3567 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 12.5,17.5 @@ -35502,7 +35475,7 @@ entities: - canCollide: False type: Physics - uid: 3568 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 12.5,16.5 @@ -35511,7 +35484,7 @@ entities: - canCollide: False type: Physics - uid: 3569 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 12.5,15.5 @@ -35520,7 +35493,7 @@ entities: - canCollide: False type: Physics - uid: 3570 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 12.5,14.5 @@ -35529,7 +35502,7 @@ entities: - canCollide: False type: Physics - uid: 3571 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 11.5,14.5 @@ -35538,7 +35511,7 @@ entities: - canCollide: False type: Physics - uid: 3572 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 10.5,14.5 @@ -35547,7 +35520,7 @@ entities: - canCollide: False type: Physics - uid: 3573 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 10.5,13.5 @@ -35556,7 +35529,7 @@ entities: - canCollide: False type: Physics - uid: 3574 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 10.5,12.5 @@ -35565,7 +35538,7 @@ entities: - canCollide: False type: Physics - uid: 3575 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 10.5,11.5 @@ -35576,7 +35549,7 @@ entities: - canCollide: False type: Physics - uid: 3576 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 11.5,11.5 @@ -35585,7 +35558,7 @@ entities: - canCollide: False type: Physics - uid: 3577 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 12.5,11.5 @@ -35596,7 +35569,7 @@ entities: - canCollide: False type: Physics - uid: 3578 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 13.5,11.5 @@ -35615,7 +35588,7 @@ entities: - canCollide: False type: Physics - uid: 3580 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 15.5,11.5 @@ -35626,7 +35599,7 @@ entities: - canCollide: False type: Physics - uid: 3581 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 16.5,11.5 @@ -35637,7 +35610,7 @@ entities: - canCollide: False type: Physics - uid: 3582 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 17.5,11.5 @@ -35648,7 +35621,7 @@ entities: - canCollide: False type: Physics - uid: 3583 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 18.5,11.5 @@ -35659,7 +35632,7 @@ entities: - canCollide: False type: Physics - uid: 3584 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 19.5,11.5 @@ -35670,7 +35643,7 @@ entities: - canCollide: False type: Physics - uid: 3585 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 20.5,11.5 @@ -35681,7 +35654,7 @@ entities: - canCollide: False type: Physics - uid: 3586 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 21.5,11.5 @@ -35692,7 +35665,7 @@ entities: - canCollide: False type: Physics - uid: 3587 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 22.5,11.5 @@ -35703,7 +35676,7 @@ entities: - canCollide: False type: Physics - uid: 3588 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 23.5,11.5 @@ -35714,7 +35687,7 @@ entities: - canCollide: False type: Physics - uid: 3589 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 24.5,11.5 @@ -35725,7 +35698,7 @@ entities: - canCollide: False type: Physics - uid: 3590 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 25.5,11.5 @@ -35734,7 +35707,7 @@ entities: - canCollide: False type: Physics - uid: 3591 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 26.5,11.5 @@ -35745,7 +35718,7 @@ entities: - canCollide: False type: Physics - uid: 3592 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 27.5,11.5 @@ -35756,7 +35729,7 @@ entities: - canCollide: False type: Physics - uid: 3593 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 27.5,12.5 @@ -35767,7 +35740,7 @@ entities: - canCollide: False type: Physics - uid: 3594 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 27.5,13.5 @@ -35776,7 +35749,7 @@ entities: - canCollide: False type: Physics - uid: 3595 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 28.5,11.5 @@ -35787,7 +35760,7 @@ entities: - canCollide: False type: Physics - uid: 3596 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 29.5,11.5 @@ -35796,7 +35769,7 @@ entities: - canCollide: False type: Physics - uid: 3597 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 30.5,11.5 @@ -35807,7 +35780,7 @@ entities: - canCollide: False type: Physics - uid: 3598 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 31.5,11.5 @@ -35818,7 +35791,7 @@ entities: - canCollide: False type: Physics - uid: 3599 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 32.5,11.5 @@ -35829,7 +35802,7 @@ entities: - canCollide: False type: Physics - uid: 3600 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 33.5,11.5 @@ -35840,7 +35813,7 @@ entities: - canCollide: False type: Physics - uid: 3601 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 34.5,11.5 @@ -35851,7 +35824,7 @@ entities: - canCollide: False type: Physics - uid: 3602 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 34.5,10.5 @@ -35862,7 +35835,7 @@ entities: - canCollide: False type: Physics - uid: 3603 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 34.5,9.5 @@ -35873,7 +35846,7 @@ entities: - canCollide: False type: Physics - uid: 3604 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 34.5,8.5 @@ -35884,7 +35857,7 @@ entities: - canCollide: False type: Physics - uid: 3605 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 34.5,7.5 @@ -35893,7 +35866,7 @@ entities: - canCollide: False type: Physics - uid: 3606 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 34.5,6.5 @@ -35904,7 +35877,7 @@ entities: - canCollide: False type: Physics - uid: 3607 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 34.5,5.5 @@ -35915,7 +35888,7 @@ entities: - canCollide: False type: Physics - uid: 3608 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 35.5,5.5 @@ -35926,7 +35899,7 @@ entities: - canCollide: False type: Physics - uid: 3609 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 36.5,5.5 @@ -35937,7 +35910,7 @@ entities: - canCollide: False type: Physics - uid: 3610 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 37.5,5.5 @@ -35948,7 +35921,7 @@ entities: - canCollide: False type: Physics - uid: 3611 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 38.5,5.5 @@ -35959,7 +35932,7 @@ entities: - canCollide: False type: Physics - uid: 3612 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 39.5,5.5 @@ -35978,10 +35951,6 @@ entities: type: Transform - startingCharge: 3200172 type: Battery - - drawRate: 8000 - type: PowerConsumer - - supplyRate: 6000 - type: PowerSupplier - uid: 3614 type: SalternSubstation components: @@ -35991,10 +35960,6 @@ entities: type: Transform - startingCharge: 3200172 type: Battery - - drawRate: 8000 - type: PowerConsumer - - supplyRate: 6000 - type: PowerSupplier - uid: 3615 type: SalternSubstation components: @@ -36004,10 +35969,6 @@ entities: type: Transform - startingCharge: 3200172 type: Battery - - drawRate: 8000 - type: PowerConsumer - - supplyRate: 6000 - type: PowerSupplier - uid: 3616 type: SalternSubstation components: @@ -36017,10 +35978,6 @@ entities: type: Transform - startingCharge: 3200172 type: Battery - - drawRate: 8000 - type: PowerConsumer - - supplyRate: 6000 - type: PowerSupplier - uid: 3617 type: BedsheetSpawner components: @@ -36037,12 +35994,8 @@ entities: type: Transform - startingCharge: 3200172 type: Battery - - drawRate: 8000 - type: PowerConsumer - - supplyRate: 6000 - type: PowerSupplier - uid: 3619 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -0.5,-22.5 @@ -36059,10 +36012,6 @@ entities: type: Transform - startingCharge: 3200172 type: Battery - - drawRate: 8000 - type: PowerConsumer - - supplyRate: 6000 - type: PowerSupplier - uid: 3621 type: SalternSubstation components: @@ -36072,10 +36021,6 @@ entities: type: Transform - startingCharge: 3200172 type: Battery - - drawRate: 8000 - type: PowerConsumer - - supplyRate: 6000 - type: PowerSupplier - uid: 3622 type: SalternSubstation components: @@ -36085,12 +36030,8 @@ entities: type: Transform - startingCharge: 3200172 type: Battery - - drawRate: 8000 - type: PowerConsumer - - supplyRate: 6000 - type: PowerSupplier - uid: 3623 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 27.5,13.5 @@ -36099,7 +36040,7 @@ entities: - canCollide: False type: Physics - uid: 3624 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 28.5,13.5 @@ -36108,7 +36049,7 @@ entities: - canCollide: False type: Physics - uid: 3625 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 28.5,14.5 @@ -36117,7 +36058,7 @@ entities: - canCollide: False type: Physics - uid: 3626 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 26.5,13.5 @@ -36126,7 +36067,7 @@ entities: - canCollide: False type: Physics - uid: 3627 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 25.5,13.5 @@ -36135,7 +36076,7 @@ entities: - canCollide: False type: Physics - uid: 3628 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 24.5,13.5 @@ -36146,7 +36087,7 @@ entities: - canCollide: False type: Physics - uid: 3629 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 24.5,14.5 @@ -36155,7 +36096,7 @@ entities: - canCollide: False type: Physics - uid: 3630 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 24.5,12.5 @@ -36166,7 +36107,7 @@ entities: - canCollide: False type: Physics - uid: 3631 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 23.5,12.5 @@ -36177,7 +36118,7 @@ entities: - canCollide: False type: Physics - uid: 3632 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 22.5,12.5 @@ -36188,7 +36129,7 @@ entities: - canCollide: False type: Physics - uid: 3633 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 21.5,12.5 @@ -36199,7 +36140,7 @@ entities: - canCollide: False type: Physics - uid: 3634 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 20.5,12.5 @@ -36210,7 +36151,7 @@ entities: - canCollide: False type: Physics - uid: 3635 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 19.5,12.5 @@ -36221,7 +36162,7 @@ entities: - canCollide: False type: Physics - uid: 3636 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 18.5,12.5 @@ -36232,7 +36173,7 @@ entities: - canCollide: False type: Physics - uid: 3637 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 17.5,12.5 @@ -36241,7 +36182,7 @@ entities: - canCollide: False type: Physics - uid: 3638 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 16.5,12.5 @@ -36252,7 +36193,7 @@ entities: - canCollide: False type: Physics - uid: 3639 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 15.5,12.5 @@ -36263,7 +36204,7 @@ entities: - canCollide: False type: Physics - uid: 3640 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 14.5,12.5 @@ -36274,7 +36215,7 @@ entities: - canCollide: False type: Physics - uid: 3641 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 13.5,12.5 @@ -36285,7 +36226,7 @@ entities: - canCollide: False type: Physics - uid: 3642 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 12.5,12.5 @@ -36296,7 +36237,7 @@ entities: - canCollide: False type: Physics - uid: 3643 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 12.5,13.5 @@ -36305,7 +36246,7 @@ entities: - canCollide: False type: Physics - uid: 3644 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 11.5,24.5 @@ -36314,7 +36255,7 @@ entities: - canCollide: False type: Physics - uid: 3645 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 9.5,24.5 @@ -36325,7 +36266,7 @@ entities: - canCollide: False type: Physics - uid: 3646 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 10.5,24.5 @@ -36334,7 +36275,7 @@ entities: - canCollide: False type: Physics - uid: 3647 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 9.5,23.5 @@ -36345,7 +36286,7 @@ entities: - canCollide: False type: Physics - uid: 3648 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 9.5,22.5 @@ -36354,7 +36295,7 @@ entities: - canCollide: False type: Physics - uid: 3649 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 9.5,24.5 @@ -36365,7 +36306,7 @@ entities: - canCollide: False type: Physics - uid: 3650 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 9.5,25.5 @@ -36376,7 +36317,7 @@ entities: - canCollide: False type: Physics - uid: 3651 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 9.5,26.5 @@ -36387,7 +36328,7 @@ entities: - canCollide: False type: Physics - uid: 3652 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 9.5,26.5 @@ -36398,7 +36339,7 @@ entities: - canCollide: False type: Physics - uid: 3653 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 9.5,27.5 @@ -36407,7 +36348,7 @@ entities: - canCollide: False type: Physics - uid: 3654 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 8.5,25.5 @@ -36418,7 +36359,7 @@ entities: - canCollide: False type: Physics - uid: 3655 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 7.5,25.5 @@ -36429,7 +36370,7 @@ entities: - canCollide: False type: Physics - uid: 3656 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 6.5,25.5 @@ -36440,7 +36381,7 @@ entities: - canCollide: False type: Physics - uid: 3657 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 5.5,25.5 @@ -36451,7 +36392,7 @@ entities: - canCollide: False type: Physics - uid: 3658 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 4.5,25.5 @@ -36462,7 +36403,7 @@ entities: - canCollide: False type: Physics - uid: 3659 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 3.5,25.5 @@ -36473,7 +36414,7 @@ entities: - canCollide: False type: Physics - uid: 3660 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 2.5,25.5 @@ -36484,7 +36425,7 @@ entities: - canCollide: False type: Physics - uid: 3661 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 1.5,25.5 @@ -36495,7 +36436,7 @@ entities: - canCollide: False type: Physics - uid: 3662 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 0.5,25.5 @@ -36506,7 +36447,7 @@ entities: - canCollide: False type: Physics - uid: 3663 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 0.5,26.5 @@ -36517,7 +36458,7 @@ entities: - canCollide: False type: Physics - uid: 3664 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 0.5,26.5 @@ -36528,7 +36469,7 @@ entities: - canCollide: False type: Physics - uid: 3665 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -0.5,26.5 @@ -36539,7 +36480,7 @@ entities: - canCollide: False type: Physics - uid: 3666 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -1.5,26.5 @@ -36550,7 +36491,7 @@ entities: - canCollide: False type: Physics - uid: 3667 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -2.5,26.5 @@ -36561,7 +36502,7 @@ entities: - canCollide: False type: Physics - uid: 3668 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -2.5,27.5 @@ -36570,7 +36511,7 @@ entities: - canCollide: False type: Physics - uid: 3669 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 42.5,-0.5 @@ -36579,7 +36520,7 @@ entities: - canCollide: False type: Physics - uid: 3670 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 43.5,-0.5 @@ -36590,7 +36531,7 @@ entities: - canCollide: False type: Physics - uid: 3671 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 43.5,0.5 @@ -36601,7 +36542,7 @@ entities: - canCollide: False type: Physics - uid: 3672 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 43.5,1.5 @@ -36612,7 +36553,7 @@ entities: - canCollide: False type: Physics - uid: 3673 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 44.5,1.5 @@ -36623,7 +36564,7 @@ entities: - canCollide: False type: Physics - uid: 3674 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 45.5,1.5 @@ -36634,7 +36575,7 @@ entities: - canCollide: False type: Physics - uid: 3675 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 46.5,1.5 @@ -36645,7 +36586,7 @@ entities: - canCollide: False type: Physics - uid: 3676 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 47.5,1.5 @@ -36656,7 +36597,7 @@ entities: - canCollide: False type: Physics - uid: 3677 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 48.5,1.5 @@ -36667,7 +36608,7 @@ entities: - canCollide: False type: Physics - uid: 3678 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 48.5,0.5 @@ -36678,7 +36619,7 @@ entities: - canCollide: False type: Physics - uid: 3679 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 48.5,-0.5 @@ -36689,7 +36630,7 @@ entities: - canCollide: False type: Physics - uid: 3680 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 48.5,-1.5 @@ -36698,7 +36639,7 @@ entities: - canCollide: False type: Physics - uid: 3681 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 48.5,-2.5 @@ -36707,7 +36648,7 @@ entities: - canCollide: False type: Physics - uid: 3682 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 47.5,-2.5 @@ -36716,7 +36657,7 @@ entities: - canCollide: False type: Physics - uid: 3683 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 47.5,-1.5 @@ -36725,7 +36666,7 @@ entities: - canCollide: False type: Physics - uid: 3684 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 41.5,-0.5 @@ -36734,7 +36675,7 @@ entities: - canCollide: False type: Physics - uid: 3685 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 40.5,-0.5 @@ -36745,7 +36686,7 @@ entities: - canCollide: False type: Physics - uid: 3686 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 39.5,-0.5 @@ -36756,7 +36697,7 @@ entities: - canCollide: False type: Physics - uid: 3687 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 38.5,-0.5 @@ -36767,7 +36708,7 @@ entities: - canCollide: False type: Physics - uid: 3688 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 37.5,-0.5 @@ -36778,7 +36719,7 @@ entities: - canCollide: False type: Physics - uid: 3689 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 36.5,-0.5 @@ -36787,7 +36728,7 @@ entities: - canCollide: False type: Physics - uid: 3690 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 35.5,-0.5 @@ -36798,7 +36739,7 @@ entities: - canCollide: False type: Physics - uid: 3691 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 34.5,-0.5 @@ -36809,7 +36750,7 @@ entities: - canCollide: False type: Physics - uid: 3692 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 33.5,-0.5 @@ -36820,7 +36761,7 @@ entities: - canCollide: False type: Physics - uid: 3693 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 32.5,-0.5 @@ -36831,7 +36772,7 @@ entities: - canCollide: False type: Physics - uid: 3694 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 32.5,0.5 @@ -36842,7 +36783,7 @@ entities: - canCollide: False type: Physics - uid: 3695 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 31.5,0.5 @@ -36853,7 +36794,7 @@ entities: - canCollide: False type: Physics - uid: 3696 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 31.5,1.5 @@ -36862,7 +36803,7 @@ entities: - canCollide: False type: Physics - uid: 3697 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 43.5,2.5 @@ -36873,7 +36814,7 @@ entities: - canCollide: False type: Physics - uid: 3698 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 43.5,3.5 @@ -36884,7 +36825,7 @@ entities: - canCollide: False type: Physics - uid: 3699 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 43.5,4.5 @@ -36895,7 +36836,7 @@ entities: - canCollide: False type: Physics - uid: 3700 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 43.5,5.5 @@ -36906,7 +36847,7 @@ entities: - canCollide: False type: Physics - uid: 3701 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 43.5,6.5 @@ -36917,7 +36858,7 @@ entities: - canCollide: False type: Physics - uid: 3702 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 43.5,7.5 @@ -36928,7 +36869,7 @@ entities: - canCollide: False type: Physics - uid: 3703 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 43.5,8.5 @@ -36939,7 +36880,7 @@ entities: - canCollide: False type: Physics - uid: 3704 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 43.5,9.5 @@ -36950,7 +36891,7 @@ entities: - canCollide: False type: Physics - uid: 3705 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 43.5,10.5 @@ -36959,7 +36900,7 @@ entities: - canCollide: False type: Physics - uid: 3706 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 21.5,-9.5 @@ -36968,7 +36909,7 @@ entities: - canCollide: False type: Physics - uid: 3707 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 21.5,-8.5 @@ -36977,7 +36918,7 @@ entities: - canCollide: False type: Physics - uid: 3708 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 21.5,-7.5 @@ -36988,7 +36929,7 @@ entities: - canCollide: False type: Physics - uid: 3709 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 21.5,-6.5 @@ -36999,7 +36940,7 @@ entities: - canCollide: False type: Physics - uid: 3710 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 21.5,-5.5 @@ -37010,7 +36951,7 @@ entities: - canCollide: False type: Physics - uid: 3711 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 21.5,-4.5 @@ -37021,7 +36962,7 @@ entities: - canCollide: False type: Physics - uid: 3712 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 22.5,-4.5 @@ -37032,7 +36973,7 @@ entities: - canCollide: False type: Physics - uid: 3713 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 22.5,-3.5 @@ -37041,7 +36982,7 @@ entities: - canCollide: False type: Physics - uid: 3714 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 20.5,-9.5 @@ -37050,7 +36991,7 @@ entities: - canCollide: False type: Physics - uid: 3715 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 19.5,-9.5 @@ -37061,7 +37002,7 @@ entities: - canCollide: False type: Physics - uid: 3716 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 21.5,-9.5 @@ -37070,7 +37011,7 @@ entities: - canCollide: False type: Physics - uid: 3717 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 18.5,-9.5 @@ -37081,7 +37022,7 @@ entities: - canCollide: False type: Physics - uid: 3718 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 17.5,-9.5 @@ -37092,7 +37033,7 @@ entities: - canCollide: False type: Physics - uid: 3719 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 16.5,-9.5 @@ -37103,7 +37044,7 @@ entities: - canCollide: False type: Physics - uid: 3720 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 15.5,-9.5 @@ -37114,7 +37055,7 @@ entities: - canCollide: False type: Physics - uid: 3721 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 14.5,-9.5 @@ -37125,7 +37066,7 @@ entities: - canCollide: False type: Physics - uid: 3722 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 13.5,-9.5 @@ -37136,7 +37077,7 @@ entities: - canCollide: False type: Physics - uid: 3723 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 12.5,-9.5 @@ -37147,7 +37088,7 @@ entities: - canCollide: False type: Physics - uid: 3724 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 11.5,-9.5 @@ -37158,7 +37099,7 @@ entities: - canCollide: False type: Physics - uid: 3725 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 10.5,-9.5 @@ -37169,7 +37110,7 @@ entities: - canCollide: False type: Physics - uid: 3726 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 9.5,-9.5 @@ -37180,7 +37121,7 @@ entities: - canCollide: False type: Physics - uid: 3727 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 8.5,-9.5 @@ -37191,7 +37132,7 @@ entities: - canCollide: False type: Physics - uid: 3728 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 8.5,-10.5 @@ -37202,7 +37143,7 @@ entities: - canCollide: False type: Physics - uid: 3729 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 8.5,-11.5 @@ -37213,7 +37154,7 @@ entities: - canCollide: False type: Physics - uid: 3730 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 8.5,-12.5 @@ -37224,7 +37165,7 @@ entities: - canCollide: False type: Physics - uid: 3731 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 8.5,-13.5 @@ -37235,7 +37176,7 @@ entities: - canCollide: False type: Physics - uid: 3732 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 8.5,-14.5 @@ -37246,7 +37187,7 @@ entities: - canCollide: False type: Physics - uid: 3733 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 8.5,-15.5 @@ -37257,7 +37198,7 @@ entities: - canCollide: False type: Physics - uid: 3734 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 8.5,-16.5 @@ -37268,7 +37209,7 @@ entities: - canCollide: False type: Physics - uid: 3735 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 7.5,-16.5 @@ -37279,7 +37220,7 @@ entities: - canCollide: False type: Physics - uid: 3736 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 7.5,-17.5 @@ -37288,7 +37229,7 @@ entities: - canCollide: False type: Physics - uid: 3737 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 15.5,-8.5 @@ -37299,7 +37240,7 @@ entities: - canCollide: False type: Physics - uid: 3738 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 15.5,-7.5 @@ -37310,7 +37251,7 @@ entities: - canCollide: False type: Physics - uid: 3739 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 15.5,-6.5 @@ -37321,7 +37262,7 @@ entities: - canCollide: False type: Physics - uid: 3740 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 15.5,-5.5 @@ -37332,7 +37273,7 @@ entities: - canCollide: False type: Physics - uid: 3741 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 15.5,-4.5 @@ -37343,7 +37284,7 @@ entities: - canCollide: False type: Physics - uid: 3742 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 15.5,-3.5 @@ -37354,7 +37295,7 @@ entities: - canCollide: False type: Physics - uid: 3743 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 15.5,-2.5 @@ -37365,7 +37306,7 @@ entities: - canCollide: False type: Physics - uid: 3744 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 15.5,-1.5 @@ -37376,7 +37317,7 @@ entities: - canCollide: False type: Physics - uid: 3745 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 15.5,-0.5 @@ -37387,7 +37328,7 @@ entities: - canCollide: False type: Physics - uid: 3746 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 15.5,0.5 @@ -37398,7 +37339,7 @@ entities: - canCollide: False type: Physics - uid: 3747 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 15.5,1.5 @@ -37409,7 +37350,7 @@ entities: - canCollide: False type: Physics - uid: 3748 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 16.5,1.5 @@ -37420,7 +37361,7 @@ entities: - canCollide: False type: Physics - uid: 3749 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 16.5,2.5 @@ -37429,7 +37370,7 @@ entities: - canCollide: False type: Physics - uid: 3750 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -0.5,-22.5 @@ -37438,7 +37379,7 @@ entities: - canCollide: False type: Physics - uid: 3751 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -0.5,-21.5 @@ -37447,7 +37388,7 @@ entities: - canCollide: False type: Physics - uid: 3752 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -0.5,-20.5 @@ -37458,7 +37399,7 @@ entities: - canCollide: False type: Physics - uid: 3753 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -16.5,15.5 @@ -37469,7 +37410,7 @@ entities: - canCollide: False type: Physics - uid: 3754 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -1.5,-19.5 @@ -37480,7 +37421,7 @@ entities: - canCollide: False type: Physics - uid: 3755 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -1.5,-18.5 @@ -37489,7 +37430,7 @@ entities: - canCollide: False type: Physics - uid: 3756 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -1.5,-20.5 @@ -37500,7 +37441,7 @@ entities: - canCollide: False type: Physics - uid: 3757 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -2.5,-20.5 @@ -37511,7 +37452,7 @@ entities: - canCollide: False type: Physics - uid: 3758 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -3.5,-20.5 @@ -37522,7 +37463,7 @@ entities: - canCollide: False type: Physics - uid: 3759 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -4.5,-20.5 @@ -37533,7 +37474,7 @@ entities: - canCollide: False type: Physics - uid: 3760 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -5.5,-20.5 @@ -37544,7 +37485,7 @@ entities: - canCollide: False type: Physics - uid: 3761 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -6.5,-20.5 @@ -37555,7 +37496,7 @@ entities: - canCollide: False type: Physics - uid: 3762 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -7.5,-20.5 @@ -37566,7 +37507,7 @@ entities: - canCollide: False type: Physics - uid: 3763 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -8.5,-20.5 @@ -37577,7 +37518,7 @@ entities: - canCollide: False type: Physics - uid: 3764 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -9.5,-20.5 @@ -37588,7 +37529,7 @@ entities: - canCollide: False type: Physics - uid: 3765 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -9.5,-21.5 @@ -37597,7 +37538,7 @@ entities: - canCollide: False type: Physics - uid: 3766 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -10.5,-20.5 @@ -37608,7 +37549,7 @@ entities: - canCollide: False type: Physics - uid: 3767 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -11.5,-20.5 @@ -37619,7 +37560,7 @@ entities: - canCollide: False type: Physics - uid: 3768 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -12.5,-20.5 @@ -37630,7 +37571,7 @@ entities: - canCollide: False type: Physics - uid: 3769 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -13.5,-20.5 @@ -37641,7 +37582,7 @@ entities: - canCollide: False type: Physics - uid: 3770 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -13.5,-19.5 @@ -37652,7 +37593,7 @@ entities: - canCollide: False type: Physics - uid: 3771 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -13.5,-18.5 @@ -37663,7 +37604,7 @@ entities: - canCollide: False type: Physics - uid: 3772 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -13.5,-17.5 @@ -37674,7 +37615,7 @@ entities: - canCollide: False type: Physics - uid: 3773 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -14.5,-17.5 @@ -37685,7 +37626,7 @@ entities: - canCollide: False type: Physics - uid: 3774 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -14.5,-16.5 @@ -37694,7 +37635,7 @@ entities: - canCollide: False type: Physics - uid: 3775 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 0.5,-6.5 @@ -37705,7 +37646,7 @@ entities: - canCollide: False type: Physics - uid: 3776 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 0.5,-7.5 @@ -37714,7 +37655,7 @@ entities: - canCollide: False type: Physics - uid: 3777 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 0.5,-8.5 @@ -37723,7 +37664,7 @@ entities: - canCollide: False type: Physics - uid: 3778 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -0.5,-8.5 @@ -37734,7 +37675,7 @@ entities: - canCollide: False type: Physics - uid: 3779 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -1.5,-8.5 @@ -37745,7 +37686,7 @@ entities: - canCollide: False type: Physics - uid: 3780 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -1.5,-9.5 @@ -37756,7 +37697,7 @@ entities: - canCollide: False type: Physics - uid: 3781 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -2.5,-9.5 @@ -37767,7 +37708,7 @@ entities: - canCollide: False type: Physics - uid: 3782 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -3.5,-9.5 @@ -37778,7 +37719,7 @@ entities: - canCollide: False type: Physics - uid: 3783 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -4.5,-9.5 @@ -37789,7 +37730,7 @@ entities: - canCollide: False type: Physics - uid: 3784 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -5.5,-9.5 @@ -37800,7 +37741,7 @@ entities: - canCollide: False type: Physics - uid: 3785 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -5.5,-8.5 @@ -37809,7 +37750,7 @@ entities: - canCollide: False type: Physics - uid: 3786 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -6.5,-9.5 @@ -37820,7 +37761,7 @@ entities: - canCollide: False type: Physics - uid: 3787 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -7.5,-9.5 @@ -37831,7 +37772,7 @@ entities: - canCollide: False type: Physics - uid: 3788 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -8.5,-9.5 @@ -37842,7 +37783,7 @@ entities: - canCollide: False type: Physics - uid: 3789 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -9.5,-9.5 @@ -37851,7 +37792,7 @@ entities: - canCollide: False type: Physics - uid: 3790 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -9.5,-8.5 @@ -37860,7 +37801,7 @@ entities: - canCollide: False type: Physics - uid: 3791 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -9.5,-7.5 @@ -37871,7 +37812,7 @@ entities: - canCollide: False type: Physics - uid: 3792 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -9.5,-6.5 @@ -37882,7 +37823,7 @@ entities: - canCollide: False type: Physics - uid: 3793 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -10.5,-6.5 @@ -37893,7 +37834,7 @@ entities: - canCollide: False type: Physics - uid: 3794 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -11.5,-6.5 @@ -37904,7 +37845,7 @@ entities: - canCollide: False type: Physics - uid: 3795 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -12.5,-6.5 @@ -37915,7 +37856,7 @@ entities: - canCollide: False type: Physics - uid: 3796 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -12.5,-5.5 @@ -37924,7 +37865,7 @@ entities: - canCollide: False type: Physics - uid: 3797 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -12.5,-4.5 @@ -37935,7 +37876,7 @@ entities: - canCollide: False type: Physics - uid: 3798 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -12.5,-3.5 @@ -37946,7 +37887,7 @@ entities: - canCollide: False type: Physics - uid: 3799 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -12.5,-2.5 @@ -37957,7 +37898,7 @@ entities: - canCollide: False type: Physics - uid: 3800 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -12.5,-1.5 @@ -37968,7 +37909,7 @@ entities: - canCollide: False type: Physics - uid: 3801 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -12.5,-0.5 @@ -37979,7 +37920,7 @@ entities: - canCollide: False type: Physics - uid: 3802 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -12.5,0.5 @@ -37990,7 +37931,7 @@ entities: - canCollide: False type: Physics - uid: 3803 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -12.5,1.5 @@ -38001,7 +37942,7 @@ entities: - canCollide: False type: Physics - uid: 3804 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -11.5,1.5 @@ -38012,7 +37953,7 @@ entities: - canCollide: False type: Physics - uid: 3805 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -11.5,2.5 @@ -38021,7 +37962,7 @@ entities: - canCollide: False type: Physics - uid: 3806 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -21.5,-10.5 @@ -38032,7 +37973,7 @@ entities: - canCollide: False type: Physics - uid: 3807 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -21.5,-9.5 @@ -38041,7 +37982,7 @@ entities: - canCollide: False type: Physics - uid: 3808 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -21.5,-8.5 @@ -38052,7 +37993,7 @@ entities: - canCollide: False type: Physics - uid: 3809 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -20.5,-8.5 @@ -38061,7 +38002,7 @@ entities: - canCollide: False type: Physics - uid: 3810 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -19.5,-8.5 @@ -38072,7 +38013,7 @@ entities: - canCollide: False type: Physics - uid: 3811 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -18.5,-8.5 @@ -38083,7 +38024,7 @@ entities: - canCollide: False type: Physics - uid: 3812 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -17.5,-8.5 @@ -38094,7 +38035,7 @@ entities: - canCollide: False type: Physics - uid: 3813 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -17.5,-9.5 @@ -38105,7 +38046,7 @@ entities: - canCollide: False type: Physics - uid: 3814 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -16.5,-9.5 @@ -38114,7 +38055,7 @@ entities: - canCollide: False type: Physics - uid: 3815 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -15.5,-9.5 @@ -38125,7 +38066,7 @@ entities: - canCollide: False type: Physics - uid: 3816 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -14.5,-9.5 @@ -38136,7 +38077,7 @@ entities: - canCollide: False type: Physics - uid: 3817 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -14.5,-8.5 @@ -38147,7 +38088,7 @@ entities: - canCollide: False type: Physics - uid: 3818 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -22.5,-8.5 @@ -38158,7 +38099,7 @@ entities: - canCollide: False type: Physics - uid: 3819 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -21.5,-11.5 @@ -38167,7 +38108,7 @@ entities: - canCollide: False type: Physics - uid: 3820 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -21.5,-12.5 @@ -38176,7 +38117,7 @@ entities: - canCollide: False type: Physics - uid: 3821 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -20.5,-12.5 @@ -38185,7 +38126,7 @@ entities: - canCollide: False type: Physics - uid: 3822 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -23.5,-8.5 @@ -38196,7 +38137,7 @@ entities: - canCollide: False type: Physics - uid: 3823 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -24.5,-8.5 @@ -38207,7 +38148,7 @@ entities: - canCollide: False type: Physics - uid: 3824 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -25.5,-8.5 @@ -38218,7 +38159,7 @@ entities: - canCollide: False type: Physics - uid: 3825 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -26.5,-8.5 @@ -38227,7 +38168,7 @@ entities: - canCollide: False type: Physics - uid: 3826 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -27.5,-8.5 @@ -38238,7 +38179,7 @@ entities: - canCollide: False type: Physics - uid: 3827 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -28.5,-8.5 @@ -38249,7 +38190,7 @@ entities: - canCollide: False type: Physics - uid: 3828 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -29.5,-8.5 @@ -38260,7 +38201,7 @@ entities: - canCollide: False type: Physics - uid: 3829 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -29.5,-7.5 @@ -38271,7 +38212,7 @@ entities: - canCollide: False type: Physics - uid: 3830 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -29.5,-6.5 @@ -38280,7 +38221,7 @@ entities: - canCollide: False type: Physics - uid: 3831 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -29.5,-5.5 @@ -38291,7 +38232,7 @@ entities: - canCollide: False type: Physics - uid: 3832 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -29.5,-4.5 @@ -38302,7 +38243,7 @@ entities: - canCollide: False type: Physics - uid: 3833 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -30.5,-4.5 @@ -38313,7 +38254,7 @@ entities: - canCollide: False type: Physics - uid: 3834 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -30.5,-3.5 @@ -38322,7 +38263,7 @@ entities: - canCollide: False type: Physics - uid: 3835 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -32.5,7.5 @@ -38331,7 +38272,7 @@ entities: - canCollide: False type: Physics - uid: 3836 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -32.5,8.5 @@ -38340,7 +38281,7 @@ entities: - canCollide: False type: Physics - uid: 3837 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -32.5,9.5 @@ -38349,7 +38290,7 @@ entities: - canCollide: False type: Physics - uid: 3838 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -33.5,9.5 @@ -38358,7 +38299,7 @@ entities: - canCollide: False type: Physics - uid: 3839 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -34.5,9.5 @@ -38369,7 +38310,7 @@ entities: - canCollide: False type: Physics - uid: 3840 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -35.5,9.5 @@ -38380,7 +38321,7 @@ entities: - canCollide: False type: Physics - uid: 3841 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -36.5,9.5 @@ -38391,7 +38332,7 @@ entities: - canCollide: False type: Physics - uid: 3842 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -37.5,9.5 @@ -38402,7 +38343,7 @@ entities: - canCollide: False type: Physics - uid: 3843 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -38.5,9.5 @@ -38413,7 +38354,7 @@ entities: - canCollide: False type: Physics - uid: 3844 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -38.5,10.5 @@ -38424,7 +38365,7 @@ entities: - canCollide: False type: Physics - uid: 3845 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -39.5,10.5 @@ -38435,7 +38376,7 @@ entities: - canCollide: False type: Physics - uid: 3846 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -39.5,11.5 @@ -38444,7 +38385,7 @@ entities: - canCollide: False type: Physics - uid: 3847 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -28.5,12.5 @@ -38453,7 +38394,7 @@ entities: - canCollide: False type: Physics - uid: 3848 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -31.5,9.5 @@ -38464,7 +38405,7 @@ entities: - canCollide: False type: Physics - uid: 3849 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -31.5,10.5 @@ -38475,7 +38416,7 @@ entities: - canCollide: False type: Physics - uid: 3850 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -31.5,11.5 @@ -38486,7 +38427,7 @@ entities: - canCollide: False type: Physics - uid: 3851 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -31.5,12.5 @@ -38497,7 +38438,7 @@ entities: - canCollide: False type: Physics - uid: 3852 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -31.5,13.5 @@ -38508,7 +38449,7 @@ entities: - canCollide: False type: Physics - uid: 3853 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -30.5,13.5 @@ -38519,7 +38460,7 @@ entities: - canCollide: False type: Physics - uid: 3854 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -29.5,13.5 @@ -38530,7 +38471,7 @@ entities: - canCollide: False type: Physics - uid: 3855 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -28.5,13.5 @@ -38541,7 +38482,7 @@ entities: - canCollide: False type: Physics - uid: 3856 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -15.5,16.5 @@ -38550,7 +38491,7 @@ entities: - canCollide: False type: Physics - uid: 3857 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -14.5,16.5 @@ -38561,7 +38502,7 @@ entities: - canCollide: False type: Physics - uid: 3858 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -13.5,16.5 @@ -38572,7 +38513,7 @@ entities: - canCollide: False type: Physics - uid: 3859 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -13.5,15.5 @@ -38583,7 +38524,7 @@ entities: - canCollide: False type: Physics - uid: 3860 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -13.5,14.5 @@ -38594,7 +38535,7 @@ entities: - canCollide: False type: Physics - uid: 3861 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -13.5,13.5 @@ -38605,7 +38546,7 @@ entities: - canCollide: False type: Physics - uid: 3862 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -12.5,13.5 @@ -38616,7 +38557,7 @@ entities: - canCollide: False type: Physics - uid: 3863 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -12.5,12.5 @@ -38625,7 +38566,7 @@ entities: - canCollide: False type: Physics - uid: 3864 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -11.5,13.5 @@ -38636,7 +38577,7 @@ entities: - canCollide: False type: Physics - uid: 3865 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -10.5,13.5 @@ -38645,7 +38586,7 @@ entities: - canCollide: False type: Physics - uid: 3866 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -9.5,13.5 @@ -38656,7 +38597,7 @@ entities: - canCollide: False type: Physics - uid: 3867 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -8.5,13.5 @@ -38667,7 +38608,7 @@ entities: - canCollide: False type: Physics - uid: 3868 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -7.5,13.5 @@ -38678,7 +38619,7 @@ entities: - canCollide: False type: Physics - uid: 3869 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -6.5,13.5 @@ -38689,7 +38630,7 @@ entities: - canCollide: False type: Physics - uid: 3870 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -5.5,13.5 @@ -38700,7 +38641,7 @@ entities: - canCollide: False type: Physics - uid: 3871 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -4.5,13.5 @@ -38711,7 +38652,7 @@ entities: - canCollide: False type: Physics - uid: 3872 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -3.5,13.5 @@ -38722,7 +38663,7 @@ entities: - canCollide: False type: Physics - uid: 3873 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -3.5,14.5 @@ -38733,7 +38674,7 @@ entities: - canCollide: False type: Physics - uid: 3874 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -3.5,15.5 @@ -38742,7 +38683,7 @@ entities: - canCollide: False type: Physics - uid: 3875 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -15.5,16.5 @@ -38751,7 +38692,7 @@ entities: - canCollide: False type: Physics - uid: 3876 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: -16.5,16.5 @@ -38779,7 +38720,7 @@ entities: light_bulb: !type:ContainerSlot {} type: ContainerContainer - uid: 3879 - type: ApcExtensionCable + type: CableApcExtension components: - pos: 22.5,-7.5 parent: 853 @@ -38826,7 +38767,7 @@ entities: parent: 853 type: Transform - powerLoad: 1 - type: PowerReceiver + type: ApcPowerReceiver - startingCharge: 30000 type: Battery - uid: 3884 @@ -38837,7 +38778,7 @@ entities: parent: 853 type: Transform - powerLoad: 1 - type: PowerReceiver + type: ApcPowerReceiver - startingCharge: 30000 type: Battery - uid: 3885 @@ -38848,7 +38789,7 @@ entities: parent: 853 type: Transform - powerLoad: 1 - type: PowerReceiver + type: ApcPowerReceiver - startingCharge: 30000 type: Battery - uid: 3886 @@ -38859,7 +38800,7 @@ entities: parent: 853 type: Transform - powerLoad: 1 - type: PowerReceiver + type: ApcPowerReceiver - startingCharge: 30000 type: Battery - uid: 3887 @@ -38870,7 +38811,7 @@ entities: parent: 853 type: Transform - powerLoad: 1 - type: PowerReceiver + type: ApcPowerReceiver - startingCharge: 30000 type: Battery - uid: 3888 @@ -38881,7 +38822,7 @@ entities: parent: 853 type: Transform - powerLoad: 1 - type: PowerReceiver + type: ApcPowerReceiver - startingCharge: 30000 type: Battery - uid: 3889 @@ -38892,7 +38833,7 @@ entities: parent: 853 type: Transform - powerLoad: 1 - type: PowerReceiver + type: ApcPowerReceiver - startingCharge: 30000 type: Battery - uid: 3890 @@ -38903,7 +38844,7 @@ entities: parent: 853 type: Transform - powerLoad: 1 - type: PowerReceiver + type: ApcPowerReceiver - startingCharge: 30000 type: Battery - uid: 3891 @@ -38914,7 +38855,7 @@ entities: parent: 853 type: Transform - powerLoad: 1 - type: PowerReceiver + type: ApcPowerReceiver - startingCharge: 30000 type: Battery - uid: 3892 @@ -38925,7 +38866,7 @@ entities: parent: 853 type: Transform - powerLoad: 1 - type: PowerReceiver + type: ApcPowerReceiver - startingCharge: 30000 type: Battery - uid: 3893 @@ -38936,7 +38877,7 @@ entities: parent: 853 type: Transform - powerLoad: 1 - type: PowerReceiver + type: ApcPowerReceiver - startingCharge: 30000 type: Battery - uid: 3894 @@ -38947,7 +38888,7 @@ entities: parent: 853 type: Transform - powerLoad: 1 - type: PowerReceiver + type: ApcPowerReceiver - startingCharge: 30000 type: Battery - uid: 3895 @@ -38958,7 +38899,7 @@ entities: parent: 853 type: Transform - powerLoad: 1 - type: PowerReceiver + type: ApcPowerReceiver - startingCharge: 30000 type: Battery - uid: 3896 @@ -38969,7 +38910,7 @@ entities: parent: 853 type: Transform - powerLoad: 1 - type: PowerReceiver + type: ApcPowerReceiver - startingCharge: 30000 type: Battery - uid: 3897 @@ -38980,7 +38921,7 @@ entities: parent: 853 type: Transform - powerLoad: 1 - type: PowerReceiver + type: ApcPowerReceiver - startingCharge: 30000 type: Battery - uid: 3898 @@ -38991,7 +38932,7 @@ entities: parent: 853 type: Transform - powerLoad: 1 - type: PowerReceiver + type: ApcPowerReceiver - startingCharge: 30000 type: Battery - uid: 3899 @@ -39002,7 +38943,7 @@ entities: parent: 853 type: Transform - powerLoad: 1 - type: PowerReceiver + type: ApcPowerReceiver - startingCharge: 30000 type: Battery - uid: 3900 @@ -39013,7 +38954,7 @@ entities: parent: 853 type: Transform - powerLoad: 1 - type: PowerReceiver + type: ApcPowerReceiver - startingCharge: 30000 type: Battery - uid: 3901 @@ -39024,7 +38965,7 @@ entities: parent: 853 type: Transform - powerLoad: 1 - type: PowerReceiver + type: ApcPowerReceiver - startingCharge: 30000 type: Battery - uid: 3902 @@ -39035,7 +38976,7 @@ entities: parent: 853 type: Transform - powerLoad: 1 - type: PowerReceiver + type: ApcPowerReceiver - startingCharge: 30000 type: Battery - uid: 3903 @@ -39046,7 +38987,7 @@ entities: parent: 853 type: Transform - powerLoad: 1 - type: PowerReceiver + type: ApcPowerReceiver - startingCharge: 30000 type: Battery - uid: 3904 @@ -39065,7 +39006,7 @@ entities: parent: 853 type: Transform - powerLoad: 1 - type: PowerReceiver + type: ApcPowerReceiver - startingCharge: 30000 type: Battery - uid: 3906 @@ -39076,7 +39017,7 @@ entities: parent: 853 type: Transform - powerLoad: 1 - type: PowerReceiver + type: ApcPowerReceiver - startingCharge: 30000 type: Battery - uid: 3907 @@ -39087,7 +39028,7 @@ entities: parent: 853 type: Transform - powerLoad: 1 - type: PowerReceiver + type: ApcPowerReceiver - startingCharge: 30000 type: Battery - uid: 3908 @@ -39098,7 +39039,7 @@ entities: parent: 853 type: Transform - powerLoad: 1 - type: PowerReceiver + type: ApcPowerReceiver - startingCharge: 30000 type: Battery - uid: 3909 @@ -39109,7 +39050,7 @@ entities: parent: 853 type: Transform - powerLoad: 1 - type: PowerReceiver + type: ApcPowerReceiver - startingCharge: 30000 type: Battery - uid: 3910 @@ -39120,11 +39061,11 @@ entities: parent: 853 type: Transform - powerLoad: 1 - type: PowerReceiver + type: ApcPowerReceiver - startingCharge: 30000 type: Battery - uid: 3911 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -24.5,10.5 @@ -39135,7 +39076,7 @@ entities: - canCollide: False type: Physics - uid: 3912 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -24.5,11.5 @@ -39146,7 +39087,7 @@ entities: - canCollide: False type: Physics - uid: 3913 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 41.5,7.5 @@ -39188,7 +39129,7 @@ entities: parent: 853 type: Transform - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: light_bulb: !type:ContainerSlot {} type: ContainerContainer @@ -39214,7 +39155,7 @@ entities: parent: 853 type: Transform - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: light_bulb: !type:ContainerSlot {} type: ContainerContainer @@ -39227,8 +39168,6 @@ entities: type: Transform - startingCharge: 11999.217 type: Battery - - drawRate: 2000 - type: PowerConsumer - uid: 3922 type: EmergencyLight components: @@ -39237,7 +39176,7 @@ entities: parent: 853 type: Transform - powerLoad: 1 - type: PowerReceiver + type: ApcPowerReceiver - startingCharge: 30000 type: Battery - uid: 3923 @@ -39248,7 +39187,7 @@ entities: parent: 853 type: Transform - powerLoad: 1 - type: PowerReceiver + type: ApcPowerReceiver - startingCharge: 30000 type: Battery - uid: 3924 @@ -39259,7 +39198,7 @@ entities: parent: 853 type: Transform - powerLoad: 1 - type: PowerReceiver + type: ApcPowerReceiver - startingCharge: 30000 type: Battery - uid: 3925 @@ -39270,7 +39209,7 @@ entities: parent: 853 type: Transform - powerLoad: 1 - type: PowerReceiver + type: ApcPowerReceiver - startingCharge: 30000 type: Battery - uid: 3926 @@ -39326,21 +39265,21 @@ entities: parent: 853 type: Transform - uid: 3933 - type: HVWireStack + type: CableHVStack components: - rot: 4.371139006309477E-08 rad pos: 50.5,4.5 parent: 853 type: Transform - uid: 3934 - type: MVWireStack + type: CableMVStack components: - rot: 4.371139006309477E-08 rad pos: 50.288177,4.693361 parent: 853 type: Transform - uid: 3935 - type: ApcExtensionCableStack + type: CableApcStack components: - rot: 4.371139006309477E-08 rad pos: 50.053802,4.474611 @@ -39408,7 +39347,7 @@ entities: - canCollide: False type: Physics - uid: 3944 - type: ApcExtensionCable + type: CableApcExtension components: - pos: 3.5,0.5 parent: 853 @@ -39418,7 +39357,7 @@ entities: - canCollide: False type: Physics - uid: 3945 - type: MVWire + type: CableMV components: - pos: 13.5,-24.5 parent: 853 @@ -39426,7 +39365,7 @@ entities: - canCollide: False type: Physics - uid: 3946 - type: MVWire + type: CableMV components: - pos: 13.5,-23.5 parent: 853 @@ -39434,7 +39373,7 @@ entities: - canCollide: False type: Physics - uid: 3947 - type: ApcExtensionCable + type: CableApcExtension components: - pos: 8.5,20.5 parent: 853 @@ -39462,7 +39401,7 @@ entities: - airBlocked: False type: Airtight - uid: 3950 - type: ApcExtensionCable + type: CableApcExtension components: - pos: 3.5,1.5 parent: 853 @@ -39526,7 +39465,7 @@ entities: - airBlocked: False type: Airtight - uid: 3957 - type: ApcExtensionCable + type: CableApcExtension components: - pos: 2.5,0.5 parent: 853 @@ -39536,7 +39475,7 @@ entities: - canCollide: False type: Physics - uid: 3958 - type: ApcExtensionCable + type: CableApcExtension components: - pos: 1.5,0.5 parent: 853 @@ -39582,7 +39521,7 @@ entities: - airBlocked: False type: Airtight - uid: 3963 - type: ApcExtensionCable + type: CableApcExtension components: - pos: -31.5,5.5 parent: 853 @@ -39592,7 +39531,7 @@ entities: - canCollide: False type: Physics - uid: 3964 - type: ApcExtensionCable + type: CableApcExtension components: - pos: 7.5,20.5 parent: 853 @@ -39620,7 +39559,7 @@ entities: - airBlocked: False type: Airtight - uid: 3967 - type: ApcExtensionCable + type: CableApcExtension components: - pos: -30.5,5.5 parent: 853 @@ -39630,7 +39569,7 @@ entities: - canCollide: False type: Physics - uid: 3968 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -23.5,5.5 @@ -39659,7 +39598,7 @@ entities: - airBlocked: False type: Airtight - uid: 3971 - type: ApcExtensionCable + type: CableApcExtension components: - pos: 12.5,-8.5 parent: 853 @@ -39688,7 +39627,7 @@ entities: - canCollide: False type: Physics - uid: 3974 - type: ApcExtensionCable + type: CableApcExtension components: - pos: 2.5,6.5 parent: 853 @@ -39698,7 +39637,7 @@ entities: - canCollide: False type: Physics - uid: 3975 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -26.5,7.5 @@ -39707,7 +39646,7 @@ entities: - canCollide: False type: Physics - uid: 3976 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -26.5,6.5 @@ -39716,7 +39655,7 @@ entities: - canCollide: False type: Physics - uid: 3977 - type: ApcExtensionCable + type: CableApcExtension components: - pos: -21.5,13.5 parent: 853 @@ -39735,7 +39674,7 @@ entities: - airBlocked: False type: Airtight - uid: 3979 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -26.5,6.5 @@ -39744,7 +39683,7 @@ entities: - canCollide: False type: Physics - uid: 3980 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -26.5,5.5 @@ -39762,7 +39701,7 @@ entities: parent: 853 type: Transform - uid: 3982 - type: ApcExtensionCable + type: CableApcExtension components: - pos: 3.5,6.5 parent: 853 @@ -39772,7 +39711,7 @@ entities: - canCollide: False type: Physics - uid: 3983 - type: ApcExtensionCable + type: CableApcExtension components: - pos: 4.5,6.5 parent: 853 @@ -39800,7 +39739,7 @@ entities: - airBlocked: False type: Airtight - uid: 3986 - type: ApcExtensionCable + type: CableApcExtension components: - pos: 12.5,-9.5 parent: 853 @@ -39846,7 +39785,7 @@ entities: - airBlocked: False type: Airtight - uid: 3991 - type: ApcExtensionCable + type: CableApcExtension components: - pos: -32.5,-8.5 parent: 853 @@ -39973,7 +39912,7 @@ entities: parent: 853 type: Transform - uid: 4005 - type: ApcExtensionCable + type: CableApcExtension components: - pos: -32.5,-7.5 parent: 853 @@ -40111,7 +40050,7 @@ entities: - canCollide: False type: Physics - uid: 4021 - type: ApcExtensionCable + type: CableApcExtension components: - pos: 23.5,-18.5 parent: 853 @@ -40331,7 +40270,7 @@ entities: parent: 853 type: Transform - uid: 4048 - type: ApcExtensionCable + type: CableApcExtension components: - pos: -18.5,13.5 parent: 853 @@ -40339,7 +40278,7 @@ entities: - canCollide: False type: Physics - uid: 4049 - type: ApcExtensionCable + type: CableApcExtension components: - pos: -17.5,13.5 parent: 853 @@ -40347,7 +40286,7 @@ entities: - canCollide: False type: Physics - uid: 4050 - type: ApcExtensionCable + type: CableApcExtension components: - pos: -17.5,14.5 parent: 853 @@ -40355,7 +40294,7 @@ entities: - canCollide: False type: Physics - uid: 4051 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: -5.5,-26.5 @@ -40372,7 +40311,7 @@ entities: - airBlocked: False type: Airtight - uid: 4053 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -5.5,-26.5 @@ -40389,7 +40328,7 @@ entities: - airBlocked: False type: Airtight - uid: 4055 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: -4.5,-26.5 @@ -40454,7 +40393,7 @@ entities: - airBlocked: False type: Airtight - uid: 4063 - type: ApcExtensionCable + type: CableApcExtension components: - pos: -20.5,13.5 parent: 853 @@ -40471,7 +40410,7 @@ entities: - airBlocked: False type: Airtight - uid: 4065 - type: ApcExtensionCable + type: CableApcExtension components: - pos: -8.5,-7.5 parent: 853 @@ -40481,7 +40420,7 @@ entities: - canCollide: False type: Physics - uid: 4066 - type: ApcExtensionCable + type: CableApcExtension components: - pos: -32.5,-6.5 parent: 853 @@ -40505,7 +40444,7 @@ entities: - airBlocked: False type: Airtight - uid: 4069 - type: ApcExtensionCable + type: CableApcExtension components: - pos: -26.5,4.5 parent: 853 @@ -40541,7 +40480,7 @@ entities: - airBlocked: False type: Airtight - uid: 4073 - type: ApcExtensionCable + type: CableApcExtension components: - pos: -19.5,13.5 parent: 853 @@ -40549,7 +40488,7 @@ entities: - canCollide: False type: Physics - uid: 4074 - type: ApcExtensionCable + type: CableApcExtension components: - pos: 0.5,6.5 parent: 853 @@ -40557,7 +40496,7 @@ entities: - canCollide: False type: Physics - uid: 4075 - type: ApcExtensionCable + type: CableApcExtension components: - pos: -0.5,6.5 parent: 853 @@ -40592,7 +40531,7 @@ entities: parent: 853 type: Transform - uid: 4080 - type: MVWire + type: CableMV components: - pos: -5.5,-7.5 parent: 853 @@ -40842,8 +40781,7 @@ entities: type: Transform - startingCharge: 11999.233 type: Battery - - drawRate: 2000 - type: PowerConsumer + - uid: 4112 type: Bed components: @@ -40870,7 +40808,7 @@ entities: parent: 853 type: Transform - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: light_bulb: !type:ContainerSlot {} type: ContainerContainer @@ -41434,7 +41372,7 @@ entities: ents: [] type: ContainerContainer - uid: 4183 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 26.5,-10.5 @@ -41443,7 +41381,7 @@ entities: - canCollide: False type: Physics - uid: 4184 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 25.5,-10.5 @@ -41739,7 +41677,7 @@ entities: parent: 853 type: Transform - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: WeaponCapacitorCharger-powerCellContainer: !type:ContainerSlot {} type: ContainerContainer @@ -41860,7 +41798,7 @@ entities: parent: 853 type: Transform - powerLoad: 0 - type: PowerReceiver + type: ApcPowerReceiver - containers: WeaponCapacitorCharger-powerCellContainer: !type:ContainerSlot {} type: ContainerContainer @@ -42480,7 +42418,7 @@ entities: light_bulb: !type:ContainerSlot {} type: ContainerContainer - uid: 4322 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 45.5,8.5 @@ -42491,7 +42429,7 @@ entities: - canCollide: False type: Physics - uid: 4323 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 46.5,8.5 @@ -42502,7 +42440,7 @@ entities: - canCollide: False type: Physics - uid: 4324 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 46.5,12.5 @@ -42513,7 +42451,7 @@ entities: - canCollide: False type: Physics - uid: 4325 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 47.5,9.5 @@ -42524,7 +42462,7 @@ entities: - canCollide: False type: Physics - uid: 4326 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 47.5,10.5 @@ -42535,7 +42473,7 @@ entities: - canCollide: False type: Physics - uid: 4327 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 47.5,11.5 @@ -42546,7 +42484,7 @@ entities: - canCollide: False type: Physics - uid: 4328 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 47.5,12.5 @@ -42557,7 +42495,7 @@ entities: - canCollide: False type: Physics - uid: 4329 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 47.5,8.5 @@ -42568,7 +42506,7 @@ entities: - canCollide: False type: Physics - uid: 4330 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 47.5,7.5 @@ -42579,7 +42517,7 @@ entities: - canCollide: False type: Physics - uid: 4331 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 49.5,12.5 @@ -42590,7 +42528,7 @@ entities: - canCollide: False type: Physics - uid: 4332 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 49.5,11.5 @@ -42601,7 +42539,7 @@ entities: - canCollide: False type: Physics - uid: 4333 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 49.5,10.5 @@ -42612,7 +42550,7 @@ entities: - canCollide: False type: Physics - uid: 4334 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 49.5,9.5 @@ -42623,7 +42561,7 @@ entities: - canCollide: False type: Physics - uid: 4335 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 49.5,8.5 @@ -42634,7 +42572,7 @@ entities: - canCollide: False type: Physics - uid: 4336 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 49.5,7.5 @@ -42645,7 +42583,7 @@ entities: - canCollide: False type: Physics - uid: 4337 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 48.5,9.5 @@ -42666,7 +42604,7 @@ entities: light_bulb: !type:ContainerSlot {} type: ContainerContainer - uid: 4339 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 42.5,7.5 @@ -42677,7 +42615,7 @@ entities: - canCollide: False type: Physics - uid: 4340 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 43.5,7.5 @@ -42688,7 +42626,7 @@ entities: - canCollide: False type: Physics - uid: 4341 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 44.5,7.5 @@ -42699,7 +42637,7 @@ entities: - canCollide: False type: Physics - uid: 4342 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 45.5,7.5 @@ -42710,7 +42648,7 @@ entities: - canCollide: False type: Physics - uid: 4343 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 46.5,7.5 @@ -42721,7 +42659,7 @@ entities: - canCollide: False type: Physics - uid: 4344 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 47.5,7.5 @@ -42732,7 +42670,7 @@ entities: - canCollide: False type: Physics - uid: 4345 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 48.5,7.5 @@ -42743,7 +42681,7 @@ entities: - canCollide: False type: Physics - uid: 4346 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 48.5,8.5 @@ -42754,7 +42692,7 @@ entities: - canCollide: False type: Physics - uid: 4347 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 48.5,9.5 @@ -42765,7 +42703,7 @@ entities: - canCollide: False type: Physics - uid: 4348 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 48.5,10.5 @@ -42776,7 +42714,7 @@ entities: - canCollide: False type: Physics - uid: 4349 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 48.5,11.5 @@ -42787,7 +42725,7 @@ entities: - canCollide: False type: Physics - uid: 4350 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 48.5,12.5 @@ -43237,7 +43175,7 @@ entities: parent: 853 type: Transform - uid: 4413 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 44.5,-12.5 @@ -43246,7 +43184,7 @@ entities: - canCollide: False type: Physics - uid: 4414 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 44.5,-11.5 @@ -43255,7 +43193,7 @@ entities: - canCollide: False type: Physics - uid: 4415 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 44.5,-10.5 @@ -43264,7 +43202,7 @@ entities: - canCollide: False type: Physics - uid: 4416 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 44.5,-9.5 @@ -43273,7 +43211,7 @@ entities: - canCollide: False type: Physics - uid: 4417 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 45.5,-9.5 @@ -43282,7 +43220,7 @@ entities: - canCollide: False type: Physics - uid: 4418 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 46.5,-9.5 @@ -43293,7 +43231,7 @@ entities: - canCollide: False type: Physics - uid: 4419 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 54.5,-12.5 @@ -43302,7 +43240,7 @@ entities: - canCollide: False type: Physics - uid: 4420 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 54.5,-11.5 @@ -43311,7 +43249,7 @@ entities: - canCollide: False type: Physics - uid: 4421 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 54.5,-10.5 @@ -43320,7 +43258,7 @@ entities: - canCollide: False type: Physics - uid: 4422 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 54.5,-9.5 @@ -43329,7 +43267,7 @@ entities: - canCollide: False type: Physics - uid: 4423 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 53.5,-9.5 @@ -43338,7 +43276,7 @@ entities: - canCollide: False type: Physics - uid: 4424 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 52.5,-9.5 @@ -43349,7 +43287,7 @@ entities: - canCollide: False type: Physics - uid: 4425 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 51.5,-9.5 @@ -43358,7 +43296,7 @@ entities: - canCollide: False type: Physics - uid: 4426 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 47.5,-9.5 @@ -43367,7 +43305,7 @@ entities: - canCollide: False type: Physics - uid: 4427 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 48.5,-9.5 @@ -43378,7 +43316,7 @@ entities: - canCollide: False type: Physics - uid: 4428 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 49.5,-9.5 @@ -43389,7 +43327,7 @@ entities: - canCollide: False type: Physics - uid: 4429 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 50.5,-9.5 @@ -43400,7 +43338,7 @@ entities: - canCollide: False type: Physics - uid: 4430 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 49.5,-8.5 @@ -43409,7 +43347,7 @@ entities: - canCollide: False type: Physics - uid: 4431 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 49.5,-7.5 @@ -43420,7 +43358,7 @@ entities: - canCollide: False type: Physics - uid: 4432 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 49.5,-6.5 @@ -43429,7 +43367,7 @@ entities: - canCollide: False type: Physics - uid: 4433 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 48.5,-6.5 @@ -43438,7 +43376,7 @@ entities: - canCollide: False type: Physics - uid: 4434 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 47.5,-6.5 @@ -43447,7 +43385,7 @@ entities: - canCollide: False type: Physics - uid: 4435 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 47.5,-5.5 @@ -43456,7 +43394,7 @@ entities: - canCollide: False type: Physics - uid: 4436 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 47.5,-4.5 @@ -43465,7 +43403,7 @@ entities: - canCollide: False type: Physics - uid: 4437 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 49.5,-10.5 @@ -43476,7 +43414,7 @@ entities: - canCollide: False type: Physics - uid: 4438 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 49.5,-11.5 @@ -43487,7 +43425,7 @@ entities: - canCollide: False type: Physics - uid: 4439 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 49.5,-12.5 @@ -43498,7 +43436,7 @@ entities: - canCollide: False type: Physics - uid: 4440 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 48.5,-11.5 @@ -43509,7 +43447,7 @@ entities: - canCollide: False type: Physics - uid: 4441 - type: ApcExtensionCable + type: CableApcExtension components: - rot: 4.371139006309477E-08 rad pos: 50.5,-11.5 @@ -43520,7 +43458,7 @@ entities: - canCollide: False type: Physics - uid: 4442 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 45.5,-11.5 @@ -43529,7 +43467,7 @@ entities: - canCollide: False type: Physics - uid: 4443 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 45.5,-10.5 @@ -43540,7 +43478,7 @@ entities: - canCollide: False type: Physics - uid: 4444 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 45.5,-12.5 @@ -43551,7 +43489,7 @@ entities: - canCollide: False type: Physics - uid: 4445 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 46.5,-11.5 @@ -43560,7 +43498,7 @@ entities: - canCollide: False type: Physics - uid: 4446 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 47.5,-11.5 @@ -43569,7 +43507,7 @@ entities: - canCollide: False type: Physics - uid: 4447 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 48.5,-11.5 @@ -43580,7 +43518,7 @@ entities: - canCollide: False type: Physics - uid: 4448 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 48.5,-10.5 @@ -43591,7 +43529,7 @@ entities: - canCollide: False type: Physics - uid: 4449 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 49.5,-10.5 @@ -43602,7 +43540,7 @@ entities: - canCollide: False type: Physics - uid: 4450 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 50.5,-10.5 @@ -43613,7 +43551,7 @@ entities: - canCollide: False type: Physics - uid: 4451 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 49.5,-12.5 @@ -43624,7 +43562,7 @@ entities: - canCollide: False type: Physics - uid: 4452 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 51.5,-11.5 @@ -43633,7 +43571,7 @@ entities: - canCollide: False type: Physics - uid: 4453 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 52.5,-11.5 @@ -43642,7 +43580,7 @@ entities: - canCollide: False type: Physics - uid: 4454 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 53.5,-11.5 @@ -43651,7 +43589,7 @@ entities: - canCollide: False type: Physics - uid: 4455 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 53.5,-10.5 @@ -43662,7 +43600,7 @@ entities: - canCollide: False type: Physics - uid: 4456 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 53.5,-12.5 @@ -43673,7 +43611,7 @@ entities: - canCollide: False type: Physics - uid: 4457 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 49.5,-9.5 @@ -43684,7 +43622,7 @@ entities: - canCollide: False type: Physics - uid: 4458 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 49.5,-8.5 @@ -43693,7 +43631,7 @@ entities: - canCollide: False type: Physics - uid: 4459 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 49.5,-7.5 @@ -43704,7 +43642,7 @@ entities: - canCollide: False type: Physics - uid: 4460 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 49.5,-6.5 @@ -43713,7 +43651,7 @@ entities: - canCollide: False type: Physics - uid: 4461 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 48.5,-6.5 @@ -43722,7 +43660,7 @@ entities: - canCollide: False type: Physics - uid: 4462 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 47.5,-6.5 @@ -43731,7 +43669,7 @@ entities: - canCollide: False type: Physics - uid: 4463 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 47.5,-5.5 @@ -43740,7 +43678,7 @@ entities: - canCollide: False type: Physics - uid: 4464 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 47.5,-4.5 @@ -43749,7 +43687,7 @@ entities: - canCollide: False type: Physics - uid: 4465 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 47.5,-3.5 @@ -43758,7 +43696,7 @@ entities: - canCollide: False type: Physics - uid: 4466 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 47.5,-2.5 @@ -43767,7 +43705,7 @@ entities: - canCollide: False type: Physics - uid: 4467 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 48.5,-2.5 @@ -43776,7 +43714,7 @@ entities: - canCollide: False type: Physics - uid: 4468 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 48.5,-1.5 @@ -43785,7 +43723,7 @@ entities: - canCollide: False type: Physics - uid: 4469 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 48.5,-0.5 @@ -43796,7 +43734,7 @@ entities: - canCollide: False type: Physics - uid: 4470 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 48.5,0.5 @@ -43807,7 +43745,7 @@ entities: - canCollide: False type: Physics - uid: 4471 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 48.5,1.5 @@ -43818,7 +43756,7 @@ entities: - canCollide: False type: Physics - uid: 4472 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 47.5,1.5 @@ -43829,7 +43767,7 @@ entities: - canCollide: False type: Physics - uid: 4473 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 46.5,1.5 @@ -43840,7 +43778,7 @@ entities: - canCollide: False type: Physics - uid: 4474 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 45.5,1.5 @@ -43851,7 +43789,7 @@ entities: - canCollide: False type: Physics - uid: 4475 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 44.5,1.5 @@ -43919,10 +43857,6 @@ entities: type: Transform - startingCharge: 3200136 type: Battery - - drawRate: 8000 - type: PowerConsumer - - supplyRate: 6000 - type: PowerSupplier - uid: 4482 type: SalternSubstation components: @@ -43932,10 +43866,6 @@ entities: type: Transform - startingCharge: 3200136 type: Battery - - drawRate: 8000 - type: PowerConsumer - - supplyRate: 6000 - type: PowerSupplier - uid: 4483 type: Poweredlight components: @@ -43977,7 +43907,7 @@ entities: light_bulb: !type:ContainerSlot {} type: ContainerContainer - uid: 4487 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 45.5,-10.5 @@ -43988,7 +43918,7 @@ entities: - canCollide: False type: Physics - uid: 4488 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 45.5,-11.5 @@ -43997,7 +43927,7 @@ entities: - canCollide: False type: Physics - uid: 4489 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 53.5,-10.5 @@ -44008,7 +43938,7 @@ entities: - canCollide: False type: Physics - uid: 4490 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 53.5,-11.5 @@ -44017,7 +43947,7 @@ entities: - canCollide: False type: Physics - uid: 4491 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 52.5,-11.5 @@ -44026,7 +43956,7 @@ entities: - canCollide: False type: Physics - uid: 4492 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 51.5,-11.5 @@ -44035,7 +43965,7 @@ entities: - canCollide: False type: Physics - uid: 4493 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 51.5,-12.5 @@ -44044,7 +43974,7 @@ entities: - canCollide: False type: Physics - uid: 4494 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 46.5,-11.5 @@ -44053,7 +43983,7 @@ entities: - canCollide: False type: Physics - uid: 4495 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 47.5,-11.5 @@ -44062,7 +43992,7 @@ entities: - canCollide: False type: Physics - uid: 4496 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 47.5,-12.5 @@ -44071,7 +44001,7 @@ entities: - canCollide: False type: Physics - uid: 4497 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 47.5,-13.5 @@ -44080,7 +44010,7 @@ entities: - canCollide: False type: Physics - uid: 4498 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 49.5,-13.5 @@ -44089,7 +44019,7 @@ entities: - canCollide: False type: Physics - uid: 4499 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 48.5,-13.5 @@ -44098,7 +44028,7 @@ entities: - canCollide: False type: Physics - uid: 4500 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 50.5,-13.5 @@ -44107,7 +44037,7 @@ entities: - canCollide: False type: Physics - uid: 4501 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 51.5,-13.5 @@ -44116,7 +44046,7 @@ entities: - canCollide: False type: Physics - uid: 4502 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 49.5,-14.5 @@ -44125,7 +44055,7 @@ entities: - canCollide: False type: Physics - uid: 4503 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 49.5,-15.5 @@ -44134,7 +44064,7 @@ entities: - canCollide: False type: Physics - uid: 4504 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 49.5,-16.5 @@ -44143,7 +44073,7 @@ entities: - canCollide: False type: Physics - uid: 4505 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 49.5,-17.5 @@ -44152,7 +44082,7 @@ entities: - canCollide: False type: Physics - uid: 4506 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 48.5,-17.5 @@ -44161,7 +44091,7 @@ entities: - canCollide: False type: Physics - uid: 4507 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 47.5,-17.5 @@ -44170,7 +44100,7 @@ entities: - canCollide: False type: Physics - uid: 4508 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 46.5,-17.5 @@ -44179,7 +44109,7 @@ entities: - canCollide: False type: Physics - uid: 4509 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 45.5,-17.5 @@ -44188,7 +44118,7 @@ entities: - canCollide: False type: Physics - uid: 4510 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 50.5,-17.5 @@ -44197,7 +44127,7 @@ entities: - canCollide: False type: Physics - uid: 4511 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 51.5,-17.5 @@ -44206,7 +44136,7 @@ entities: - canCollide: False type: Physics - uid: 4512 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 52.5,-17.5 @@ -44215,7 +44145,7 @@ entities: - canCollide: False type: Physics - uid: 4513 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 53.5,-17.5 @@ -44224,7 +44154,7 @@ entities: - canCollide: False type: Physics - uid: 4514 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 54.5,-17.5 @@ -44233,7 +44163,7 @@ entities: - canCollide: False type: Physics - uid: 4515 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 55.5,-17.5 @@ -44242,7 +44172,7 @@ entities: - canCollide: False type: Physics - uid: 4516 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 56.5,-17.5 @@ -44251,7 +44181,7 @@ entities: - canCollide: False type: Physics - uid: 4517 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 56.5,-18.5 @@ -44260,7 +44190,7 @@ entities: - canCollide: False type: Physics - uid: 4518 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 56.5,-19.5 @@ -44269,7 +44199,7 @@ entities: - canCollide: False type: Physics - uid: 4519 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 56.5,-20.5 @@ -44278,7 +44208,7 @@ entities: - canCollide: False type: Physics - uid: 4520 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 56.5,-21.5 @@ -44287,7 +44217,7 @@ entities: - canCollide: False type: Physics - uid: 4521 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 56.5,-22.5 @@ -44296,7 +44226,7 @@ entities: - canCollide: False type: Physics - uid: 4522 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 56.5,-23.5 @@ -44305,7 +44235,7 @@ entities: - canCollide: False type: Physics - uid: 4523 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 56.5,-24.5 @@ -44314,7 +44244,7 @@ entities: - canCollide: False type: Physics - uid: 4524 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 56.5,-25.5 @@ -44323,7 +44253,7 @@ entities: - canCollide: False type: Physics - uid: 4525 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 56.5,-26.5 @@ -44332,7 +44262,7 @@ entities: - canCollide: False type: Physics - uid: 4526 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 56.5,-27.5 @@ -44341,7 +44271,7 @@ entities: - canCollide: False type: Physics - uid: 4527 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 56.5,-28.5 @@ -44350,7 +44280,7 @@ entities: - canCollide: False type: Physics - uid: 4528 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 56.5,-29.5 @@ -44359,7 +44289,7 @@ entities: - canCollide: False type: Physics - uid: 4529 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 56.5,-30.5 @@ -44368,7 +44298,7 @@ entities: - canCollide: False type: Physics - uid: 4530 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 56.5,-31.5 @@ -44377,7 +44307,7 @@ entities: - canCollide: False type: Physics - uid: 4531 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 55.5,-31.5 @@ -44386,7 +44316,7 @@ entities: - canCollide: False type: Physics - uid: 4532 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 54.5,-31.5 @@ -44395,7 +44325,7 @@ entities: - canCollide: False type: Physics - uid: 4533 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 53.5,-31.5 @@ -44404,7 +44334,7 @@ entities: - canCollide: False type: Physics - uid: 4534 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 52.5,-31.5 @@ -44413,7 +44343,7 @@ entities: - canCollide: False type: Physics - uid: 4535 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 51.5,-31.5 @@ -44422,7 +44352,7 @@ entities: - canCollide: False type: Physics - uid: 4536 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 50.5,-31.5 @@ -44431,7 +44361,7 @@ entities: - canCollide: False type: Physics - uid: 4537 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 49.5,-31.5 @@ -44440,7 +44370,7 @@ entities: - canCollide: False type: Physics - uid: 4538 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 48.5,-31.5 @@ -44449,7 +44379,7 @@ entities: - canCollide: False type: Physics - uid: 4539 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 47.5,-31.5 @@ -44458,7 +44388,7 @@ entities: - canCollide: False type: Physics - uid: 4540 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 46.5,-31.5 @@ -44467,7 +44397,7 @@ entities: - canCollide: False type: Physics - uid: 4541 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 45.5,-31.5 @@ -44476,7 +44406,7 @@ entities: - canCollide: False type: Physics - uid: 4542 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 44.5,-31.5 @@ -44485,7 +44415,7 @@ entities: - canCollide: False type: Physics - uid: 4543 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 43.5,-31.5 @@ -44494,7 +44424,7 @@ entities: - canCollide: False type: Physics - uid: 4544 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 42.5,-31.5 @@ -44503,7 +44433,7 @@ entities: - canCollide: False type: Physics - uid: 4545 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 42.5,-30.5 @@ -44512,7 +44442,7 @@ entities: - canCollide: False type: Physics - uid: 4546 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 42.5,-29.5 @@ -44521,7 +44451,7 @@ entities: - canCollide: False type: Physics - uid: 4547 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 42.5,-28.5 @@ -44530,7 +44460,7 @@ entities: - canCollide: False type: Physics - uid: 4548 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 42.5,-27.5 @@ -44539,7 +44469,7 @@ entities: - canCollide: False type: Physics - uid: 4549 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 42.5,-26.5 @@ -44548,7 +44478,7 @@ entities: - canCollide: False type: Physics - uid: 4550 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 42.5,-25.5 @@ -44557,7 +44487,7 @@ entities: - canCollide: False type: Physics - uid: 4551 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 42.5,-22.5 @@ -44566,7 +44496,7 @@ entities: - canCollide: False type: Physics - uid: 4552 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 42.5,-23.5 @@ -44575,7 +44505,7 @@ entities: - canCollide: False type: Physics - uid: 4553 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 42.5,-24.5 @@ -44584,7 +44514,7 @@ entities: - canCollide: False type: Physics - uid: 4554 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 42.5,-21.5 @@ -44593,7 +44523,7 @@ entities: - canCollide: False type: Physics - uid: 4555 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 42.5,-20.5 @@ -44602,7 +44532,7 @@ entities: - canCollide: False type: Physics - uid: 4556 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 42.5,-19.5 @@ -44611,7 +44541,7 @@ entities: - canCollide: False type: Physics - uid: 4557 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 42.5,-18.5 @@ -44620,7 +44550,7 @@ entities: - canCollide: False type: Physics - uid: 4558 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 42.5,-17.5 @@ -44629,7 +44559,7 @@ entities: - canCollide: False type: Physics - uid: 4559 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 43.5,-17.5 @@ -44638,7 +44568,7 @@ entities: - canCollide: False type: Physics - uid: 4560 - type: MVWire + type: CableMV components: - rot: 4.371139006309477E-08 rad pos: 44.5,-17.5 @@ -44850,7 +44780,7 @@ entities: parent: 853 type: Transform - uid: 4590 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 49.5,-11.5 @@ -44931,7 +44861,7 @@ entities: parent: 853 type: Transform - uid: 4601 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 50.5,-11.5 @@ -45117,7 +45047,7 @@ entities: parent: 853 type: Transform - uid: 4627 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 46.5,-17.5 @@ -45126,7 +45056,7 @@ entities: - canCollide: False type: Physics - uid: 4628 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 47.5,-17.5 @@ -45135,7 +45065,7 @@ entities: - canCollide: False type: Physics - uid: 4629 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 48.5,-17.5 @@ -45144,7 +45074,7 @@ entities: - canCollide: False type: Physics - uid: 4630 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 49.5,-17.5 @@ -45153,7 +45083,7 @@ entities: - canCollide: False type: Physics - uid: 4631 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 50.5,-17.5 @@ -45162,7 +45092,7 @@ entities: - canCollide: False type: Physics - uid: 4632 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 51.5,-17.5 @@ -45171,7 +45101,7 @@ entities: - canCollide: False type: Physics - uid: 4633 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 52.5,-17.5 @@ -45180,7 +45110,7 @@ entities: - canCollide: False type: Physics - uid: 4634 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 53.5,-17.5 @@ -45189,7 +45119,7 @@ entities: - canCollide: False type: Physics - uid: 4635 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 45.5,-17.5 @@ -45198,7 +45128,7 @@ entities: - canCollide: False type: Physics - uid: 4636 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 44.5,-17.5 @@ -45207,7 +45137,7 @@ entities: - canCollide: False type: Physics - uid: 4637 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 43.5,-17.5 @@ -45216,7 +45146,7 @@ entities: - canCollide: False type: Physics - uid: 4638 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 42.5,-17.5 @@ -45225,7 +45155,7 @@ entities: - canCollide: False type: Physics - uid: 4639 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 54.5,-17.5 @@ -45234,7 +45164,7 @@ entities: - canCollide: False type: Physics - uid: 4640 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 55.5,-17.5 @@ -45243,7 +45173,7 @@ entities: - canCollide: False type: Physics - uid: 4641 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 56.5,-17.5 @@ -45252,7 +45182,7 @@ entities: - canCollide: False type: Physics - uid: 4642 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 57.5,-17.5 @@ -45261,7 +45191,7 @@ entities: - canCollide: False type: Physics - uid: 4643 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 58.5,-17.5 @@ -45270,7 +45200,7 @@ entities: - canCollide: False type: Physics - uid: 4644 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 58.5,-18.5 @@ -45279,7 +45209,7 @@ entities: - canCollide: False type: Physics - uid: 4645 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 58.5,-19.5 @@ -45288,7 +45218,7 @@ entities: - canCollide: False type: Physics - uid: 4646 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 58.5,-20.5 @@ -45297,7 +45227,7 @@ entities: - canCollide: False type: Physics - uid: 4647 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 58.5,-21.5 @@ -45306,7 +45236,7 @@ entities: - canCollide: False type: Physics - uid: 4648 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 58.5,-22.5 @@ -45315,7 +45245,7 @@ entities: - canCollide: False type: Physics - uid: 4649 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 57.5,-24.5 @@ -45324,7 +45254,7 @@ entities: - canCollide: False type: Physics - uid: 4650 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 58.5,-24.5 @@ -45333,7 +45263,7 @@ entities: - canCollide: False type: Physics - uid: 4651 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 58.5,-23.5 @@ -45342,7 +45272,7 @@ entities: - canCollide: False type: Physics - uid: 4652 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 41.5,-24.5 @@ -45351,7 +45281,7 @@ entities: - canCollide: False type: Physics - uid: 4653 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 40.5,-24.5 @@ -45360,7 +45290,7 @@ entities: - canCollide: False type: Physics - uid: 4654 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 40.5,-23.5 @@ -45369,7 +45299,7 @@ entities: - canCollide: False type: Physics - uid: 4655 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 40.5,-22.5 @@ -45378,7 +45308,7 @@ entities: - canCollide: False type: Physics - uid: 4656 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 40.5,-21.5 @@ -45387,7 +45317,7 @@ entities: - canCollide: False type: Physics - uid: 4657 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 40.5,-20.5 @@ -45396,7 +45326,7 @@ entities: - canCollide: False type: Physics - uid: 4658 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 40.5,-19.5 @@ -45405,7 +45335,7 @@ entities: - canCollide: False type: Physics - uid: 4659 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 40.5,-18.5 @@ -45414,7 +45344,7 @@ entities: - canCollide: False type: Physics - uid: 4660 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 40.5,-17.5 @@ -45423,7 +45353,7 @@ entities: - canCollide: False type: Physics - uid: 4661 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 41.5,-17.5 @@ -45432,7 +45362,7 @@ entities: - canCollide: False type: Physics - uid: 4662 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 42.5,-24.5 @@ -45441,7 +45371,7 @@ entities: - canCollide: False type: Physics - uid: 4663 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 42.5,-23.5 @@ -45450,7 +45380,7 @@ entities: - canCollide: False type: Physics - uid: 4664 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 42.5,-22.5 @@ -45459,7 +45389,7 @@ entities: - canCollide: False type: Physics - uid: 4665 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 42.5,-21.5 @@ -45468,7 +45398,7 @@ entities: - canCollide: False type: Physics - uid: 4666 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 42.5,-25.5 @@ -45477,7 +45407,7 @@ entities: - canCollide: False type: Physics - uid: 4667 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 42.5,-26.5 @@ -45486,7 +45416,7 @@ entities: - canCollide: False type: Physics - uid: 4668 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 42.5,-27.5 @@ -45495,7 +45425,7 @@ entities: - canCollide: False type: Physics - uid: 4669 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 56.5,-24.5 @@ -45504,7 +45434,7 @@ entities: - canCollide: False type: Physics - uid: 4670 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 56.5,-23.5 @@ -45513,7 +45443,7 @@ entities: - canCollide: False type: Physics - uid: 4671 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 56.5,-22.5 @@ -45522,7 +45452,7 @@ entities: - canCollide: False type: Physics - uid: 4672 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 56.5,-21.5 @@ -45531,7 +45461,7 @@ entities: - canCollide: False type: Physics - uid: 4673 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 56.5,-25.5 @@ -45540,7 +45470,7 @@ entities: - canCollide: False type: Physics - uid: 4674 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 56.5,-26.5 @@ -45549,7 +45479,7 @@ entities: - canCollide: False type: Physics - uid: 4675 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 56.5,-27.5 @@ -45558,7 +45488,7 @@ entities: - canCollide: False type: Physics - uid: 4676 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 49.5,-16.5 @@ -45567,7 +45497,7 @@ entities: - canCollide: False type: Physics - uid: 4677 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 49.5,-15.5 @@ -45576,7 +45506,7 @@ entities: - canCollide: False type: Physics - uid: 4678 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 49.5,-14.5 @@ -45585,7 +45515,7 @@ entities: - canCollide: False type: Physics - uid: 4679 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 49.5,-13.5 @@ -45608,7 +45538,7 @@ entities: parent: 853 type: Transform - uid: 4682 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 49.5,-31.5 @@ -45617,7 +45547,7 @@ entities: - canCollide: False type: Physics - uid: 4683 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 48.5,-31.5 @@ -45626,7 +45556,7 @@ entities: - canCollide: False type: Physics - uid: 4684 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 47.5,-31.5 @@ -45635,7 +45565,7 @@ entities: - canCollide: False type: Physics - uid: 4685 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 46.5,-31.5 @@ -45644,7 +45574,7 @@ entities: - canCollide: False type: Physics - uid: 4686 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 50.5,-31.5 @@ -45653,7 +45583,7 @@ entities: - canCollide: False type: Physics - uid: 4687 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 51.5,-31.5 @@ -45662,7 +45592,7 @@ entities: - canCollide: False type: Physics - uid: 4688 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 52.5,-31.5 @@ -45671,7 +45601,7 @@ entities: - canCollide: False type: Physics - uid: 4689 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 49.5,-32.5 @@ -45680,7 +45610,7 @@ entities: - canCollide: False type: Physics - uid: 4690 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 49.5,-33.5 @@ -45689,7 +45619,7 @@ entities: - canCollide: False type: Physics - uid: 4691 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 48.5,-33.5 @@ -45698,7 +45628,7 @@ entities: - canCollide: False type: Physics - uid: 4692 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 47.5,-33.5 @@ -45707,7 +45637,7 @@ entities: - canCollide: False type: Physics - uid: 4693 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 46.5,-33.5 @@ -45716,7 +45646,7 @@ entities: - canCollide: False type: Physics - uid: 4694 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 45.5,-33.5 @@ -45725,7 +45655,7 @@ entities: - canCollide: False type: Physics - uid: 4695 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 44.5,-33.5 @@ -45734,7 +45664,7 @@ entities: - canCollide: False type: Physics - uid: 4696 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 43.5,-33.5 @@ -45743,7 +45673,7 @@ entities: - canCollide: False type: Physics - uid: 4697 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 42.5,-33.5 @@ -45752,7 +45682,7 @@ entities: - canCollide: False type: Physics - uid: 4698 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 41.5,-33.5 @@ -45761,7 +45691,7 @@ entities: - canCollide: False type: Physics - uid: 4699 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 40.5,-33.5 @@ -45770,7 +45700,7 @@ entities: - canCollide: False type: Physics - uid: 4700 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 40.5,-32.5 @@ -45779,7 +45709,7 @@ entities: - canCollide: False type: Physics - uid: 4701 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 40.5,-31.5 @@ -45788,7 +45718,7 @@ entities: - canCollide: False type: Physics - uid: 4702 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 40.5,-30.5 @@ -45797,7 +45727,7 @@ entities: - canCollide: False type: Physics - uid: 4703 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 40.5,-29.5 @@ -45806,7 +45736,7 @@ entities: - canCollide: False type: Physics - uid: 4704 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 40.5,-28.5 @@ -45815,7 +45745,7 @@ entities: - canCollide: False type: Physics - uid: 4705 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 40.5,-27.5 @@ -45824,7 +45754,7 @@ entities: - canCollide: False type: Physics - uid: 4706 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 40.5,-26.5 @@ -45833,7 +45763,7 @@ entities: - canCollide: False type: Physics - uid: 4707 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 40.5,-25.5 @@ -45842,7 +45772,7 @@ entities: - canCollide: False type: Physics - uid: 4708 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 50.5,-33.5 @@ -45851,7 +45781,7 @@ entities: - canCollide: False type: Physics - uid: 4709 - type: HVWire + type: CableHV components: - rot: 4.371139006309477E-08 rad pos: 51.5,-33.5 @@ -45912,10 +45842,6 @@ entities: type: Transform - startingCharge: 3969174 type: Battery - - drawRate: 8000 - type: PowerConsumer - - supplyRate: 6000 - type: PowerSupplier - uid: 4717 type: HydroponicsToolSpade components: @@ -46152,7 +46078,7 @@ entities: ents: [] type: ContainerContainer - uid: 4746 - type: ApcExtensionCable + type: CableApcExtension components: - pos: 7.5,-29.5 parent: 853 @@ -46332,7 +46258,7 @@ entities: parent: 853 type: Transform - uid: 4769 - type: ApcExtensionCable + type: CableApcExtension components: - pos: 8.5,-29.5 parent: 853 @@ -46351,7 +46277,7 @@ entities: - canCollide: False type: Physics - uid: 4771 - type: ApcExtensionCable + type: CableApcExtension components: - pos: 5.5,-25.5 parent: 853 @@ -46359,7 +46285,7 @@ entities: - canCollide: False type: Physics - uid: 4772 - type: ApcExtensionCable + type: CableApcExtension components: - pos: 6.5,-28.5 parent: 853 @@ -46411,7 +46337,7 @@ entities: parent: 853 type: Transform - uid: 4778 - type: ApcExtensionCable + type: CableApcExtension components: - pos: 6.5,-29.5 parent: 853 @@ -46421,7 +46347,7 @@ entities: - canCollide: False type: Physics - uid: 4779 - type: ApcExtensionCable + type: CableApcExtension components: - pos: 4.5,-29.5 parent: 853 @@ -46431,7 +46357,7 @@ entities: - canCollide: False type: Physics - uid: 4780 - type: ApcExtensionCable + type: CableApcExtension components: - pos: 5.5,-29.5 parent: 853 @@ -46439,7 +46365,7 @@ entities: - canCollide: False type: Physics - uid: 4781 - type: ApcExtensionCable + type: CableApcExtension components: - pos: 6.5,-27.5 parent: 853 @@ -46468,7 +46394,7 @@ entities: light_bulb: !type:ContainerSlot {} type: ContainerContainer - uid: 4784 - type: ApcExtensionCable + type: CableApcExtension components: - rot: -1.5707963267948966 rad pos: 13.5,-23.5 @@ -46477,7 +46403,7 @@ entities: - canCollide: False type: Physics - uid: 4785 - type: ApcExtensionCable + type: CableApcExtension components: - rot: -1.5707963267948966 rad pos: 12.5,-23.5 @@ -46488,7 +46414,7 @@ entities: - canCollide: False type: Physics - uid: 4786 - type: ApcExtensionCable + type: CableApcExtension components: - rot: -1.5707963267948966 rad pos: 12.5,-24.5 @@ -46499,7 +46425,7 @@ entities: - canCollide: False type: Physics - uid: 4787 - type: ApcExtensionCable + type: CableApcExtension components: - rot: -1.5707963267948966 rad pos: 12.5,-24.5 @@ -46510,7 +46436,7 @@ entities: - canCollide: False type: Physics - uid: 4788 - type: ApcExtensionCable + type: CableApcExtension components: - rot: -1.5707963267948966 rad pos: 12.5,-25.5 @@ -46521,7 +46447,7 @@ entities: - canCollide: False type: Physics - uid: 4789 - type: ApcExtensionCable + type: CableApcExtension components: - rot: -1.5707963267948966 rad pos: 12.5,-25.5 @@ -46532,7 +46458,7 @@ entities: - canCollide: False type: Physics - uid: 4790 - type: ApcExtensionCable + type: CableApcExtension components: - rot: -1.5707963267948966 rad pos: 12.5,-26.5 @@ -46543,7 +46469,7 @@ entities: - canCollide: False type: Physics - uid: 4791 - type: ApcExtensionCable + type: CableApcExtension components: - rot: -1.5707963267948966 rad pos: 12.5,-26.5 @@ -46554,7 +46480,7 @@ entities: - canCollide: False type: Physics - uid: 4792 - type: ApcExtensionCable + type: CableApcExtension components: - rot: -1.5707963267948966 rad pos: 12.5,-27.5 @@ -46565,7 +46491,7 @@ entities: - canCollide: False type: Physics - uid: 4793 - type: ApcExtensionCable + type: CableApcExtension components: - rot: -1.5707963267948966 rad pos: 12.5,-27.5 @@ -46576,7 +46502,7 @@ entities: - canCollide: False type: Physics - uid: 4794 - type: ApcExtensionCable + type: CableApcExtension components: - rot: -1.5707963267948966 rad pos: 12.5,-28.5 @@ -46585,7 +46511,7 @@ entities: - canCollide: False type: Physics - uid: 4795 - type: ApcExtensionCable + type: CableApcExtension components: - rot: -1.5707963267948966 rad pos: 12.5,-29.5 @@ -46596,7 +46522,7 @@ entities: - canCollide: False type: Physics - uid: 4796 - type: ApcExtensionCable + type: CableApcExtension components: - rot: -1.5707963267948966 rad pos: 11.5,-29.5 @@ -46607,7 +46533,7 @@ entities: - canCollide: False type: Physics - uid: 4797 - type: ApcExtensionCable + type: CableApcExtension components: - rot: -1.5707963267948966 rad pos: 10.5,-29.5 @@ -46616,7 +46542,7 @@ entities: - canCollide: False type: Physics - uid: 4798 - type: ApcExtensionCable + type: CableApcExtension components: - rot: -1.5707963267948966 rad pos: 9.5,-29.5 @@ -46627,7 +46553,7 @@ entities: - canCollide: False type: Physics - uid: 4799 - type: ApcExtensionCable + type: CableApcExtension components: - rot: -1.5707963267948966 rad pos: 12.5,-23.5 @@ -46638,7 +46564,7 @@ entities: - canCollide: False type: Physics - uid: 4800 - type: ApcExtensionCable + type: CableApcExtension components: - rot: -1.5707963267948966 rad pos: 11.5,-23.5 @@ -46649,7 +46575,7 @@ entities: - canCollide: False type: Physics - uid: 4801 - type: ApcExtensionCable + type: CableApcExtension components: - rot: -1.5707963267948966 rad pos: 10.5,-23.5 @@ -46660,7 +46586,7 @@ entities: - canCollide: False type: Physics - uid: 4802 - type: ApcExtensionCable + type: CableApcExtension components: - rot: -1.5707963267948966 rad pos: 9.5,-23.5 @@ -46951,7 +46877,7 @@ entities: ents: [] type: ContainerContainer - uid: 4832 - type: HVWire + type: CableHV components: - pos: 3.5,-24.5 parent: 853 @@ -46961,7 +46887,7 @@ entities: - canCollide: False type: Physics - uid: 4833 - type: HVWire + type: CableHV components: - pos: 3.5,-25.5 parent: 853 @@ -46971,7 +46897,7 @@ entities: - canCollide: False type: Physics - uid: 4834 - type: HVWire + type: CableHV components: - pos: 3.5,-26.5 parent: 853 @@ -46981,7 +46907,7 @@ entities: - canCollide: False type: Physics - uid: 4835 - type: HVWire + type: CableHV components: - pos: 3.5,-27.5 parent: 853 @@ -46991,7 +46917,7 @@ entities: - canCollide: False type: Physics - uid: 4836 - type: HVWire + type: CableHV components: - pos: 3.5,-28.5 parent: 853 @@ -47088,7 +47014,7 @@ entities: parent: 853 type: Transform - uid: 4850 - type: ApcExtensionCable + type: CableApcExtension components: - pos: 6.5,-26.5 parent: 853 @@ -47098,7 +47024,7 @@ entities: - canCollide: False type: Physics - uid: 4851 - type: ApcExtensionCable + type: CableApcExtension components: - pos: 6.5,-25.5 parent: 853 @@ -47138,7 +47064,7 @@ entities: light_bulb: !type:ContainerSlot {} type: ContainerContainer - uid: 4855 - type: ApcExtensionCable + type: CableApcExtension components: - pos: 8.5,-23.5 parent: 853 @@ -47148,7 +47074,7 @@ entities: - canCollide: False type: Physics - uid: 4856 - type: ApcExtensionCable + type: CableApcExtension components: - pos: 7.5,-23.5 parent: 853 @@ -47164,7 +47090,7 @@ entities: parent: 853 type: Transform - uid: 4858 - type: ApcExtensionCable + type: CableApcExtension components: - pos: 4.5,-25.5 parent: 853 @@ -47340,7 +47266,7 @@ entities: ents: [] type: ContainerContainer - uid: 4885 - type: ApcExtensionCable + type: CableApcExtension components: - pos: -15.5,-10.5 parent: 853 @@ -47356,7 +47282,7 @@ entities: parent: 853 type: Transform - uid: 4887 - type: ApcExtensionCable + type: CableApcExtension components: - pos: -13.5,-10.5 parent: 853 @@ -47376,7 +47302,7 @@ entities: light_bulb: !type:ContainerSlot {} type: ContainerContainer - uid: 4889 - type: ApcExtensionCable + type: CableApcExtension components: - pos: 11.5,20.5 parent: 853 @@ -47386,7 +47312,7 @@ entities: - canCollide: False type: Physics - uid: 4890 - type: ApcExtensionCable + type: CableApcExtension components: - pos: 12.5,20.5 parent: 853 @@ -47394,7 +47320,7 @@ entities: - canCollide: False type: Physics - uid: 4891 - type: ApcExtensionCable + type: CableApcExtension components: - pos: 12.5,21.5 parent: 853 @@ -47404,7 +47330,7 @@ entities: - canCollide: False type: Physics - uid: 4892 - type: ApcExtensionCable + type: CableApcExtension components: - pos: 12.5,22.5 parent: 853 @@ -47414,7 +47340,7 @@ entities: - canCollide: False type: Physics - uid: 4893 - type: ApcExtensionCable + type: CableApcExtension components: - pos: 12.5,23.5 parent: 853 diff --git a/Resources/Prototypes/Catalog/Fills/Crates/engineering.yml b/Resources/Prototypes/Catalog/Fills/Crates/engineering.yml index 88e7b10c28..de38aab797 100644 --- a/Resources/Prototypes/Catalog/Fills/Crates/engineering.yml +++ b/Resources/Prototypes/Catalog/Fills/Crates/engineering.yml @@ -51,7 +51,7 @@ components: - type: StorageFill contents: - - id: ApcExtensionCableStack + - id: CableApcStack amount: 3 - type: entity @@ -61,7 +61,7 @@ components: - type: StorageFill contents: - - id: MVWireStack + - id: CableMVStack amount: 3 - type: entity @@ -71,7 +71,7 @@ components: - type: StorageFill contents: - - id: HVWireStack + - id: CableHVStack amount: 3 - type: entity @@ -81,9 +81,9 @@ components: - type: StorageFill contents: - - id: HVWireStack + - id: CableHVStack amount: 2 - - id: MVWireStack + - id: CableMVStack amount: 2 - - id: ApcExtensionCableStack + - id: CableApcStack amount: 2 diff --git a/Resources/Prototypes/Catalog/Fills/Items/belt.yml b/Resources/Prototypes/Catalog/Fills/Items/belt.yml index 893dc3231b..f67ff53d7c 100644 --- a/Resources/Prototypes/Catalog/Fills/Items/belt.yml +++ b/Resources/Prototypes/Catalog/Fills/Items/belt.yml @@ -24,7 +24,7 @@ - id: Crowbar - id: WelderExperimental - id: Multitool - - id: ApcExtensionCableStack + - id: CableApcStack - type: entity id: ClothingBeltSecurityFilled diff --git a/Resources/Prototypes/Catalog/Fills/Items/toolboxes.yml b/Resources/Prototypes/Catalog/Fills/Items/toolboxes.yml index 018414e302..4d367f3c09 100644 --- a/Resources/Prototypes/Catalog/Fills/Items/toolboxes.yml +++ b/Resources/Prototypes/Catalog/Fills/Items/toolboxes.yml @@ -30,12 +30,12 @@ - id: Screwdriver - id: Crowbar - id: Wirecutter - - id: ApcExtensionCableStack - - id: MVWireStack + - id: CableApcStack + - id: CableMVStack - id: ClothingHandsGlovesColorYellow prob: 0.05 orGroup: GlovesOrWires - - id: HVWireStack + - id: CableHVStack orGroup: GlovesOrWires - type: entity diff --git a/Resources/Prototypes/Catalog/Fills/Lockers/engineer.yml b/Resources/Prototypes/Catalog/Fills/Lockers/engineer.yml index b92e47ec69..c44efffef7 100644 --- a/Resources/Prototypes/Catalog/Fills/Lockers/engineer.yml +++ b/Resources/Prototypes/Catalog/Fills/Lockers/engineer.yml @@ -27,11 +27,11 @@ prob: 0.05 - id: ClothingHeadHatHardhatRed prob: 0.4 - - id: ApcExtensionCableStack + - id: CableApcStack prob: 0.3 - - id: ApcExtensionCableStack + - id: CableApcStack prob: 0.3 - - id: ApcExtensionCableStack + - id: CableApcStack prob: 0.3 - type: entity @@ -47,9 +47,9 @@ prob: 0.05 - id: APCElectronics prob: 0.1 - - id: MVWireStack + - id: CableMVStack prob: 0.2 - - id: ApcExtensionCableStack + - id: CableApcStack prob: 0.3 - type: entity @@ -91,7 +91,7 @@ - id: OxygenTankFilled - id: ClothingShoesBootsMag prob: 0.15 - + - type: entity id: LockerRadiationSuitFilled parent: LockerRadiationSuit diff --git a/Resources/Prototypes/Catalog/Research/technologies.yml b/Resources/Prototypes/Catalog/Research/technologies.yml index 9645d50403..2978056ac6 100644 --- a/Resources/Prototypes/Catalog/Research/technologies.yml +++ b/Resources/Prototypes/Catalog/Research/technologies.yml @@ -16,7 +16,7 @@ - type: technology name: "cleaning technology" - id: MopBucket + id: MopBucket description: Start to a shiny clean station icon: sprite: Objects/Specific/Janitorial/janitorial.rsi @@ -44,7 +44,7 @@ unlockedRecipes: - Scythe - Hatchet - - KitchenKnife + - KitchenKnife - type: technology name: "advanced botany" @@ -234,8 +234,8 @@ - BasicResearch unlockedRecipes: - CableStack - - MVWireStack - - HVWireStack + - CableMVStack + - CableHVStack - LightBulb - LightTube - FirelockElectronics @@ -253,4 +253,4 @@ # state: icon # requiredPoints: 999999 # requiredTechnologies: -# - BasicResearch \ No newline at end of file +# - BasicResearch diff --git a/Resources/Prototypes/Catalog/VendingMachines/Inventories/youtool.yml b/Resources/Prototypes/Catalog/VendingMachines/Inventories/youtool.yml index 233b9ccde1..10938a6eaa 100644 --- a/Resources/Prototypes/Catalog/VendingMachines/Inventories/youtool.yml +++ b/Resources/Prototypes/Catalog/VendingMachines/Inventories/youtool.yml @@ -5,7 +5,7 @@ animationDuration: 1.1 spriteName: youtool startingInventory: - ApcExtensionCableStack1: 10 + CableApcStack1: 10 Crowbar: 5 Welder: 3 Wirecutter: 5 diff --git a/Resources/Prototypes/Entities/Constructible/Doors/airlock_base.yml b/Resources/Prototypes/Entities/Constructible/Doors/airlock_base.yml index 77436e43f9..523a1e4c62 100644 --- a/Resources/Prototypes/Entities/Constructible/Doors/airlock_base.yml +++ b/Resources/Prototypes/Entities/Constructible/Doors/airlock_base.yml @@ -46,7 +46,7 @@ close_sound: /Audio/Machines/airlock_close.ogg deny_sound: /Audio/Machines/airlock_deny.ogg - type: WiresVisualizer - - type: PowerReceiver + - type: ApcPowerReceiver - type: Wires BoardName: "Airlock Control" LayoutId: Airlock diff --git a/Resources/Prototypes/Entities/Constructible/Power/Engines/AME/controller.yml b/Resources/Prototypes/Entities/Constructible/Power/Engines/AME/controller.yml index ef85ffa558..c34c0821b9 100644 --- a/Resources/Prototypes/Entities/Constructible/Power/Engines/AME/controller.yml +++ b/Resources/Prototypes/Entities/Constructible/Power/Engines/AME/controller.yml @@ -54,12 +54,12 @@ examinable: true nodes: ame: - !type:AdjacentNode + !type:CableDeviceNode nodeGroupID: AMEngine input: - !type:AdjacentNode + !type:CableDeviceNode nodeGroupID: HVPower - - type: PowerReceiver + - type: ApcPowerReceiver - type: PowerSupplier supplyRate: 0 diff --git a/Resources/Prototypes/Entities/Constructible/Power/Engines/PA/control_box.yml b/Resources/Prototypes/Entities/Constructible/Power/Engines/PA/control_box.yml index 65e8d061cb..14494511f7 100644 --- a/Resources/Prototypes/Entities/Constructible/Power/Engines/PA/control_box.yml +++ b/Resources/Prototypes/Entities/Constructible/Power/Engines/PA/control_box.yml @@ -17,7 +17,7 @@ visuals: - type: ParticleAcceleratorPartVisualizer baseState: unlit - - type: PowerReceiver + - type: ApcPowerReceiver - type: ParticleAcceleratorControlBox - type: Construction graph: particleAcceleratorControlBox diff --git a/Resources/Prototypes/Entities/Constructible/Power/Engines/PA/power_box.yml b/Resources/Prototypes/Entities/Constructible/Power/Engines/PA/power_box.yml index 81fd4cd3ba..b9b24c7d43 100644 --- a/Resources/Prototypes/Entities/Constructible/Power/Engines/PA/power_box.yml +++ b/Resources/Prototypes/Entities/Constructible/Power/Engines/PA/power_box.yml @@ -24,7 +24,7 @@ examinable: true nodes: input: - !type:AdjacentNode + !type:CableDeviceNode nodeGroupID: HVPower - type: Construction graph: particleAcceleratorPowerBox diff --git a/Resources/Prototypes/Entities/Constructible/Power/Engines/Singularity/collector.yml b/Resources/Prototypes/Entities/Constructible/Power/Engines/Singularity/collector.yml index 2fae75c43c..b5e8c6ea33 100644 --- a/Resources/Prototypes/Entities/Constructible/Power/Engines/Singularity/collector.yml +++ b/Resources/Prototypes/Entities/Constructible/Power/Engines/Singularity/collector.yml @@ -36,7 +36,7 @@ examinable: true nodes: input: - !type:AdjacentNode + !type:CableDeviceNode nodeGroupID: HVPower - type: RadiationCollector # Note that this doesn't matter too much (see next comment) @@ -47,8 +47,10 @@ - type: BatteryDischarger # This is JUST a default. It has to be dynamically adjusted to ensure that the battery doesn't discharge "too fast" & run out immediately, while still scaling by input power. activeSupplyRate: 100000 - - type: PowerSupplier - supplyRate: 0 - type: Anchorable - type: Rotatable - type: Pullable + - type: PowerNetworkBattery + maxSupply: 1000000000 + supplyRampTolerance: 1000000000 + diff --git a/Resources/Prototypes/Entities/Constructible/Power/Engines/Singularity/emitter.yml b/Resources/Prototypes/Entities/Constructible/Power/Engines/Singularity/emitter.yml index 1067d20264..c8ba2e3832 100644 --- a/Resources/Prototypes/Entities/Constructible/Power/Engines/Singularity/emitter.yml +++ b/Resources/Prototypes/Entities/Constructible/Power/Engines/Singularity/emitter.yml @@ -41,7 +41,7 @@ examinable: true nodes: input: - !type:AdjacentNode + !type:CableDeviceNode nodeGroupID: MVPower - type: Damageable resistances: metallicResistances diff --git a/Resources/Prototypes/Entities/Constructible/Power/Generation/generator.yml b/Resources/Prototypes/Entities/Constructible/Power/Generation/generator.yml index 45091750d8..6772432f48 100644 --- a/Resources/Prototypes/Entities/Constructible/Power/Generation/generator.yml +++ b/Resources/Prototypes/Entities/Constructible/Power/Generation/generator.yml @@ -33,12 +33,11 @@ examinable: true nodes: output: - !type:AdjacentNode + !type:CableDeviceNode nodeGroupID: HVPower - type: PowerSupplier supplyRate: 3000 + supplyRampRate: 500 + supplyRampTolerance: 500 - type: Anchorable - type: Pullable - - type: ClientEntitySpawner - prototypes: - - HVDummyWire diff --git a/Resources/Prototypes/Entities/Constructible/Power/Generation/solar.yml b/Resources/Prototypes/Entities/Constructible/Power/Generation/solar.yml index 9f852d0c9a..0daea56341 100644 --- a/Resources/Prototypes/Entities/Constructible/Power/Generation/solar.yml +++ b/Resources/Prototypes/Entities/Constructible/Power/Generation/solar.yml @@ -29,9 +29,11 @@ examinable: true nodes: output: - !type:AdjacentNode + !type:CableDeviceNode nodeGroupID: HVPower - type: PowerSupplier + supplyRampTolerance: 500 + supplyRampRate: 500 - type: SolarPanel supply: 1500 - type: SnapGrid @@ -47,9 +49,6 @@ acts: ["Breakage"] - type: Anchorable - type: Pullable - - type: ClientEntitySpawner - prototypes: - - HVDummyWire - type: Construction graph: solarpanel node: solarpanel diff --git a/Resources/Prototypes/Entities/Constructible/Power/Specific/debug_power.yml b/Resources/Prototypes/Entities/Constructible/Power/Specific/debug_power.yml index 963521c356..24f55dfcfa 100644 --- a/Resources/Prototypes/Entities/Constructible/Power/Specific/debug_power.yml +++ b/Resources/Prototypes/Entities/Constructible/Power/Specific/debug_power.yml @@ -25,7 +25,7 @@ - type: NodeContainer nodes: input: - !type:AdjacentNode + !type:CableDeviceNode nodeGroupID: HVPower - type: PowerConsumer drawRate: 50 @@ -64,10 +64,8 @@ - type: NodeContainer nodes: input: - !type:AdjacentNode + !type:CableDeviceNode nodeGroupID: HVPower - - type: PowerConsumer - - type: BatteryStorage - type: Anchorable - type: entity @@ -93,9 +91,8 @@ - type: NodeContainer nodes: input: - !type:AdjacentNode + !type:CableDeviceNode nodeGroupID: HVPower - - type: PowerSupplier - type: BatteryDischarger - type: Anchorable @@ -133,5 +130,5 @@ - type: Sprite sprite: Constructible/Power/power.rsi state: wirelessmachine - - type: PowerReceiver + - type: ApcPowerReceiver - type: Anchorable diff --git a/Resources/Prototypes/Entities/Constructible/Power/Specific/saltern_power.yml b/Resources/Prototypes/Entities/Constructible/Power/Specific/saltern_power.yml index 91e1e4f651..d9cdf02d91 100644 --- a/Resources/Prototypes/Entities/Constructible/Power/Specific/saltern_power.yml +++ b/Resources/Prototypes/Entities/Constructible/Power/Specific/saltern_power.yml @@ -12,10 +12,6 @@ - type: Battery maxCharge: 10000000 startingCharge: 10000000 - - type: BatteryStorage - activeDrawRate: 0 - - type: BatteryDischarger - activeSupplyRate: 0 - type: entity parent: BaseSubstation @@ -24,10 +20,6 @@ - type: Battery maxCharge: 4000000 startingCharge: 4000000 - - type: BatteryStorage - activeDrawRate: 8000 - - type: BatteryDischarger - activeSupplyRate: 6000 - type: entity parent: BaseApc @@ -36,5 +28,3 @@ - type: Battery maxCharge: 12000 startingCharge: 2000 - - type: BatteryStorage - activeDrawRate: 2000 diff --git a/Resources/Prototypes/Entities/Constructible/Power/arcade.yml b/Resources/Prototypes/Entities/Constructible/Power/arcade.yml index 5f3b4009e5..f0db5e326a 100644 --- a/Resources/Prototypes/Entities/Constructible/Power/arcade.yml +++ b/Resources/Prototypes/Entities/Constructible/Power/arcade.yml @@ -5,7 +5,7 @@ name: arcade parent: ComputerBase components: - - type: PowerReceiver + - type: ApcPowerReceiver - type: Sprite sprite: Constructible/Power/computers.rsi layers: diff --git a/Resources/Prototypes/Entities/Constructible/Power/cable_terminal.yml b/Resources/Prototypes/Entities/Constructible/Power/cable_terminal.yml new file mode 100644 index 0000000000..ef3c90a1cb --- /dev/null +++ b/Resources/Prototypes/Entities/Constructible/Power/cable_terminal.yml @@ -0,0 +1,42 @@ +- type: entity + id: CableTerminal + name: cable terminal + placement: + mode: SnapgridCenter + components: + - type: Sprite + sprite: Constructible/Power/wire_terminal.rsi + state: term + netsync: false + drawdepth: BelowFloor + - type: Clickable + - type: Physics + fixtures: + - shape: + !type:PhysShapeAabb + bounds: "-0.5, -0.5, 0.5, 0.5" + layer: + - Underplating + - type: InteractionOutline + - type: SnapGrid + - type: Damageable + resistances: metallicResistances + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 100 + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] + - type: SubFloorHide + - type: NodeContainer + nodes: + # Just define nodes for both MV and HV. One will end up unused in 99% of cases + # but it means one cable terminal type. + powerHV: + !type:CableTerminalNode + nodeGroupID: HVPower + powerMV: + !type:CableTerminalNode + nodeGroupID: MVPower diff --git a/Resources/Prototypes/Entities/Constructible/Power/wires.yml b/Resources/Prototypes/Entities/Constructible/Power/cables.yml similarity index 60% rename from Resources/Prototypes/Entities/Constructible/Power/wires.yml rename to Resources/Prototypes/Entities/Constructible/Power/cables.yml index 36ba146627..4970d246cb 100644 --- a/Resources/Prototypes/Entities/Constructible/Power/wires.yml +++ b/Resources/Prototypes/Entities/Constructible/Power/cables.yml @@ -1,6 +1,6 @@ - type: entity abstract: true - id: WireBase + id: CableBase placement: mode: SnapgridCenter components: @@ -17,8 +17,6 @@ - type: Sprite netsync: false drawdepth: BelowFloor - - type: IconSmooth - mode: CardinalFlags - type: Damageable resistances: metallicResistances - type: Destructible @@ -30,11 +28,13 @@ - !type:DoActsBehavior acts: ["Destruction"] - type: SubFloorHide + - type: CableVis + node: power - type: entity - parent: WireBase - id: HVWire - name: HV Wire + parent: CableBase + id: CableHV + name: HV power cable description: An orange high voltage power cable. components: - type: Sprite @@ -43,20 +43,17 @@ - type: Icon sprite: Constructible/Power/Wires/hv_cable.rsi state: hvcable_4 - - type: IconSmooth - base: hvcable_ - key: hv_cables - type: NodeContainer nodes: power: - !type:AdjacentNode + !type:CableNode nodeGroupID: HVPower wire: !type:AdjacentNode nodeGroupID: WireNet - - type: Wire - wireDroppedOnCutPrototype: HVWireStack1 - wireType: HighVoltage + - type: Cable + cableDroppedOnCutPrototype: CableHVStack1 + cableType: HighVoltage - type: Destructible thresholds: - trigger: @@ -65,16 +62,20 @@ behaviors: - !type:SpawnEntitiesBehavior spawn: - HVWireStack1: + CableHVStack1: min: 1 max: 1 - !type:DoActsBehavior acts: [ "Destruction" ] + - type: Appearance + visuals: + - type: CableVisualizer + base: hvcable_ - type: entity - parent: WireBase - id: MVWire - name: MV Wire + parent: CableBase + id: CableMV + name: MV power cable description: A medium voltage power cable. components: - type: Sprite @@ -85,20 +86,17 @@ color: Yellow sprite: Constructible/Power/Wires/mv_cable.rsi state: mvcable_4 - - type: IconSmooth - base: mvcable_ - key: mv_cables - type: NodeContainer nodes: power: - !type:AdjacentNode + !type:CableNode nodeGroupID: MVPower wire: !type:AdjacentNode nodeGroupID: WireNet - - type: Wire - wireDroppedOnCutPrototype: MVWireStack1 - wireType: MediumVoltage + - type: Cable + cableDroppedOnCutPrototype: CableMVStack1 + cableType: MediumVoltage - type: Destructible thresholds: - trigger: @@ -107,16 +105,20 @@ behaviors: - !type:SpawnEntitiesBehavior spawn: - MVWireStack1: + CableMVStack1: min: 1 max: 1 - !type:DoActsBehavior acts: [ "Destruction" ] + - type: Appearance + visuals: + - type: CableVisualizer + base: mvcable_ - type: entity - parent: WireBase - id: ApcExtensionCable - name: LV Wire + parent: CableBase + id: CableApcExtension + name: LV power cable description: A cable used to connect machines to an APC. #ACPs aren't area defined anymore so need this cable to connect things to the APC. This description should be dynamic in future. components: - type: Sprite @@ -127,22 +129,19 @@ color: Green sprite: Constructible/Power/Wires/lv_cable.rsi state: lvcable_4 - - type: IconSmooth - base: lvcable_ - key: lv_cables - type: NodeContainer nodes: power: - !type:AdjacentNode + !type:CableNode nodeGroupID: Apc wire: !type:AdjacentNode nodeGroupID: WireNet - type: PowerProvider voltage: Apc - - type: Wire - wireDroppedOnCutPrototype: ApcExtensionCableStack1 - wireType: Apc + - type: Cable + cableDroppedOnCutPrototype: CableApcStack1 + cableType: Apc - type: Destructible thresholds: - trigger: @@ -151,64 +150,12 @@ behaviors: - !type:SpawnEntitiesBehavior spawn: - ApcExtensionCableStack1: + CableApcStack1: min: 1 max: 1 - !type:DoActsBehavior acts: [ "Destruction" ] - -#Dummy wires - -- type: entity - abstract: true - id: BaseDummyWire - placement: - mode: SnapgridCenter - components: - - type: SnapGrid - - type: Sprite - drawdepth: BelowFloor - - type: IconSmooth - mode: CardinalFlags - - type: SubFloorHide - -- type: entity - abstract: true - parent: BaseDummyWire - id: HVDummyWire - name: HV Connector Wire - components: - - type: Sprite - sprite: Constructible/Power/Wires/hv_cable.rsi - state: hvcable_0 - - type: IconSmooth - base: hvcable_ - key: hv_cables - -- type: entity - abstract: true - parent: BaseDummyWire - id: MVDummyWire - name: MV Connector Wire - components: - - type: Sprite - sprite: Constructible/Power/Wires/mv_cable.rsi - state: mvcable_0 - color: Yellow - - type: IconSmooth - base: mvcable_ - key: mv_cables - -- type: entity - abstract: true - parent: BaseDummyWire - id: LVDummyWire - name: LV Connector Wire - components: - - type: Sprite - sprite: Constructible/Power/Wires/lv_cable.rsi - state: lvcable_0 - color: Green - - type: IconSmooth - base: lvcable_ - key: lv_cables + - type: Appearance + visuals: + - type: CableVisualizer + base: lvcable_ diff --git a/Resources/Prototypes/Entities/Constructible/Power/chargers.yml b/Resources/Prototypes/Entities/Constructible/Power/chargers.yml index 17cb057c14..017ebeeac9 100644 --- a/Resources/Prototypes/Entities/Constructible/Power/chargers.yml +++ b/Resources/Prototypes/Entities/Constructible/Power/chargers.yml @@ -11,7 +11,7 @@ state: empty - type: PowerCellCharger transfer_efficiency: 0.85 - - type: PowerReceiver + - type: ApcPowerReceiver - type: Appearance visuals: - type: PowerChargerVisualizer @@ -32,7 +32,7 @@ state: empty - type: WeaponCapacitorCharger transfer_efficiency: 0.85 - - type: PowerReceiver + - type: ApcPowerReceiver - type: Appearance visuals: - type: PowerChargerVisualizer @@ -53,7 +53,7 @@ state: empty - type: WeaponCapacitorCharger transfer_efficiency: 0.95 - - type: PowerReceiver + - type: ApcPowerReceiver - type: Appearance visuals: - type: PowerChargerVisualizer diff --git a/Resources/Prototypes/Entities/Constructible/Power/computers.yml b/Resources/Prototypes/Entities/Constructible/Power/computers.yml index 9a53554a1d..d19ec4cb9e 100644 --- a/Resources/Prototypes/Entities/Constructible/Power/computers.yml +++ b/Resources/Prototypes/Entities/Constructible/Power/computers.yml @@ -82,7 +82,7 @@ graph: computer node: computer - type: Computer - - type: PowerReceiver + - type: ApcPowerReceiver - type: Sprite sprite: Constructible/Power/computers.rsi layers: @@ -158,7 +158,7 @@ type: ResearchConsoleBoundUserInterface - key: enum.ResearchClientUiKey.Key type: ResearchClientBoundUserInterface - - type: PowerReceiver + - type: ApcPowerReceiver load: 200 priority: Low - type: Computer diff --git a/Resources/Prototypes/Entities/Constructible/Power/lathe.yml b/Resources/Prototypes/Entities/Constructible/Power/lathe.yml index 0cb0e591c6..7202bd93f7 100644 --- a/Resources/Prototypes/Entities/Constructible/Power/lathe.yml +++ b/Resources/Prototypes/Entities/Constructible/Power/lathe.yml @@ -30,7 +30,7 @@ interfaces: - key: enum.LatheUiKey.Key type: LatheBoundUserInterface - - type: PowerReceiver + - type: ApcPowerReceiver - type: entity parent: BaseLathe @@ -138,8 +138,8 @@ - SheetRGlass - SheetPlastic - CableStack - - MVWireStack - - HVWireStack + - CableMVStack + - CableHVStack - ConveyorAssembly - RCD - RCDAmmo diff --git a/Resources/Prototypes/Entities/Constructible/Power/parts.yml b/Resources/Prototypes/Entities/Constructible/Power/parts.yml index a5300917ae..f80f119e3d 100644 --- a/Resources/Prototypes/Entities/Constructible/Power/parts.yml +++ b/Resources/Prototypes/Entities/Constructible/Power/parts.yml @@ -1,43 +1,3 @@ -- type: entity - abstract: true - id: BaseSmes - parent: BaseMachine - name: SMES - description: A high-capacity superconducting magnetic energy storage (SMES) unit. - placement: - mode: SnapgridCenter - components: - - type: Sprite - netsync: false - sprite: Constructible/Power/smes.rsi - layers: - - state: smes - - state: smes-display - shader: unshaded - - type: Smes - - type: Appearance - visuals: - - type: SmesVisualizer - - type: Battery - maxCharge: 1000 - startingCharge: 1000 - - type: ExaminableBattery - - type: NodeContainer - examinable: true - nodes: - power: - !type:AdjacentNode - nodeGroupID: HVPower - - type: PowerConsumer - - type: BatteryStorage - activeDrawRate: 1500 - - type: PowerSupplier - - type: BatteryDischarger - activeSupplyRate: 1000 - - type: ClientEntitySpawner - prototypes: - - HVDummyWire - - type: entity abstract: true id: BaseSubstation @@ -63,23 +23,20 @@ examinable: true nodes: input: - !type:AdjacentNode + !type:CableDeviceNode nodeGroupID: HVPower output: - !type:AdjacentNode + !type:CableDeviceNode nodeGroupID: MVPower - - type: PowerConsumer - - type: BatteryStorage - activeDrawRate: 1500 - - type: PowerSupplier - voltage: Medium + - type: BatteryCharger + voltage: High - type: BatteryDischarger - activeSupplyRate: 1000 - - type: ClientEntitySpawner - prototypes: - - HVDummyWire - - MVDummyWire - + voltage: Medium + - type: PowerNetworkBattery + maxSupply: 150000 + maxChargeRate: 5000 + supplyRampTolerance: 5000 + supplyRampRate: 1000 - type: entity abstract: true id: BaseApc @@ -115,15 +72,13 @@ examinable: true nodes: input: - !type:AdjacentNode + !type:CableDeviceNode nodeGroupID: MVPower output: - !type:AdjacentNode + !type:CableDeviceNode nodeGroupID: Apc - - type: PowerConsumer + - type: BatteryCharger voltage: Medium - - type: BatteryStorage - activeDrawRate: 1000 - type: PowerProvider voltage: Apc - type: Apc @@ -135,7 +90,9 @@ - type: Construction graph: apc node: apc - - type: ClientEntitySpawner - prototypes: - - MVDummyWire - - LVDummyWire + - type: PowerNetworkBattery + maxSupply: 10000 + maxChargeRate: 5000 + supplyRampTolerance: 1000 + supplyRampRate: 500 + diff --git a/Resources/Prototypes/Entities/Constructible/Power/smes.yml b/Resources/Prototypes/Entities/Constructible/Power/smes.yml new file mode 100644 index 0000000000..cce3cbebf2 --- /dev/null +++ b/Resources/Prototypes/Entities/Constructible/Power/smes.yml @@ -0,0 +1,46 @@ +- type: entity + abstract: true + id: BaseSmes + parent: BaseMachine + name: SMES + description: A high-capacity superconducting magnetic energy storage (SMES) unit. + placement: + mode: SnapgridCenter + components: + - type: Sprite + netsync: false + sprite: Constructible/Power/smes.rsi + layers: + - state: smes + - state: smes-display + shader: unshaded + - type: Smes + - type: Appearance + visuals: + - type: SmesVisualizer + - type: Battery + maxCharge: 1000 + startingCharge: 1000 + - type: ExaminableBattery + - type: NodeContainer + examinable: true + nodes: + input: + !type:CableDeviceNode + nodeGroupID: HVPower + output: + !type:CableTerminalPortNode + nodeGroupID: HVPower + - type: BatteryCharger + voltage: High + node: output + + - type: BatteryDischarger + voltage: High + node: input + + - type: PowerNetworkBattery + maxSupply: 150000 + maxChargeRate: 5000 + supplyRampTolerance: 5000 + supplyRampRate: 1000 diff --git a/Resources/Prototypes/Entities/Constructible/Power/vending_machines.yml b/Resources/Prototypes/Entities/Constructible/Power/vending_machines.yml index 50f2e4c882..5b11907247 100644 --- a/Resources/Prototypes/Entities/Constructible/Power/vending_machines.yml +++ b/Resources/Prototypes/Entities/Constructible/Power/vending_machines.yml @@ -38,7 +38,7 @@ type: VendingMachineBoundUserInterface - key: enum.WiresUiKey.Key type: WiresBoundUserInterface - - type: PowerReceiver + - type: ApcPowerReceiver - type: Wires BoardName: "Vending Machine" LayoutId: Vending diff --git a/Resources/Prototypes/Entities/Constructible/Specific/Conveyor/conveyor.yml b/Resources/Prototypes/Entities/Constructible/Specific/Conveyor/conveyor.yml index 3fe0e117cf..0aa313a130 100644 --- a/Resources/Prototypes/Entities/Constructible/Specific/Conveyor/conveyor.yml +++ b/Resources/Prototypes/Entities/Constructible/Specific/Conveyor/conveyor.yml @@ -27,7 +27,7 @@ drawdepth: FloorObjects - type: SignalReceiver maxTransmitters: 1 - - type: PowerReceiver + - type: ApcPowerReceiver - type: Conveyor - type: Appearance visuals: diff --git a/Resources/Prototypes/Entities/Constructible/Specific/Dispensers/chem_dispenser.yml b/Resources/Prototypes/Entities/Constructible/Specific/Dispensers/chem_dispenser.yml index 47139c65f2..84ae79f823 100644 --- a/Resources/Prototypes/Entities/Constructible/Specific/Dispensers/chem_dispenser.yml +++ b/Resources/Prototypes/Entities/Constructible/Specific/Dispensers/chem_dispenser.yml @@ -12,4 +12,4 @@ state: industrial_dispenser - type: ReagentDispenser pack: ChemDispenserStandardInventory - - type: PowerReceiver + - type: ApcPowerReceiver diff --git a/Resources/Prototypes/Entities/Constructible/Specific/Dispensers/reagent_dispenser_base.yml b/Resources/Prototypes/Entities/Constructible/Specific/Dispensers/reagent_dispenser_base.yml index dd6a6ac8c1..412c455d39 100644 --- a/Resources/Prototypes/Entities/Constructible/Specific/Dispensers/reagent_dispenser_base.yml +++ b/Resources/Prototypes/Entities/Constructible/Specific/Dispensers/reagent_dispenser_base.yml @@ -21,7 +21,7 @@ - Opaque - MobImpassable - SmallImpassable - - type: PowerReceiver + - type: ApcPowerReceiver - type: UserInterface interfaces: - key: enum.ReagentDispenserUiKey.Key diff --git a/Resources/Prototypes/Entities/Constructible/Specific/Kitchen/microwave.yml b/Resources/Prototypes/Entities/Constructible/Specific/Kitchen/microwave.yml index 8a29b60620..38c3bae6c9 100644 --- a/Resources/Prototypes/Entities/Constructible/Specific/Kitchen/microwave.yml +++ b/Resources/Prototypes/Entities/Constructible/Specific/Kitchen/microwave.yml @@ -39,7 +39,7 @@ - state: mw_unlit shader: unshaded map: ["enum.MicrowaveVisualizerLayers.BaseUnlit"] - - type: PowerReceiver + - type: ApcPowerReceiver - type: Damageable resistances: metallicResistances - type: Destructible diff --git a/Resources/Prototypes/Entities/Constructible/Specific/Kitchen/reagent_grinder.yml b/Resources/Prototypes/Entities/Constructible/Specific/Kitchen/reagent_grinder.yml index 9ab61d3506..1261dcbebb 100644 --- a/Resources/Prototypes/Entities/Constructible/Specific/Kitchen/reagent_grinder.yml +++ b/Resources/Prototypes/Entities/Constructible/Specific/Kitchen/reagent_grinder.yml @@ -17,7 +17,7 @@ - type: ReagentGrinderVisualizer - type: Clickable - type: InteractionOutline - - type: PowerReceiver + - type: ApcPowerReceiver - type: LoopingSound - type: Physics fixtures: diff --git a/Resources/Prototypes/Entities/Constructible/Specific/Research/research.yml b/Resources/Prototypes/Entities/Constructible/Specific/Research/research.yml index 10efe5da0d..68ce5a5646 100644 --- a/Resources/Prototypes/Entities/Constructible/Specific/Research/research.yml +++ b/Resources/Prototypes/Entities/Constructible/Specific/Research/research.yml @@ -21,7 +21,7 @@ - MobImpassable - type: ResearchServer - type: TechnologyDatabase - - type: PowerReceiver + - type: ApcPowerReceiver powerLoad: 200 priority: Low - type: Damageable @@ -77,7 +77,7 @@ - type: Appearance visuals: - type: PowerDeviceVisualizer - - type: PowerReceiver + - type: ApcPowerReceiver - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Constructible/Specific/cargo_telepad.yml b/Resources/Prototypes/Entities/Constructible/Specific/cargo_telepad.yml index f041f5a07b..aefaaff479 100644 --- a/Resources/Prototypes/Entities/Constructible/Specific/cargo_telepad.yml +++ b/Resources/Prototypes/Entities/Constructible/Specific/cargo_telepad.yml @@ -33,5 +33,5 @@ max: 1 - !type:DoActsBehavior acts: ["Destruction"] - - type: PowerReceiver + - type: ApcPowerReceiver - type: CargoTelepad diff --git a/Resources/Prototypes/Entities/Constructible/Specific/chem_master.yml b/Resources/Prototypes/Entities/Constructible/Specific/chem_master.yml index 7b1653ced2..08526a09de 100644 --- a/Resources/Prototypes/Entities/Constructible/Specific/chem_master.yml +++ b/Resources/Prototypes/Entities/Constructible/Specific/chem_master.yml @@ -16,7 +16,7 @@ sprite: Constructible/Power/mixer.rsi state: mixer_loaded - type: ChemMaster - - type: PowerReceiver + - type: ApcPowerReceiver - type: InteractionOutline - type: Anchorable - type: Physics diff --git a/Resources/Prototypes/Entities/Constructible/Specific/gravity_generator.yml b/Resources/Prototypes/Entities/Constructible/Specific/gravity_generator.yml index 4708e06aee..527bcade39 100644 --- a/Resources/Prototypes/Entities/Constructible/Specific/gravity_generator.yml +++ b/Resources/Prototypes/Entities/Constructible/Specific/gravity_generator.yml @@ -14,7 +14,7 @@ shader: unshaded map: ["enum.GravityGeneratorVisualLayers.Core"] - type: SnapGrid - - type: PowerReceiver + - type: ApcPowerReceiver powerLoad: 500 - type: Physics fixtures: diff --git a/Resources/Prototypes/Entities/Constructible/Specific/recycler.yml b/Resources/Prototypes/Entities/Constructible/Specific/recycler.yml index 419981a1d1..683b59074d 100644 --- a/Resources/Prototypes/Entities/Constructible/Specific/recycler.yml +++ b/Resources/Prototypes/Entities/Constructible/Specific/recycler.yml @@ -32,4 +32,4 @@ state_clean: grinder-o1 state_bloody: grinder-o1bld - type: Recycler - - type: PowerReceiver + - type: ApcPowerReceiver diff --git a/Resources/Prototypes/Entities/Constructible/Walls/bar_sign.yml b/Resources/Prototypes/Entities/Constructible/Walls/bar_sign.yml index be8f01c2dc..9cf0b64ab5 100644 --- a/Resources/Prototypes/Entities/Constructible/Walls/bar_sign.yml +++ b/Resources/Prototypes/Entities/Constructible/Walls/bar_sign.yml @@ -14,7 +14,7 @@ drawdepth: WallTops sprite: Constructible/Misc/barsign.rsi state: empty - - type: PowerReceiver + - type: ApcPowerReceiver - type: BarSign - type: Destructible thresholds: @@ -37,7 +37,7 @@ drawdepth: WallTops sprite: Constructible/Misc/sylphs.rsi state: sylph - - type: PowerReceiver + - type: ApcPowerReceiver - type: BarSign - type: entity diff --git a/Resources/Prototypes/Entities/Constructible/Walls/emergency_light.yml b/Resources/Prototypes/Entities/Constructible/Walls/emergency_light.yml index 69c2c5a1ac..f4e6bb0181 100644 --- a/Resources/Prototypes/Entities/Constructible/Walls/emergency_light.yml +++ b/Resources/Prototypes/Entities/Constructible/Walls/emergency_light.yml @@ -11,7 +11,7 @@ offset: "0, 0.8" color: "#FF4020" mask: /Textures/Effects/LightMasks/emergency_mask.png - - type: PowerReceiver + - type: ApcPowerReceiver - type: Battery maxCharge: 30000 startingCharge: 0 @@ -20,6 +20,10 @@ sprite: Constructible/Lighting/emergency_light.rsi layers: - state: emergency_light_off + - type: Appearance + visuals: + - type: EmergencyLightVisualizer + placement: snap: - Wallmount diff --git a/Resources/Prototypes/Entities/Constructible/Walls/lighting.yml b/Resources/Prototypes/Entities/Constructible/Walls/lighting.yml index 4a41b66ea6..3a1c355533 100644 --- a/Resources/Prototypes/Entities/Constructible/Walls/lighting.yml +++ b/Resources/Prototypes/Entities/Constructible/Walls/lighting.yml @@ -63,7 +63,7 @@ enabled: false - type: PoweredLight bulb: Tube - - type: PowerReceiver + - type: ApcPowerReceiver - type: Appearance visuals: - type: PoweredLightVisualizer @@ -135,7 +135,7 @@ layer: [ Passable ] - type: PoweredLight bulb: Bulb - - type: PowerReceiver + - type: ApcPowerReceiver - type: Appearance visuals: - type: PoweredLightVisualizer diff --git a/Resources/Prototypes/Entities/Constructible/base_machine.yml b/Resources/Prototypes/Entities/Constructible/base_machine.yml index 14928a150b..b19a2a4167 100644 --- a/Resources/Prototypes/Entities/Constructible/base_machine.yml +++ b/Resources/Prototypes/Entities/Constructible/base_machine.yml @@ -29,10 +29,10 @@ acts: ["Destruction"] - !type:PlaySoundBehavior sound: /Audio/Effects/metalbreak.ogg - + - type: entity abstract: true parent: BaseMachine id: BaseMachinePowered components: - - type: PowerReceiver + - type: ApcPowerReceiver diff --git a/Resources/Prototypes/Entities/Objects/Tools/cable_coils.yml b/Resources/Prototypes/Entities/Objects/Tools/cable_coils.yml index df9e7ac1d5..6e57604d46 100644 --- a/Resources/Prototypes/Entities/Objects/Tools/cable_coils.yml +++ b/Resources/Prototypes/Entities/Objects/Tools/cable_coils.yml @@ -16,26 +16,26 @@ netsync: false - type: Item sprite: Objects/Tools/cable-coils.rsi - - type: WirePlacer + - type: CablePlacer - type: Clickable - type: entity - id: HVWireStack + id: CableHVStack parent: CableStack name: HV cable coil suffix: Full components: - type: Stack - stackType: HVCable + stackType: CableHV - type: Sprite state: coilhv-30 - type: Item size: 10 HeldPrefix: coilhv - - type: WirePlacer - wirePrototypeID: HVWire - blockingWireType: HighVoltage + - type: CablePlacer + cablePrototypeID: CableHV + blockingCableType: HighVoltage - type: Appearance visuals: - type: StackVisualizer @@ -45,8 +45,8 @@ - coilhv-30 - type: entity - parent: HVWireStack - id: HVWireStack1 + parent: CableHVStack + id: CableHVStack1 suffix: 1 components: - type: Sprite @@ -54,12 +54,11 @@ - type: Item size: 3 - type: Stack - stackType: HVWireStack1 count: 1 - type: entity parent: CableStack - id: ApcExtensionCableStack + id: CableApcStack name: cable coil description: Low-Voltage stack of wires for connecting APCs to machines and other purposes. suffix: Full @@ -69,9 +68,9 @@ - type: Item size: 10 HeldPrefix: coillv - - type: WirePlacer - wirePrototypeID: ApcExtensionCable - blockingWireType: Apc + - type: CablePlacer + cablePrototypeID: CableApcExtension + blockingCableType: Apc - type: Appearance visuals: - type: StackVisualizer @@ -81,8 +80,8 @@ - coillv-30 - type: entity - parent: ApcExtensionCableStack - id: ApcExtensionCableStack1 + parent: CableApcStack + id: CableApcStack1 suffix: 1 components: - type: Sprite @@ -94,20 +93,20 @@ - type: entity parent: CableStack - id: MVWireStack + id: CableMVStack name: MV cable coil suffix: Full components: - type: Stack - stackType: MVCable + stackType: CableMV - type: Sprite state: coilmv-30 - type: Item size: 10 HeldPrefix: coilmv - - type: WirePlacer - wirePrototypeID: MVWire - blockingWireType: MediumVoltage + - type: CablePlacer + cablePrototypeID: CableMV + blockingCableType: MediumVoltage - type: Appearance visuals: - type: StackVisualizer @@ -117,8 +116,8 @@ - coilmv-30 - type: entity - parent: MVWireStack - id: MVWireStack1 + parent: CableMVStack + id: CableMVStack1 suffix: 1 components: - type: Sprite @@ -126,5 +125,4 @@ - type: Item size: 3 - type: Stack - stackType: MVWireStack1 count: 1 diff --git a/Resources/Prototypes/Recipes/Construction/Graphs/airlock.yml b/Resources/Prototypes/Recipes/Construction/Graphs/airlock.yml index cd744c5983..32c5c8c337 100644 --- a/Resources/Prototypes/Recipes/Construction/Graphs/airlock.yml +++ b/Resources/Prototypes/Recipes/Construction/Graphs/airlock.yml @@ -58,7 +58,7 @@ - to: assembly completed: - !type:SpawnPrototype - prototype: ApcExtensionCableStack1 + prototype: CableApcStack1 amount: 5 steps: - tool: Cutting diff --git a/Resources/Prototypes/Recipes/Construction/Graphs/computer.yml b/Resources/Prototypes/Recipes/Construction/Graphs/computer.yml index 7e185a449d..3de0a915fd 100644 --- a/Resources/Prototypes/Recipes/Construction/Graphs/computer.yml +++ b/Resources/Prototypes/Recipes/Construction/Graphs/computer.yml @@ -100,7 +100,7 @@ - !type:EntityAnchored { } completed: - !type:SpawnPrototype - prototype: ApcExtensionCableStack1 + prototype: CableApcStack1 amount: 5 steps: - tool: Cutting diff --git a/Resources/Prototypes/Recipes/Construction/Graphs/firelock.yml b/Resources/Prototypes/Recipes/Construction/Graphs/firelock.yml index cf2fa03416..000dfdda8c 100644 --- a/Resources/Prototypes/Recipes/Construction/Graphs/firelock.yml +++ b/Resources/Prototypes/Recipes/Construction/Graphs/firelock.yml @@ -59,7 +59,7 @@ - to: frame1 completed: - !type:SpawnPrototype - prototype: ApcExtensionCableStack1 + prototype: CableApcStack1 amount: 2 conditions: - !type:EntityAnchored diff --git a/Resources/Prototypes/Recipes/Construction/Graphs/machine.yml b/Resources/Prototypes/Recipes/Construction/Graphs/machine.yml index 916d48ad17..53c8cb6478 100644 --- a/Resources/Prototypes/Recipes/Construction/Graphs/machine.yml +++ b/Resources/Prototypes/Recipes/Construction/Graphs/machine.yml @@ -63,7 +63,7 @@ - !type:EntityAnchored {} completed: - !type:SpawnPrototype - prototype: ApcExtensionCableStack1 + prototype: CableApcStack1 steps: - tool: Prying doAfter: 2 diff --git a/Resources/Prototypes/Recipes/Construction/Graphs/particle_accelerator.yml b/Resources/Prototypes/Recipes/Construction/Graphs/particle_accelerator.yml index 0f1b5f504e..6c9f668220 100644 --- a/Resources/Prototypes/Recipes/Construction/Graphs/particle_accelerator.yml +++ b/Resources/Prototypes/Recipes/Construction/Graphs/particle_accelerator.yml @@ -34,7 +34,7 @@ - !type:EntityAnchored {} completed: - !type:SpawnPrototype - prototype: ApcExtensionCableStack1 + prototype: CableApcStack1 steps: - tool: Cutting doAfter: 0.5 @@ -86,7 +86,7 @@ - !type:EntityAnchored {} completed: - !type:SpawnPrototype - prototype: ApcExtensionCableStack1 + prototype: CableApcStack1 steps: - tool: Cutting doAfter: 0.5 @@ -138,7 +138,7 @@ - !type:EntityAnchored {} completed: - !type:SpawnPrototype - prototype: ApcExtensionCableStack1 + prototype: CableApcStack1 steps: - tool: Cutting doAfter: 0.5 @@ -189,7 +189,7 @@ - !type:EntityAnchored {} completed: - !type:SpawnPrototype - prototype: ApcExtensionCableStack1 + prototype: CableApcStack1 steps: - tool: Cutting doAfter: 0.5 @@ -240,7 +240,7 @@ - !type:EntityAnchored {} completed: - !type:SpawnPrototype - prototype: ApcExtensionCableStack1 + prototype: CableApcStack1 steps: - tool: Cutting doAfter: 0.5 @@ -291,7 +291,7 @@ - !type:EntityAnchored {} completed: - !type:SpawnPrototype - prototype: ApcExtensionCableStack1 + prototype: CableApcStack1 steps: - tool: Cutting doAfter: 0.5 @@ -342,7 +342,7 @@ - !type:EntityAnchored {} completed: - !type:SpawnPrototype - prototype: ApcExtensionCableStack1 + prototype: CableApcStack1 steps: - tool: Cutting doAfter: 0.5 diff --git a/Resources/Prototypes/Recipes/Lathes/tools.yml b/Resources/Prototypes/Recipes/Lathes/tools.yml index ddfce393ee..37160c400f 100644 --- a/Resources/Prototypes/Recipes/Lathes/tools.yml +++ b/Resources/Prototypes/Recipes/Lathes/tools.yml @@ -38,25 +38,25 @@ id: CableStack name: cable coil icon: /Textures/Objects/Tools/cable-coils.rsi/coillv-30.png - result: ApcExtensionCableStack1 + result: CableApcStack1 completetime: 500 materials: Steel: 100 - type: latheRecipe - id: MVWireStack + id: CableMVStack name: MV cable coil icon: /Textures/Objects/Tools/cable-coils.rsi/coilmv-30.png - result: MVWireStack1 + result: CableMVStack1 completetime: 500 materials: Steel: 150 - type: latheRecipe - id: HVWireStack + id: CableHVStack name: HV cable coil icon: /Textures/Objects/Tools/cable-coils.rsi/coilhv-30.png - result: HVWireStack1 + result: CableHVStack1 completetime: 500 materials: Steel: 200 diff --git a/Resources/Prototypes/Stacks/power_stacks.yml b/Resources/Prototypes/Stacks/power_stacks.yml index b72177af1a..bc49118433 100644 --- a/Resources/Prototypes/Stacks/power_stacks.yml +++ b/Resources/Prototypes/Stacks/power_stacks.yml @@ -2,24 +2,13 @@ id: Cable name: cable icon: "/Textures/Objects/Tools/cable-coils.rsi/coil-30.png" - spawn: ApcExtensionCableStack1 + spawn: CableApcStack1 - type: stack - id: MVCable + id: CableMV name: mv cable + spawn: CableHVStack1 - type: stack - id: HVCable + id: CableHV name: hv cable - -- type: stack - id: HVWireStack1 - name: hv wire - -- type: stack - id: MVWireStack1 - name: mv wire - -- type: stack - id: ApcExtensionCableStack1 - name: apc extension cable diff --git a/Resources/Textures/Constructible/Power/wire_terminal.rsi/meta.json b/Resources/Textures/Constructible/Power/wire_terminal.rsi/meta.json new file mode 100644 index 0000000000..5344175985 --- /dev/null +++ b/Resources/Textures/Constructible/Power/wire_terminal.rsi/meta.json @@ -0,0 +1,32 @@ +{ + "version": 1, + "size": + { + "x": 32, + "y": 32 + }, + "copyright": "Taken from https://github.com/tgstation/tgstation at 21e50aebdac3e30b3f85b5e44e552e3e37ed00ea", + "license": "CC-BY-SA-3.0", + "states": + [ + { + "name": "term", + "directions": 4, + "delays": + [ + [ + 1.0 + ], + [ + 1.0 + ], + [ + 1.0 + ], + [ + 1.0 + ] + ] + } + ] +} \ No newline at end of file diff --git a/Resources/Textures/Constructible/Power/wire_terminal.rsi/term.png b/Resources/Textures/Constructible/Power/wire_terminal.rsi/term.png new file mode 100644 index 0000000000..dbae38dbe9 Binary files /dev/null and b/Resources/Textures/Constructible/Power/wire_terminal.rsi/term.png differ diff --git a/SpaceStation14.sln b/SpaceStation14.sln index 9746998c5a..e9d03b7d4b 100644 --- a/SpaceStation14.sln +++ b/SpaceStation14.sln @@ -104,6 +104,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Linguini.Syntax", "RobustTo EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PluralRules.Generator", "RobustToolbox\Linguini\PluralRules.Generator\PluralRules.Generator.csproj", "{9210CCA8-94AA-407F-8F9A-64101D0E552D}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Pow3r", "Pow3r\Pow3r.csproj", "{1C048C9F-00A9-4796-BE4D-BB36B7769720}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -245,6 +247,10 @@ Global {9210CCA8-94AA-407F-8F9A-64101D0E552D}.Debug|Any CPU.Build.0 = Debug|Any CPU {9210CCA8-94AA-407F-8F9A-64101D0E552D}.Release|Any CPU.ActiveCfg = Release|Any CPU {9210CCA8-94AA-407F-8F9A-64101D0E552D}.Release|Any CPU.Build.0 = Release|Any CPU + {1C048C9F-00A9-4796-BE4D-BB36B7769720}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1C048C9F-00A9-4796-BE4D-BB36B7769720}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1C048C9F-00A9-4796-BE4D-BB36B7769720}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1C048C9F-00A9-4796-BE4D-BB36B7769720}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE