diff --git a/Content.Server/Power/EntitySystems/ChargerSystem.cs b/Content.Server/Power/EntitySystems/ChargerSystem.cs index 3959f25bf7..7b6bcbcb06 100644 --- a/Content.Server/Power/EntitySystems/ChargerSystem.cs +++ b/Content.Server/Power/EntitySystems/ChargerSystem.cs @@ -92,7 +92,10 @@ internal sealed class ChargerSystem : EntitySystem if (!TryComp(args.EntityUid, out PowerCellSlotComponent? cellSlot)) return; - if (!cellSlot.FitsInCharger || !cellSlot.CellSlot.HasItem) + if (!_itemSlotsSystem.TryGetSlotById(args.EntityUid, cellSlot.CellSlotId, out ItemSlot? itemSlot)) + return; + + if (!cellSlot.FitsInCharger || !itemSlot.HasItem) args.Cancel(); } } diff --git a/Content.Server/PowerCell/PowerCellSystem.cs b/Content.Server/PowerCell/PowerCellSystem.cs index 1a997bf484..7d7d13fffa 100644 --- a/Content.Server/PowerCell/PowerCellSystem.cs +++ b/Content.Server/PowerCell/PowerCellSystem.cs @@ -10,6 +10,7 @@ using Content.Shared.Rounding; using Robust.Shared.Containers; using System.Diagnostics.CodeAnalysis; using Content.Server.Kitchen.Components; +using Content.Shared.Containers.ItemSlots; namespace Content.Server.PowerCell; @@ -17,8 +18,10 @@ public sealed class PowerCellSystem : SharedPowerCellSystem { [Dependency] private readonly SolutionContainerSystem _solutionsSystem = default!; [Dependency] private readonly ExplosionSystem _explosionSystem = default!; - [Dependency] private readonly IAdminLogManager _adminLogger= default!; + [Dependency] private readonly IAdminLogManager _adminLogger = default!; [Dependency] private readonly SharedContainerSystem _containerSystem = default!; + [Dependency] private readonly ItemSlotsSystem _itemSlotsSystem = default!; + [Dependency] private readonly SharedAppearanceSystem _sharedAppearanceSystem = default!; public override void Initialize() { @@ -36,10 +39,13 @@ public sealed class PowerCellSystem : SharedPowerCellSystem private void OnSlotMicrowaved(EntityUid uid, PowerCellSlotComponent component, BeingMicrowavedEvent args) { - if (component.CellSlot.Item == null) - return; + if (_itemSlotsSystem.TryGetSlotById(uid, component.CellSlotId, out ItemSlot? slot)) + { + if (slot.Item == null) + return; - RaiseLocalEvent(component.CellSlot.Item.Value, args, false); + RaiseLocalEvent(slot.Item.Value, args, false); + } } private void OnMicrowaved(EntityUid uid, BatteryComponent component, BeingMicrowavedEvent args) @@ -69,14 +75,15 @@ public sealed class PowerCellSystem : SharedPowerCellSystem var frac = battery.CurrentCharge / battery.MaxCharge; var level = (byte) ContentHelpers.RoundToNearestLevels(frac, 1, PowerCellComponent.PowerCellVisualsLevels); - appearance.SetData(PowerCellVisuals.ChargeLevel, level); + _sharedAppearanceSystem.SetData(uid, PowerCellVisuals.ChargeLevel, level, appearance); // If this power cell is inside a cell-slot, inform that entity that the power has changed (for updating visuals n such). if (_containerSystem.TryGetContainingContainer(uid, out var container) && TryComp(container.Owner, out PowerCellSlotComponent? slot) - && slot.CellSlot.Item == uid) + && _itemSlotsSystem.TryGetSlotById(container.Owner, slot.CellSlotId, out ItemSlot? itemSlot)) { - RaiseLocalEvent(container.Owner, new PowerCellChangedEvent(false), false); + if (itemSlot.Item == uid) + RaiseLocalEvent(container.Owner, new PowerCellChangedEvent(false), false); } } @@ -101,7 +108,13 @@ public sealed class PowerCellSystem : SharedPowerCellSystem return false; } - return TryComp(component.CellSlot.Item, out battery); + if (_itemSlotsSystem.TryGetSlotById(uid, component.CellSlotId, out ItemSlot? slot)) + { + return TryComp(slot.Item, out battery); + } + + battery = null; + return false; } private void OnSolutionChange(EntityUid uid, PowerCellComponent component, SolutionChangedEvent args) diff --git a/Content.Shared/Containers/ItemSlot/ItemSlotsSystem.cs b/Content.Shared/Containers/ItemSlot/ItemSlotsSystem.cs index 1b68b393f4..2157e1edfd 100644 --- a/Content.Shared/Containers/ItemSlot/ItemSlotsSystem.cs +++ b/Content.Shared/Containers/ItemSlot/ItemSlotsSystem.cs @@ -125,6 +125,16 @@ namespace Content.Shared.Containers.ItemSlots else Dirty(itemSlots); } + + public bool TryGetSlotById(EntityUid uid, string slotId, [NotNullWhen(true)] out ItemSlot? itemSlot, ItemSlotsComponent? component = null) + { + itemSlot = null; + + if (!Resolve(uid, ref component)) + return false; + + return component.Slots.TryGetValue(slotId, out itemSlot); + } #endregion #region Interactions diff --git a/Content.Shared/PowerCell/Components/PowerCellSlotComponent.cs b/Content.Shared/PowerCell/Components/PowerCellSlotComponent.cs index 304ba3dac9..990a4ec128 100644 --- a/Content.Shared/PowerCell/Components/PowerCellSlotComponent.cs +++ b/Content.Shared/PowerCell/Components/PowerCellSlotComponent.cs @@ -12,37 +12,8 @@ public sealed class PowerCellSlotComponent : Component /// Given that needs to verify that a given cell has the correct cell-size before /// inserting anyways, there is no need to specify a separate entity whitelist. In this slot's yaml definition. /// - [DataField("cellSlot")] - public ItemSlot CellSlot = new(); - - /// - /// Name of the item-slot used to store cells. Determines the eject/insert verb text. E.g., "Eject > Power cell". - /// - /// - /// This is simply used provide a default value for . If this string is empty or - /// whitespace, the verb will instead use the full name of any cell (e.g., "eject > small super-capacity power - /// cell"). - /// - [DataField("slotName")] - public readonly string SlotName = "power-cell-slot-component-slot-name-default"; // gets Loc.GetString()-ed by ItemSlotsSystem - - /// - /// True if we don't want a cell inserted during map init. If a starting item is defined - /// in the yaml definition, that always takes precedence. - /// - /// - /// If false, the cell will start with a standard cell with a matching cell-size. - /// - [DataField("startEmpty")] - public bool StartEmpty = false; - - /// - /// Descriptive text to add to add when examining an entity with a cell slot. If empty or whitespace, will not add - /// any text. - /// - [ViewVariables(VVAccess.ReadWrite)] - [DataField("descFormatString")] - public string? DescFormatString { get; set; } = "power-cell-slot-component-description-default"; + [DataField("cellSlotId", required: true)] + public string CellSlotId = string.Empty; /// /// Can this entity be inserted directly into a charging station? If false, you need to manually remove the power @@ -50,6 +21,7 @@ public sealed class PowerCellSlotComponent : Component /// [DataField("fitsInCharger")] public bool FitsInCharger = true; + } /// diff --git a/Content.Shared/PowerCell/SharedPowerCellSystem.cs b/Content.Shared/PowerCell/SharedPowerCellSystem.cs index ae9c9f973c..c0d80bdd33 100644 --- a/Content.Shared/PowerCell/SharedPowerCellSystem.cs +++ b/Content.Shared/PowerCell/SharedPowerCellSystem.cs @@ -1,5 +1,3 @@ -using Content.Shared.Containers.ItemSlots; -using Content.Shared.Examine; using Content.Shared.PowerCell.Components; using Robust.Shared.Containers; @@ -7,17 +5,9 @@ namespace Content.Shared.PowerCell; public abstract class SharedPowerCellSystem : EntitySystem { - [Dependency] private readonly ItemSlotsSystem _itemSlotsSystem = default!; - - public const string CellSlotContainer = "cell_slot"; - public override void Initialize() { base.Initialize(); - - SubscribeLocalEvent(OnCellSlotInit); - SubscribeLocalEvent(OnCellSlotRemove); - SubscribeLocalEvent(OnCellInserted); SubscribeLocalEvent(OnCellRemoved); SubscribeLocalEvent(OnCellInsertAttempt); @@ -28,7 +18,7 @@ public abstract class SharedPowerCellSystem : EntitySystem if (!component.Initialized) return; - if (args.Container.ID != component.CellSlot.ID) + if (args.Container.ID != component.CellSlotId) return; if (!HasComp(args.EntityUid)) @@ -42,7 +32,7 @@ public abstract class SharedPowerCellSystem : EntitySystem if (!component.Initialized) return; - if (args.Container.ID != component.CellSlot.ID) + if (args.Container.ID != component.CellSlotId) return; RaiseLocalEvent(uid, new PowerCellChangedEvent(false), false); @@ -50,25 +40,9 @@ public abstract class SharedPowerCellSystem : EntitySystem private void OnCellRemoved(EntityUid uid, PowerCellSlotComponent component, EntRemovedFromContainerMessage args) { - if (args.Container.ID != component.CellSlot.ID) + if (args.Container.ID != component.CellSlotId) return; RaiseLocalEvent(uid, new PowerCellChangedEvent(true), false); } - - private void OnCellSlotInit(EntityUid uid, PowerCellSlotComponent component, ComponentInit args) - { - _itemSlotsSystem.AddItemSlot(uid, CellSlotContainer, component.CellSlot); - - if (string.IsNullOrWhiteSpace(component.CellSlot.Name) && - !string.IsNullOrWhiteSpace(component.SlotName)) - { - component.CellSlot.Name = component.SlotName; - } - } - - private void OnCellSlotRemove(EntityUid uid, PowerCellSlotComponent component, ComponentRemove args) - { - _itemSlotsSystem.RemoveItemSlot(uid, component.CellSlot); - } } diff --git a/Resources/Locale/en-US/power-cell/components/power-cell-slot-component.ftl b/Resources/Locale/en-US/power-cell/components/power-cell-slot-component.ftl index a5357eca44..c40c50d469 100644 --- a/Resources/Locale/en-US/power-cell/components/power-cell-slot-component.ftl +++ b/Resources/Locale/en-US/power-cell/components/power-cell-slot-component.ftl @@ -1,8 +1,2 @@ -# Default examine descriptions -power-cell-slot-component-description-default = It uses {$size} power cells. -power-cell-slot-component-description-size-small = small -power-cell-slot-component-description-size-medium = medium-sized -power-cell-slot-component-description-size-large = large - # Verbs power-cell-slot-component-slot-name-default = Power cell diff --git a/Resources/Prototypes/Entities/Clothing/Head/base_clothinghead.yml b/Resources/Prototypes/Entities/Clothing/Head/base_clothinghead.yml index 03f49baeba..518d98eb3d 100644 --- a/Resources/Prototypes/Entities/Clothing/Head/base_clothinghead.yml +++ b/Resources/Prototypes/Entities/Clothing/Head/base_clothinghead.yml @@ -58,12 +58,16 @@ - type: FlashLightVisualizer - type: HandheldLight addPrefix: true - - type: Battery - maxCharge: 600 #lights drain 3/s but recharge of 2 makes this 1/s. Therefore 600 is 10 minutes of light. - startingCharge: 600 - - type: BatterySelfRecharger - autoRecharge: true - autoRechargeRate: 2 #recharge of 2 makes total drain 1w / s so max charge is 1:1 with time. Time to fully charge should be 5 minutes. Having recharge gives light an extended flicker period which gives you some warning to return to light area. + - type: PowerCellSlot + cellSlotId: cell_slot + - type: ItemSlots + slots: + cell_slot: + name: power-cell-slot-component-slot-name-default + startingItem: PowerCellMedium + - type: ContainerContainer + containers: + cell_slot: !type:ContainerSlot {} - type: entity abstract: true diff --git a/Resources/Prototypes/Entities/Clothing/Head/hardhats.yml b/Resources/Prototypes/Entities/Clothing/Head/hardhats.yml index 20bf63df30..83774cc8f1 100644 --- a/Resources/Prototypes/Entities/Clothing/Head/hardhats.yml +++ b/Resources/Prototypes/Entities/Clothing/Head/hardhats.yml @@ -35,14 +35,17 @@ head: - state: on-equipped-HELMET - type: PowerCellSlot - cellSlot: - startingItem: PowerCellMedium + cellSlotId: cell_slot + - type: ItemSlots + slots: + cell_slot: + name: power-cell-slot-component-slot-name-default + startingItem: PowerCellMedium - type: Item heldPrefix: off - type: ContainerContainer containers: cell_slot: !type:ContainerSlot - - type: ItemSlots - type: entity parent: ClothingHeadHatHardhatBase diff --git a/Resources/Prototypes/Entities/Clothing/Head/helmets.yml b/Resources/Prototypes/Entities/Clothing/Head/helmets.yml index 8328d8c3ff..62deb27c12 100644 --- a/Resources/Prototypes/Entities/Clothing/Head/helmets.yml +++ b/Resources/Prototypes/Entities/Clothing/Head/helmets.yml @@ -207,9 +207,6 @@ sprite: Clothing/Head/Helmets/firehelmet.rsi quickEquip: true - type: IngestionBlocker - - type: PowerCellSlot - cellSlot: - startingItem: PowerCellMedium - type: TemperatureProtection coefficient: 0.01 - type: Armor @@ -221,10 +218,10 @@ Heat: 0.65 Radiation: 1 - type: IdentityBlocker - - type: ItemSlots - - type: ContainerContainer - containers: - cell_slot: !type:ContainerSlot {} + - type: Tag + tags: + - HidesHair + - WhitelistChameleon - type: entity parent: ClothingHeadLightBase diff --git a/Resources/Prototypes/Entities/Objects/Devices/holoprojectors.yml b/Resources/Prototypes/Entities/Objects/Devices/holoprojectors.yml index a2789a15f2..cf74cb4b38 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/holoprojectors.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/holoprojectors.yml @@ -8,13 +8,16 @@ - type: ItemCooldown - type: UseDelay delay: 1.0 - - type: ItemSlots - type: ContainerContainer containers: cell_slot: !type:ContainerSlot {} - type: PowerCellSlot - cellSlot: - startingItem: PowerCellMedium + cellSlotId: cell_slot + - type: ItemSlots + slots: + cell_slot: + name: power-cell-slot-component-slot-name-default + startingItem: PowerCellMedium - type: Sprite sprite: Objects/Devices/Holoprojectors/custodial.rsi state: icon diff --git a/Resources/Prototypes/Entities/Objects/Misc/fluff_lights.yml b/Resources/Prototypes/Entities/Objects/Misc/fluff_lights.yml index f68b97b231..7f44193281 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/fluff_lights.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/fluff_lights.yml @@ -7,7 +7,11 @@ - type: HandheldLight addPrefix: true - type: PowerCellSlot + cellSlotId: cell_slot - type: ItemSlots + slots: + cell_slot: + name: power-cell-slot-component-slot-name-default - type: ContainerContainer containers: cell_slot: !type:ContainerSlot diff --git a/Resources/Prototypes/Entities/Objects/Tools/flashlights.yml b/Resources/Prototypes/Entities/Objects/Tools/flashlights.yml index 5efab18f72..5e179be37f 100644 --- a/Resources/Prototypes/Entities/Objects/Tools/flashlights.yml +++ b/Resources/Prototypes/Entities/Objects/Tools/flashlights.yml @@ -26,12 +26,15 @@ - state: inhand-right-light shader: unshaded - type: PowerCellSlot - cellSlot: - startingItem: PowerCellMedium + cellSlotId: cell_slot - type: ContainerContainer containers: cell_slot: !type:ContainerSlot - type: ItemSlots + slots: + cell_slot: + name: power-cell-slot-component-slot-name-default + startingItem: PowerCellMedium - type: Sprite sprite: Objects/Tools/flashlight.rsi netsync: false @@ -64,9 +67,11 @@ - type: Tag tags: - SecBeltEquip - - type: PowerCellSlot - cellSlot: - startingItem: PowerCellHigh + - type: ItemSlots + slots: + cell_slot: + name: power-cell-slot-component-slot-name-default + startingItem: PowerCellHigh - type: HandheldLight addPrefix: false - type: ToggleableLightVisuals diff --git a/Resources/Prototypes/Entities/Objects/Tools/lantern.yml b/Resources/Prototypes/Entities/Objects/Tools/lantern.yml index 94b6711b3b..15abd2d80c 100644 --- a/Resources/Prototypes/Entities/Objects/Tools/lantern.yml +++ b/Resources/Prototypes/Entities/Objects/Tools/lantern.yml @@ -28,9 +28,12 @@ - type: LanternVisualizer - type: ToggleableLightVisuals - type: PowerCellSlot - cellSlot: - startingItem: PowerCellMedium + cellSlotId: cell_slot - type: ItemSlots + slots: + cell_slot: + name: power-cell-slot-component-slot-name-default + startingItem: PowerCellMedium - type: ContainerContainer containers: cell_slot: !type:ContainerSlot {}