Files
YachtDice/Assets/Scripts/Game/GameLoopController.cs
T
2026-03-18 09:13:48 +07:00

198 lines
7.1 KiB
C#

using System;
using UnityEngine;
using VContainer;
using YachtDice.Categories;
using YachtDice.Run;
using YachtDice.Scoring;
namespace YachtDice.Game
{
public class GameLoopController : MonoBehaviour
{
private DiceManager _diceManager;
private RunLoopService _runLoopService;
private ScoringSystem _scoringSystem;
public int CurrentRoll => _runLoopService != null ? _runLoopService.State.CurrentRoll : 0;
public int CurrentTurn => _runLoopService != null ? _runLoopService.State.StageNumber : 0;
public int CurrentBet => _runLoopService != null ? _runLoopService.State.BetIndex : 0;
public int CurrentStage => _runLoopService != null ? _runLoopService.State.StageNumber : 0;
public int CurrentStageTarget => _runLoopService != null ? _runLoopService.State.CurrentStageTarget : 0;
public int CurrentBaseQuota => _runLoopService != null ? _runLoopService.State.BaseQuota : 0;
public int StoredRolls => _runLoopService != null ? _runLoopService.State.StoredRolls : 0;
public int MaxRollsPerTurn => _runLoopService != null ? _runLoopService.State.CurrentStageRollBudget : 0;
public RunPhase CurrentPhase => _runLoopService != null ? _runLoopService.State.Phase : RunPhase.None;
public bool CanRoll => _runLoopService != null && _runLoopService.CanRoll() && !_diceManager.IsAnyRolling;
public bool CanScore => _runLoopService != null && CurrentPhase == RunPhase.CategorySelection && !_diceManager.IsAnyRolling;
public bool IsGameOver => _runLoopService != null && _runLoopService.State.IsFailed;
public bool IsShopOpen => CurrentPhase == RunPhase.Shop;
public event Action<int> OnTurnStarted;
public event Action<int> OnRollComplete;
public event Action<CategoryDefinition, int> OnScored;
public event Action<int> OnGameOver;
public event Action<int> OnBetStarted;
public event Action OnShopOpened;
public event Action OnShopClosed;
public event Action<int> OnStoredRollsChanged;
public event Action<int> OnCurrencyChanged;
public event Action<int> OnQuotaChanged;
public event Action<int, int> OnCycleCompleted;
public event Action<RunPhase> OnPhaseChanged;
[Inject]
public void Construct(DiceManager diceManager, RunLoopService runLoopService, ScoringSystem scoringSystem)
{
_diceManager = diceManager;
_runLoopService = runLoopService;
_scoringSystem = scoringSystem;
_runLoopService.OnStageStarted += HandleStageStarted;
_runLoopService.OnStageCleared += HandleStageCleared;
_runLoopService.OnRunFailed += HandleRunFailed;
_runLoopService.OnBetStarted += HandleBetStarted;
_runLoopService.OnShopOpened += HandleShopOpened;
_runLoopService.OnStoredRollsChanged += HandleStoredRollsChanged;
_runLoopService.OnCurrencyChanged += HandleCurrencyChanged;
_runLoopService.OnQuotaChanged += HandleQuotaChanged;
_runLoopService.OnCycleCompleted += HandleCycleCompleted;
_runLoopService.OnPhaseChanged += HandlePhaseChanged;
}
private void OnDestroy()
{
if (_runLoopService == null)
return;
_runLoopService.OnStageStarted -= HandleStageStarted;
_runLoopService.OnStageCleared -= HandleStageCleared;
_runLoopService.OnRunFailed -= HandleRunFailed;
_runLoopService.OnBetStarted -= HandleBetStarted;
_runLoopService.OnShopOpened -= HandleShopOpened;
_runLoopService.OnStoredRollsChanged -= HandleStoredRollsChanged;
_runLoopService.OnCurrencyChanged -= HandleCurrencyChanged;
_runLoopService.OnQuotaChanged -= HandleQuotaChanged;
_runLoopService.OnCycleCompleted -= HandleCycleCompleted;
_runLoopService.OnPhaseChanged -= HandlePhaseChanged;
}
public void StartNewGame()
{
_diceManager.UnlockAll();
_runLoopService.StartNewRun();
}
public void CompleteShop()
{
if (!IsShopOpen)
return;
_runLoopService.CompleteShop();
OnShopClosed?.Invoke();
}
public void Roll()
{
if (!CanRoll)
return;
if (!_runLoopService.TryBeginRoll())
return;
_diceManager.OnAllDiceSettled += HandleAllDiceSettled;
_diceManager.RollUnlocked();
}
private void HandleAllDiceSettled()
{
_diceManager.OnAllDiceSettled -= HandleAllDiceSettled;
_runLoopService.NotifyRollResolved(_diceManager.GetDice());
OnRollComplete?.Invoke(CurrentRoll);
}
public void ToggleDiceLock(int index)
{
if (_diceManager.IsAnyRolling) return;
if (CurrentRoll == 0) return;
_diceManager.ToggleLock(index);
}
public bool CanScoreCategory(CategoryDefinition category)
{
return _runLoopService != null && _runLoopService.CanScoreCategory(_diceManager.GetDice(), category);
}
public ScoreResult PreviewCategory(CategoryDefinition category)
{
return _runLoopService.PreviewScore(_diceManager.GetDice(), category);
}
public async void ScoreInCategory(CategoryDefinition category)
{
if (!CanScore)
return;
await _runLoopService.TryScoreCategoryAsync(_diceManager.GetDice(), category);
}
public bool CanOpenShopManually()
{
return IsShopOpen;
}
private void HandleStageStarted(RunStageState stage)
{
_diceManager.UnlockAll();
OnTurnStarted?.Invoke(stage.Index + 1);
}
private void HandleStageCleared(RunStageState stage, CategoryDefinition category, ScoreResult result)
{
_diceManager.UnlockAll();
OnScored?.Invoke(category, result.FinalScore);
}
private void HandleRunFailed(RunState state)
{
OnGameOver?.Invoke(_scoringSystem != null ? _scoringSystem.TotalScore : 0);
}
private void HandleBetStarted(RunState state)
{
OnBetStarted?.Invoke(state.BetIndex);
}
private void HandleShopOpened(RunState state)
{
OnShopOpened?.Invoke();
}
private void HandleStoredRollsChanged(int value)
{
OnStoredRollsChanged?.Invoke(value);
}
private void HandleCurrencyChanged(int value)
{
OnCurrencyChanged?.Invoke(value);
}
private void HandleQuotaChanged(int value)
{
OnQuotaChanged?.Invoke(value);
}
private void HandleCycleCompleted(int bonus, int storedRolls)
{
OnCycleCompleted?.Invoke(bonus, storedRolls);
}
private void HandlePhaseChanged(RunPhase phase)
{
OnPhaseChanged?.Invoke(phase);
}
}
}