Add some wiggle-room for fire/reload delay

main
copygirl 4 years ago
parent 4dbc9cef92
commit 4aeb380aa8
  1. 9
      src/HUD/WeaponInfo.cs
  2. 44
      src/Items/Weapon.cs

@ -33,17 +33,14 @@ public class WeaponInfo : Node2D
if ((weapon != _previousWeapon) || if ((weapon != _previousWeapon) ||
(weapon.Rounds != _previousRounds) || (weapon.Rounds != _previousRounds) ||
(weapon.ReloadProgress != null)) { (weapon.ReloadProgress < 1.0F)) {
_visibleFor = 0.0F; _visibleFor = 0.0F;
Modulate = Colors.White; Modulate = Colors.White;
Rounds.Visible = weapon.Capacity > 1; Rounds.Visible = weapon.Capacity > 1;
Rounds.Text = $"{weapon.Rounds}/{weapon.Capacity}"; Rounds.Text = $"{weapon.Rounds}/{weapon.Capacity}";
Reloading.Value = weapon.ReloadProgress;
if (weapon.ReloadProgress is float reloading) { Reloading.Visible = weapon.ReloadProgress < 1.0F;
Reloading.Visible = true;
Reloading.Value = reloading;
} else Reloading.Visible = false;
_previousWeapon = weapon; _previousWeapon = weapon;
_previousRounds = weapon.Rounds; _previousRounds = weapon.Rounds;

@ -1,5 +1,4 @@
using System; using System;
using System.Security.Cryptography.X509Certificates;
using Godot; using Godot;
// TODO: "Click" sound when attempting to fire when not ready, or empty. // TODO: "Click" sound when attempting to fire when not ready, or empty.
@ -8,6 +7,8 @@ using Godot;
public class Weapon : Sprite public class Weapon : Sprite
{ {
private const float NETWORK_EPSILON = 0.05F;
[Export] public bool Automatic { get; set; } = false; [Export] public bool Automatic { get; set; } = false;
[Export] public int RateOfFire { get; set; } = 100; // rounds/minute [Export] public int RateOfFire { get; set; } = 100; // rounds/minute
[Export] public int Capacity { get; set; } = 12; [Export] public int Capacity { get; set; } = 12;
@ -28,7 +29,7 @@ public class Weapon : Sprite
public float _fireDelay; public float _fireDelay;
public float? _reloading; public float _reloadDelay;
public bool _lowered; public bool _lowered;
private float _currentSpreadInc = 0.0F; private float _currentSpreadInc = 0.0F;
@ -38,7 +39,9 @@ public class Weapon : Sprite
public float AimDirection { get; private set; } public float AimDirection { get; private set; }
public TimeSpan? HoldingTrigger { get; private set; } public TimeSpan? HoldingTrigger { get; private set; }
// TODO: Tell the server when we're pressing/releasing the trigger. // 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; } public Cursor Cursor { get; private set; }
@ -74,22 +77,19 @@ public class Weapon : Sprite
_currentRecoil = Mathf.Max(0, _currentRecoil - recoilDecrease * delta); _currentRecoil = Mathf.Max(0, _currentRecoil - recoilDecrease * delta);
if (!Player.IsAlive) { if (!Player.IsAlive) {
// TODO: Do this once when player respawns.
_fireDelay = 0.0F; _fireDelay = 0.0F;
_reloading = null; _reloadDelay = 0.0F;
Rounds = Capacity; Rounds = Capacity;
HoldingTrigger = null; HoldingTrigger = null;
// TODO: Technically only needs to be called once.
if (Player is LocalPlayer) Update(); if (Player is LocalPlayer) Update();
} else if (Visible) { } else if (Visible) {
if (HoldingTrigger is TimeSpan holding) if (HoldingTrigger is TimeSpan holding)
HoldingTrigger = holding + TimeSpan.FromSeconds(delta); HoldingTrigger = holding + TimeSpan.FromSeconds(delta);
if (_reloading is float reloading) { if (IsReloading && ((_reloadDelay -= delta) <= 0)) {
_reloading = reloading - delta; _reloadDelay = 0.0F;
if (_reloading <= 0) {
Rounds = Capacity; Rounds = Capacity;
_reloading = null;
}
} }
if (_fireDelay > 0) { if (_fireDelay > 0) {
@ -146,7 +146,7 @@ public class Weapon : Sprite
Update(); Update();
} }
} else { } else {
_reloading = null; _reloadDelay = 0.0F;
} }
var angle = Mathf.PosMod(AimDirection + Mathf.Pi, Mathf.Tau) - Mathf.Pi; 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) protected virtual bool FireInternal(float aimDirection, bool toRight, int seed)
{ {
if (!Visible || _lowered || !Player.IsAlive || var isServer = this.GetGame() is Server;
(_reloading != null) || (Rounds <= 0) || (_fireDelay > 0)) return false; 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) if (!isServer) GetNodeOrNull<AudioStreamPlayer2D>("Fire")?.Play();
GetNodeOrNull<AudioStreamPlayer2D>("Fire")?.Play();
var random = new Random(seed); var random = new Random(seed);
var angle = aimDirection - _currentRecoil * (toRight ? 1 : -1); var angle = aimDirection - _currentRecoil * (toRight ? 1 : -1);
@ -202,7 +209,7 @@ public class Weapon : Sprite
_currentSpreadInc += Mathf.Deg2Rad(SpreadIncrease); _currentSpreadInc += Mathf.Deg2Rad(SpreadIncrease);
_currentRecoil += Mathf.Deg2Rad(random.NextFloat(RecoilMin, RecoilMax)); _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. // Do not keep track of fire rate or ammo for other players.
_fireDelay += 60.0F / RateOfFire; _fireDelay += 60.0F / RateOfFire;
Rounds -= 1; Rounds -= 1;
@ -229,11 +236,10 @@ public class Weapon : Sprite
private bool ReloadInternal() private bool ReloadInternal()
{ {
if (!Visible || !Player.IsAlive || if (!Visible || !Player.IsAlive || (Rounds >= Capacity) || IsReloading) return false;
(Rounds >= Capacity) || (_reloading != null)) return false;
// TODO: Play reload sound. // TODO: Play reload sound.
_reloading = ReloadTime; _reloadDelay += ReloadTime;
return true; return true;
} }

Loading…
Cancel
Save