118 lines
3.5 KiB
C#
118 lines
3.5 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using YachtDice.Dice;
|
|
|
|
namespace YachtDice.Game
|
|
{
|
|
public class DiceManager : MonoBehaviour
|
|
{
|
|
[SerializeField] private List<DiceRoller> diceRollers = new();
|
|
|
|
public event Action OnAllDiceSettled;
|
|
public event Action<int, int> OnDiceSettled;
|
|
|
|
public int DiceCount => diceRollers.Count;
|
|
|
|
private DiceInstance[] diceInstances;
|
|
private int pendingCount;
|
|
|
|
private void Awake()
|
|
{
|
|
int count = diceRollers.Count;
|
|
diceInstances = new DiceInstance[count];
|
|
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
var definition = diceRollers[i].Definition;
|
|
diceInstances[i] = new DiceInstance(definition);
|
|
}
|
|
}
|
|
|
|
public bool IsLocked(int index) => diceInstances[index].IsLocked;
|
|
|
|
public void ToggleLock(int index)
|
|
{
|
|
diceInstances[index].IsLocked = !diceInstances[index].IsLocked;
|
|
}
|
|
|
|
public void SetLocked(int index, bool isLocked)
|
|
{
|
|
diceInstances[index].IsLocked = isLocked;
|
|
}
|
|
|
|
public void UnlockAll()
|
|
{
|
|
for (int i = 0; i < diceInstances.Length; i++)
|
|
diceInstances[i].IsLocked = false;
|
|
}
|
|
|
|
public void RollUnlocked()
|
|
{
|
|
for (int i = 0; i < diceRollers.Count; i++)
|
|
if (diceRollers[i].IsRolling) return;
|
|
|
|
pendingCount = 0;
|
|
|
|
for (int i = 0; i < diceRollers.Count; i++)
|
|
{
|
|
if (diceInstances[i].IsLocked) continue;
|
|
|
|
pendingCount++;
|
|
int capturedIndex = i;
|
|
|
|
void Handler(int value)
|
|
{
|
|
diceRollers[capturedIndex].OnRollFinished -= Handler;
|
|
diceInstances[capturedIndex].Value = value;
|
|
OnDiceSettled?.Invoke(capturedIndex, value);
|
|
|
|
pendingCount--;
|
|
if (pendingCount <= 0)
|
|
OnAllDiceSettled?.Invoke();
|
|
}
|
|
|
|
diceRollers[i].OnRollFinished += Handler;
|
|
diceRollers[i].Roll();
|
|
}
|
|
|
|
if (pendingCount == 0)
|
|
OnAllDiceSettled?.Invoke();
|
|
}
|
|
|
|
/// <summary>Возвращает абстрактный список дайсов (основной API).</summary>
|
|
public IReadOnlyList<IDice> GetDice() => diceInstances;
|
|
|
|
/// <summary>Возвращает копию текущих значений (обратная совместимость).</summary>
|
|
public int[] GetCurrentValues()
|
|
{
|
|
int[] values = new int[diceInstances.Length];
|
|
for (int i = 0; i < diceInstances.Length; i++)
|
|
values[i] = diceInstances[i].Value;
|
|
return values;
|
|
}
|
|
|
|
public int GetValue(int index) => diceInstances[index].Value;
|
|
|
|
public bool IsAnyRolling
|
|
{
|
|
get
|
|
{
|
|
for (int i = 0; i < diceRollers.Count; i++)
|
|
if (diceRollers[i].IsRolling) return true;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public void ReadAllValues()
|
|
{
|
|
for (int i = 0; i < diceRollers.Count; i++)
|
|
{
|
|
var diceComponent = diceRollers[i].GetComponent<Dice.Dice>();
|
|
if (diceComponent != null && diceComponent.TryGetTopValue(out int val))
|
|
diceInstances[i].Value = val;
|
|
}
|
|
}
|
|
}
|
|
}
|