diff --git a/Content.Server/GameObjects/Components/NodeContainer/NodeGroups/PowerNetNodeGroup.cs b/Content.Server/GameObjects/Components/NodeContainer/NodeGroups/PowerNetNodeGroup.cs index 676242f894..0bcf076251 100644 --- a/Content.Server/GameObjects/Components/NodeContainer/NodeGroups/PowerNetNodeGroup.cs +++ b/Content.Server/GameObjects/Components/NodeContainer/NodeGroups/PowerNetNodeGroup.cs @@ -123,7 +123,8 @@ namespace Content.Server.GameObjects.Components.NodeContainer.NodeGroups public void RemoveConsumer(PowerConsumerComponent consumer) { Debug.Assert(_consumersByPriority[consumer.Priority].Contains(consumer)); - _consumersByPriority[consumer.Priority].Add(consumer); + consumer.ReceivedPower = 0; + _consumersByPriority[consumer.Priority].Remove(consumer); _drawByPriority[consumer.Priority] -= consumer.DrawRate; UpdateConsumerReceivedPower(); } diff --git a/Content.Server/GameObjects/Components/NodeContainer/Nodes/Node.cs b/Content.Server/GameObjects/Components/NodeContainer/Nodes/Node.cs index dfbd843845..3ea4e305a2 100644 --- a/Content.Server/GameObjects/Components/NodeContainer/Nodes/Node.cs +++ b/Content.Server/GameObjects/Components/NodeContainer/Nodes/Node.cs @@ -1,4 +1,5 @@ using Content.Server.GameObjects.Components.NodeContainer.NodeGroups; +using Robust.Server.GameObjects; using Robust.Shared.Interfaces.GameObjects; using Robust.Shared.IoC; using Robust.Shared.ViewVariables; @@ -28,8 +29,19 @@ namespace Content.Server.GameObjects.Components.NodeContainer.Nodes [ViewVariables] public IEntity Owner { get; private set; } + [ViewVariables] private bool _needsGroup = true; + /// + /// If this node should be considered for connection by other nodes. + /// + private bool Connectable => !_deleting && Anchored; + + private bool Anchored => !Owner.TryGetComponent(out var physics) || physics.Anchored; + + /// + /// Prevents a node from being used by other nodes while midway through removal. + /// private bool _deleting = false; @@ -47,11 +59,21 @@ namespace Content.Server.GameObjects.Components.NodeContainer.Nodes { TryAssignGroupIfNeeded(); CombineGroupWithReachable(); + if (Owner.TryGetComponent(out var physics)) + { + AnchorUpdate(); + physics.AnchoredChanged += AnchorUpdate; + } } public void OnContainerRemove() { _deleting = true; + if (Owner.TryGetComponent(out var physics)) + { + AnchorUpdate(); + physics.AnchoredChanged -= AnchorUpdate; + } NodeGroup.RemoveNode(this); } @@ -75,7 +97,7 @@ namespace Content.Server.GameObjects.Components.NodeContainer.Nodes public void SpreadGroup() { Debug.Assert(!_needsGroup); - foreach (var node in GetReachableCompatibleNodes().Where(node => node._needsGroup == true)) + foreach (var node in GetReachableCompatibleNodes().Where(node => node._needsGroup)) { node.NodeGroup = NodeGroup; node.SpreadGroup(); @@ -97,12 +119,12 @@ namespace Content.Server.GameObjects.Components.NodeContainer.Nodes private IEnumerable GetReachableCompatibleNodes() { return GetReachableNodes().Where(node => node.NodeGroupID == NodeGroupID) - .Where(node => node._deleting == false); + .Where(node => node.Connectable); } private IEnumerable GetReachableCompatibleGroups() { - return GetReachableCompatibleNodes().Where(node => node._needsGroup == false) + return GetReachableCompatibleNodes().Where(node => !node._needsGroup) .Select(node => node.NodeGroup) .Where(group => group != NodeGroup); } @@ -127,5 +149,22 @@ namespace Content.Server.GameObjects.Components.NodeContainer.Nodes { return _nodeGroupFactory.MakeNodeGroup(NodeGroupID); } + + private void AnchorUpdate() + { + if (Anchored) + { + if (_needsGroup) + { + TryAssignGroupIfNeeded(); + CombineGroupWithReachable(); + } + } + else + { + NodeGroup.RemoveNode(this); + ClearNodeGroup(); + } + } } } diff --git a/Content.Server/GameObjects/Components/Power/ApcNetComponents/PowerProviderComponent.cs b/Content.Server/GameObjects/Components/Power/ApcNetComponents/PowerProviderComponent.cs index 94f789252a..69cf10e6f9 100644 --- a/Content.Server/GameObjects/Components/Power/ApcNetComponents/PowerProviderComponent.cs +++ b/Content.Server/GameObjects/Components/Power/ApcNetComponents/PowerProviderComponent.cs @@ -96,6 +96,7 @@ namespace Content.Server.GameObjects.Components.Power.ApcNetComponents .GetEntitiesInRange(Owner, PowerTransferRange); return nearbyEntities.Select(entity => entity.TryGetComponent(out var receiver) ? receiver : null) .Where(receiver => receiver != null) + .Where(receiver => receiver.Connectable) .Where(receiver => receiver.NeedsProvider) .Where(receiver => receiver.Owner.Transform.GridPosition.Distance(mapManager, Owner.Transform.GridPosition) < Math.Min(PowerTransferRange, receiver.PowerReceptionRange)) .ToList(); diff --git a/Content.Server/GameObjects/Components/Power/ApcNetComponents/PowerReceiverComponent.cs b/Content.Server/GameObjects/Components/Power/ApcNetComponents/PowerReceiverComponent.cs index 2839482512..ccb2629e93 100644 --- a/Content.Server/GameObjects/Components/Power/ApcNetComponents/PowerReceiverComponent.cs +++ b/Content.Server/GameObjects/Components/Power/ApcNetComponents/PowerReceiverComponent.cs @@ -39,6 +39,13 @@ namespace Content.Server.GameObjects.Components.Power.ApcNetComponents public IPowerProvider Provider { get => _provider; set => SetProvider(value); } private IPowerProvider _provider = PowerProviderComponent.NullProvider; + /// + /// If this should be considered for connection by s. + /// + public bool Connectable => Anchored; + + private bool Anchored => !Owner.TryGetComponent(out var physics) || physics.Anchored; + [ViewVariables] public bool NeedsProvider { get; private set; } = true; @@ -78,10 +85,19 @@ namespace Content.Server.GameObjects.Components.Power.ApcNetComponents { TryFindAndSetProvider(); } + if (Owner.TryGetComponent(out var physics)) + { + AnchorUpdate(); + physics.AnchoredChanged += AnchorUpdate; + } } public override void OnRemove() { + if (Owner.TryGetComponent(out var physics)) + { + physics.AnchoredChanged -= AnchorUpdate; + } _provider.RemoveReceiver(this); base.OnRemove(); } @@ -184,6 +200,21 @@ namespace Content.Server.GameObjects.Components.Power.ApcNetComponents appearance.SetData(PowerDeviceVisuals.Powered, Powered); } } + + private void AnchorUpdate() + { + if (Anchored) + { + if (NeedsProvider) + { + TryFindAndSetProvider(); + } + } + else + { + ClearProvider(); + } + } } public class PowerStateEventArgs : EventArgs diff --git a/Resources/Prototypes/Entities/Buildings/Storage/StorageTanks/storage_tank.yml b/Resources/Prototypes/Entities/Buildings/Storage/StorageTanks/storage_tank.yml index f51fc68250..b80a3f932c 100644 --- a/Resources/Prototypes/Entities/Buildings/Storage/StorageTanks/storage_tank.yml +++ b/Resources/Prototypes/Entities/Buildings/Storage/StorageTanks/storage_tank.yml @@ -1,4 +1,4 @@ -- type: entity +- type: entity id: StorageTank name: storage tank description: "A liquids storage tank" diff --git a/Resources/Prototypes/Entities/Buildings/Storage/crate_base.yml b/Resources/Prototypes/Entities/Buildings/Storage/crate_base.yml index feb5123131..49356ce829 100644 --- a/Resources/Prototypes/Entities/Buildings/Storage/crate_base.yml +++ b/Resources/Prototypes/Entities/Buildings/Storage/crate_base.yml @@ -1,4 +1,4 @@ -- type: entity +- type: entity id: CrateGeneric name: crate description: A large container for items. diff --git a/Resources/Prototypes/Entities/Buildings/mirror.yml b/Resources/Prototypes/Entities/Buildings/mirror.yml index 6643418e8e..5e2f79cce8 100644 --- a/Resources/Prototypes/Entities/Buildings/mirror.yml +++ b/Resources/Prototypes/Entities/Buildings/mirror.yml @@ -1,4 +1,4 @@ -- type: entity +- type: entity id: Mirror name: mirror components: diff --git a/Resources/Prototypes/Entities/Buildings/power.yml b/Resources/Prototypes/Entities/Buildings/power.yml index 8d8bc3ac0d..f13f210960 100644 --- a/Resources/Prototypes/Entities/Buildings/power.yml +++ b/Resources/Prototypes/Entities/Buildings/power.yml @@ -103,6 +103,8 @@ nodeTypes: { HVPower : ["AdjacentNode"] } - type: PowerSupplier supplyRate: 3000 + - type: Physics + Anchored: true - type: Anchorable - type: entity @@ -114,6 +116,10 @@ - type: Clickable - type: InteractionOutline - type: Collidable + shapes: + - !type:PhysShapeAabb + bounds: "-0.5, -0.5, 0.5, 0.5" + layer: [MobMask, Opaque] - type: SnapGrid offset: Center - type: Sprite @@ -127,6 +133,8 @@ - type: Damageable - type: Breakable thresholdvalue: 100 + - type: Physics + Anchored: true - type: Anchorable - type: entity @@ -138,6 +146,10 @@ - type: Clickable - type: InteractionOutline - type: Collidable + shapes: + - !type:PhysShapeAabb + bounds: "-0.5, -0.5, 0.5, 0.5" + layer: [MobMask, Opaque] - type: SnapGrid offset: Center - type: Sprite @@ -149,6 +161,9 @@ nodeTypes: { HVPower : ["AdjacentNode"] } - type: PowerConsumer - type: BatteryStorage + - type: Physics + Anchored: true + - type: Anchorable - type: entity id: DebugBatteryDischarger @@ -159,6 +174,10 @@ - type: Clickable - type: InteractionOutline - type: Collidable + shapes: + - !type:PhysShapeAabb + bounds: "-0.5, -0.5, 0.5, 0.5" + layer: [MobMask, Opaque] - type: SnapGrid offset: Center - type: Sprite @@ -170,6 +189,9 @@ nodeTypes: { HVPower : ["AdjacentNode"] } - type: PowerSupplier - type: BatteryDischarger + - type: Physics + Anchored: true + - type: Anchorable - type: entity id: DebugSmes @@ -211,6 +233,8 @@ - type: PowerSupplier - type: BatteryDischarger activeSupplyRate: 1000 + - type: Physics + Anchored: true - type: Anchorable - type: entity @@ -222,6 +246,10 @@ - type: Clickable - type: InteractionOutline - type: Collidable + shapes: + - !type:PhysShapeAabb + bounds: "-0.5, -0.5, 0.5, 0.5" + layer: [MobMask, Opaque] - type: SnapGrid offset: Center - type: Sprite @@ -241,6 +269,9 @@ voltage: Medium - type: BatteryDischarger activeSupplyRate: 1000 + - type: Physics + Anchored: true + - type: Anchorable - type: entity id: DebugApc @@ -294,6 +325,10 @@ - type: Clickable - type: InteractionOutline - type: Collidable + shapes: + - !type:PhysShapeAabb + bounds: "-0.5, -0.5, 0.5, 0.5" + layer: [MobMask, Opaque] - type: SnapGrid offset: Center - type: Sprite @@ -301,6 +336,9 @@ - type: Icon texture: Objects/Furniture/wirelessmachine.png - type: PowerReceiver + - type: Physics + Anchored: true + - type: Anchorable - type: entity id: SolarPanel diff --git a/Resources/Prototypes/Entities/janitor.yml b/Resources/Prototypes/Entities/janitor.yml index b425689eba..311079ca23 100644 --- a/Resources/Prototypes/Entities/janitor.yml +++ b/Resources/Prototypes/Entities/janitor.yml @@ -1,4 +1,4 @@ -- type: entity +- type: entity parent: BaseItem name: mop id: MopItem