using System; using System.IO; using IronMountain.SaveSystem; using UnityEngine; namespace SpellBoundAR.Items { public class ScriptedItemInstanceData : ScriptableObject, IItemInstanceData { public static event Action OnAnyVisibleChanged; public static event Action OnAnyInteractableChanged; public static event Action OnAnyInteractionCountChanged; public event Action OnVisibleChanged; public event Action OnInteractableChanged; public event Action OnInteractionCountChanged; [SerializeField] private string id = string.Empty; [SerializeField] private ScriptedItemTypeData type; [Space] [SerializeField] private bool initiallyVisible = true; [SerializeField] private bool initiallyInteractable = true; public string ID { get => id; set => id = value; } public ScriptedItemTypeData ScriptedItemTypeData { get => type; set => type = value; } public string Name => name; public IItemTypeData Type { get => type; set => type = value as ScriptedItemTypeData; } public bool InitiallyVisible => initiallyVisible; public bool InitiallyInteractable => initiallyInteractable; private SavedBool _visible; private SavedBool _interactable; private SavedInt _interactionCount; public virtual bool Visible { get => _visible.Value; set { if (_visible.Value == value) return; _visible.Value = value; } } public virtual bool Interactable { get => _interactable.Value; set { if (_interactable.Value == value) return; _interactable.Value = value; } } public virtual int InteractionCount { get => _interactionCount.Value; set { if (_interactionCount.Value == value) return; _interactionCount.Value = value; } } protected virtual string Directory => Path.Combine("Items", "Instances", ID); protected virtual void OnEnable() { LoadSavedInformation(); BroadcastSavedInformation(); ItemsManager.Instances.Add(this); } protected virtual void OnDisable() { ItemsManager.Instances.Remove(this); } protected void LoadSavedInformation() { string directory = Directory; _visible = new SavedBool(directory, "Visible.txt", initiallyVisible, () => { OnVisibleChanged?.Invoke(); OnAnyVisibleChanged?.Invoke(this); }); _interactable = new SavedBool(directory, "Interactable.txt", initiallyInteractable, () => { OnInteractableChanged?.Invoke(); OnAnyInteractableChanged?.Invoke(this); }); _interactionCount = new SavedInt(directory, "Interaction Count.txt", 0, () => { OnInteractionCountChanged?.Invoke(); OnAnyInteractionCountChanged?.Invoke(this); }); } protected void BroadcastSavedInformation() { OnVisibleChanged?.Invoke(); OnAnyVisibleChanged?.Invoke(this); OnInteractableChanged?.Invoke(); OnAnyInteractableChanged?.Invoke(this); OnInteractionCountChanged?.Invoke(); OnAnyInteractionCountChanged?.Invoke(this); } #if UNITY_EDITOR public void Reset() { RefreshType(); RefreshName(); } public void OnValidate() { foreach (IItemInstanceData instance in type.Instances) instance.RefreshName(); } [ContextMenu("Refresh Type")] private void RefreshType() { if (Type != null) return; IItemTypeData itemTypeData = ItemsManager.Types.Find(test => test.Instances.Contains(this)); if (itemTypeData is ScriptedItemTypeData scriptedItemTypeData) { ScriptedItemTypeData = scriptedItemTypeData; } } [ContextMenu("Refresh Name")] public virtual void RefreshName() { if (Type == null) return; int index = 0; int total = 0; foreach (IItemInstanceData itemInstanceData in type.Instances) { total++; if ((ScriptedItemInstanceData) itemInstanceData == this) index = total; } name = (Type != null ? Type.Name : string.Empty) + (total > 1 ? " " + index : string.Empty); } #endif } }