#region File Description
//-----------------------------------------------------------------------------
// Combatant.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
{
///
/// Base class for all combatants.
///
abstract class Combatant
{
///
/// The character encapsulated by this combatant.
///
public abstract FightingCharacter Character
{
get;
}
#region State Data
///
/// The current state of this combatant.
///
public abstract Character.CharacterState State
{
get;
set;
}
///
/// Returns true if the character is dead or dying.
///
public bool IsDeadOrDying
{
get
{
return ((State == RolePlayingGameData.Character.CharacterState.Dying) ||
(State == RolePlayingGameData.Character.CharacterState.Dead));
}
}
///
/// If true, the combatant has taken their turn this round.
///
private bool isTurnTaken;
///
/// If true, the combatant has taken their turn this round.
///
public bool IsTurnTaken
{
get { return isTurnTaken; }
set { isTurnTaken = value; }
}
#endregion
#region Graphics Data
///
/// Accessor for the combat sprite for this combatant.
///
public abstract AnimatingSprite CombatSprite
{
get;
}
///
/// The current position on screen for this combatant.
///
private Vector2 position;
///
/// The current position on screen for this combatant.
///
public Vector2 Position
{
get { return position; }
set { position = value; }
}
///
/// The original position on screen for this combatant.
///
private Vector2 originalPosition;
///
/// The original position on screen for this combatant.
///
public Vector2 OriginalPosition
{
get { return originalPosition; }
set { originalPosition = value; }
}
#endregion
#region Current Statistics
///
/// The current statistics of this combatant.
///
public abstract StatisticsValue Statistics
{
get;
}
///
/// Heals the combatant's health by the given amount.
///
public void HealHealth(int healthHealingAmount, int duration)
{
Heal(new StatisticsValue(healthHealingAmount, 0, 0, 0, 0, 0), duration);
}
///
/// Heal the combatant by the given amount.
///
public virtual void Heal(StatisticsValue healingStatistics, int duration)
{
CombatEngine.AddNewHealingEffects(OriginalPosition, healingStatistics);
}
///
/// Damages the combatant's health by the given amount.
///
public void DamageHealth(int healthDamageAmount, int duration)
{
Damage(new StatisticsValue(healthDamageAmount, 0, 0, 0, 0, 0), duration);
}
///
/// Damages the combatant by the given amount.
///
public virtual void Damage(StatisticsValue damageStatistics, int duration)
{
State = RolePlayingGameData.Character.CharacterState.Hit;
CombatEngine.AddNewDamageEffects(OriginalPosition, damageStatistics);
}
///
/// Pay the cost for the given spell.
///
/// True if the cost could be paid (and therefore was paid).
public virtual bool PayCostForSpell(Spell spell) { return false; }
#endregion
#region Combat Action
///
/// The current combat action for this combatant.
///
private CombatAction combatAction;
///
/// The current combat action for this combatant.
///
public CombatAction CombatAction
{
get { return combatAction; }
set { combatAction = value; }
}
#endregion
#region Combat Effects
///
/// Statistics stack of the combat effects that are applied to this combatant.
///
private StatisticsValueStack combatEffects = new StatisticsValueStack();
///
/// Statistics stack of the combat effects that are applied to this combatant.
///
public StatisticsValueStack CombatEffects
{
get { return combatEffects; }
}
#endregion
#region Initialization
///
/// Constructs a new Combatant object.
///
protected Combatant() { }
#endregion
#region Updating
///
/// Update the combatant for this frame.
///
public virtual void Update(GameTime gameTime)
{
float elapsedSeconds = (float)gameTime.ElapsedGameTime.TotalSeconds;
// update the combat action
if (combatAction != null)
{
// update the combat action
combatAction.Update(gameTime);
// remove the combat action if it is done and set the turn-taken flag
if (combatAction.Stage == CombatAction.CombatActionStage.Complete)
{
combatAction = null;
isTurnTaken = true;
}
}
// update the combat sprite animation
CombatSprite.UpdateAnimation(elapsedSeconds);
// check for death
if (!IsDeadOrDying && (Statistics.HealthPoints <= 0))
{
AudioManager.PlayCue("Death");
State = RolePlayingGameData.Character.CharacterState.Dying;
}
// check for waking up
else if (IsDeadOrDying && (Statistics.HealthPoints > 0))
{
State = RolePlayingGameData.Character.CharacterState.Idle;
}
else if (CombatSprite.IsPlaybackComplete)
{
if (State == RolePlayingGameData.Character.CharacterState.Hit)
{
State = RolePlayingGameData.Character.CharacterState.Idle;
}
else if (State == RolePlayingGameData.Character.CharacterState.Dying)
{
State = RolePlayingGameData.Character.CharacterState.Dead;
}
}
}
///
/// Advance the combatant state for one combat round.
///
public virtual void AdvanceRound()
{
// advance the combat effects stack
combatEffects.Advance();
}
#endregion
#region Drawing
///
/// Draw the combatant for this frame.
///
public virtual void Draw(GameTime gameTime)
{
CombatSprite.Draw(Session.ScreenManager.SpriteBatch,
Position, 1f - Position.Y / 720f);
Session.ScreenManager.SpriteBatch.Draw(Character.ShadowTexture, Position,
null, Color.White, 0f, new Vector2(Character.ShadowTexture.Width / 2,
Character.ShadowTexture.Height / 2), 1f, SpriteEffects.None, 1f);
// draw the combat action
if (combatAction != null)
{
// update the combat action
combatAction.Draw(gameTime, Session.ScreenManager.SpriteBatch);
}
}
#endregion
}
}