using System.Collections;
using System.Collections.Generic;
using UnityEngine;
///
/// Base class all logic blocks are derived from
///
[System.Serializable]
public abstract class LogicBlock : ScriptableObject
{
#region Inspector Fields
[SerializeField]
[Header("UI Settings")]
[Tooltip("Color which will identify this element")]
public Color Color;
[SerializeField]
[Tooltip("Name which will appear in the UI")]
protected string _DisplayName;
[SerializeField]
[Header("Base Settings")]
[Tooltip("Wait until this block is resolved before moving to next")]
protected bool _WaitUntilFinished = false;
[SerializeField]
[Tooltip("Amount of times to run this Block before moving to next")]
protected int RepeatAmount = 1;
[SerializeField]
[Tooltip("Speed this block will be played back at. (Default = 1)")]
protected float SpeedMultiplier = 1;
#endregion Inspector Fields
#region ReadOnly Variables
public string DisplayName { get { return (string.IsNullOrEmpty(_DisplayName)) ? name : _DisplayName; } }
[HideInInspector]
public bool hasBeenRemoved = false;
public virtual bool WaitUntilFinished { get { return _WaitUntilFinished; } }
#endregion
#region private variables
///
/// Amount of times this block has run
///
protected int RepeatCount = 0;
#endregion private variables
#region Class Functions
///
/// Runs the block
///
/// Player which will be affected by the block
/// returns true if block is finished
public virtual IEnumerator Run(Character player, float animationSpeed,bool useBlockDirection = false)
{
float TotalAnimationTime = animationSpeed / SpeedMultiplier;
if(GlobalVariables.playerMoves == true){
player.DisplayBlock(this);
}
if (WaitUntilFinished)
{
for (int i = 0; i < RepeatAmount; i++)
{
if (player.stuck)
yield break;
RepeatCount++;
yield return player.StartCoroutine(BlockLogic(player, TotalAnimationTime, useBlockDirection));
}
}
else
{
RepeatCount++;
yield return player.StartCoroutine(BlockLogic(player, TotalAnimationTime, useBlockDirection));
}
}
///
/// Returns the amount of space this logic block takes up
///
/// Int which controlls how much space this takes up
public virtual int Size()
{
return 1;
}
///
/// Where derived callses should implement the logic for their classes
///
/// Player which will be affected by the block
/// returns true if block is finished
protected abstract IEnumerator BlockLogic(Character player, float animationTime,bool useBlockDirection = false);
///
/// Returns the block that the character will endUp on after they use this logic element
///
/// block character is on
/// transform function will be based off
/// layers to ignore
/// block which character will finish on after performing this function
public abstract Block GetEndBlock(Block startBlock, Transform transform, LayerMask layerMask);
///
/// Resets the block to be ready to used again
///
public virtual void Reset()
{
RepeatCount = 0;
}
///
/// False if this block needs to be run again
///
/// bool false if block needs to be run again
public virtual bool isFinished()
{
return (RepeatCount == RepeatAmount);
}
#region Serialisation Functions
///
/// Copies data from BlockToken to this Block
///
/// Token to Copy
public virtual void CopyToken(BlockToken token)
{
Color = token.Color;
_DisplayName = token._DisplayName;
_WaitUntilFinished = token.WaitUntilFinished;
RepeatAmount = token.RepeatAmount;
name = token.ObjectName;
SpeedMultiplier = token.SpeedMultiplier;
}
///
/// Copies Block data to supplied token, if token is null creates new token
///
/// token to copy data to
///
public virtual BlockToken ToToken(BlockToken token = null)
{
if (token == null)
token = new BlockToken(this);
token.Color = Color;
token._DisplayName = _DisplayName;
token.WaitUntilFinished = WaitUntilFinished;
token.RepeatAmount = RepeatAmount;
token.ObjectName = name;
token.SpeedMultiplier = SpeedMultiplier;
return token;
}
#endregion Serialisation Functions
public bool isSameType(object other)
{
if (Object.ReferenceEquals(null, other))
return false;
if (Object.ReferenceEquals(other.GetType(), other))
return false;
LogicBlock otherLogic = other as LogicBlock;
return !Object.ReferenceEquals(null, otherLogic)
&& string.Equals(name, otherLogic.name);
}
public virtual LogicBlock Clone()
{
LogicBlock retVal = Instantiate(this);
retVal.name = this.name;
return retVal;
}
public virtual LogicBlock[] GetAllBlocks()
{
return new LogicBlock[] { this };
}
#endregion Class Functions
}
[System.Serializable]
public class BlockToken
{
public System.Type blockType;
public Color Color;
public string _DisplayName;
public string ObjectName;
public bool WaitUntilFinished;
public int RepeatAmount;
public float SpeedMultiplier;
public BlockToken(LogicBlock block)
{
blockType = block.GetType();
}
public LogicBlock ToLogicBlock()
{
LogicBlock retVal = (LogicBlock)ScriptableObject.CreateInstance(blockType);
//Debug.Log("type: " + retVal.GetType());
retVal.CopyToken(this);
return retVal;
}
}