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(); } }