220 lines
5.2 KiB
C#
Raw Normal View History

2025-09-24 11:24:38 +05:00
using Fusion;
using UnityEngine;
namespace TPSBR
{
public abstract class Weapon : ContextBehaviour, IDynamicPickupProvider
{
// PUBLIC MEMBERS
public string WeaponID => _weaponID;
public int WeaponSlot => _weaponSlot;
public Transform LeftHandTarget => _leftHandTarget;
public DynamicPickup PickupPrefab => _pickupPrefab;
public EHitType HitType => _hitType;
public float AimFOV => _aimFOV;
public string DisplayName => _displayName;
public string NameShortcut => _nameShortcut;
public Sprite Icon => _icon;
public bool ValidOnlyWithAmmo => _validOnlyWithAmmo;
public bool IsInitialized => _isInitialized;
public bool IsArmed => _isArmed;
public NetworkObject Owner => _owner;
public Character Character => _character;
// PRIVATE MEMBERS
[SerializeField]
private string _weaponID;
[SerializeField]
private int _weaponSlot;
[SerializeField]
private bool _validOnlyWithAmmo;
[SerializeField]
private Transform _leftHandTarget;
[SerializeField]
private EHitType _hitType;
[SerializeField]
private float _aimFOV;
[Header("Pickup")]
[SerializeField]
private string _displayName;
[SerializeField, Tooltip("Up to 4 letter name shown in thumbnail")]
private string _nameShortcut;
[SerializeField]
private Sprite _icon;
[SerializeField]
private Collider _pickupCollider;
[SerializeField]
private Transform _pickupInterpolationTarget;
[SerializeField]
private DynamicPickup _pickupPrefab;
private bool _isInitialized;
private bool _isArmed;
private NetworkObject _owner;
private Character _character;
private Transform _armedParent;
private Transform _disarmedParent;
private AudioEffect[] _audioEffects;
// PUBLIC METHODS
public void ArmWeapon()
{
if (_isArmed == true)
return;
_isArmed = true;
OnIsArmedChanged();
}
public void DisarmWeapon()
{
if (_isArmed == false)
return;
_isArmed = false;
OnIsArmedChanged();
}
public void Initialize(NetworkObject owner, Transform armedParent, Transform disarmedParent)
{
if (_isInitialized == true)
return;
_isInitialized = true;
_owner = owner;
_character = owner.GetComponent<Character>();
_armedParent = armedParent;
_disarmedParent = disarmedParent;
RefreshParent();
}
public void Deinitialize(NetworkObject owner)
{
if (_owner != null && _owner != owner)
return;
_isInitialized = default;
_owner = default;
_character = default;
_armedParent = default;
_disarmedParent = default;
AssignFireAudioEffects(null, null);
}
public virtual bool IsBusy() { return false; }
public abstract bool CanFire(bool keyDown);
public abstract void Fire(Vector3 firePosition, Vector3 targetPosition, LayerMask hitMask);
public virtual bool CanReload(bool autoReload) { return false; }
public virtual void Reload() {}
public virtual bool CanAim() { return false; }
public virtual void AssignFireAudioEffects(Transform root, AudioEffect[] audioEffects)
{
_audioEffects = audioEffects;
}
public virtual bool HasAmmo() { return true; }
public virtual bool AddAmmo(int ammo) { return false; }
public virtual bool CanFireToPosition(Vector3 firePosition, ref Vector3 targetPosition, LayerMask hitMask) { return true; }
// NetworkBehaviour INTERFACE
public override void Spawned()
{
if (ApplicationSettings.IsStrippedBatch == true)
{
gameObject.SetActive(false);
}
}
public override void Despawned(NetworkRunner runner, bool hasState)
{
if (hasState == true)
{
DisarmWeapon();
}
else
{
_isArmed = false;
}
Deinitialize(_owner);
}
// PROTECTED METHODS
protected virtual void OnWeaponArmed()
{
}
protected virtual void OnWeaponDisarmed()
{
}
protected bool PlaySound(AudioSetup setup)
{
if (_audioEffects.PlaySound(setup, EForceBehaviour.ForceAny) == false)
{
Debug.LogWarning($"No free audio effects on weapon {gameObject.name}. Add more audio effects in Player prefab.");
return false;
}
return true;
}
// IPickupProvider INTERFACE
string IDynamicPickupProvider.Name => _displayName;
string IDynamicPickupProvider.Description => null;
Collider IDynamicPickupProvider.Collider => _pickupCollider;
Transform IDynamicPickupProvider.InterpolationTarget => _pickupInterpolationTarget;
float IDynamicPickupProvider.DespawnTime => 60f;
void IDynamicPickupProvider.Assigned(DynamicPickup pickup)
{
Deinitialize(_owner);
}
void IDynamicPickupProvider.Unassigned(DynamicPickup pickup)
{
}
// NETWORK CALLBACKS
private void OnIsArmedChanged()
{
RefreshParent();
if (IsArmed == true)
{
OnWeaponArmed();
}
else
{
OnWeaponDisarmed();
}
}
private void RefreshParent()
{
if (_isInitialized == false)
return;
transform.SetParent(_isArmed == true ? _armedParent : _disarmedParent, false);
transform.localPosition = Vector3.zero;
transform.localRotation = Quaternion.identity;
}
}
}