// Assets/_Project/Scripts/Gameplay/SelectionState.cs
using UnityEngine;
namespace TD.Gameplay
{
///
/// Minimal scene-local selection state. Holds a reference to whichever
/// the local player has selected, fires an event when
/// the selection changes, and exposes a query for "is this builder selected
/// right now?".
///
///
/// Scope. D2 only needs this for: "Escape with builder selected
/// cancels its queue", and "right-click with builder selected and queue
/// established cancels the queue (the right-click is consumed by selection
/// instead of issuing a move)". A full selection system that supports world
/// highlighting, multi-select, and HUD context panels is deferred to the HUD
/// path.
///
/// Local-only. Selection is a UI concept, not a gameplay one.
/// Other clients have no business knowing whether you've selected your own
/// builder. The component is a plain MonoBehaviour and lives in the scene
/// alongside other client-side controllers.
///
/// Singleton. One per scene, accessed via .
/// The selection consumer (BuilderInputController) and the selection driver
/// (mouse-click raycast) both go through this single source of truth.
///
public class SelectionState : MonoBehaviour
{
// ----- Singleton --------------------------------------------------
///
/// The active SelectionState. Null before the scene loads. Always null-check.
///
public static SelectionState Instance { get; private set; }
private void Awake()
{
if (Instance != null && Instance != this)
{
Debug.LogWarning("[SelectionState] Multiple instances detected. " +
"Only one SelectionState should exist per scene.");
}
Instance = this;
}
private void OnDestroy()
{
if (Instance == this) Instance = null;
}
// ----- Selection state --------------------------------------------
private Builder selectedBuilder;
/// The currently selected builder, or null if nothing is selected.
public Builder SelectedBuilder => selectedBuilder;
/// True if any builder is currently selected.
public bool HasSelection => selectedBuilder != null;
/// True if is the currently selected builder.
public bool IsSelected(Builder b) => b != null && selectedBuilder == b;
// ----- Events -----------------------------------------------------
///
/// Fired when the selection changes. Argument is the new selection (may be null).
/// Subscribe to drive selection-aware UI: highlights, context panels, hotkey hints.
///
public event System.Action OnSelectionChanged;
// ----- Mutators ---------------------------------------------------
///
/// Sets the selected builder. Pass null to clear.
/// Fires only if the selection actually changes.
///
public void Select(Builder builder)
{
if (selectedBuilder == builder) return;
selectedBuilder = builder;
OnSelectionChanged?.Invoke(selectedBuilder);
}
/// Clears the selection. Equivalent to Select(null).
public void Clear() => Select(null);
}
}