using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace BossRoom.Server
{
///
/// The abstract parent class that all Actions derive from.
///
///
/// The Action System is a generalized mechanism for Characters to "do stuff" in a networked way. Actions
/// include everything from your basic character attack, to a fancy skill like the Archer's Volley Shot, but also
/// include more mundane things like pulling a lever.
/// For every ActionLogic enum, there will be one specialization of this class.
/// There is only ever one active Action at a time on a character, but multiple Actions may exist at once, with subsequent Actions
/// pending behind the currently playing one. See ActionPlayer.cs
///
public abstract class Action
{
protected ServerCharacter m_Parent;
///
/// The level this action plays back at. e.g. a weak "level 0" melee attack, vs a strong "level 3" melee attack.
///
protected int m_Level;
protected ActionRequestData m_Data;
///
/// Time when this Action was started (from Time.time) in seconds. Set by the ActionPlayer.
///
public float TimeStarted { get; set; }
///
/// RequestData we were instantiated with. Value should be treated as readonly.
///
public ref ActionRequestData Data { get { return ref m_Data; } }
///
/// Data Description for this action.
///
public ActionDescription Description
{
get
{
var list = ActionData.ActionDescriptions[Data.ActionTypeEnum];
int level = Mathf.Min(m_Level, list.Count - 1); //if we don't go up to the requested level, just cap at the max level.
return list[level];
}
}
///
/// constructor. The "data" parameter should not be retained after passing in to this method, because we take ownership of its internal memory.
///
public Action(ServerCharacter parent, ref ActionRequestData data, int level)
{
m_Parent = parent;
m_Level = level;
m_Data = data; //do a shallow copy.
m_Data.Level = level;
}
///
/// Called when the Action starts actually playing (which may be after it is created, because of queueing).
///
/// false if the action decided it doesn't want to run after all, true otherwise.
public abstract bool Start();
///
/// Called each frame while the action is running.
///
/// true to keep running, false to stop. The Action will stop by default when its duration expires, if it has a duration set.
public abstract bool Update();
///
/// This will get called when the Action gets canceled. The Action should clean up any ongoing effects at this point.
/// (e.g. an Action that involves moving should cancel the current active move).
///
public virtual void Cancel() { }
///
/// Factory method that creates Actions from their request data.
///
/// the NetworkCharacterState of the character that owns our ActionPlayer
/// the data to instantiate this skill from.
/// the level to play the skill at.
/// the newly created action.
public static Action MakeAction(ServerCharacter parent, ref ActionRequestData data, int level )
{
var logic = ActionData.ActionDescriptions[data.ActionTypeEnum][0].Logic;
switch(logic)
{
case ActionLogic.MELEE: return new MeleeAction(parent, ref data, level);
case ActionLogic.CHASE: return new ChaseAction(parent, ref data, level);
case ActionLogic.REVIVE: return new ReviveAction(parent, ref data, level);
default: throw new System.NotImplementedException();
}
}
}
}