You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
127 lines
2.9 KiB
C#
127 lines
2.9 KiB
C#
using Fusion;
|
|
using UnityEngine;
|
|
|
|
namespace Projectiles
|
|
{
|
|
/// <summary>
|
|
/// Handles weapon action ammo.
|
|
/// </summary>
|
|
public class WeaponMagazine : WeaponComponent
|
|
{
|
|
// PUBLIC MEMBERS
|
|
|
|
public bool IsReloading => _isReloading;
|
|
public float ReloadProgress => IsReloading == true ? _reloadCooldown.RemainingTime(Runner).Value / _reloadTime : 0f;
|
|
public bool HasMagazine => _hasMagazine;
|
|
public bool HasUnlimitedAmmo => _hasUnlimitedAmmo;
|
|
public int MagazineAmmo => _magazineAmmo;
|
|
public int WeaponAmmo => _weaponAmmo;
|
|
|
|
// PRIVATE MEMBERS
|
|
|
|
[SerializeField]
|
|
private int _initialAmmo = 150;
|
|
[SerializeField]
|
|
private bool _hasMagazine = true;
|
|
[SerializeField]
|
|
private int _maxMagazineAmmo = 30;
|
|
[SerializeField]
|
|
private int _maxWeaponAmmo = 120;
|
|
[SerializeField]
|
|
private bool _hasUnlimitedAmmo;
|
|
[SerializeField]
|
|
private float _reloadTime = 2f;
|
|
|
|
[Networked]
|
|
private NetworkBool _isReloading { get; set; }
|
|
[Networked]
|
|
private int _magazineAmmo { get; set; }
|
|
[Networked]
|
|
private int _weaponAmmo { get; set; }
|
|
[Networked]
|
|
private TickTimer _reloadCooldown { get; set; }
|
|
|
|
// WeaponComponent INTERFACE
|
|
|
|
public override bool IsBusy => _reloadCooldown.ExpiredOrNotRunning(Runner) == false;
|
|
|
|
public override bool CanFire()
|
|
{
|
|
if (_isReloading == true)
|
|
return false;
|
|
|
|
int availableAmmo = _hasMagazine == true ? _magazineAmmo : _weaponAmmo;
|
|
return availableAmmo > 0;
|
|
}
|
|
|
|
public override void Fire()
|
|
{
|
|
if (_hasMagazine == true)
|
|
{
|
|
_magazineAmmo--;
|
|
}
|
|
else if (_hasUnlimitedAmmo == false)
|
|
{
|
|
_weaponAmmo--;
|
|
}
|
|
}
|
|
|
|
// NetworkBehaviour INTERFACE
|
|
|
|
public override void FixedUpdateNetwork()
|
|
{
|
|
if (_isReloading == true && _reloadCooldown.Expired(Runner) == true)
|
|
{
|
|
int reloadAmmo = _maxMagazineAmmo - _magazineAmmo;
|
|
|
|
if (_hasUnlimitedAmmo == false)
|
|
{
|
|
reloadAmmo = Mathf.Min(reloadAmmo, _weaponAmmo);
|
|
_weaponAmmo -= reloadAmmo;
|
|
}
|
|
|
|
_magazineAmmo += reloadAmmo;
|
|
|
|
_isReloading = false;
|
|
}
|
|
|
|
if (ShouldReload() == true)
|
|
{
|
|
_reloadCooldown = TickTimer.CreateFromSeconds(Runner, _reloadTime);
|
|
_isReloading = true;
|
|
}
|
|
}
|
|
|
|
public override void Spawned()
|
|
{
|
|
int initialAmmo = _hasUnlimitedAmmo == true ? int.MaxValue : _initialAmmo;
|
|
|
|
_magazineAmmo = _hasMagazine == true ? Mathf.Clamp(initialAmmo, 0, _maxMagazineAmmo) : 0;
|
|
_weaponAmmo = Mathf.Clamp(initialAmmo - _magazineAmmo, 0, _maxWeaponAmmo);
|
|
}
|
|
|
|
// PRIVATE MEMBERS
|
|
|
|
private bool ShouldReload()
|
|
{
|
|
if (_isReloading == true)
|
|
return false;
|
|
|
|
if (_hasMagazine == false)
|
|
return false; // Weapon without reloading
|
|
|
|
if (_magazineAmmo == _maxMagazineAmmo)
|
|
return false; // Already max
|
|
|
|
if (_weaponAmmo == 0)
|
|
return false; // No ammo to reload
|
|
|
|
bool reloadRequested = Buttons.IsSet(EInputButton.Reload) == true || _magazineAmmo == 0;
|
|
if (reloadRequested == false)
|
|
return false;
|
|
|
|
return Weapon.IsBusy() == false;
|
|
}
|
|
}
|
|
}
|