using System.Collections.Generic; using UnityEngine; using FishNet.Object; using Ashwild.Inventory; using Ashwild.Player; namespace Ashwild.Crafting { /// /// The local player's craft-discovery knowledge: the set of items it has ever acquired. /// A recipe is only revealed (and only craftable) once its ingredients have been discovered, /// so the player uncovers crafts by gathering resources rather than seeing the whole catalog /// at once. Discovery is triggered the first time an item enters the inventory — pickups, /// harvest drops AND craft results all count, which lets crafting chains reveal step by step. /// /// This is owner-only local state: each player keeps its own knowledge, and it is never /// replicated over the wire (no one else needs to read it). It mirrors PlayerInventory's /// singleton pattern purely for reliable owner gating — set the Instance for the owning /// client in OnStartNetwork, and gate the component off on remotes via ownerOnlyBehaviours. /// [DisallowMultipleComponent] public class CraftDiscovery : NetworkBehaviour { #region Singleton /// /// The local player's discovery knowledge (set only on the owning client). /// public static CraftDiscovery Instance { get; private set; } #endregion #region State private readonly HashSet discovered = new HashSet(); #endregion #region Network Lifecycle /// /// Registers the singleton on the owning client only (before LocalPlayerSpawned fires). /// public override void OnStartNetwork() { base.OnStartNetwork(); if (base.Owner.IsLocalClient) Instance = this; } /// /// Clears the singleton when this player leaves the network. /// public override void OnStopNetwork() { base.OnStopNetwork(); if (Instance == this) Instance = null; } #endregion #region Unity Lifecycle /// /// Starts tracking every item the local player acquires. /// private void OnEnable() { PlayerEvents.ItemAdded += HandleItemAdded; } /// /// Stops tracking — mirrors OnEnable exactly. /// private void OnDisable() { PlayerEvents.ItemAdded -= HandleItemAdded; } #endregion #region Event Handlers /// /// Marks an acquired item as discovered. Guarded to the owning instance so a remote puppet /// that briefly subscribed before being gated off can never drive discovery on the wrong copy. /// private void HandleItemAdded(ItemData item, int quantity) { if (Instance != this) return; Discover(item); } #endregion #region Public API /// /// Whether the local player has ever acquired this item (and therefore knows it). /// public bool IsDiscovered(ItemData item) => item != null && discovered.Contains(item); #endregion #region Internal Helpers /// /// Adds an item to the discovered set the first time it is seen and announces it on the bus /// so the crafting view can reveal any recipe the item unlocks. /// private void Discover(ItemData item) { if (item == null) return; if (discovered.Add(item)) PlayerEvents.RaiseItemDiscovered(item); } #endregion } }