using System.Collections; using System.Collections.Generic; using UnityEngine; /// <summary> /// Class which reads a a list of logic blocks and applies to a character /// </summary> [System.Serializable] public class BlockReader { #region Inspector Variables [SerializeField] [Tooltip("List of LogicBlocks which will affected this character")] public List<LogicBlock> LogicChain = new List<LogicBlock>(); #endregion Inspector Variables #region Read-only Variables /// <summary> /// returns true if all LogicBlocks in LogicChain have been completed /// </summary> public bool Finished { get { return currentBlockIndex >= LogicChain.Count; } } /// <summary> /// Fired whenever the logic chain is updated, useful for UI /// </summary> public event System.Action OnUpdate; /// <summary> /// Gets the current block in the logic chain /// </summary> public LogicBlock CurrentBlock { get { return ((currentBlockIndex < LogicChain.Count) ? LogicChain[currentBlockIndex] : null); } } /// <summary> /// Sum of size of all Blocks in the chain /// </summary> public int Length { get { int retVal = 0; LogicChain.ForEach(p => retVal += p.Size()); return retVal; } } #endregion Read-only Variables #region Private Variables private int currentBlockIndex;//Block currently on #endregion Private Variables #region Class Implementation /// <summary> /// Resets Block reader; /// </summary> public void Reset() { currentBlockIndex = 0; } /// <summary> /// Reads the current block in the logic chain /// </summary> /// <param name="character">Character to control</param> /// <returns>Returns false if other readers should wait for this one to run again</returns> public IEnumerator Read(Character character, float speedMultiplier) { if(currentBlockIndex >= LogicChain.Count) { yield break; } LogicBlock currentBlock = LogicChain[currentBlockIndex]; //If the character has become stuck, they forfeit their remaining moves - we skip directly to their end of their chain if (character.stuck == true) { currentBlockIndex = LogicChain.Count; currentBlock.Reset(); yield break; } //apply blocks to character yield return character.StartCoroutine(currentBlock.Run(character, speedMultiplier)); //if the block is finished reset it and move on to next one //(it might not be finished if it is a for loop or something) if (currentBlock.isFinished()) { currentBlockIndex++; currentBlock.Reset(); } } /// <summary> /// Clears all elements out of the Block Reader /// </summary> public void Clear() { LogicChain.Clear(); if (OnUpdate != null) OnUpdate.Invoke(); } /// <summary> /// Removes the first instance found in the Block Reader /// </summary> /// <param name="item">LogicElement to remove</param> public void Remove(LogicBlock item) { LogicChain.Remove(item); if (OnUpdate != null) OnUpdate.Invoke(); } /// <summary> /// Addes item to the end of the BlockReader /// </summary> /// <param name="item">item to add</param> public void Add(LogicBlock item) { LogicChain.Add(item); if (OnUpdate != null) OnUpdate.Invoke(); } /// <summary> /// Inserts item at index of the Block Reader /// </summary> /// <param name="index">index to insert at</param> /// <param name="item">item to insert</param> public void Insert(int index, LogicBlock item) { LogicChain.Insert(index, item); if (OnUpdate != null) OnUpdate.Invoke(); } #endregion }