Files

202 lines
5.8 KiB
C#

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 NUnit.Framework;
using UnityEngine;
namespace BriarQueen.Framework.Managers.Player.Data.Tools
{
public class Toolbelt : IDisposable
{
private readonly Dictionary<ToolID, bool> _unlockedTools = new();
private readonly EventCoordinator _eventCoordinator;
private readonly TutorialService _tutorialService;
public IReadOnlyDictionary<ToolID, bool> 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<OnNextToolChangedEvent>(OnNextToolChanged);
_eventCoordinator.Subscribe<OnPreviousToolChangedEvent>(OnPreviousToolChanged);
}
public void Dispose()
{
_eventCoordinator.Unsubscribe<OnNextToolChangedEvent>(OnNextToolChanged);
_eventCoordinator.Unsubscribe<OnPreviousToolChangedEvent>(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<ToolID> 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;
}
}
}