From 4aeb380aa8ee3a544c01989e153037479f302364 Mon Sep 17 00:00:00 2001 From: copygirl Date: Thu, 20 May 2021 12:01:22 +0200 Subject: [PATCH] Add some wiggle-room for fire/reload delay --- src/HUD/WeaponInfo.cs | 9 +++------ src/Items/Weapon.cs | 46 ++++++++++++++++++++++++------------------- 2 files changed, 29 insertions(+), 26 deletions(-) diff --git a/src/HUD/WeaponInfo.cs b/src/HUD/WeaponInfo.cs index ad08668..da1110a 100644 --- a/src/HUD/WeaponInfo.cs +++ b/src/HUD/WeaponInfo.cs @@ -33,17 +33,14 @@ public class WeaponInfo : Node2D if ((weapon != _previousWeapon) || (weapon.Rounds != _previousRounds) || - (weapon.ReloadProgress != null)) { + (weapon.ReloadProgress < 1.0F)) { _visibleFor = 0.0F; Modulate = Colors.White; Rounds.Visible = weapon.Capacity > 1; Rounds.Text = $"{weapon.Rounds}/{weapon.Capacity}"; - - if (weapon.ReloadProgress is float reloading) { - Reloading.Visible = true; - Reloading.Value = reloading; - } else Reloading.Visible = false; + Reloading.Value = weapon.ReloadProgress; + Reloading.Visible = weapon.ReloadProgress < 1.0F; _previousWeapon = weapon; _previousRounds = weapon.Rounds; diff --git a/src/Items/Weapon.cs b/src/Items/Weapon.cs index e30e661..e4d1f30 100644 --- a/src/Items/Weapon.cs +++ b/src/Items/Weapon.cs @@ -1,5 +1,4 @@ using System; -using System.Security.Cryptography.X509Certificates; using Godot; // TODO: "Click" sound when attempting to fire when not ready, or empty. @@ -8,6 +7,8 @@ using Godot; public class Weapon : Sprite { + private const float NETWORK_EPSILON = 0.05F; + [Export] public bool Automatic { get; set; } = false; [Export] public int RateOfFire { get; set; } = 100; // rounds/minute [Export] public int Capacity { get; set; } = 12; @@ -28,7 +29,7 @@ public class Weapon : Sprite public float _fireDelay; - public float? _reloading; + public float _reloadDelay; public bool _lowered; private float _currentSpreadInc = 0.0F; @@ -38,7 +39,9 @@ public class Weapon : Sprite public float AimDirection { get; private set; } public TimeSpan? HoldingTrigger { get; private set; } // TODO: Tell the server when we're pressing/releasing the trigger. - public float? ReloadProgress => 1 - _reloading / ReloadTime; + + public bool IsReloading => _reloadDelay > 0.0F; + public float ReloadProgress => 1 - _reloadDelay / ReloadTime; public Cursor Cursor { get; private set; } @@ -74,22 +77,19 @@ public class Weapon : Sprite _currentRecoil = Mathf.Max(0, _currentRecoil - recoilDecrease * delta); if (!Player.IsAlive) { + // TODO: Do this once when player respawns. _fireDelay = 0.0F; - _reloading = null; + _reloadDelay = 0.0F; Rounds = Capacity; HoldingTrigger = null; - // TODO: Technically only needs to be called once. if (Player is LocalPlayer) Update(); } else if (Visible) { if (HoldingTrigger is TimeSpan holding) HoldingTrigger = holding + TimeSpan.FromSeconds(delta); - if (_reloading is float reloading) { - _reloading = reloading - delta; - if (_reloading <= 0) { - Rounds = Capacity; - _reloading = null; - } + if (IsReloading && ((_reloadDelay -= delta) <= 0)) { + _reloadDelay = 0.0F; + Rounds = Capacity; } if (_fireDelay > 0) { @@ -146,7 +146,7 @@ public class Weapon : Sprite Update(); } } else { - _reloading = null; + _reloadDelay = 0.0F; } var angle = Mathf.PosMod(AimDirection + Mathf.Pi, Mathf.Tau) - Mathf.Pi; @@ -180,11 +180,18 @@ public class Weapon : Sprite protected virtual bool FireInternal(float aimDirection, bool toRight, int seed) { - if (!Visible || _lowered || !Player.IsAlive || - (_reloading != null) || (Rounds <= 0) || (_fireDelay > 0)) return false; + var isServer = this.GetGame() is Server; + var epsilon = isServer ? NETWORK_EPSILON : 0.0F; + if (!Visible || _lowered || !Player.IsAlive || (_fireDelay > epsilon)) return false; + + if (Rounds <= 0) { + if (_reloadDelay <= epsilon) { + _reloadDelay += ReloadTime; + Rounds = Capacity; + } else return false; + } - if (this.GetGame() is Client) - GetNodeOrNull("Fire")?.Play(); + if (!isServer) GetNodeOrNull("Fire")?.Play(); var random = new Random(seed); var angle = aimDirection - _currentRecoil * (toRight ? 1 : -1); @@ -202,7 +209,7 @@ public class Weapon : Sprite _currentSpreadInc += Mathf.Deg2Rad(SpreadIncrease); _currentRecoil += Mathf.Deg2Rad(random.NextFloat(RecoilMin, RecoilMax)); - if ((this.GetGame() is Server) || (Player is LocalPlayer)) { + if (isServer || (Player is LocalPlayer)) { // Do not keep track of fire rate or ammo for other players. _fireDelay += 60.0F / RateOfFire; Rounds -= 1; @@ -229,11 +236,10 @@ public class Weapon : Sprite private bool ReloadInternal() { - if (!Visible || !Player.IsAlive || - (Rounds >= Capacity) || (_reloading != null)) return false; + if (!Visible || !Player.IsAlive || (Rounds >= Capacity) || IsReloading) return false; // TODO: Play reload sound. - _reloading = ReloadTime; + _reloadDelay += ReloadTime; return true; }