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 0000000000..f35714867b Binary files /dev/null and b/Resources/Textures/Objects/Power/PowerCells/cell_recharger.rsi/empty.png differ diff --git a/Resources/Textures/Objects/Power/PowerCells/cell_recharger.rsi/full.png b/Resources/Textures/Objects/Power/PowerCells/cell_recharger.rsi/full.png new file mode 100644 index 0000000000..539dec1e56 Binary files /dev/null and b/Resources/Textures/Objects/Power/PowerCells/cell_recharger.rsi/full.png differ diff --git a/Resources/Textures/Objects/Power/PowerCells/cell_recharger.rsi/light-charged.png b/Resources/Textures/Objects/Power/PowerCells/cell_recharger.rsi/light-charged.png new file mode 100644 index 0000000000..f30e8365a1 Binary files /dev/null and b/Resources/Textures/Objects/Power/PowerCells/cell_recharger.rsi/light-charged.png differ diff --git a/Resources/Textures/Objects/Power/PowerCells/cell_recharger.rsi/light-charging.png b/Resources/Textures/Objects/Power/PowerCells/cell_recharger.rsi/light-charging.png new file mode 100644 index 0000000000..c990794c86 Binary files /dev/null and b/Resources/Textures/Objects/Power/PowerCells/cell_recharger.rsi/light-charging.png differ diff --git a/Resources/Textures/Objects/Power/PowerCells/cell_recharger.rsi/light-empty.png b/Resources/Textures/Objects/Power/PowerCells/cell_recharger.rsi/light-empty.png new file mode 100644 index 0000000000..4a5c1c74f1 Binary files /dev/null and b/Resources/Textures/Objects/Power/PowerCells/cell_recharger.rsi/light-empty.png differ 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 0000000000..1bdf052387 Binary files /dev/null and b/Resources/Textures/Objects/Power/PowerCells/cell_recharger.rsi/light-off.png differ 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 0000000000..2243cb263a Binary files /dev/null and b/Resources/Textures/Objects/Power/PowerCells/cell_recharger.rsi/open.png differ 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 0000000000..d9f0521a20 Binary files /dev/null and b/Resources/Textures/Objects/Power/PowerCells/recharger.rsi/empty.png differ diff --git a/Resources/Textures/Objects/Power/PowerCells/recharger.rsi/full.png b/Resources/Textures/Objects/Power/PowerCells/recharger.rsi/full.png new file mode 100644 index 0000000000..d9f0521a20 Binary files /dev/null and b/Resources/Textures/Objects/Power/PowerCells/recharger.rsi/full.png differ diff --git a/Resources/Textures/Objects/Power/PowerCells/recharger.rsi/light-charged.png b/Resources/Textures/Objects/Power/PowerCells/recharger.rsi/light-charged.png new file mode 100644 index 0000000000..4cc391bb8f Binary files /dev/null and b/Resources/Textures/Objects/Power/PowerCells/recharger.rsi/light-charged.png differ diff --git a/Resources/Textures/Objects/Power/PowerCells/recharger.rsi/light-charging.png b/Resources/Textures/Objects/Power/PowerCells/recharger.rsi/light-charging.png new file mode 100644 index 0000000000..cf95e5ae1c Binary files /dev/null and b/Resources/Textures/Objects/Power/PowerCells/recharger.rsi/light-charging.png differ diff --git a/Resources/Textures/Objects/Power/PowerCells/recharger.rsi/light-empty.png b/Resources/Textures/Objects/Power/PowerCells/recharger.rsi/light-empty.png new file mode 100644 index 0000000000..1c2d4ea6fc Binary files /dev/null and b/Resources/Textures/Objects/Power/PowerCells/recharger.rsi/light-empty.png differ diff --git a/Resources/Textures/Objects/Power/PowerCells/recharger.rsi/light-off.png b/Resources/Textures/Objects/Power/PowerCells/recharger.rsi/light-off.png new file mode 100644 index 0000000000..1bdf052387 Binary files /dev/null and b/Resources/Textures/Objects/Power/PowerCells/recharger.rsi/light-off.png differ 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 0000000000..8552874f10 Binary files /dev/null and b/Resources/Textures/Objects/Power/PowerCells/wall_recharger.rsi/empty.png differ diff --git a/Resources/Textures/Objects/Power/PowerCells/wall_recharger.rsi/full.png b/Resources/Textures/Objects/Power/PowerCells/wall_recharger.rsi/full.png new file mode 100644 index 0000000000..8552874f10 Binary files /dev/null and b/Resources/Textures/Objects/Power/PowerCells/wall_recharger.rsi/full.png differ diff --git a/Resources/Textures/Objects/Power/PowerCells/wall_recharger.rsi/light-charged.png b/Resources/Textures/Objects/Power/PowerCells/wall_recharger.rsi/light-charged.png new file mode 100644 index 0000000000..d43831ec47 Binary files /dev/null and b/Resources/Textures/Objects/Power/PowerCells/wall_recharger.rsi/light-charged.png differ 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 0000000000..f1e81df222 Binary files /dev/null and b/Resources/Textures/Objects/Power/PowerCells/wall_recharger.rsi/light-charging.png differ 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 0000000000..a97a1d873c Binary files /dev/null and b/Resources/Textures/Objects/Power/PowerCells/wall_recharger.rsi/light-empty.png differ 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 0000000000..091dc8c7da Binary files /dev/null and b/Resources/Textures/Objects/Power/PowerCells/wall_recharger.rsi/light-off.png differ diff --git a/Resources/Textures/Objects/Power/PowerCells/wall_recharger.rsi/meta.json b/Resources/Textures/Objects/Power/PowerCells/wall_recharger.rsi/meta.json new file mode 100644 index 0000000000..67d2cf23bb --- /dev/null +++ b/Resources/Textures/Objects/Power/PowerCells/wall_recharger.rsi/meta.json @@ -0,0 +1,71 @@ +{ + "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 + ] + ] + }, + { + "name": "light-charged", + "directions": 1, + "delays": [ + [ + 0.2, + 0.1 + ] + ] + } + ] +} \ No newline at end of file