using System; using System.Collections; using System.Collections.Generic; using BITKit; using UnityEngine; namespace BITFALL.Guns { #region Interfaces /// /// 射击模式的接口 /// public interface IFireMode { float FireRate { get; } } /// /// 后坐力接口定义 /// public interface IRecoil:IProperty { /// /// 后坐力的方向 /// Vector3 Recoil { get; } Vector3 ViewRecoilScale { get; } } public interface ISpread:IProperty { /// /// 散射的方向 /// Vector2 Spread { get; } } /// /// 弹药类型 /// public interface IAmmoType:IProperty { } /// /// 弹匣属性,无此属性则为无弹匣 /// public interface IClip:IProperty,ICount,ICloneable { /// /// 剩余子弹 /// public int Remaining { get; set; } /// /// 容量 /// public int Capacity { get; } /// /// 为空则为默认 /// public IAmmoType AmmoType { get; } /// /// 指向的ScriptableObject /// public string AddressablePath { get; } } #endregion [Serializable] [CustomType(typeof(ISpread))] public struct VectorSpread:ISpread { [SerializeField] private Vector2 spread; public Vector2 Spread => spread; } [Serializable] [CustomType(typeof(IRecoil))] public struct VectorRecoil:IRecoil { [SerializeField] private Vector3 recoil; [SerializeField] private Vector3 viewRecoilWeight; public Vector3 Recoil => recoil; public Vector3 ViewRecoilScale => viewRecoilWeight; } /// /// 射击模式的基类 /// public record FireMode : IFireMode { [SerializeField]protected float fireRate; public float FireRate => fireRate; } /// /// 自动开火模式 /// [System.Serializable] public record AutoFireMode : FireMode { } /// /// 半自动开火模式 /// [System.Serializable] public record SemiFireMode : FireMode { [SerializeField] private bool requireBoltAction; public bool RequireBoltAction => requireBoltAction; } /// /// 爆炸射击模式 BurstRound为爆炸开火时一次发射的子弹数量 /// /// [System.Serializable] public record BurstFireMode : FireMode { [SerializeField] protected int brustRound; [SerializeField] protected float burstFireInterval; public int BurstRound=> brustRound; public float BurstFireInterval => burstFireInterval; } [CustomType(typeof(IClip))] [CustomType(typeof(ICount))] [Serializable] public class DefaultClip:IClip { [SerializeField]private int remaining; [SerializeField]private int capacity; [SerializeReference,SubclassSelector]private IAmmoType ammoType; [SerializeField] private ScriptableItem ammoItem; private int _count; public int Remaining { get => remaining; set => remaining = value; } public int Capacity => capacity; public IAmmoType AmmoType => ammoType; public string AddressablePath => ammoItem.AddressablePath; public override string ToString() { return $"{(ammoItem != null ? ammoItem.Name : nameof(DefaultClip))}:{remaining}/{capacity}"; } public object Clone() => new DefaultClip() { _count = _count, ammoItem = ammoItem, ammoType = ammoType, capacity = capacity, remaining = remaining }; public int Count => Remaining; } }