using System; using System.Collections.Generic; using System.Linq; using BriarQueen.Data.Identifiers; using BriarQueen.Framework.Coordinators.Events; using BriarQueen.Framework.Events.Gameplay; using BriarQueen.Framework.Events.UI; using BriarQueen.Framework.Managers.UI; using BriarQueen.Framework.Services.Tutorials; using UnityEngine; namespace BriarQueen.Framework.Managers.Player.Data.Tools { public class Toolbelt : IDisposable { private readonly Dictionary _unlockedTools = new(); private readonly EventCoordinator _eventCoordinator; private readonly TutorialService _tutorialService; public IReadOnlyDictionary UnlockedTools => _unlockedTools; public ToolID CurrentTool { get; private set; } = ToolID.None; public Toolbelt(EventCoordinator eventCoordinator, TutorialService tutorialService) { _eventCoordinator = eventCoordinator; _tutorialService = tutorialService; } public void Initialize() { _eventCoordinator.Subscribe(OnNextToolChanged); _eventCoordinator.Subscribe(OnPreviousToolChanged); } public void Dispose() { _eventCoordinator.Unsubscribe(OnNextToolChanged); _eventCoordinator.Unsubscribe(OnPreviousToolChanged); } public void Unlock(ToolID id) { if (id == ToolID.None) return; _unlockedTools[id] = true; Debug.Log($"{this} Tool {id} has been unlocked"); } public void Lock(ToolID id) { if (id == ToolID.None) return; if (_unlockedTools.ContainsKey(id)) _unlockedTools[id] = false; if (CurrentTool == id) SelectNextTool(); } public bool HasAccess(ToolID id) { if (id == ToolID.None) return true; return _unlockedTools.TryGetValue(id, out var unlocked) && unlocked; } public bool IsKnown(ToolID id) { if (id == ToolID.None) return true; return _unlockedTools.ContainsKey(id); } public void SelectTool(ToolID id) { if (!HasAccess(id)) return; SetCurrentTool(id, 0); } public void SelectEmptyHands() { SetCurrentTool(ToolID.None, 0); } public void SelectNextTool() { Debug.Log($"SelectNextTool: {CurrentTool}"); CycleTool(1); } public void SelectPreviousTool() { CycleTool(-1); } private void OnNextToolChanged(OnNextToolChangedEvent e) { SelectNextTool(); } private void OnPreviousToolChanged(OnPreviousToolChangedEvent e) { SelectPreviousTool(); } private void CycleTool(int direction) { var selectableTools = GetSelectableTools(); Debug.Log($"CycleTool: {selectableTools.Count}"); foreach (var selectableTool in selectableTools) { Debug.Log($"CycleTool: {selectableTool}"); } if (selectableTools.Count == 0) { SetCurrentTool(ToolID.None, direction); return; } int currentIndex = selectableTools.IndexOf(CurrentTool); if (currentIndex < 0) { int fallbackIndex = direction > 0 ? 0 : selectableTools.Count - 1; SetCurrentTool(selectableTools[fallbackIndex], direction); return; } int nextIndex = currentIndex + direction; if (nextIndex < 0) nextIndex = selectableTools.Count - 1; else if (nextIndex >= selectableTools.Count) nextIndex = 0; Debug.Log($"CycleTool: Setting tool to {selectableTools[nextIndex]}"); SetCurrentTool(selectableTools[nextIndex], direction); } private void CheckToolsCycling() { _tutorialService.DisplayTutorial(TutorialPopupID.ToolCycling); } private void SetCurrentTool(ToolID newTool, int direction) { if (CurrentTool == newTool) return; CurrentTool = newTool; CheckToolsCycling(); _eventCoordinator.Publish(new SelectedToolChangedEvent(CurrentTool, direction)); if (newTool == ToolID.None) { _eventCoordinator.Publish( new OverrideCursorStyleChangeEvent(UICursorService.CursorStyle.Default)); return; } if (Enum.TryParse(newTool.ToString(), out UICursorService.CursorStyle style)) { _eventCoordinator.Publish(new OverrideCursorStyleChangeEvent(style)); } else { _eventCoordinator.Publish( new OverrideCursorStyleChangeEvent(UICursorService.CursorStyle.Default)); } } private List GetSelectableTools() { var tools = _unlockedTools .Where(x => x.Value && x.Key != ToolID.None) .Select(x => x.Key) .OrderBy(x => (int)x) .ToList(); Debug.Log($"{_unlockedTools.Count} tools have been unlocked"); tools.Insert(0, ToolID.None); Debug.Log($"[Get Selectable Tools: {tools.Count}]"); return tools; } } }