Encounter / Assets / Scripts / GUIHandlers / DiceGUI.cs
DiceGUI.cs
Raw
using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.UI;
using static Dice;

public class DiceGUI : MonoBehaviour
{
    [SerializeField] private Sprite[] diceImageFiles;
    [SerializeField] private DiceR diceType;

    private Image diceImageComp;
    private DiceRollerGUI diceRoller;
    private int actualDiceRoll;

    private Dictionary<int, Sprite[]> diceImages;

    public int HeldDiceValue 
    {
        get => actualDiceRoll;
    }

    public DiceR GetDiceType()
        => diceType;
    /// <summary>
    /// Initializes the Dice Image Dictionary generally
    /// </summary>
    /// <exception cref="DataMisalignedException">If D100 is indicated the data is misaligned</exception>
    public Task InitializeDiceDic(DiceRollerGUI diceRoller)
    {
        diceImages = new Dictionary<int, Sprite[]>();
        this.diceRoller = diceRoller;

        switch (diceType)
        {
            case DiceR.Four:             
                int groupings = 3;
                for (int i = 0; i < 4; ++i)
                {
                    // Only double FOR initialization, rest use single FOR loop
                    // 0, 3, 6, 9 are the starting point locations for each grouping in the array
                    int startLocation = i * groupings;
                    Sprite[] spriteGrouping = new Sprite[3];
                    
                    // startLocation + groupings is the end point
                    for (int j = startLocation; j < startLocation + groupings; ++j)
                        spriteGrouping[j - startLocation] = diceImageFiles[j];
                    
                    // Initialize the value to sprite array 
                    diceImages.Add(i + 1, spriteGrouping);
                }
                break;
            case DiceR.Six:
                InitializeDiceImageDic(6);
                break;
            case DiceR.Eight:
                InitializeDiceImageDic(8);
                break;
            case DiceR.Ten:
                InitializeDiceImageDic(10);
                break;
            case DiceR.Twelve:
                InitializeDiceImageDic(12);
                break;
            case DiceR.Twenty:
                InitializeDiceImageDic(20);
                break;
            default:
                throw new DataMisalignedException();
        }

        // This should increment through all of the available counters in the end values
        StartDiceRoll(this.diceRoller.EndValues[diceRoller.Counter], this.diceRoller.RollDuration);
        return Task.CompletedTask;
    }
    /// <summary>
    /// Initializes the dice image dictionary by setting the indicated sprite files to the indicated value
    /// </summary>
    /// <param name="sides">Dice sides</param>
    private void InitializeDiceImageDic(int sides)
    {
        for (int i = 0; i < sides; ++i)
            diceImages.Add(i + 1, new Sprite[] { diceImageFiles[i] });
    }
    /// <summary>
    /// Calls to roll the dice after setting the actual value and indicating the roll time
    /// </summary>
    /// <param name="actualValue">The actual value the dice image will land on</param>
    /// <param name="rollTime">Duration for which the dice will rapidly switch</param>
    private void StartDiceRoll(int actualValue, float rollTime)
    {
        diceImageComp = GetComponent<Image>();
        actualDiceRoll = actualValue;

        StartCoroutine(RollDice(rollTime));
    }

    /// <summary>
    /// Rolls the dice by rapidly switching the image until the true image is shown after a duration period
    /// </summary>
    /// <param name="rollTime">The time frame for which this dice will roll</param>
    /// <returns></returns>
    private IEnumerator RollDice(float rollTime)
    {
        // Set initial image to the image component --> Random value into the dice images dictionary
        // for a random value shown then gets the image itself with the second index reference
        diceImageComp.sprite = diceImages[UnityEngine.Random.Range(1, diceImages.Count + 1)][diceType is not DiceR.Four ? 0 : UnityEngine.Random.Range(0, 3)];
        float timeDuration = .01f;
        float totalTimeRolled = 0.0f;
        while (true)
        {
            if (totalTimeRolled >= rollTime)
                break;
            
            timeDuration += timeDuration / 2;
            yield return new WaitForSeconds(timeDuration);
            totalTimeRolled += timeDuration;
            diceImageComp.sprite = diceImages[UnityEngine.Random.Range(1, diceImages.Count + 1)][diceType is not DiceR.Four ? 0 : UnityEngine.Random.Range(0, 3)];
        }
        // Sets the actual dice value image and calls for this gui to be completed
        diceImageComp.sprite = diceImages[actualDiceRoll][diceType is not DiceR.Four ? 0 : UnityEngine.Random.Range(0, 3)];
        StartCoroutine(diceRoller.DeactivateDiceGUI(this));
    }

    public override int GetHashCode()
    {
        return base.GetHashCode();
    }
}