#region File Description
//-----------------------------------------------------------------------------
// CombatAction.cs
//
// Microsoft XNA Community Game Platform
// Copyright (C) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#endregion
#region Using Statements
using System;
using RolePlayingGameData;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
#endregion
namespace RolePlaying
{
///
/// An action taken by an individual character in combat.
///
///
/// Note that party actions, like Flee, are not represented here. These are only
/// the actions that individual characters, on either side, can perform in combat.
///
abstract class CombatAction
{
#region State
///
/// Returns true if the action is offensive, targeting the opponents.
///
public abstract bool IsOffensive
{
get;
}
///
/// Returns true if this action requires a target.
///
public abstract bool IsTargetNeeded
{
get;
}
#endregion
#region Combat Stage
///
/// Stages of the action as it is executed.
///
public enum CombatActionStage
{
///
/// The initial state, with no action taken yet.
///
NotStarted,
///
/// The action is getting ready to start.
///
///
/// Spell actions stay in this stage while the casting animation plays.
///
Preparing,
///
/// The effect is traveling to the target, if needed.
///
///
/// The character walks to melee targets while in this stage. Spell effects
/// also travel to the target while in this state.
///
Advancing,
///
/// The action is being applied to the target(s).
///
Executing,
///
/// The effect is returning from the target, if needed.
///
///
/// The character walks back from the melee target while in this stage.
///
Returning,
///
/// The action is performing any final actions.
///
Finishing,
///
/// The action is complete.
///
Complete,
};
///
/// The current state of the action.
///
protected CombatActionStage stage = CombatActionStage.NotStarted;
///
/// The current state of the action.
///
public CombatActionStage Stage
{
get { return stage; }
}
///
/// Starts a new combat stage. Called right after the stage changes.
///
/// The stage never changes into NotStarted.
protected virtual void StartStage()
{
switch (stage)
{
case CombatActionStage.Preparing: // called from Start()
break;
case CombatActionStage.Advancing:
break;
case CombatActionStage.Executing:
break;
case CombatActionStage.Returning:
break;
case CombatActionStage.Finishing:
break;
case CombatActionStage.Complete:
break;
}
}
///
/// Update the action for the current stage.
///
///
/// This function is guaranteed to be called at least once per stage.
///
protected virtual void UpdateCurrentStage(GameTime gameTime)
{
switch (stage)
{
case CombatActionStage.NotStarted:
break;
case CombatActionStage.Preparing:
break;
case CombatActionStage.Advancing:
break;
case CombatActionStage.Executing:
break;
case CombatActionStage.Returning:
break;
case CombatActionStage.Finishing:
break;
case CombatActionStage.Complete:
break;
}
}
///
/// Returns true if the combat action is ready to proceed to the next stage.
///
protected virtual bool IsReadyForNextStage
{
get
{
switch (stage)
{
case CombatActionStage.Preparing: // ready to advance?
break;
case CombatActionStage.Advancing: // ready to execute?
break;
case CombatActionStage.Executing: // ready to return?
break;
case CombatActionStage.Returning: // ready to finish?
break;
case CombatActionStage.Finishing: // ready to complete?
break;
}
// fall through - the action doesn't care about the state, so move on
return true;
}
}
#endregion
#region Combatant
///
/// The character performing this action.
///
protected Combatant combatant;
///
/// The character performing this action.
///
public Combatant Combatant
{
get { return combatant; }
}
///
/// Returns true if the character can use this action.
///
public virtual bool IsCharacterValidUser
{
get { return true; }
}
#endregion
#region Target
///
/// The target of the action.
///
public Combatant Target = null;
///
/// The number of adjacent targets in each direction that are affected.
///
protected int adjacentTargets = 0;
///
/// The number of adjacent targets in each direction that are affected.
///
public int AdjacentTargets
{
get { return adjacentTargets; }
}
#endregion
#region Heuristic
///
/// The heuristic used to compare actions of this type to similar ones.
///
public abstract int Heuristic
{
get;
}
///
/// Compares the combat actions by their heuristic, in descending order.
///
public static int CompareCombatActionsByHeuristic(
CombatAction a, CombatAction b)
{
return b.Heuristic.CompareTo(a.Heuristic);
}
#endregion
#region Initialization
///
/// Constructs a new CombatAction object.
///
/// The combatant performing the action.
public CombatAction(Combatant combatant)
{
// check the parameter
if (combatant == null)
{
throw new ArgumentNullException("combatant");
}
// assign the parameter
this.combatant = combatant;
Reset();
}
///
/// Reset the action so that it may be started again.
///
public virtual void Reset()
{
// set the state to not-started
stage = CombatActionStage.NotStarted;
}
///
/// Start executing the combat action.
///
public virtual void Start()
{
// set the state to the first step
stage = CombatActionStage.Preparing;
StartStage();
}
#endregion
#region Updating
///
/// Updates the action over time.
///
public virtual void Update(GameTime gameTime)
{
// update the current stage
UpdateCurrentStage(gameTime);
// if the action is ready for the next stage, then advance
if ((stage != CombatActionStage.NotStarted) &&
(stage != CombatActionStage.Complete) && IsReadyForNextStage)
{
switch (stage)
{
case CombatActionStage.Preparing:
stage = CombatActionStage.Advancing;
break;
case CombatActionStage.Advancing:
stage = CombatActionStage.Executing;
break;
case CombatActionStage.Executing:
stage = CombatActionStage.Returning;
break;
case CombatActionStage.Returning:
stage = CombatActionStage.Finishing;
break;
case CombatActionStage.Finishing:
stage = CombatActionStage.Complete;
break;
}
StartStage();
}
}
#endregion
#region Drawing
///
/// Draw any elements of the action that are independent of the character.
///
public virtual void Draw(GameTime gameTime, SpriteBatch spriteBatch) { }
#endregion
}
}