#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 } }