]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
BatteryWeaponPowerCell tweaks (#33500)
authorKirus59 <145689588+Kirus59@users.noreply.github.com>
Tue, 29 Apr 2025 01:12:25 +0000 (04:12 +0300)
committerGitHub <noreply@github.com>
Tue, 29 Apr 2025 01:12:25 +0000 (21:12 -0400)
* BatteryWeaponPowerCell tweaks

* add update ammo ev & shuttle guns tweaks

* MilonPL requested changes

* revert changes in OnPowerCellChanged

* Add events to get charge info & change current charge

---------

Co-authored-by: Nemanja <98561806+EmoGarbage404@users.noreply.github.com>
Content.Server/Power/Components/BatteryComponent.cs
Content.Server/Power/EntitySystems/BatterySystem.cs
Content.Server/PowerCell/PowerCellSystem.cs
Content.Server/Weapons/Ranged/Systems/GunSystem.Battery.cs
Content.Server/Weapons/Ranged/Systems/GunSystem.cs
Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.Battery.cs
Resources/Prototypes/Entities/Objects/Power/powercells.yml
Resources/Prototypes/Entities/Objects/Weapons/Guns/Battery/battery_guns.yml
Resources/Prototypes/Entities/Structures/Shuttles/cannons.yml

index 860b7b219a83e7b76e0f9c4e86781a69f37e1ff9..96571bcca3242f863a928ab67dfd3c8db5458438 100644 (file)
@@ -38,4 +38,30 @@ namespace Content.Server.Power.Components
     /// </summary>
     [ByRefEvent]
     public readonly record struct ChargeChangedEvent(float Charge, float MaxCharge);
+
+    /// <summary>
+    ///     Raised when it is necessary to get information about battery charges.
+    /// </summary>
+    [ByRefEvent]
+    public sealed class GetChargeEvent : EntityEventArgs
+    {
+        public float CurrentCharge;
+        public float MaxCharge;
+    }
+
+    /// <summary>
+    ///     Raised when it is necessary to change the current battery charge to a some value.
+    /// </summary>
+    [ByRefEvent]
+    public sealed class ChangeChargeEvent : EntityEventArgs
+    {
+        public float OriginalValue;
+        public float ResidualValue;
+
+        public ChangeChargeEvent(float value)
+        {
+            OriginalValue = value;
+            ResidualValue = value;
+        }
+    }
 }
index 89e3ed2c1f62367ab9858674068493fc02c66087..a0ce3ddaade9e7777dd2b4bbc2216645eb08a548 100644 (file)
@@ -24,6 +24,8 @@ namespace Content.Server.Power.EntitySystems
             SubscribeLocalEvent<BatteryComponent, RejuvenateEvent>(OnBatteryRejuvenate);
             SubscribeLocalEvent<BatteryComponent, PriceCalculationEvent>(CalculateBatteryPrice);
             SubscribeLocalEvent<BatteryComponent, EmpPulseEvent>(OnEmpPulse);
+            SubscribeLocalEvent<BatteryComponent, ChangeChargeEvent>(OnChangeCharge);
+            SubscribeLocalEvent<BatteryComponent, GetChargeEvent>(OnGetCharge);
 
             SubscribeLocalEvent<NetworkBatteryPreSync>(PreSync);
             SubscribeLocalEvent<NetworkBatteryPostSync>(PostSync);
@@ -116,21 +118,26 @@ namespace Content.Server.Power.EntitySystems
             TrySetChargeCooldown(uid);
         }
 
-        public float UseCharge(EntityUid uid, float value, BatteryComponent? battery = null)
+        private void OnChangeCharge(Entity<BatteryComponent> entity, ref ChangeChargeEvent args)
         {
-            if (value <= 0 ||  !Resolve(uid, ref battery) || battery.CurrentCharge == 0)
-                return 0;
+            if (args.ResidualValue == 0)
+                return;
 
-            var newValue = Math.Clamp(0, battery.CurrentCharge - value, battery.MaxCharge);
-            var delta = newValue - battery.CurrentCharge;
-            battery.CurrentCharge = newValue;
+            args.ResidualValue -= ChangeCharge(entity, args.ResidualValue);
+        }
 
-            // Apply a cooldown to the entity's self recharge if needed.
-            TrySetChargeCooldown(uid);
+        private void OnGetCharge(Entity<BatteryComponent> entity, ref GetChargeEvent args)
+        {
+            args.CurrentCharge += entity.Comp.CurrentCharge;
+            args.MaxCharge += entity.Comp.MaxCharge;
+        }
 
-            var ev = new ChargeChangedEvent(battery.CurrentCharge, battery.MaxCharge);
-            RaiseLocalEvent(uid, ref ev);
-            return delta;
+        public float UseCharge(EntityUid uid, float value, BatteryComponent? battery = null)
+        {
+            if (value <= 0 || !Resolve(uid, ref battery) || battery.CurrentCharge == 0)
+                return 0;
+
+            return ChangeCharge(uid, -value, battery);
         }
 
         public void SetMaxCharge(EntityUid uid, float value, BatteryComponent? battery = null)
@@ -164,6 +171,26 @@ namespace Content.Server.Power.EntitySystems
             var ev = new ChargeChangedEvent(battery.CurrentCharge, battery.MaxCharge);
             RaiseLocalEvent(uid, ref ev);
         }
+
+        /// <summary>
+        /// Changes the current battery charge by some value
+        /// </summary>
+        public float ChangeCharge(EntityUid uid, float value, BatteryComponent? battery = null)
+        {
+            if (!Resolve(uid, ref battery))
+                return 0;
+
+            var newValue = Math.Clamp(0, battery.CurrentCharge + value, battery.MaxCharge);
+            var delta = newValue - battery.CurrentCharge;
+            battery.CurrentCharge = newValue;
+
+            TrySetChargeCooldown(uid);
+
+            var ev = new ChargeChangedEvent(battery.CurrentCharge, battery.MaxCharge);
+            RaiseLocalEvent(uid, ref ev);
+            return delta;
+        }
+
         /// <summary>
         /// Checks if the entity has a self recharge and puts it on cooldown if applicable.
         /// </summary>
index f7b4cf024917e805d92ae5f98a009b6c825b1df3..01767d6c41e8f1ef5b58abccb42279392fa95683 100644 (file)
@@ -42,6 +42,9 @@ public sealed partial class PowerCellSystem : SharedPowerCellSystem
         SubscribeLocalEvent<PowerCellSlotComponent, ExaminedEvent>(OnCellSlotExamined);
         // funny
         SubscribeLocalEvent<PowerCellSlotComponent, BeingMicrowavedEvent>(OnSlotMicrowaved);
+
+        SubscribeLocalEvent<PowerCellSlotComponent, GetChargeEvent>(OnGetCharge);
+        SubscribeLocalEvent<PowerCellSlotComponent, ChangeChargeEvent>(OnChangeCharge);
     }
 
     private void OnSlotMicrowaved(EntityUid uid, PowerCellSlotComponent component, BeingMicrowavedEvent args)
@@ -244,4 +247,20 @@ public sealed partial class PowerCellSystem : SharedPowerCellSystem
             args.PushMarkup(Loc.GetString("power-cell-component-examine-details-no-battery"));
         }
     }
+
+    private void OnGetCharge(Entity<PowerCellSlotComponent> entity, ref GetChargeEvent args)
+    {
+        if (!TryGetBatteryFromSlot(entity, out var batteryUid, out _))
+            return;
+
+        RaiseLocalEvent(batteryUid.Value, ref args);
+    }
+
+    private void OnChangeCharge(Entity<PowerCellSlotComponent> entity, ref ChangeChargeEvent args)
+    {
+        if (!TryGetBatteryFromSlot(entity, out var batteryUid, out _))
+            return;
+
+        RaiseLocalEvent(batteryUid.Value, ref args);
+    }
 }
index ad4bb714d938d464db89aa05bf513aaeddbd23d5..1cb19f075589dfe62c694212e3fb7f3c97217e34 100644 (file)
@@ -2,9 +2,11 @@ using Content.Server.Power.Components;
 using Content.Shared.Damage;
 using Content.Shared.Damage.Events;
 using Content.Shared.FixedPoint;
+using Content.Shared.PowerCell.Components;
 using Content.Shared.Projectiles;
 using Content.Shared.Weapons.Ranged;
 using Content.Shared.Weapons.Ranged.Components;
+using Content.Shared.Weapons.Ranged.Events;
 using Robust.Shared.Prototypes;
 
 namespace Content.Server.Weapons.Ranged.Systems;
@@ -19,29 +21,36 @@ public sealed partial class GunSystem
         SubscribeLocalEvent<HitscanBatteryAmmoProviderComponent, ComponentStartup>(OnBatteryStartup);
         SubscribeLocalEvent<HitscanBatteryAmmoProviderComponent, ChargeChangedEvent>(OnBatteryChargeChange);
         SubscribeLocalEvent<HitscanBatteryAmmoProviderComponent, DamageExamineEvent>(OnBatteryDamageExamine);
+        SubscribeLocalEvent<HitscanBatteryAmmoProviderComponent, PowerCellChangedEvent>(OnPowerCellChanged);
 
         // Projectile
         SubscribeLocalEvent<ProjectileBatteryAmmoProviderComponent, ComponentStartup>(OnBatteryStartup);
         SubscribeLocalEvent<ProjectileBatteryAmmoProviderComponent, ChargeChangedEvent>(OnBatteryChargeChange);
         SubscribeLocalEvent<ProjectileBatteryAmmoProviderComponent, DamageExamineEvent>(OnBatteryDamageExamine);
+        SubscribeLocalEvent<ProjectileBatteryAmmoProviderComponent, PowerCellChangedEvent>(OnPowerCellChanged);
     }
 
-    private void OnBatteryStartup(EntityUid uid, BatteryAmmoProviderComponent component, ComponentStartup args)
+    private void OnBatteryStartup<T>(Entity<T> entity, ref ComponentStartup args) where T : BatteryAmmoProviderComponent
     {
-        UpdateShots(uid, component);
+        UpdateShots(entity, entity.Comp);
     }
 
-    private void OnBatteryChargeChange(EntityUid uid, BatteryAmmoProviderComponent component, ref ChargeChangedEvent args)
+    private void OnBatteryChargeChange<T>(Entity<T> entity, ref ChargeChangedEvent args) where T : BatteryAmmoProviderComponent
     {
-        UpdateShots(uid, component, args.Charge, args.MaxCharge);
+        UpdateShots(entity, entity.Comp, args.Charge, args.MaxCharge);
+    }
+
+    private void OnPowerCellChanged<T>(Entity<T> entity, ref PowerCellChangedEvent args) where T : BatteryAmmoProviderComponent
+    {
+        UpdateShots(entity, entity.Comp);
     }
 
     private void UpdateShots(EntityUid uid, BatteryAmmoProviderComponent component)
     {
-        if (!TryComp<BatteryComponent>(uid, out var battery))
-            return;
+        var ev = new GetChargeEvent();
+        RaiseLocalEvent(uid, ref ev);
 
-        UpdateShots(uid, component, battery.CurrentCharge, battery.MaxCharge);
+        UpdateShots(uid, component, ev.CurrentCharge, ev.MaxCharge);
     }
 
     private void UpdateShots(EntityUid uid, BatteryAmmoProviderComponent component, float charge, float maxCharge)
@@ -55,18 +64,24 @@ public sealed partial class GunSystem
         }
 
         component.Shots = shots;
-        component.Capacity = maxShots;
+
+        if (maxShots > 0)
+            component.Capacity = maxShots;
+
         UpdateBatteryAppearance(uid, component);
+
+        var updateAmmoEv = new UpdateClientAmmoEvent();
+        RaiseLocalEvent(uid, ref updateAmmoEv);
     }
 
-    private void OnBatteryDamageExamine(EntityUid uid, BatteryAmmoProviderComponent component, ref DamageExamineEvent args)
+    private void OnBatteryDamageExamine<T>(Entity<T> entity, ref DamageExamineEvent args) where T : BatteryAmmoProviderComponent
     {
-        var damageSpec = GetDamage(component);
+        var damageSpec = GetDamage(entity.Comp);
 
         if (damageSpec == null)
             return;
 
-        var damageType = component switch
+        var damageType = entity.Comp switch
         {
             HitscanBatteryAmmoProviderComponent => Loc.GetString("damage-hitscan"),
             ProjectileBatteryAmmoProviderComponent => Loc.GetString("damage-projectile"),
@@ -103,9 +118,9 @@ public sealed partial class GunSystem
         return null;
     }
 
-    protected override void TakeCharge(EntityUid uid, BatteryAmmoProviderComponent component)
+    protected override void TakeCharge(Entity<BatteryAmmoProviderComponent> entity)
     {
-        // Will raise ChargeChangedEvent
-        _battery.UseCharge(uid, component.FireCost);
+        var ev = new ChangeChargeEvent(-entity.Comp.FireCost);
+        RaiseLocalEvent(entity, ref ev);
     }
 }
index b8d488b575a160ae6daf9620175d57f1ddf3e4ff..b8622817259657adcd5cc89f3089646faad20a5e 100644 (file)
@@ -22,6 +22,7 @@ using Robust.Shared.Player;
 using Robust.Shared.Prototypes;
 using Robust.Shared.Utility;
 using Robust.Shared.Containers;
+using Content.Server.PowerCell;
 
 namespace Content.Server.Weapons.Ranged.Systems;
 
@@ -34,6 +35,7 @@ public sealed partial class GunSystem : SharedGunSystem
     [Dependency] private readonly SharedColorFlashEffectSystem _color = default!;
     [Dependency] private readonly StaminaSystem _stamina = default!;
     [Dependency] private readonly SharedContainerSystem _container = default!;
+    [Dependency] private readonly PowerCellSystem _powerCell = default!;
     [Dependency] private readonly SharedMapSystem _map = default!;
 
     private const float DamagePitchVariation = 0.05f;
index d6e741fed6e47b1ecfc2429490de66ba731d0a10..ea865fced663a9ab04ea35c812cdc995ed67da66 100644 (file)
@@ -67,7 +67,7 @@ public abstract partial class SharedGunSystem
             component.Shots--;
         }
 
-        TakeCharge(uid, component);
+        TakeCharge((uid, component));
         UpdateBatteryAppearance(uid, component);
         Dirty(uid, component);
     }
@@ -81,9 +81,9 @@ public abstract partial class SharedGunSystem
     /// <summary>
     /// Update the battery (server-only) whenever fired.
     /// </summary>
-    protected virtual void TakeCharge(EntityUid uid, BatteryAmmoProviderComponent component)
+    protected virtual void TakeCharge(Entity<BatteryAmmoProviderComponent> entity)
     {
-        UpdateAmmoCount(uid, prediction: false);
+        UpdateAmmoCount(entity, prediction: false);
     }
 
     protected void UpdateBatteryAppearance(EntityUid uid, BatteryAmmoProviderComponent component)
index 8ca2ba7b1128c5cc9412c98badfd843b711b942a..15d15cc6acd18d5f8137e48767666c299e07a477 100644 (file)
@@ -33,9 +33,6 @@
   - type: Appearance
   - type: PowerCellVisuals
   - type: Riggable
-  - type: HitscanBatteryAmmoProvider
-    proto: RedLightLaser
-    fireCost: 50
 
 - type: entity
   name: potato battery
   - type: Tag
     tags:
       - PowerCage
-  - type: HitscanBatteryAmmoProvider
-    proto: RedShuttleLaser
-    fireCost: 150
   - type: ClothingSpeedModifier
     walkModifier: 0.8
     sprintModifier: 0.8
index 47f8e8496c3c80586624f0f8345b577edf37e3b7..427af659f30340fd38b74c3a60936c99d2cbf365 100644 (file)
     - SemiAuto
     soundGunshot:
       path: /Audio/Weapons/Guns/Gunshots/laser.ogg
-  - type: MagazineAmmoProvider
+  - type: HitscanBatteryAmmoProvider
+    proto: RedLightLaser
+    fireCost: 50
   - type: ItemSlots
     slots:
-      gun_magazine:
+      cell_slot:
         name: Magazine
         startingItem: PowerCellSmall
         insertSound: /Audio/Weapons/Guns/MagIn/batrifle_magin.ogg
           tags:
             - PowerCell
             - PowerCellSmall
+  - type: PowerCellSlot
+    cellSlotId: cell_slot
   - type: Appearance
   - type: StaticPrice
     price: 500
   - type: ContainerContainer
     containers:
-      gun_magazine: !type:ContainerSlot
+      cell_slot: !type:ContainerSlot
 
 - type: entity
   id: BaseWeaponBatterySmall
index 1926b3e87487d845f3077948b0f17c06f18577f1..f056a48f0dbbc6681337a8eee3234f696375753d 100644 (file)
@@ -56,7 +56,7 @@
     containers:
       machine_board: !type:Container
       machine_parts: !type:Container
-      gun_magazine: !type:ContainerSlot
+      cell_slot: !type:ContainerSlot
   - type: Destructible
     thresholds:
     - trigger:
     zeroVisible: true
   - type: Machine
     board: ShuttleGunSvalinnMachineGunCircuitboard
+  - type: PowerCellSlot
+    cellSlotId: cell_slot
   - type: ItemSlots
     slots:
-      gun_magazine:
+      cell_slot:
         name: Magazine
         insertSound: /Audio/Weapons/Guns/MagIn/batrifle_magin.ogg
         ejectSound: /Audio/Weapons/Guns/MagOut/batrifle_magout.ogg
@@ -90,7 +92,9 @@
           tags:
             - PowerCell
             - PowerCellSmall
-  - type: MagazineAmmoProvider
+  - type: HitscanBatteryAmmoProvider
+    proto: RedLightLaser
+    fireCost: 50
 
 - type: entity
   id: ShuttleGunPerforator
     containers:
       machine_board: !type:Container
       machine_parts: !type:Container
-      gun_magazine: !type:ContainerSlot
+      cell_slot: !type:ContainerSlot
   - type: Destructible
     thresholds:
     - trigger:
     zeroVisible: true
   - type: Machine
     board: ShuttleGunPerforatorCircuitboard
+  - type: PowerCellSlot
+    cellSlotId: cell_slot
   - type: ItemSlots
     slots:
-      gun_magazine:
+      cell_slot:
         name: Magazine
         insertSound: /Audio/Weapons/Guns/MagIn/batrifle_magin.ogg
         ejectSound: /Audio/Weapons/Guns/MagOut/batrifle_magout.ogg
         whitelist:
           tags:
             - PowerCage
-  - type: MagazineAmmoProvider
+  - type: HitscanBatteryAmmoProvider
+    proto: RedShuttleLaser
+    fireCost: 150
 
 # ---- Launchers ----
 # naming: EXP (Explosion) + conventional power + suffix (g for Grenade, c for RPG Cartridge) + Name