using System; using KitsuneCafe.Entities; using KitsuneCafe.SOAP; using R3; using UnityEngine; namespace KitsuneCafe.ItemSystem { public record ChangedEquipmentEvent(IEquippable Previous, IEquippable Current); public class EquipmentInstance : MonoBehaviour { [SerializeField] private InventoryInstance inventory; [SerializeField] private BoneAttachment attachment; [SerializeField] private EquipmentValue primary; public EquipmentItem Primary => primary.Value; [SerializeField] private EquipmentValue secondary; public EquipmentItem Secondary => secondary.Value; private IEquippable equippedPrimary; public event EventHandler ChangedEquipment; public event EventHandler Readied; public event EventHandler Attacked; public event EventHandler Reloaded; public bool HasPrimaryEquipped => primary != null; public bool HasSecondaryEquipped => secondary != null; private void OnValidate() { if (inventory == null) { inventory = GetComponent(); } if (attachment == null) { attachment = GetComponent(); } } private void Start() { var d = Disposable.CreateBuilder(); primary.AsObservable() .Subscribe(EquipPrimary) .AddTo(ref d); secondary.AsObservable() .Subscribe() .AddTo(ref d); d.RegisterTo(destroyCancellationToken); } private void EquipPrimary(EquipmentItem equipment) { var previous = equippedPrimary; if (equippedPrimary != null) { equippedPrimary.OnUnequip(); equippedPrimary.Readied -= OnReady; equippedPrimary.Attacked -= OnAttack; equippedPrimary.Reloaded -= OnReload; Destroy(equippedPrimary.gameObject); equippedPrimary = null; } IEquippable instance = null; if (equipment != null) { instance = equipment.CreateEquipment(); instance.Readied += OnReady; instance.Attacked += OnAttack; instance.Reloaded += OnReload; instance.gameObject.transform.SetParent(attachment.transform, false); equippedPrimary = instance; equippedPrimary.OnEquip(inventory); } ChangedEquipment?.Invoke(this, new ChangedEquipmentEvent(previous, instance)); } private void OnReload(object sender, EventArgs e) { Reloaded?.Invoke(sender, e); } private void OnAttack(object sender, EventArgs e) { Attacked?.Invoke(sender, e); } private void OnReady(object sender, bool e) { Readied?.Invoke(sender, e); } } }