using System;
using Framework.Services;
namespace Framework.Actors {
/// Action that can be performed by an actor
///
///
/// Think of a move as when someone says "cool moves" - these are actions,
/// feats or stunts an actor can perform. For player-controlled actors, possible moves
/// might be standing around, running, jumping, punching, falling over and so on.
/// For AI-controlled actors, moves are usually atomic actions such as
/// "run to position x" or "jump onto the platform".
///
///
/// Each move can decide which other moves it can transition to. For example,
/// crawling while jumping doesn't make much sense, but jumping while running does.
///
///
/// Usually, moves have a class derived from this one to add more properties
/// specific to the actor implementation (eg. platformer moves would reference a
/// platformer actor). Overriding moves to use custom implementations can be done
/// through the specific move repository classes.
///
///
/// Moves have to be cancellable at any time and also needs to be reusable.
///
///
public class Move {
/// Initializes the move on the specified actor
/// Actor that will perform the move
public void Initialize(ActorController actor) {
if(this.isInitialized) {
return;
}
ServiceInjector.InjectDependencies(this);
Awake(actor);
this.isInitialized = true;
}
/// Whether the move has completed executing
///
///
/// This is checked by the to see whether its
/// currently active move has ended (allowing it to decide on a new move).
/// Moves are not required to ever finish, but they have to be interruptible at
/// any time. It is also okay to for the moves themselves to take care of their
/// transition to other moves.
///
///
/// If a move can finish, this property should return 'true' as soon as the move
/// finishes and reset to 'false' when the move receives the
/// notification or the notification.
///
///
/// Moves that can finish are usually only used for AI characters where moves are
/// scheduled by a 'strategy' (or other high-level control system) that uses them
/// in a fashion similar to behavior tree nodes (eg. a 'MoveTowardsPlayer' strategy
/// or behavior tree node might use multiple 'run' and 'jump' moves to achieve its goal.
///
///
/// When a move completes, the
/// method is invoked. By default, this just sets the active move to null, but
/// custom actor controllers can override this to notify their AI 'strategy' or
/// fall back to some kind of default move, for example.
///
///
public virtual bool IsCompleted { get { return false; } }
/// Called once when the move is assigned to an actor
/// Actor the move has been assigned to
protected virtual void Awake(ActorController actor) {}
/// Called when the actor has started the move
public virtual void OnStarted() {}
/// Called when the move has completed or was interrupted
public virtual void OnEnded() {}
/// Called once per physics frame
///
/// Use this method to update the world position of the actor and do other
/// things that have an impact on game play. Input processing should happen
/// in this method alone.
///
public virtual void FixedUpdate() {}
/// Called once per visual frame
///
/// Use this method to update the visual state of the actor.
///
public virtual void Update() {}
/// Whether the move has been initialized yet
private bool isInitialized;
}
} // namespace Framework.Actors