]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Rework the HoS's Energy Shotgun (Varying energy consumption depending on fire-mode...
authorBramvanZijp <56019239+BramvanZijp@users.noreply.github.com>
Wed, 11 Dec 2024 16:21:04 +0000 (17:21 +0100)
committerGitHub <noreply@github.com>
Wed, 11 Dec 2024 16:21:04 +0000 (17:21 +0100)
* Rebalance HoS's Energy Shotgun

* SLIGHTLY Up the max charge so the gun properly recharges all of its charges, which matters a lot more with the self charge cooldown system.

* Prevent recharge cooldown if 0 power is used.

* Makes the clientside HUD actually update to reflect the changes in firecost and thus max/current charges.

* Properly fix that recharging to just under full issue instead of applying a budget fix to only the eshotgun.

* Clean up the client ammo UI fix.

* Update the self recharger component to comply with maintainer request.

Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
* Remove code that was made redundant by a hotfix from another PR.

* Make the recharge pause on EMP, document things where needed, clean up code as per maintainer request, add a note to make the code better when power is moved to shared.

* Fix another internal issue

* Code cleanup + fix the rapid recharge verb to remove pause.

* cleanup

---------

Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
Co-authored-by: metalgearsloth <comedian_vs_clown@hotmail.com>
Content.Client/Weapons/Ranged/Systems/GunSystem.cs
Content.Server/Administration/Systems/AdminVerbSystem.Tools.cs
Content.Server/Power/Components/BatterySelfRechargerComponent.cs
Content.Server/Power/EntitySystems/BatterySystem.cs
Content.Shared/Weapons/Ranged/Events/UpdateClientAmmoEvent.cs [new file with mode: 0644]
Content.Shared/Weapons/Ranged/Systems/BatteryWeaponFireModesSystem.cs
Resources/Prototypes/Entities/Objects/Weapons/Guns/Battery/battery_guns.yml

index 710ee7c7cbf7365a21fe4cd1c6afc9fed94254cd..0ad22bf1d8787814c255278f0fc93be92ab031bc 100644 (file)
@@ -77,6 +77,7 @@ public sealed partial class GunSystem : SharedGunSystem
         base.Initialize();
         UpdatesOutsidePrediction = true;
         SubscribeLocalEvent<AmmoCounterComponent, ItemStatusCollectMessage>(OnAmmoCounterCollect);
+        SubscribeLocalEvent<AmmoCounterComponent, UpdateClientAmmoEvent>(OnUpdateClientAmmo);
         SubscribeAllEvent<MuzzleFlashEvent>(OnMuzzleFlash);
 
         // Plays animated effects on the client.
@@ -86,6 +87,11 @@ public sealed partial class GunSystem : SharedGunSystem
         InitializeSpentAmmo();
     }
 
+    private void OnUpdateClientAmmo(EntityUid uid, AmmoCounterComponent ammoComp, ref UpdateClientAmmoEvent args)
+    {
+        UpdateAmmoCount(uid, ammoComp);
+    }
+
     private void OnMuzzleFlash(MuzzleFlashEvent args)
     {
         var gunUid = GetEntity(args.Uid);
index 70fcfccc4eb9f161e82131264d4fcae803d4685b..8dccaabad6088f11c32a1e17fe2a10cbdcc2ef69 100644 (file)
@@ -204,6 +204,7 @@ public sealed partial class AdminVerbSystem
                         var recharger = EnsureComp<BatterySelfRechargerComponent>(args.Target);
                         recharger.AutoRecharge = true;
                         recharger.AutoRechargeRate = battery.MaxCharge; // Instant refill.
+                        recharger.AutoRechargePause = false; // No delay.
                     },
                     Impact = LogImpact.Medium,
                     Message = Loc.GetString("admin-trick-infinite-battery-object-description"),
@@ -603,6 +604,7 @@ public sealed partial class AdminVerbSystem
 
                         recharger.AutoRecharge = true;
                         recharger.AutoRechargeRate = battery.MaxCharge; // Instant refill.
+                        recharger.AutoRechargePause = false; // No delay.
                     }
                 },
                 Impact = LogImpact.Extreme,
index 4798beb7573976075601e75742824499a4cf3fda..1cb92d9cd6311d51ae327d8eab1661dc47ef74cb 100644 (file)
@@ -1,3 +1,5 @@
+using System;
+
 namespace Content.Server.Power.Components
 {
     /// <summary>
@@ -6,8 +8,29 @@ namespace Content.Server.Power.Components
     [RegisterComponent]
     public sealed partial class BatterySelfRechargerComponent : Component
     {
-        [ViewVariables(VVAccess.ReadWrite)] [DataField("autoRecharge")] public bool AutoRecharge { get; set; }
+        /// <summary>
+        /// Does the entity auto recharge?
+        /// </summary>
+        [DataField] public bool AutoRecharge;
+
+        /// <summary>
+        /// At what rate does the entity automatically recharge?
+        /// </summary>
+        [DataField] public float AutoRechargeRate;
+
+        /// <summary>
+        /// Should this entity stop automatically recharging if a charge is used?
+        /// </summary>
+        [DataField] public bool AutoRechargePause = false;
+
+        /// <summary>
+        /// How long should the entity stop automatically recharging if a charge is used?
+        /// </summary>
+        [DataField] public float AutoRechargePauseTime = 0f;
 
-        [ViewVariables(VVAccess.ReadWrite)] [DataField("autoRechargeRate")] public float AutoRechargeRate { get; set; }
+        /// <summary>
+        /// Do not auto recharge if this timestamp has yet to happen, set for the auto recharge pause system.
+        /// </summary>
+        [DataField] public TimeSpan NextAutoRecharge = TimeSpan.FromSeconds(0f);
     }
 }
index ed2d54ffaa60f0aa3432809050324d630481ab71..eac31ecef789d1864c2cd563f503f0e21537de3a 100644 (file)
@@ -3,14 +3,18 @@ using Content.Server.Emp;
 using Content.Server.Power.Components;
 using Content.Shared.Examine;
 using Content.Shared.Rejuvenate;
+using Content.Shared.Timing;
 using JetBrains.Annotations;
 using Robust.Shared.Utility;
+using Robust.Shared.Timing;
 
 namespace Content.Server.Power.EntitySystems
 {
     [UsedImplicitly]
     public sealed class BatterySystem : EntitySystem
     {
+        [Dependency] protected readonly IGameTiming Timing = default!;
+
         public override void Initialize()
         {
             base.Initialize();
@@ -84,6 +88,14 @@ namespace Content.Server.Power.EntitySystems
             while (query.MoveNext(out var uid, out var comp, out var batt))
             {
                 if (!comp.AutoRecharge) continue;
+                if (batt.IsFullyCharged) continue;
+
+                if (comp.AutoRechargePause)
+                {
+                    if (comp.NextAutoRecharge > Timing.CurTime)
+                        continue;
+                }
+
                 SetCharge(uid, batt.CurrentCharge + comp.AutoRechargeRate * frameTime, batt);
             }
         }
@@ -100,6 +112,8 @@ namespace Content.Server.Power.EntitySystems
         {
             args.Affected = true;
             UseCharge(uid, args.EnergyConsumption, component);
+            // Apply a cooldown to the entity's self recharge if needed to avoid it immediately self recharging after an EMP.
+            TrySetChargeCooldown(uid);
         }
 
         public float UseCharge(EntityUid uid, float value, BatteryComponent? battery = null)
@@ -110,6 +124,10 @@ namespace Content.Server.Power.EntitySystems
             var newValue = Math.Clamp(0, battery.CurrentCharge - value, battery.MaxCharge);
             var delta = newValue - battery.CurrentCharge;
             battery.CurrentCharge = newValue;
+
+            // Apply a cooldown to the entity's self recharge if needed.
+            TrySetChargeCooldown(uid);
+
             var ev = new ChargeChangedEvent(battery.CurrentCharge, battery.MaxCharge);
             RaiseLocalEvent(uid, ref ev);
             return delta;
@@ -139,11 +157,47 @@ namespace Content.Server.Power.EntitySystems
             battery.CurrentCharge = MathHelper.Clamp(value, 0, battery.MaxCharge);
             if (MathHelper.CloseTo(battery.CurrentCharge, old) &&
                 !(old != battery.CurrentCharge && battery.CurrentCharge == battery.MaxCharge))
+            {
                 return;
+            }
 
             var ev = new ChargeChangedEvent(battery.CurrentCharge, battery.MaxCharge);
             RaiseLocalEvent(uid, ref ev);
         }
+        /// <summary>
+        /// Checks if the entity has a self recharge and puts it on cooldown if applicable.
+        /// </summary>
+        public void TrySetChargeCooldown(EntityUid uid, float value = -1)
+        {
+            if (!TryComp<BatterySelfRechargerComponent>(uid, out var batteryself))
+                return;
+
+            if (!batteryself.AutoRechargePause)
+                return;
+
+            // If no answer or a negative is given for value, use the default from AutoRechargePauseTime.
+            if (value < 0)
+                value = batteryself.AutoRechargePauseTime;
+
+            if (Timing.CurTime + TimeSpan.FromSeconds(value) <= batteryself.NextAutoRecharge)
+                return;
+
+            SetChargeCooldown(uid, batteryself.AutoRechargePauseTime, batteryself);
+        }
+
+        /// <summary>
+        /// Puts the entity's self recharge on cooldown for the specified time.
+        /// </summary>
+        public void SetChargeCooldown(EntityUid uid, float value, BatterySelfRechargerComponent? batteryself = null)
+        {
+            if (!Resolve(uid, ref batteryself))
+                return;
+
+            if (value >= 0)
+                batteryself.NextAutoRecharge = Timing.CurTime + TimeSpan.FromSeconds(value);
+            else
+                batteryself.NextAutoRecharge = Timing.CurTime;
+        }
 
         /// <summary>
         ///     If sufficient charge is available on the battery, use it. Otherwise, don't.
diff --git a/Content.Shared/Weapons/Ranged/Events/UpdateClientAmmoEvent.cs b/Content.Shared/Weapons/Ranged/Events/UpdateClientAmmoEvent.cs
new file mode 100644 (file)
index 0000000..57f7318
--- /dev/null
@@ -0,0 +1,4 @@
+namespace Content.Shared.Weapons.Ranged.Events;
+
+[ByRefEvent]
+public readonly record struct UpdateClientAmmoEvent();
\ No newline at end of file
index 8e44576d28345807c756f086fa19ca7af583d248..bae5b95a193db13c0c376018d279055c5ada56e6 100644 (file)
@@ -5,6 +5,7 @@ using Content.Shared.Interaction;
 using Content.Shared.Popups;
 using Content.Shared.Verbs;
 using Content.Shared.Weapons.Ranged.Components;
+using Content.Shared.Weapons.Ranged.Events;
 using Robust.Shared.Prototypes;
 
 namespace Content.Shared.Weapons.Ranged.Systems;
@@ -99,13 +100,21 @@ public sealed class BatteryWeaponFireModesSystem : EntitySystem
         component.CurrentFireMode = index;
         Dirty(uid, component);
 
-        if (TryComp(uid, out ProjectileBatteryAmmoProviderComponent? projectileBatteryAmmoProvider))
+        if (TryComp(uid, out ProjectileBatteryAmmoProviderComponent? projectileBatteryAmmoProviderComponent))
         {
             if (!_prototypeManager.TryIndex<EntityPrototype>(fireMode.Prototype, out var prototype))
                 return;
 
-            projectileBatteryAmmoProvider.Prototype = fireMode.Prototype;
-            projectileBatteryAmmoProvider.FireCost = fireMode.FireCost;
+            // TODO: Have this get the info directly from the batteryComponent when power is moved to shared.
+            var OldFireCost = projectileBatteryAmmoProviderComponent.FireCost;
+            projectileBatteryAmmoProviderComponent.Prototype = fireMode.Prototype;
+            projectileBatteryAmmoProviderComponent.FireCost = fireMode.FireCost;
+            float FireCostDiff = (float)fireMode.FireCost / (float)OldFireCost;
+            projectileBatteryAmmoProviderComponent.Shots = (int)Math.Round(projectileBatteryAmmoProviderComponent.Shots/FireCostDiff);
+            projectileBatteryAmmoProviderComponent.Capacity = (int)Math.Round(projectileBatteryAmmoProviderComponent.Capacity/FireCostDiff);
+            Dirty(uid, projectileBatteryAmmoProviderComponent);
+            var updateClientAmmoEvent = new UpdateClientAmmoEvent();
+            RaiseLocalEvent(uid, ref updateClientAmmoEvent);
 
             if (user != null)
             {
index e7fef78f809afa292402d8c29ebcbc1638aa399a..46c3d36ebcfadc585bb3e0a1cc8dbac148646680 100644 (file)
       path: /Audio/Weapons/Guns/Gunshots/laser_cannon.ogg
   - type: ProjectileBatteryAmmoProvider
     proto: BulletLaserSpread
-    fireCost: 100
+    fireCost: 150
   - type: BatteryWeaponFireModes
     fireModes:
     - proto: BulletLaserSpread
-      fireCost: 100
+      fireCost: 150
     - proto: BulletLaserSpreadNarrow
-      fireCost: 100
+      fireCost: 200
     - proto: BulletDisablerSmgSpread
-      fireCost: 100
+      fireCost: 120
   - type: Item
     size: Large
     shape:
     stealGroup: WeaponEnergyShotgun
   - type: GunRequiresWield #remove when inaccuracy on spreads is fixed
   - type: Battery
-    maxCharge: 800
-    startingCharge: 800
+    maxCharge: 1200
+    startingCharge: 1200
+  - type: BatterySelfRecharger
+    autoRecharge: true
+    autoRechargeRate: 24
+    autoRechargePause: true
+    autoRechargePauseTime: 10
\ No newline at end of file