From 58709d2d26093c70e75b29ecff9368273a5ad913 Mon Sep 17 00:00:00 2001 From: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> Date: Fri, 22 Nov 2019 09:48:56 +1100 Subject: [PATCH] Add power cell and weapon chargers (#430) * Add power cell and weapon chargers Functionality's similar to SS13. The cell charger won't show the discrete charging levels because effort to not make it spam appearance updates over the network. There's some stuff I wasn't sure on: 1. Updating power? Particularly around fixing rounding 2. Duplicating the full and empty sprites as I couldn't figure out a way to not have AppearanceVisualizer throw if the state isn't found 3. I made a BaseCharger abstract class under the assumption that when a mech / borg charger is added it would also inherit from it. 4. GetText currently isn't localized * Address PJB's feedback Updated the BaseCharger * Change nullref exception to invalidoperation * If the user doesn't have hands it will just return instead --- Content.Client/EntryPoint.cs | 2 + .../Power/PowerChargerVisualizer2D.cs | 77 +++++++ .../Components/Power/Chargers/BaseCharger.cs | 153 ++++++++++++++ .../Chargers/PowerCellChargerComponent.cs | 192 ++++++++++++++++++ .../WeaponCapacitorChargerComponent.cs | 183 +++++++++++++++++ .../EntitySystems/CellChargerSystem.cs | 25 +++ .../WeaponCapacitorChargerSystem.cs | 26 +++ .../Power/SharedPowerItemCharger.cs | 21 ++ .../Prototypes/Entities/items/powercells.yml | 92 +++++++++ .../PowerCells/cell_recharger.rsi/empty.png | Bin 0 -> 328 bytes .../PowerCells/cell_recharger.rsi/full.png | Bin 0 -> 450 bytes .../cell_recharger.rsi/light-charged.png | Bin 0 -> 1611 bytes .../cell_recharger.rsi/light-charging.png | Bin 0 -> 2059 bytes .../cell_recharger.rsi/light-empty.png | Bin 0 -> 214 bytes .../cell_recharger.rsi/light-off.png | Bin 0 -> 1886 bytes .../PowerCells/cell_recharger.rsi/meta.json | 59 ++++++ .../PowerCells/cell_recharger.rsi/open.png | Bin 0 -> 345 bytes .../Power/PowerCells/recharger.rsi/empty.png | Bin 0 -> 1902 bytes .../Power/PowerCells/recharger.rsi/full.png | Bin 0 -> 1902 bytes .../recharger.rsi/light-charged.png | Bin 0 -> 3189 bytes .../recharger.rsi/light-charging.png | Bin 0 -> 6554 bytes .../PowerCells/recharger.rsi/light-empty.png | Bin 0 -> 2796 bytes .../PowerCells/recharger.rsi/light-off.png | Bin 0 -> 1886 bytes .../Power/PowerCells/recharger.rsi/meta.json | 74 +++++++ .../PowerCells/wall_recharger.rsi/empty.png | Bin 0 -> 1884 bytes .../PowerCells/wall_recharger.rsi/full.png | Bin 0 -> 1884 bytes .../wall_recharger.rsi/light-charged.png | Bin 0 -> 3535 bytes .../wall_recharger.rsi/light-charging.png | Bin 0 -> 5743 bytes .../wall_recharger.rsi/light-empty.png | Bin 0 -> 3097 bytes .../wall_recharger.rsi/light-off.png | Bin 0 -> 1883 bytes .../PowerCells/wall_recharger.rsi/meta.json | 71 +++++++ 31 files changed, 975 insertions(+) create mode 100644 Content.Client/GameObjects/Components/Power/PowerChargerVisualizer2D.cs create mode 100644 Content.Server/GameObjects/Components/Power/Chargers/BaseCharger.cs create mode 100644 Content.Server/GameObjects/Components/Power/Chargers/PowerCellChargerComponent.cs create mode 100644 Content.Server/GameObjects/Components/Power/Chargers/WeaponCapacitorChargerComponent.cs create mode 100644 Content.Server/GameObjects/EntitySystems/CellChargerSystem.cs create mode 100644 Content.Server/GameObjects/EntitySystems/WeaponCapacitorChargerSystem.cs create mode 100644 Content.Shared/GameObjects/Components/Power/SharedPowerItemCharger.cs create mode 100644 Resources/Textures/Objects/Power/PowerCells/cell_recharger.rsi/empty.png create mode 100644 Resources/Textures/Objects/Power/PowerCells/cell_recharger.rsi/full.png create mode 100644 Resources/Textures/Objects/Power/PowerCells/cell_recharger.rsi/light-charged.png create mode 100644 Resources/Textures/Objects/Power/PowerCells/cell_recharger.rsi/light-charging.png create mode 100644 Resources/Textures/Objects/Power/PowerCells/cell_recharger.rsi/light-empty.png create mode 100644 Resources/Textures/Objects/Power/PowerCells/cell_recharger.rsi/light-off.png create mode 100644 Resources/Textures/Objects/Power/PowerCells/cell_recharger.rsi/meta.json create mode 100644 Resources/Textures/Objects/Power/PowerCells/cell_recharger.rsi/open.png create mode 100644 Resources/Textures/Objects/Power/PowerCells/recharger.rsi/empty.png create mode 100644 Resources/Textures/Objects/Power/PowerCells/recharger.rsi/full.png create mode 100644 Resources/Textures/Objects/Power/PowerCells/recharger.rsi/light-charged.png create mode 100644 Resources/Textures/Objects/Power/PowerCells/recharger.rsi/light-charging.png create mode 100644 Resources/Textures/Objects/Power/PowerCells/recharger.rsi/light-empty.png create mode 100644 Resources/Textures/Objects/Power/PowerCells/recharger.rsi/light-off.png create mode 100644 Resources/Textures/Objects/Power/PowerCells/recharger.rsi/meta.json create mode 100644 Resources/Textures/Objects/Power/PowerCells/wall_recharger.rsi/empty.png create mode 100644 Resources/Textures/Objects/Power/PowerCells/wall_recharger.rsi/full.png create mode 100644 Resources/Textures/Objects/Power/PowerCells/wall_recharger.rsi/light-charged.png create mode 100644 Resources/Textures/Objects/Power/PowerCells/wall_recharger.rsi/light-charging.png create mode 100644 Resources/Textures/Objects/Power/PowerCells/wall_recharger.rsi/light-empty.png create mode 100644 Resources/Textures/Objects/Power/PowerCells/wall_recharger.rsi/light-off.png create mode 100644 Resources/Textures/Objects/Power/PowerCells/wall_recharger.rsi/meta.json diff --git a/Content.Client/EntryPoint.cs b/Content.Client/EntryPoint.cs index 0a430aff72..865ab6fd31 100644 --- a/Content.Client/EntryPoint.cs +++ b/Content.Client/EntryPoint.cs @@ -97,6 +97,8 @@ namespace Content.Client "BallisticBullet", "HitscanWeaponCapacitor", "PowerCell", + "WeaponCapacitorCharger", + "PowerCellCharger", "AiController", "PlayerInputMover", "Computer", diff --git a/Content.Client/GameObjects/Components/Power/PowerChargerVisualizer2D.cs b/Content.Client/GameObjects/Components/Power/PowerChargerVisualizer2D.cs new file mode 100644 index 0000000000..7c9085941f --- /dev/null +++ b/Content.Client/GameObjects/Components/Power/PowerChargerVisualizer2D.cs @@ -0,0 +1,77 @@ +using Content.Shared.GameObjects.Components.Power; +using JetBrains.Annotations; +using Robust.Client.GameObjects; +using Robust.Client.Interfaces.GameObjects.Components; +using Robust.Shared.Interfaces.GameObjects; + +namespace Content.Client.GameObjects.Components.Power +{ + [UsedImplicitly] + public class PowerChargerVisualizer2D : AppearanceVisualizer + { + public override void InitializeEntity(IEntity entity) + { + base.InitializeEntity(entity); + + var sprite = entity.GetComponent(); + + // Base item + sprite.LayerMapSet(Layers.Base, sprite.AddLayerState("empty")); + + // Light + sprite.LayerMapSet(Layers.Light, sprite.AddLayerState("light-off")); + sprite.LayerSetShader(Layers.Light, "unshaded"); + } + + public override void OnChangeData(AppearanceComponent component) + { + base.OnChangeData(component); + + var sprite = component.Owner.GetComponent(); + + // Update base item + if (component.TryGetData(CellVisual.Occupied, out bool occupied)) + { + // TODO: don't throw if it doesn't have a full state + sprite.LayerSetState(Layers.Base, occupied ? "full" : "empty"); + } + else + { + sprite.LayerSetState(Layers.Base, "empty"); + } + + // Update lighting + if (component.TryGetData(CellVisual.Light, out CellChargerStatus status)) + { + switch (status) + { + case CellChargerStatus.Off: + sprite.LayerSetState(Layers.Light, "light-off"); + break; + case CellChargerStatus.Empty: + sprite.LayerSetState(Layers.Light, "light-empty"); + break; + case CellChargerStatus.Charging: + sprite.LayerSetState(Layers.Light, "light-charging"); + break; + case CellChargerStatus.Charged: + sprite.LayerSetState(Layers.Light, "light-charged"); + break; + default: + sprite.LayerSetState(Layers.Light, "light-off"); + break; + } + } + else + { + sprite.LayerSetState(Layers.Light, "light-off"); + } + } + + enum Layers + { + Base, + Light, + } + } +} diff --git a/Content.Server/GameObjects/Components/Power/Chargers/BaseCharger.cs b/Content.Server/GameObjects/Components/Power/Chargers/BaseCharger.cs new file mode 100644 index 0000000000..17e144bad8 --- /dev/null +++ b/Content.Server/GameObjects/Components/Power/Chargers/BaseCharger.cs @@ -0,0 +1,153 @@ +using System; +using Content.Shared.GameObjects.Components.Power; +using Robust.Server.GameObjects; +using Robust.Server.GameObjects.Components.Container; +using Robust.Shared.GameObjects; +using Robust.Shared.Interfaces.GameObjects; +using Robust.Shared.Log; +using Robust.Shared.Serialization; +using Robust.Shared.ViewVariables; + +namespace Content.Server.GameObjects.Components.Power.Chargers +{ + public abstract class BaseCharger : Component + { + + protected IEntity _heldItem; + protected ContainerSlot _container; + protected PowerDeviceComponent _powerDevice; + public CellChargerStatus Status => _status; + protected CellChargerStatus _status; + + protected AppearanceComponent _appearanceComponent; + + public abstract double CellChargePercent { get; } + + // Powered items have their own charge rates, this is just a way to have chargers with different rates as well + public float TransferRatio => _transferRatio; + [ViewVariables] + protected float _transferRatio; + + public float TransferEfficiency => _transferEfficiency; + [ViewVariables] + protected float _transferEfficiency; + + public override void ExposeData(ObjectSerializer serializer) + { + base.ExposeData(serializer); + + serializer.DataField(ref _transferRatio, "transfer_ratio", 0.1f); + serializer.DataField(ref _transferEfficiency, "transfer_efficiency", 0.85f); + } + + public override void Initialize() + { + base.Initialize(); + _powerDevice = Owner.GetComponent(); + if (_powerDevice == null) + { + var exc = new InvalidOperationException("Chargers requires a PowerDevice to function"); + Logger.FatalS("charger", exc.Message); + throw exc; + } + _container = + ContainerManagerComponent.Ensure($"{Name}-powerCellContainer", Owner); + _appearanceComponent = Owner.GetComponent(); + // Default state in the visualizer is OFF, so when this gets powered on during initialization it will generally show empty + _powerDevice.OnPowerStateChanged += PowerUpdate; + } + + /// + /// This will remove the item directly into the user's hand rather than the floor + /// + /// + public void RemoveItemToHand(IEntity user) + { + var heldItem = _container.ContainedEntity; + if (heldItem == null) + { + return; + } + RemoveItem(); + + if (user.TryGetComponent(out HandsComponent handsComponent) && + heldItem.TryGetComponent(out ItemComponent itemComponent)) + { + handsComponent.PutInHand(itemComponent); + } + } + + /// + /// Will put the charger's item on the floor if available + /// + public void RemoveItem() + { + if (_container.ContainedEntity == null) + { + return; + } + + _container.Remove(_heldItem); + UpdateStatus(); + } + + protected void PowerUpdate(object sender, PowerStateEventArgs eventArgs) + { + UpdateStatus(); + } + + protected abstract CellChargerStatus GetStatus(); + protected abstract void TransferPower(float frameTime); + + protected void UpdateStatus() + { + // Not called UpdateAppearance just because it messes with the load + var status = GetStatus(); + + if (_status == status) + { + return; + } + + _status = status; + + switch (_status) + { + // Update load just in case + case CellChargerStatus.Off: + _powerDevice.Load = 0; + _appearanceComponent?.SetData(CellVisual.Light, CellChargerStatus.Off); + break; + case CellChargerStatus.Empty: + _powerDevice.Load = 0; + _appearanceComponent?.SetData(CellVisual.Light, CellChargerStatus.Empty); ; + break; + case CellChargerStatus.Charging: + _appearanceComponent?.SetData(CellVisual.Light, CellChargerStatus.Charging); + break; + case CellChargerStatus.Charged: + _powerDevice.Load = 0; + _appearanceComponent?.SetData(CellVisual.Light, CellChargerStatus.Charged); + break; + default: + throw new ArgumentOutOfRangeException(); + } + + _appearanceComponent?.SetData(CellVisual.Occupied, _container.ContainedEntity != null); + + _status = status; + } + + public void OnUpdate(float frameTime) + { + if (_status == CellChargerStatus.Empty || _status == CellChargerStatus.Charged || + _container.ContainedEntity == null) + { + return; + } + + TransferPower(frameTime); + } + + } +} diff --git a/Content.Server/GameObjects/Components/Power/Chargers/PowerCellChargerComponent.cs b/Content.Server/GameObjects/Components/Power/Chargers/PowerCellChargerComponent.cs new file mode 100644 index 0000000000..5bbc43d1d6 --- /dev/null +++ b/Content.Server/GameObjects/Components/Power/Chargers/PowerCellChargerComponent.cs @@ -0,0 +1,192 @@ +using System; +using Content.Server.GameObjects.EntitySystems; +using Content.Shared.GameObjects; +using Content.Shared.GameObjects.Components.Power; +using Content.Shared.Interfaces; +using Robust.Server.GameObjects; +using Robust.Server.GameObjects.Components.Container; +using Robust.Shared.GameObjects; +using Robust.Shared.Interfaces.GameObjects; +using Robust.Shared.IoC; +using Robust.Shared.Localization; + +namespace Content.Server.GameObjects.Components.Power.Chargers +{ + /// + /// This is used for the standalone cell rechargers (e.g. from a flashlight) + /// + [RegisterComponent] + [ComponentReference(typeof(IActivate))] + [ComponentReference(typeof(IAttackBy))] + public sealed class PowerCellChargerComponent : BaseCharger, IActivate, IAttackBy + { + public override string Name => "PowerCellCharger"; + public override double CellChargePercent => _container.ContainedEntity != null ? + _container.ContainedEntity.GetComponent().Charge / + _container.ContainedEntity.GetComponent().Capacity * 100 : 0.0f; + + public override void Initialize() + { + base.Initialize(); + _powerDevice = Owner.GetComponent(); + _container = + ContainerManagerComponent.Ensure($"{Name}-powerCellContainer", Owner); + _appearanceComponent = Owner.GetComponent(); + // Default state in the visualizer is OFF, so when this gets powered on during initialization it will generally show empty + _powerDevice.OnPowerStateChanged += PowerUpdate; + } + + bool IAttackBy.AttackBy(AttackByEventArgs eventArgs) + { + var result = TryInsertItem(eventArgs.AttackWith); + if (result) + { + return true; + } + + var localizationManager = IoCManager.Resolve(); + eventArgs.User.PopupMessage(Owner, localizationManager.GetString("Unable to insert capacitor")); + + return false; + } + + void IActivate.Activate(ActivateEventArgs eventArgs) + { + RemoveItemToHand(eventArgs.User); + } + + [Verb] + private sealed class InsertVerb : Verb + { + protected override string GetText(IEntity user, PowerCellChargerComponent component) + { + if (!user.TryGetComponent(out HandsComponent handsComponent) || handsComponent.GetActiveHand == null) + { + return "Insert"; + } + return $"Insert {handsComponent.GetActiveHand.Owner.Name}"; + } + + protected override VerbVisibility GetVisibility(IEntity user, PowerCellChargerComponent component) + { + if (!user.TryGetComponent(out HandsComponent handsComponent)) + { + return VerbVisibility.Invisible; + } + + if (component._container.ContainedEntity != null || handsComponent.GetActiveHand == null) + { + return VerbVisibility.Disabled; + } + + return VerbVisibility.Visible; + } + + protected override void Activate(IEntity user, PowerCellChargerComponent component) + { + if (!user.TryGetComponent(out HandsComponent handsComponent)) + { + return; + } + + if (handsComponent.GetActiveHand == null) + { + return; + } + var userItem = handsComponent.GetActiveHand.Owner; + handsComponent.Drop(userItem); + component.TryInsertItem(userItem); + } + } + + [Verb] + private sealed class EjectVerb : Verb + { + protected override string GetText(IEntity user, PowerCellChargerComponent component) + { + if (component._container.ContainedEntity == null) + { + return "Eject"; + } + return $"Eject {component._container.ContainedEntity.Name}"; + } + + protected override VerbVisibility GetVisibility(IEntity user, PowerCellChargerComponent component) + { + if (component._container.ContainedEntity == null) + { + return VerbVisibility.Disabled; + } + return VerbVisibility.Visible; + } + + protected override void Activate(IEntity user, PowerCellChargerComponent component) + { + component.RemoveItem(); + } + } + + public bool TryInsertItem(IEntity entity) + { + if (!entity.HasComponent() || + _container.ContainedEntity != null) + { + return false; + } + + _heldItem = entity; + if (!_container.Insert(_heldItem)) + { + return false; + } + UpdateStatus(); + return true; + } + + protected override CellChargerStatus GetStatus() + { + if (!_powerDevice.Powered) + { + return CellChargerStatus.Off; + } + + if (_container.ContainedEntity == null) + { + return CellChargerStatus.Empty; + } + + if (_container.ContainedEntity.TryGetComponent(out PowerCellComponent component) && + Math.Abs(component.Capacity - component.Charge) < 0.01) + { + return CellChargerStatus.Charged; + } + + return CellChargerStatus.Charging; + } + + protected override void TransferPower(float frameTime) + { + // Two numbers: One for how much power actually goes into the device (chargeAmount) and + // chargeLoss which is how much is drawn from the powernet + _container.ContainedEntity.TryGetComponent(out PowerCellComponent cellComponent); + var chargeLoss = cellComponent.RequestCharge(frameTime) * _transferRatio; + _powerDevice.Load = chargeLoss; + + if (!_powerDevice.Powered) + { + // No power: Event should update to Off status + return; + } + + var chargeAmount = chargeLoss * _transferEfficiency; + + cellComponent.AddCharge(chargeAmount); + // Just so the sprite won't be set to 99.99999% visibility + if (cellComponent.Capacity - cellComponent.Charge < 0.01) + { + cellComponent.Charge = cellComponent.Capacity; + } + UpdateStatus(); + } + } +} diff --git a/Content.Server/GameObjects/Components/Power/Chargers/WeaponCapacitorChargerComponent.cs b/Content.Server/GameObjects/Components/Power/Chargers/WeaponCapacitorChargerComponent.cs new file mode 100644 index 0000000000..dbe9481d6f --- /dev/null +++ b/Content.Server/GameObjects/Components/Power/Chargers/WeaponCapacitorChargerComponent.cs @@ -0,0 +1,183 @@ +using System; +using Content.Server.GameObjects.Components.Weapon.Ranged.Hitscan; +using Content.Server.GameObjects.EntitySystems; +using Content.Shared.GameObjects; +using Content.Shared.GameObjects.Components.Power; +using Content.Shared.Interfaces; +using Robust.Server.GameObjects; +using Robust.Server.GameObjects.Components.Container; +using Robust.Shared.GameObjects; +using Robust.Shared.Interfaces.GameObjects; +using Robust.Shared.IoC; +using Robust.Shared.Localization; +using Robust.Shared.Serialization; +using Robust.Shared.ViewVariables; + +namespace Content.Server.GameObjects.Components.Power.Chargers +{ + /// + /// This is used for the lasergun / flash rechargers + /// + [RegisterComponent] + [ComponentReference(typeof(IActivate))] + [ComponentReference(typeof(IAttackBy))] + public sealed class WeaponCapacitorChargerComponent : BaseCharger, IActivate, IAttackBy + { + public override string Name => "WeaponCapacitorCharger"; + public override double CellChargePercent => _container.ContainedEntity != null ? + _container.ContainedEntity.GetComponent().Charge / + _container.ContainedEntity.GetComponent().Capacity * 100 : 0.0f; + + bool IAttackBy.AttackBy(AttackByEventArgs eventArgs) + { + var result = TryInsertItem(eventArgs.AttackWith); + if (!result) + { + var localizationManager = IoCManager.Resolve(); + eventArgs.User.PopupMessage(Owner, localizationManager.GetString("Unable to insert capacitor")); + } + + return result; + } + + void IActivate.Activate(ActivateEventArgs eventArgs) + { + RemoveItemToHand(eventArgs.User); + } + + [Verb] + private sealed class InsertVerb : Verb + { + protected override string GetText(IEntity user, WeaponCapacitorChargerComponent component) + { + if (!user.TryGetComponent(out HandsComponent handsComponent) || handsComponent.GetActiveHand == null) + { + return "Insert"; + } + return $"Insert {handsComponent.GetActiveHand.Owner.Name}"; + } + + protected override VerbVisibility GetVisibility(IEntity user, WeaponCapacitorChargerComponent component) + { + if (!user.TryGetComponent(out HandsComponent handsComponent)) + { + return VerbVisibility.Invisible; + } + + if (component._container.ContainedEntity != null || handsComponent.GetActiveHand == null) + { + return VerbVisibility.Disabled; + } + + return VerbVisibility.Visible; + } + + protected override void Activate(IEntity user, WeaponCapacitorChargerComponent component) + { + if (!user.TryGetComponent(out HandsComponent handsComponent)) + { + return; + } + + if (handsComponent.GetActiveHand == null) + { + return; + } + var userItem = handsComponent.GetActiveHand.Owner; + handsComponent.Drop(userItem); + component.TryInsertItem(userItem); + } + } + + [Verb] + private sealed class EjectVerb : Verb + { + protected override string GetText(IEntity user, WeaponCapacitorChargerComponent component) + { + if (component._container.ContainedEntity == null) + { + return "Eject"; + } + return $"Eject {component._container.ContainedEntity.Name}"; + } + + protected override VerbVisibility GetVisibility(IEntity user, WeaponCapacitorChargerComponent component) + { + if (component._container.ContainedEntity == null) + { + return VerbVisibility.Disabled; + } + return VerbVisibility.Visible; + } + + protected override void Activate(IEntity user, WeaponCapacitorChargerComponent component) + { + component.RemoveItem(); + } + } + + public bool TryInsertItem(IEntity entity) + { + if (!entity.HasComponent() || + _container.ContainedEntity != null) + { + return false; + } + + _heldItem = entity; + if (!_container.Insert(_heldItem)) + { + return false; + } + UpdateStatus(); + return true; + } + + protected override CellChargerStatus GetStatus() + { + if (!_powerDevice.Powered) + { + return CellChargerStatus.Off; + } + + if (_container.ContainedEntity == null) + { + return CellChargerStatus.Empty; + } + + if (_container.ContainedEntity.TryGetComponent(out HitscanWeaponCapacitorComponent component) && + Math.Abs(component.Capacity - component.Charge) < 0.01) + { + return CellChargerStatus.Charged; + } + + return CellChargerStatus.Charging; + } + + protected override void TransferPower(float frameTime) + { + // Two numbers: One for how much power actually goes into the device (chargeAmount) and + // chargeLoss which is how much is drawn from the powernet + _container.ContainedEntity.TryGetComponent(out HitscanWeaponCapacitorComponent weaponCapacitorComponent); + var chargeLoss = weaponCapacitorComponent.RequestCharge(frameTime) * _transferRatio; + _powerDevice.Load = chargeLoss; + + if (!_powerDevice.Powered) + { + // No power: Event should update to Off status + return; + } + + var chargeAmount = chargeLoss * _transferEfficiency; + + weaponCapacitorComponent.AddCharge(chargeAmount); + // Just so the sprite won't be set to 99.99999% visibility + if (weaponCapacitorComponent.Capacity - weaponCapacitorComponent.Charge < 0.01) + { + weaponCapacitorComponent.Charge = weaponCapacitorComponent.Capacity; + } + UpdateStatus(); + } + + } +} diff --git a/Content.Server/GameObjects/EntitySystems/CellChargerSystem.cs b/Content.Server/GameObjects/EntitySystems/CellChargerSystem.cs new file mode 100644 index 0000000000..2ae5b38c65 --- /dev/null +++ b/Content.Server/GameObjects/EntitySystems/CellChargerSystem.cs @@ -0,0 +1,25 @@ +using Content.Server.GameObjects.Components.Power.Chargers; +using JetBrains.Annotations; +using Robust.Shared.GameObjects; +using Robust.Shared.GameObjects.Systems; + +namespace Content.Server.GameObjects.EntitySystems +{ + [UsedImplicitly] + internal class CellChargerSystem : EntitySystem + { + public override void Initialize() + { + EntityQuery = new TypeEntityQuery(typeof(PowerCellChargerComponent)); + } + + public override void Update(float frameTime) + { + foreach (var entity in RelevantEntities) + { + var comp = entity.GetComponent(); + comp.OnUpdate(frameTime); + } + } + } +} diff --git a/Content.Server/GameObjects/EntitySystems/WeaponCapacitorChargerSystem.cs b/Content.Server/GameObjects/EntitySystems/WeaponCapacitorChargerSystem.cs new file mode 100644 index 0000000000..199489d339 --- /dev/null +++ b/Content.Server/GameObjects/EntitySystems/WeaponCapacitorChargerSystem.cs @@ -0,0 +1,26 @@ +using Content.Server.GameObjects.Components.Power; +using Content.Server.GameObjects.Components.Power.Chargers; +using JetBrains.Annotations; +using Robust.Shared.GameObjects; +using Robust.Shared.GameObjects.Systems; + +namespace Content.Server.GameObjects.EntitySystems +{ + [UsedImplicitly] + internal class WeaponCapacitorChargerSystem : EntitySystem + { + public override void Initialize() + { + EntityQuery = new TypeEntityQuery(typeof(WeaponCapacitorChargerComponent)); + } + + public override void Update(float frameTime) + { + foreach (var entity in RelevantEntities) + { + var comp = entity.GetComponent(); + comp.OnUpdate(frameTime); + } + } + } +} diff --git a/Content.Shared/GameObjects/Components/Power/SharedPowerItemCharger.cs b/Content.Shared/GameObjects/Components/Power/SharedPowerItemCharger.cs new file mode 100644 index 0000000000..8f2675727a --- /dev/null +++ b/Content.Shared/GameObjects/Components/Power/SharedPowerItemCharger.cs @@ -0,0 +1,21 @@ +using System; +using Robust.Shared.Serialization; + +namespace Content.Shared.GameObjects.Components.Power +{ + [Serializable, NetSerializable] + public enum CellChargerStatus + { + Off, + Empty, + Charging, + Charged, + } + + [Serializable, NetSerializable] + public enum CellVisual + { + Occupied, // If there's an item in it + Light, + } +} diff --git a/Resources/Prototypes/Entities/items/powercells.yml b/Resources/Prototypes/Entities/items/powercells.yml index a1a3de21dd..f4a2824089 100644 --- a/Resources/Prototypes/Entities/items/powercells.yml +++ b/Resources/Prototypes/Entities/items/powercells.yml @@ -94,3 +94,95 @@ visuals: - type: PowerCellVisualizer2D prefix: s_hy + +- type: entity + name: Cell Recharger + id: PowerCellRecharger + components: + - type: Sprite + netsync: false + sprite: Objects/Power/PowerCells/cell_recharger.rsi + drawdepth: Items + - type: PowerCellCharger + transfer_ratio: 0.10 + transfer_efficiency: 0.85 + - type: PowerDevice + priority: Low + - type: Icon + sprite: Objects/Power/PowerCells/cell_recharger.rsi + state: empty + - type: Appearance + visuals: + - type: PowerChargerVisualizer2D + - type: Wrenchable + - type: Physics + mass: 5 + - type: Clickable + - type: Collidable + shapes: + - !type:PhysShapeAabb + bounds: "-0.25,-0.25,0.25,0.25" + mask: 19 + layer: 16 + IsScrapingFloor: true + +- type: entity + name: Recharger + id: WeaponCapacitorRecharger + components: + - type: Sprite + netsync: false + sprite: Objects/Power/PowerCells/recharger.rsi + drawdepth: Items + - type: WeaponCapacitorCharger + transfer_ratio: 0.10 + transfer_efficiency: 0.85 + - type: PowerDevice + priority: Low + - type: Icon + sprite: Objects/Power/PowerCells/recharger.rsi + state: empty + - type: Appearance + visuals: + - type: PowerChargerVisualizer2D + - type: Wrenchable + - type: Physics + mass: 5 + - type: Clickable + - type: Collidable + shapes: + - !type:PhysShapeAabb + bounds: "-0.25,-0.25,0.25,0.25" + mask: 19 + layer: 16 + IsScrapingFloor: true + +- type: entity + name: Wall recharger + id: WallWeaponCapacitorRecharger + components: + - type: Sprite + netsync: false + sprite: Objects/Power/PowerCells/wall_recharger.rsi + drawdepth: Items + - type: WeaponCapacitorCharger + transfer_ratio: 0.15 + transfer_efficiency: 0.95 + - type: PowerDevice + priority: Low + - type: Icon + sprite: Objects/Power/PowerCells/wall_recharger.rsi + state: empty + - type: Appearance + visuals: + - type: PowerChargerVisualizer2D + - type: Physics + mass: 5 + - type: Clickable + - type: Collidable + shapes: + - !type:PhysShapeAabb + bounds: "-0.25,-0.25,0.25,0.25" + mask: 19 + layer: 16 + IsScrapingFloor: true diff --git a/Resources/Textures/Objects/Power/PowerCells/cell_recharger.rsi/empty.png b/Resources/Textures/Objects/Power/PowerCells/cell_recharger.rsi/empty.png new file mode 100644 index 0000000000000000000000000000000000000000..f35714867be56cb9657cd91923da944fef139d4e GIT binary patch literal 328 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 I&MBb@0FVnzlmGw# literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Power/PowerCells/cell_recharger.rsi/light-off.png b/Resources/Textures/Objects/Power/PowerCells/cell_recharger.rsi/light-off.png new file mode 100644 index 0000000000000000000000000000000000000000..1bdf052387ecd1862e3e0a0e156d77658a1909be GIT binary patch literal 1886 zcmV-k2ch_hP) zaB^>EX>4U6ba`-PAZ2)IW&i+q+U-|cmfR=|{bv=k1SBB@%MoDC$qr`ubHT3as!AuR zB=a+8Vs}{}V?FK_j}FJ*UuO6V7gH)Bsg+!Fj<`}yl^u-|&+C*F(|+!YuUF_l>BId6 zLnV-McJpzKcj)!w151~_J?n$@%TBorT`z71WqDrS#uemcNchy#)erRw$@4=x*Kc;N zOQr36_1aGcFowdOaNt8o;(qe!Nf3opaXe{1_dwh(f_LkwU*i|<(0u~nz4d}$?3Z3X z;5ZH4(#kJ5U3${b@!KdpMnrt~%#RVJ7A-zrkNC||<~+{qJmmnm@|DyrmEFQXK$>KK zmT?#N;Jr6(y?Wyjt~>>IW$TICMSQ&$u>uBl!(5P{$99@%N*}c)n`em{Ff_$;zL1T}03d>IMKGxD zL@|>nWs1gZM8L6tA4lXYi5nOo4ax&iauUfPr||NPZ;bX>RzB5OUOCwxck89s?t_O6ECFHUVWW&X{GbD+bfiO% zeArQrdiX@GO_^!x%+qF>b^4vPi`8e=UYYwoYjm;3o2WI;K3Id=>}G=2a-xefFvf|% zxGe@y(7ZT{g;L_h+~O=&mVi}?5v4A21}(`jFUli|41)_S0ZMinc18cGkGUVV>74gQ;^1vB3lMYwIPzXvByQPeI zeicxJ37eGoW^3iQSyOTBCL6{kRCLFIgYh?I_|bq%-aMFNVXiBf3S@aDFeM}8Fe^q$ zX-}zKz#g4jJ4t!qVKn9|t@Vevn`D5sRU5tH)AxUv@6kH1q{w!79}pK;Cq)-2@xG+c zBE|=o_i^4khx_gWgnF5&X2&?7YL=0T$HZ)IMGU;68$qgJ3`oq>6X}HvJlEGfe0;x) z@+|Lrf36-SZ!*9q63;T-u!z@*r#CH~^FDEyl_Z7uoOsNj28kcJF1!53x#+OKGs8wE zHAfsK7K?2xw=pXjD)AI?L{T-$7qTuZoVPfuF6XU=)mk0S1huC{9Q&B}(0bx!pvY$wI1&OG~mDK79CsRZc*F zhoQS?DoN(CkQ;Qf=PX3wr>4Y{WeyW1@wZ@ZH%Y-wl@O4S5NF`xcWzrsn-KW$ z;R99FknMn<-<~pXORzJnTel9Yd{9sj!^>|^XAIEM!}#0 Y02}Ewnr@L;u>b%707*qoM6N<$f{Iybi~s-t literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Power/PowerCells/cell_recharger.rsi/meta.json b/Resources/Textures/Objects/Power/PowerCells/cell_recharger.rsi/meta.json new file mode 100644 index 0000000000..e2e018ddc0 --- /dev/null +++ b/Resources/Textures/Objects/Power/PowerCells/cell_recharger.rsi/meta.json @@ -0,0 +1,59 @@ +{ + "version": 1, + "size": { + "x": 32, + "y": 32 + }, + "license": "CC-BY-SA-3.0", + "copyright": "https://github.com/vgstation-coders/vgstation13/raw/78a32d846158a67dcd0ca2375e408fec298b46a0/icons/obj/power.dmi", + "states": [ + { + "name": "light-off", + "directions": 1 + }, + { + "name": "empty", + "directions": 1 + }, + { + "name": "full", + "directions": 1 + }, + { + "name": "open", + "directions": 1 + }, + { + "name": "light-charging", + "directions": 1, + "delays": [ + [ + 0.2, + 0.2, + 0.2, + 0.2 + ] + ] + }, + { + "name": "light-charged", + "directions": 1, + "delays": [ + [ + 0.5, + 0.5 + ] + ] + }, + { + "name": "light-empty", + "directions": 1, + "delays": [ + [ + 0.5, + 0.5 + ] + ] + }, + ] +} \ No newline at end of file diff --git a/Resources/Textures/Objects/Power/PowerCells/cell_recharger.rsi/open.png b/Resources/Textures/Objects/Power/PowerCells/cell_recharger.rsi/open.png new file mode 100644 index 0000000000000000000000000000000000000000..2243cb263a273e9ce16f7e89c98db4bef1e7d765 GIT binary patch literal 345 zcmV-f0jB1pw6hNO!w}P(FDN{j9x^>Gb3JNGw_T0cX$lfV|8a(#^0T0 z=PuTw0+mETIOQS_r0T?e5k#iTFwgTF{O)|Mg1?N%7mt`|`YE06_nq8z9ULMR_^xEX ri8^>xplM@Q@ju>yB#;D>K%a2}a{X2nRk`p+00000NkvXXu0mjfTV#`? literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Power/PowerCells/recharger.rsi/empty.png b/Resources/Textures/Objects/Power/PowerCells/recharger.rsi/empty.png new file mode 100644 index 0000000000000000000000000000000000000000..d9f0521a2017e06b30b8af25bb03b2914f8b132a GIT binary patch literal 1902 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 Y02}Ewnr@L;u>b%707*qoM6N<$f{Iybi~s-t literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Power/PowerCells/recharger.rsi/meta.json b/Resources/Textures/Objects/Power/PowerCells/recharger.rsi/meta.json new file mode 100644 index 0000000000..9d6f9a028f --- /dev/null +++ b/Resources/Textures/Objects/Power/PowerCells/recharger.rsi/meta.json @@ -0,0 +1,74 @@ +{ + "version": 1, + "size": { + "x": 32, + "y": 32 + }, + "license": "CC-BY-SA-3.0", + "copyright": "https://github.com/discordia-space/CEV-Eris/raw/9ea3eccbe22e18d24653949067f3d7dd12194ea9/icons/obj/stationobjs.dmi", + "states": [ + { + "name": "empty", + "directions": 1, + "delays": [ + [ + 1.0 + ] + ] + }, + { + "name": "full", + "directions": 1, + "delays": [ + [ + 1.0 + ] + ] + }, + { + "name": "light-off", + "directions": 1, + "delays": [ + [ + 1 + ] + ] + }, + { + "name": "light-empty", + "directions": 1, + "delays": [ + [ + 1, + 0.2 + ] + ] + }, + { + "name": "light-charging", + "directions": 1, + "delays": [ + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ] + ] + }, + { + "name": "light-charged", + "directions": 1, + "delays": [ + [ + 0.2, + 0.1 + ] + ] + } + ] +} \ No newline at end of file diff --git a/Resources/Textures/Objects/Power/PowerCells/wall_recharger.rsi/empty.png b/Resources/Textures/Objects/Power/PowerCells/wall_recharger.rsi/empty.png new file mode 100644 index 0000000000000000000000000000000000000000..8552874f10db5b44aa3aabfdf3a01511ef630223 GIT binary patch literal 1884 zcmV-i2c!6jP) zaB^>EX>4U6ba`-PAZ2)IW&i+q+U-|cvLh!9{bv3aPjLi-&wolq)QO_C)KhvuXVqSyaWj!K3%lS*9#>+xO08EU1D!; zz0koBjINL;?05)?-yHmf#+`ie4XAavTAi;TGBF}PDNv_Elg6GKHJBK9uwiCyESs0aICI;egmu$obHJxd z0v-*>3D|tMg|^J058nFw2 z(7a-*JHF)3qF?VR%JJE$15aU2V+!g{z zXkM84L?Q4(Zeiv#ixW|XmAb&`v=9S=VG!%2J9Zz){S-Hc=zbPAeutb}(ES_8xdq(= zazEns2DM&xyOj;lszSsR9a2z!Gx)*@AOF?a{jPv-LH|!d(`(_{c_c5bgF6+8D#6o; z8ON)l9Y1dFiF!-4Lxg?^#fiyJ2}gLP0{NZUK|!vgj@2jpHsUjLZ4^uII*My0EAl_1 z@y{UC6U|bLXYE$|EW5^X?$|U?h^eCp^B~>U#(>jTM1N8gZP5GrVW}uSoFJmYn~M7G z`RMOlE0-Y={&0kEi#O_aZAI|7_8UGdu z5SAu-SDrE`!2Z(FVAYY<;}d=YpO=fmj@UXF821CCs!JwSAbCPyOqkpX1y&O+&sv{* zvCgVW;S;kZm(~i1z|f5Dz2FOIUd^J^QF5ze^f7JJ*h?QFuB?K=1L(3}_AM{Kb?b!K z&>?S0C>>5O>*2>S7UXgHiC7-Deo0y}T7Cm%2w0?b-qvFI$=Ttr2(R4JZI7?0gLlLf z>nD;wq1>+?K2iT*towo&--5mceGB?e1>tYf?AiSd*<#Dg(|TJK0004nX+uL$Nkc;* zaB^>EX>4Tx0C=2zkv&MmKp2MKriyA$WWauh>AE$6^me@v=v%)FuC*(nlvOS zE{=k0!NH%!s)LKOt`4q(Aov5~;_9U6A|-y86k5c1$8itueecWNcYshYGu7;v094H~ zlCh|m$*ziBujr%MgJFauX6o_OVj7;~>mEM7-$i(qcio?(U&)ya@QK88OgAjz4dR(i zOXs{#9ArgFAwDM_H|T=Ik6f2se&bwlSm2pKBb}Tl4ibxnHkR9%6%CbmnmDYe8s!Ta zmle)ioYiubHSft^7|3ZWDX!BBA%-Qyk$?ypRg_SMg$V5$DJGJ19`*2#IQ|5=WO9|j z$gzM5R7j2={11Nj*33^$x=Dd3(D`E9AEQ9mF3_mi_V=-EH%AO zrG<}xfoy{D4^000SaNLh0L z04^f{04^f|c%?sf00007bV*G`2jdG12^lm=uoJ!j009(9L_t(o!|jxzj)X7}hJSLW zD+wdk5zGmax_tpcf_wfV|anJAkHkCsttw82H#VVWhnyATyp(XJDKS}Gwl>` zI2`{S&t^=L#2h`asw!`f|GP~*%Q7&=ptar%WQ@)0$xliNrIe}b+B=lMt9V(Kn}M%> zN-3miy1Qd@0%a7L3(@LO8*v;%N;y~k8x|e-yk2qVd?D`p{whdH2_mxE4=0e_ZeE_} zh64+6n~=?Rl(*+A_;@_GKx>VrY0z~YhzOi>1VMmt z95D<7`o90#J%(iznalY+S2wl!dB4@-$*(91?3sYoKVX~xt%qo1ueihEa5x-}Kfw zaB^>EX>4U6ba`-PAZ2)IW&i+q+U-|cvLh!9{bv3aPjLi-&wolq)QO_C)KhvuXVqSyaWj!K3%lS*9#>+xO08EU1D!; zz0koBjINL;?05)?-yHmf#+`ie4XAavTAi;TGBF}PDNv_Elg6GKHJBK9uwiCyESs0aICI;egmu$obHJxd z0v-*>3D|tMg|^J058nFw2 z(7a-*JHF)3qF?VR%JJE$15aU2V+!g{z zXkM84L?Q4(Zeiv#ixW|XmAb&`v=9S=VG!%2J9Zz){S-Hc=zbPAeutb}(ES_8xdq(= zazEns2DM&xyOj;lszSsR9a2z!Gx)*@AOF?a{jPv-LH|!d(`(_{c_c5bgF6+8D#6o; z8ON)l9Y1dFiF!-4Lxg?^#fiyJ2}gLP0{NZUK|!vgj@2jpHsUjLZ4^uII*My0EAl_1 z@y{UC6U|bLXYE$|EW5^X?$|U?h^eCp^B~>U#(>jTM1N8gZP5GrVW}uSoFJmYn~M7G z`RMOlE0-Y={&0kEi#O_aZAI|7_8UGdu z5SAu-SDrE`!2Z(FVAYY<;}d=YpO=fmj@UXF821CCs!JwSAbCPyOqkpX1y&O+&sv{* zvCgVW;S;kZm(~i1z|f5Dz2FOIUd^J^QF5ze^f7JJ*h?QFuB?K=1L(3}_AM{Kb?b!K z&>?S0C>>5O>*2>S7UXgHiC7-Deo0y}T7Cm%2w0?b-qvFI$=Ttr2(R4JZI7?0gLlLf z>nD;wq1>+?K2iT*towo&--5mceGB?e1>tYf?AiSd*<#Dg(|TJK0004nX+uL$Nkc;* zaB^>EX>4Tx0C=2zkv&MmKp2MKriyA$WWauh>AE$6^me@v=v%)FuC*(nlvOS zE{=k0!NH%!s)LKOt`4q(Aov5~;_9U6A|-y86k5c1$8itueecWNcYshYGu7;v094H~ zlCh|m$*ziBujr%MgJFauX6o_OVj7;~>mEM7-$i(qcio?(U&)ya@QK88OgAjz4dR(i zOXs{#9ArgFAwDM_H|T=Ik6f2se&bwlSm2pKBb}Tl4ibxnHkR9%6%CbmnmDYe8s!Ta zmle)ioYiubHSft^7|3ZWDX!BBA%-Qyk$?ypRg_SMg$V5$DJGJ19`*2#IQ|5=WO9|j z$gzM5R7j2={11Nj*33^$x=Dd3(D`E9AEQ9mF3_mi_V=-EH%AO zrG<}xfoy{D4^000SaNLh0L z04^f{04^f|c%?sf00007bV*G`2jdG12^lm=uoJ!j009(9L_t(o!|jxzj)X7}hJSLW zD+wdk5zGmax_tpcf_wfV|anJAkHkCsttw82H#VVWhnyATyp(XJDKS}Gwl>` zI2`{S&t^=L#2h`asw!`f|GP~*%Q7&=ptar%WQ@)0$xliNrIe}b+B=lMt9V(Kn}M%> zN-3miy1Qd@0%a7L3(@LO8*v;%N;y~k8x|e-yk2qVd?D`p{whdH2_mxE4=0e_ZeE_} zh64+6n~=?Rl(*+A_;@_GKx>VrY0z~YhzOi>1VMmt z95D<7`o90#J%(iznalY+S2wl!dB4@-$*(91?3sYoKVX~xt%qo1ueihEa5x-}Kfw zaB^>EX>4U6ba`-PAZ2)IW&i+q+U=NGb|bm5hTpLYFCj4mhUEYV;GDYyFW+Avlai=b zwX6I3!4D=&OcI%x;vXVVZvFHBw)+RK=u34;O3f|ji&tu?h0d3H-LL!VuXH}oD?PXP z{nqZn>qej{a*g-Tyq@Pf?ef{7JR|w>-tNkL#;MOh{$t?tiZ-)-*JqK>Kr!6y{`u|N z)1l`t+j;)Ne1?4n|Nc7_f}z5AF}SdzkJtGO_e_yh#1=cB{{9SiYv=QBPk)S``v~0+ z0j$4>-}PEq{0zrE&}&=yTb!PDFW=hZ$MoTCMLs-_gwGrHl5mad>+4JW_SU-hx_8%8 zc7!WGn|f{WeB(g|N%3^cybFKA_j2BicfI;GK~34}aLhS<^MQzOpS=3+w_oQv{bY$L ztWdayFhe|THI~rAJfI|d`yGk{2aOdxCdfsa!^c|unYY<|Ojem$Jx>PDU|{_IcHbNR z?)z<^y^ZGHTQKV#E7lc^Uo69rvrnD^5Wk<8%89Rc_vQNjGGHSJ$_aC2gZ&!!5JUVY zx8lJ$UgCH(J(BiCp8*IFa|?@s*U4YmNAcNTC4}NVajf9eS$T*l3=r_*Bq*y4DaH&q zHQ3zrDgHbgB;3u|3qVNBu>cK10j!iHW%O2|PY9YE9C9p~{aMT-O zAefd9vi%2kpUC|ZH%D~;DsJH?5^N z50!t{-@Us3?*RWL1MM)kzt)g#uGGTT=Eg?-YwFHLb8WB#%AkkOEAM)`o)_dyG9WqZZ?y0G79c4}9{YZ0XEj@cTJt*}be1_fC9eEhF^R z%U+SOKutSSS1Ap;lxMMOEZF0+d;u0G(ck%1$PoL1ZX#<{K zMLQeZ8zGGN(Pgl131N@fN)%SgX4{E#C3g}mo-K-Q3H9=xT@W;z zXjVs1v`O0cUb$*Ygfm>HgGvEwBJVyEZIDYx_D&>1$dg z6wj+R_=iEe*B7p`q^;of zK!Vi{DA1#Ak*>^BcUjC-cYbXX2TrYvPNj%Q9Y0PTQ?2Z1H_R3DvaujB0JFFZAp*Rs zV@~6^M19&nV}I$GN%p*cqJgmV=oi8|x_ ziO!9pc|osNRI8VN7Q@e4aK9r4iWNCp_;SVT*T6TKV&ZzyoxsV)rHh#%dtkv>3T`ZY z%Q4G}{ZPzLBD9oBBjZR^8>{rj?lE$XWv=%&E3J6!9+2oJ;>!N))G*vRbpsP<_bA0| z0~g5IQUd;9{ze{g1N$DU!wJmvDvOO}lT9;G9n#@iD2qK5Jcct0W5wPUbdw=59Mi4a z;kxs7T{B%gvJrl{tzRu&5DR5+42+*QSr_{rmM1dXFjFKb&dxBQu+aIM9VK8G5I#=P zvq7a}#!s{~D|!GSn8hwe_C|fJqdVpsI0(hw)T54vYjLQ|qVRl+ugC6E0-2 zm0{YP+eFsXz&V+=Wofs%`%q5Os8>+EC-D!UN(2!H2rwg)5T`{OzP^m+RVlb)YW~fK zc^1(Y>b}7Pkk){lx+o5&8(9$)iy)CRCQKWaCb4>*?0G*XLq&@329hmXnkPwP!G-%* zi7dSW{{hw%da4iXmYVWr(Hhtn)TTzUBCv?h)9>cU z$;JZ$00z`r+~(K>EC}doQzflrjf|$qyxx`^%{HmwZ|@XxlWC1m4aDLhiX%3=vIF29*0eLk#ECY4IfU0r8(?kkeT`>r=CH#cUv!2XjI4bpn z)fz{um|V8ni~Qk6S_I&U;ud(%JnWKwI6HA^7WHWByywQujieNCk#kY7GM3OyXUoIn zAW?;AxIb1=NK$(<1J z19MlZQr{Cb^tr{Fc#yB!y^^Fnvkp2LCeEn0%SZ@jmkH2JOT`xEZ(cg1T875DTYc>Q1=m-_20maT^Z)<>g=s@WP)S2W zAaHVTW@&6?004NLeUUv#!$25@-=>Ox6$d-0bjVPhEQpFYN)?M>p|llRbuhW~51KS2 zDK3tJYr(;v#j1mgv#t)Vf*|+<;^OM0=prS4mlRsWc*k)M?|tvf-FJXcFEiEbm;hAG zGLo^Vn8~h+U9ae)*@Iz(BxdUI)M6T*b4)iZ;tk@N zO-tvzPaI@LNg+Nb9yjQM#E)E;U4G+Sa9H4(K_i`u36l!9l9NIyTFE$!7Ab} zNF;d36Id`*9j;4#5*2By9D;%Omh)N9@4NT&-MzC#zu(6`+X4367ytuc01SWu?6c+8 z-3)@@-T_;!mi3^vsW1LK2n9g^&-36o4$?He^FhaP%ys5RM2MmYoleIp`EBaw{wCgT zw>1FVe7VKrmyb*f0F6dNWPVC1BuRpDxorLBx2JDynUl$-x7kfte!2w#J5`uM?jZIir>{>C=J>R@2RtA0~-mBM5?)wB6r z&*pP|a&@gI)2Z(DdTW!l9n3ED%@TNcd5JI#ar(R8RSJvoNV}D~$b5dB0j>*3DOZBL zXgwFn&jdw_Hlc5-z|!~exl}TAi3n24mHu5*Eb|M)@ZJ?*SNbbua9#aP zlH|XG*_6Ls=?nfL!ruZ6fB`T72EYIq00UqE41fVJ00yvs_6tgdSjK&r{qg_+002ov JPDHLkV1jP!y-WZA literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Power/PowerCells/wall_recharger.rsi/light-charging.png b/Resources/Textures/Objects/Power/PowerCells/wall_recharger.rsi/light-charging.png new file mode 100644 index 0000000000000000000000000000000000000000..f1e81df2228e602c61207364db91a568f48af558 GIT binary patch literal 5743 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 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Power/PowerCells/wall_recharger.rsi/light-empty.png b/Resources/Textures/Objects/Power/PowerCells/wall_recharger.rsi/light-empty.png new file mode 100644 index 0000000000000000000000000000000000000000..a97a1d873cdb5e2504e5da6ec6a525efc9cb2b6b GIT binary patch literal 3097 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 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Power/PowerCells/wall_recharger.rsi/light-off.png b/Resources/Textures/Objects/Power/PowerCells/wall_recharger.rsi/light-off.png new file mode 100644 index 0000000000000000000000000000000000000000..091dc8c7daf334b34eddf515f4d1dd73cc426bcd GIT binary patch literal 1883 zcmV-h2c-CkP) zaB^>EX>4U6ba`-PAZ2)IW&i+q+U-|aa^yA){pTri1Og-o@;KmDl^f*vd7w1yZjUF4 zT}f3wEV;Qr6qff0hz{$I-*@;87ZY*FqP4VABCgzWW5b}v>$-Z1`LyTa`w`|Z^6+@T z5GC~KnwE91H^}Af10q^z?cGki36`hDV~-uO9@`2mJBUjEniYYt7v0tKjRl3(0u^lWAqNcIBt1* zgX2>4Bdqccr&~_)F@6W7XOD;9Mt1Ytmv5srz5LLx$!upWWQ;% z2Jkae1s?;$p|`!24$mn{z|tJAd?B5;0zd@Y0%x$V zGsQwls8Cd9B?68W{1`mvl(~Zek{~?cCFhh1$f@kM@s842%fgo!>P�?YNob{M ztF1LN7`1HBWmsW^wYP2q+h^n-e2DUO`osy|eamlJW$z!+x& z$i5sPDt3WFoY)MhZ7XlH-P*>9V0IK$eADvb)r2FP=coGM2ADzK|lr& zb07lwh_=krp?JF;`sY0@d^v%90Ci)Vm}d*(3Vb>gt1jd|*UN&Y74%8~ zI|=a7qfhf@VV%s01K-VtNsM+@Sv28a_0RJ;^rM3K( zIxzc5dab2}kAQ(~;NrTa$$P-%4lwkjONQh~ep*6454@kzH)VmrTcCH%?OXF4rw>4y zdbNB592^2;1_U{K-opPP(AM@Y<000JJOGiWi{{a60|De66lK=n! z32;bRa{vG?BLDy{BLR4&KXw2B00(qQO+^Re3kwMw2_x=3EdT%k4M{{nR9M69l%bA< zFc60S%bl(yj95o7CrIk{1qca#Esus@U&9Nm1#xD%RBb3!Hh4}!mZgYt=925D+R04+ znQ5nh$K(0$yxELtnjSu|swyY{51V+N=U|M%7_%G57+cn}pHd21Yt(gpEP+>XA;fOr ztDn{yS(Z6>Y)L@GF|I_LLv18U0;SYa^>0{p;Bvd+oAZ@;5Coebr4)$BYCoJne!rtA z3UFX0ZWFTEj`IF|1)q-xzD_4ZQ3PWQhzLZ4wrwG$#57HiQo