]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Changes to "Burst" firemode; Drozd, WT550 and C20-r (#31292)
authorSlamBamActionman <83650252+SlamBamActionman@users.noreply.github.com>
Wed, 6 Nov 2024 14:39:16 +0000 (15:39 +0100)
committerGitHub <noreply@github.com>
Wed, 6 Nov 2024 14:39:16 +0000 (15:39 +0100)
* Initial commit

* Change burst fire variable to be a set value rather than a multiplier

Content.Client/Weapons/Ranged/Systems/GunSystem.cs
Content.Server/Weapons/Ranged/Systems/GunSystem.AutoFire.cs
Content.Shared/Weapons/Ranged/Components/GunComponent.cs
Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.cs
Resources/Prototypes/Entities/Objects/Weapons/Guns/SMGs/smgs.yml

index 1af471f28a3f40db6a0b96b3e358f6f6ac62472c..710ee7c7cbf7365a21fe4cd1c6afc9fed94254cd 100644 (file)
@@ -157,7 +157,7 @@ public sealed partial class GunSystem : SharedGunSystem
 
         var useKey = gun.UseKey ? EngineKeyFunctions.Use : EngineKeyFunctions.UseSecondary;
 
-        if (_inputSystem.CmdStates.GetState(useKey) != BoundKeyState.Down)
+        if (_inputSystem.CmdStates.GetState(useKey) != BoundKeyState.Down && !gun.BurstActivated)
         {
             if (gun.ShotCounter != 0)
                 EntityManager.RaisePredictiveEvent(new RequestStopShootEvent { Gun = GetNetEntity(gunUid) });
index 39cd2486ed78a7d4852f683b812599c1c7010a85..e5439cdb064a2054d236a9bba1673359bb40b09a 100644 (file)
@@ -1,4 +1,6 @@
+using Content.Shared.Damage;
 using Content.Shared.Weapons.Ranged.Components;
+using Robust.Shared.Map;
 
 namespace Content.Server.Weapons.Ranged.Systems;
 
@@ -13,17 +15,28 @@ public sealed partial class GunSystem
          */
 
         // Automatic firing without stopping if the AutoShootGunComponent component is exist and enabled
-        var query = EntityQueryEnumerator<AutoShootGunComponent, GunComponent>();
+        var query = EntityQueryEnumerator<GunComponent>();
 
-        while (query.MoveNext(out var uid, out var autoShoot, out var gun))
+        while (query.MoveNext(out var uid, out var gun))
         {
-            if (!autoShoot.Enabled)
-                continue;
-
             if (gun.NextFire > Timing.CurTime)
                 continue;
 
-            AttemptShoot(uid, gun);
+            if (TryComp(uid, out AutoShootGunComponent? autoShoot))
+            {
+                if (!autoShoot.Enabled)
+                    continue;
+
+                AttemptShoot(uid, gun);
+            }
+            else if (gun.BurstActivated)
+            {
+                var parent = _transform.GetParentUid(uid);
+                if (HasComp<DamageableComponent>(parent))
+                    AttemptShoot(parent, uid, gun, gun.ShootCoordinates ?? new EntityCoordinates(uid, gun.DefaultDirection));
+                else
+                    AttemptShoot(uid, gun);
+            }
         }
     }
 }
index b404221abfc731473ac7a0b8c00e3532a6061857..98b1d2fe2a4fba798d20a5607afa80f230555a83 100644 (file)
@@ -1,3 +1,4 @@
+using System.Numerics;
 using Content.Shared.Weapons.Ranged.Events;
 using Content.Shared.Weapons.Ranged.Systems;
 using Robust.Shared.Audio;
@@ -156,6 +157,30 @@ public sealed partial class GunComponent : Component
     [AutoNetworkedField, ViewVariables(VVAccess.ReadWrite)]
     public int ShotsPerBurstModified = 3;
 
+    /// <summary>
+    /// How long time must pass between burstfire shots.
+    /// </summary>
+    [DataField, AutoNetworkedField]
+    public float BurstCooldown = 0.25f;
+
+    /// <summary>
+    /// The fire rate of the weapon in burst fire mode.
+    /// </summary>
+    [DataField, AutoNetworkedField]
+    public float BurstFireRate = 8f;
+
+    /// <summary>
+    /// Whether the burst fire mode has been activated.
+    /// </summary>
+    [AutoNetworkedField, ViewVariables(VVAccess.ReadWrite)]
+    public bool BurstActivated = false;
+
+    /// <summary>
+    /// The burst fire bullet count.
+    /// </summary>
+    [AutoNetworkedField, ViewVariables(VVAccess.ReadWrite)]
+    public int BurstShotsCount = 0;
+
     /// <summary>
     /// Used for tracking semi-auto / burst
     /// </summary>
@@ -232,6 +257,12 @@ public sealed partial class GunComponent : Component
     /// </summary>
     [DataField]
     public bool ClumsyProof = false;
+
+    /// <summary>
+    /// Firing direction for an item not being held (e.g. shuttle cannons, thrown guns still firing).
+    /// </summary>
+    [DataField]
+    public Vector2 DefaultDirection = new Vector2(0, -1);
 }
 
 [Flags]
index 794237b145a052b9aca67c76e441833e0eccb1b9..9bd786bbe08f0f69f4f68397750b4ea82ddca2df 100644 (file)
@@ -218,7 +218,7 @@ public abstract partial class SharedGunSystem : EntitySystem
     /// </summary>
     public void AttemptShoot(EntityUid gunUid, GunComponent gun)
     {
-        var coordinates = new EntityCoordinates(gunUid, new Vector2(0, -1));
+        var coordinates = new EntityCoordinates(gunUid, gun.DefaultDirection);
         gun.ShootCoordinates = coordinates;
         AttemptShoot(gunUid, gunUid, gun);
         gun.ShotCounter = 0;
@@ -258,6 +258,9 @@ public abstract partial class SharedGunSystem : EntitySystem
 
         var fireRate = TimeSpan.FromSeconds(1f / gun.FireRateModified);
 
+        if (gun.SelectedMode == SelectiveFire.Burst || gun.BurstActivated)
+            fireRate = TimeSpan.FromSeconds(1f / gun.BurstFireRate);
+
         // First shot
         // Previously we checked shotcounter but in some cases all the bullets got dumped at once
         // curTime - fireRate is insufficient because if you time it just right you can get a 3rd shot out slightly quicker.
@@ -278,18 +281,24 @@ public abstract partial class SharedGunSystem : EntitySystem
 
         // Get how many shots we're actually allowed to make, due to clip size or otherwise.
         // Don't do this in the loop so we still reset NextFire.
-        switch (gun.SelectedMode)
+        if (!gun.BurstActivated)
+        {
+            switch (gun.SelectedMode)
+            {
+                case SelectiveFire.SemiAuto:
+                    shots = Math.Min(shots, 1 - gun.ShotCounter);
+                    break;
+                case SelectiveFire.Burst:
+                    shots = Math.Min(shots, gun.ShotsPerBurstModified - gun.ShotCounter);
+                    break;
+                case SelectiveFire.FullAuto:
+                    break;
+                default:
+                    throw new ArgumentOutOfRangeException($"No implemented shooting behavior for {gun.SelectedMode}!");
+            }
+        } else
         {
-            case SelectiveFire.SemiAuto:
-                shots = Math.Min(shots, 1 - gun.ShotCounter);
-                break;
-            case SelectiveFire.Burst:
-                shots = Math.Min(shots, gun.ShotsPerBurstModified - gun.ShotCounter);
-                break;
-            case SelectiveFire.FullAuto:
-                break;
-            default:
-                throw new ArgumentOutOfRangeException($"No implemented shooting behavior for {gun.SelectedMode}!");
+            shots = Math.Min(shots, gun.ShotsPerBurstModified - gun.ShotCounter);
         }
 
         var attemptEv = new AttemptShootEvent(user, null);
@@ -301,7 +310,8 @@ public abstract partial class SharedGunSystem : EntitySystem
             {
                 PopupSystem.PopupClient(attemptEv.Message, gunUid, user);
             }
-
+            gun.BurstActivated = false;
+            gun.BurstShotsCount = 0;
             gun.NextFire = TimeSpan.FromSeconds(Math.Max(lastFire.TotalSeconds + SafetyNextFire, gun.NextFire.TotalSeconds));
             return;
         }
@@ -328,6 +338,10 @@ public abstract partial class SharedGunSystem : EntitySystem
             var emptyGunShotEvent = new OnEmptyGunShotEvent();
             RaiseLocalEvent(gunUid, ref emptyGunShotEvent);
 
+            gun.BurstActivated = false;
+            gun.BurstShotsCount = 0;
+            gun.NextFire += TimeSpan.FromSeconds(gun.BurstCooldown);
+
             // Play empty gun sounds if relevant
             // If they're firing an existing clip then don't play anything.
             if (shots > 0)
@@ -347,6 +361,22 @@ public abstract partial class SharedGunSystem : EntitySystem
             return;
         }
 
+        // Handle burstfire
+        if (gun.SelectedMode == SelectiveFire.Burst)
+        {
+            gun.BurstActivated = true;
+        }
+        if (gun.BurstActivated)
+        {
+            gun.BurstShotsCount += shots;
+            if (gun.BurstShotsCount >= gun.ShotsPerBurstModified)
+            {
+                gun.NextFire += TimeSpan.FromSeconds(gun.BurstCooldown);
+                gun.BurstActivated = false;
+                gun.BurstShotsCount = 0;
+            }
+        }
+
         // Shoot confirmed - sounds also played here in case it's invalid (e.g. cartridge already spent).
         Shoot(gunUid, gun, ev.Ammo, fromCoordinates, toCoordinates.Value, out var userImpulse, user, throwItems: attemptEv.ThrowItems);
         var shotEv = new GunShotEvent(user, ev.Ammo);
index a22be1da04203cd342147fac7ffdecb8910a0555..5140a358e10ead34a841853f6f7d212c9901d456 100644 (file)
@@ -19,6 +19,7 @@
     minAngle: 2
     maxAngle: 16
     fireRate: 8
+    burstFireRate: 8
     angleIncrease: 3
     angleDecay: 16
     selectedMode: FullAuto
@@ -27,6 +28,7 @@
     - FullAuto
     soundGunshot:
       path: /Audio/Weapons/Guns/Gunshots/smg.ogg
+    defaultDirection: 1, 0
   - type: ChamberMagazineAmmoProvider
     soundRack:
       path: /Audio/Weapons/Guns/Cock/smg_cock.ogg
     - type: Gun
       minAngle: 21
       maxAngle: 32
-      fireRate: 6
-      selectedMode: FullAuto
+      fireRate: 12
+      burstFireRate: 12
+      selectedMode: Burst
       soundGunshot:
         path: /Audio/Weapons/Guns/Gunshots/atreides.ogg
       availableModes:
-        - FullAuto
+        - Burst
+      shotsPerBurst: 3
+      burstCooldown: 0.25
     - type: ItemSlots
       slots:
         gun_magazine:
     angleDecay: 6
     selectedMode: FullAuto
     shotsPerBurst: 5
+    burstCooldown: 0.2
+    burstFireRate: 7
     availableModes:
     - SemiAuto
     - Burst