f49cda7cdc
Implements the core game loop for Yacht dice: 5-dice rolling with lock/unlock, 3 rolls per turn, 13 standard scoring categories, and an extensible ScriptableObject-based modifier system that applies additive then multiplicative bonuses (chips+mult pattern). Includes two test modifiers: BonusForOnes (+10 per 1) and MultiplierForSixes (x6 per 6). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
104 lines
2.5 KiB
C#
104 lines
2.5 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
public sealed class DiceManager : MonoBehaviour
|
|
{
|
|
[SerializeField] private List<DiceRoller> diceRollers = new();
|
|
|
|
public event Action OnAllDiceSettled;
|
|
public event Action<int, int> OnDieSettled;
|
|
|
|
public int DiceCount => diceRollers.Count;
|
|
|
|
private bool[] locked;
|
|
private int[] currentValues;
|
|
private int pendingCount;
|
|
|
|
private void Awake()
|
|
{
|
|
int count = diceRollers.Count;
|
|
locked = new bool[count];
|
|
currentValues = new int[count];
|
|
}
|
|
|
|
public bool IsLocked(int index) => locked[index];
|
|
|
|
public void ToggleLock(int index)
|
|
{
|
|
locked[index] = !locked[index];
|
|
}
|
|
|
|
public void SetLocked(int index, bool isLocked)
|
|
{
|
|
locked[index] = isLocked;
|
|
}
|
|
|
|
public void UnlockAll()
|
|
{
|
|
for (int i = 0; i < locked.Length; i++) locked[i] = 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 (locked[i]) continue;
|
|
|
|
pendingCount++;
|
|
int capturedIndex = i;
|
|
|
|
void Handler(int value)
|
|
{
|
|
diceRollers[capturedIndex].OnRollFinished -= Handler;
|
|
currentValues[capturedIndex] = value;
|
|
OnDieSettled?.Invoke(capturedIndex, value);
|
|
|
|
pendingCount--;
|
|
if (pendingCount <= 0)
|
|
OnAllDiceSettled?.Invoke();
|
|
}
|
|
|
|
diceRollers[i].OnRollFinished += Handler;
|
|
diceRollers[i].Roll();
|
|
}
|
|
|
|
if (pendingCount == 0)
|
|
OnAllDiceSettled?.Invoke();
|
|
}
|
|
|
|
public int[] GetCurrentValues()
|
|
{
|
|
int[] copy = new int[currentValues.Length];
|
|
Array.Copy(currentValues, copy, currentValues.Length);
|
|
return copy;
|
|
}
|
|
|
|
public int GetValue(int index) => currentValues[index];
|
|
|
|
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>();
|
|
if (diceComponent != null && diceComponent.TryGetTopValue(out int val))
|
|
currentValues[i] = val;
|
|
}
|
|
}
|
|
}
|