canto/Assets/Scripts/Item/EquipmentInstance.cs
2025-08-14 19:11:32 -04:00

111 lines
2.6 KiB
C#

using System;
using KitsuneCafe.Entity;
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<ChangedEquipmentEvent> ChangedEquipment;
public event EventHandler<bool> 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<InventoryInstance>();
}
if (attachment == null)
{
attachment = GetComponent<BoneAttachment>();
}
}
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);
}
}
}