#region File Description
//-----------------------------------------------------------------------------
// Hud.cs
//
// Microsoft XNA Community Game Platform
// Copyright (C) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#endregion
#region Using Statements
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
using RolePlayingGameData;
#endregion
namespace RolePlaying
{
///
/// Displays each player's basic statistics and the combat action menu.
///
class Hud
{
private ScreenManager screenManager;
public const int HudHeight = 183;
#region Graphics Data
private Texture2D backgroundHudTexture;
private Texture2D topHudTexture;
private Texture2D combatPopupTexture;
private Texture2D activeCharInfoTexture;
private Texture2D inActiveCharInfoTexture;
private Texture2D cantUseCharInfoTexture;
private Texture2D selectionBracketTexture;
private Texture2D menuTexture;
private Texture2D statsTexture;
private Texture2D deadPortraitTexture;
private Texture2D charSelFadeLeftTexture;
private Texture2D charSelFadeRightTexture;
private Texture2D charSelArrowLeftTexture;
private Texture2D charSelArrowRightTexture;
private Texture2D actionTexture;
private Texture2D yButtonTexture;
private Texture2D startButtonTexture;
private Vector2 topHudPosition = new Vector2(353f, 30f);
private Vector2 charSelLeftPosition = new Vector2(70f, 600f);
private Vector2 charSelRightPosition = new Vector2(1170f, 600f);
private Vector2 yButtonPosition = new Vector2(0f, 560f + 20f);
private Vector2 startButtonPosition = new Vector2(0f, 560f + 35f);
private Vector2 yTextPosition = new Vector2(0f, 560f + 70f);
private Vector2 startTextPosition = new Vector2(0f, 560f + 70f);
private Vector2 actionTextPosition = new Vector2(640f, 55f);
private Vector2 backgroundHudPosition = new Vector2(0f, 525f);
private Vector2 portraitPosition = new Vector2(640f, 55f);
private Vector2 startingInfoPosition = new Vector2(0f, 550f);
private Vector2 namePosition;
private Vector2 levelPosition;
private Vector2 detailPosition;
private readonly Color activeNameColor = new Color(200, 200, 200);
private readonly Color inActiveNameColor = new Color(100, 100, 100);
private readonly Color nonSelColor = new Color(86, 26, 5);
private readonly Color selColor = new Color(229, 206, 144);
#endregion
#region Action Text
///
/// The text that is shown in the action bar at the top of the combat screen.
///
private string actionText = String.Empty;
///
/// The text that is shown in the action bar at the top of the combat screen.
///
public string ActionText
{
get { return actionText; }
set { actionText = value; }
}
#endregion
#region Initialization
///
/// Creates a new Hud object using the given ScreenManager.
///
public Hud(ScreenManager screenManager)
{
// check the parameter
if (screenManager == null)
{
throw new ArgumentNullException("screenManager");
}
this.screenManager = screenManager;
}
///
/// Load the graphics content from the content manager.
///
public void LoadContent()
{
ContentManager content = screenManager.Game.Content;
backgroundHudTexture =
content.Load(@"Textures\HUD\HudBkgd");
topHudTexture =
content.Load(@"Textures\HUD\CombatStateInfoStrip");
activeCharInfoTexture =
content.Load(@"Textures\HUD\PlankActive");
inActiveCharInfoTexture =
content.Load(@"Textures\HUD\PlankInActive");
cantUseCharInfoTexture =
content.Load(@"Textures\HUD\PlankCantUse");
selectionBracketTexture =
content.Load(@"Textures\HUD\SelectionBrackets");
deadPortraitTexture =
content.Load(@"Textures\Characters\Portraits\Tombstone");
combatPopupTexture =
content.Load(@"Textures\HUD\CombatPopup");
charSelFadeLeftTexture =
content.Load(@"Textures\Buttons\CharSelectFadeLeft");
charSelFadeRightTexture =
content.Load(@"Textures\Buttons\CharSelectFadeRight");
charSelArrowLeftTexture =
content.Load(@"Textures\Buttons\CharSelectHlLeft");
charSelArrowRightTexture =
content.Load(@"Textures\Buttons\CharSelectHlRight");
actionTexture =
content.Load(@"Textures\HUD\HudSelectButton");
yButtonTexture =
content.Load(@"Textures\Buttons\YButton");
startButtonTexture =
content.Load(@"Textures\Buttons\StartButton");
menuTexture =
content.Load(@"Textures\HUD\Menu");
statsTexture =
content.Load(@"Textures\HUD\Stats");
}
#endregion
#region Drawing
///
/// Draw the screen.
///
public void Draw()
{
SpriteBatch spriteBatch = screenManager.SpriteBatch;
spriteBatch.Begin();
startingInfoPosition.X = 640f;
startingInfoPosition.X -= Session.Party.Players.Count / 2 * 200f;
if (Session.Party.Players.Count % 2 != 0)
{
startingInfoPosition.X -= 100f;
}
spriteBatch.Draw(backgroundHudTexture, backgroundHudPosition, Color.White);
if (CombatEngine.IsActive)
{
DrawForCombat();
}
else
{
DrawForNonCombat();
}
spriteBatch.End();
}
///
/// Draws HUD for Combat Mode
///
private void DrawForCombat()
{
SpriteBatch spriteBatch = screenManager.SpriteBatch;
Vector2 position = startingInfoPosition;
foreach (CombatantPlayer combatantPlayer in CombatEngine.Players)
{
DrawCombatPlayerDetails(combatantPlayer, position);
position.X += activeCharInfoTexture.Width - 6f;
}
charSelLeftPosition.X = startingInfoPosition.X - 5f -
charSelArrowLeftTexture.Width;
charSelRightPosition.X = position.X + 5f;
// Draw character Selection Arrows
if (CombatEngine.IsPlayersTurn)
{
spriteBatch.Draw(charSelArrowLeftTexture, charSelLeftPosition,
Color.White);
spriteBatch.Draw(charSelArrowRightTexture, charSelRightPosition,
Color.White);
}
else
{
spriteBatch.Draw(charSelFadeLeftTexture, charSelLeftPosition,
Color.White);
spriteBatch.Draw(charSelFadeRightTexture, charSelRightPosition,
Color.White);
}
if (actionText.Length > 0)
{
spriteBatch.Draw(topHudTexture, topHudPosition, Color.White);
// Draw Action Text
Fonts.DrawCenteredText(spriteBatch, Fonts.PlayerStatisticsFont,
actionText, actionTextPosition, Color.Black);
}
}
///
/// Draws HUD for non Combat Mode
///
private void DrawForNonCombat()
{
SpriteBatch spriteBatch = screenManager.SpriteBatch;
Vector2 position = startingInfoPosition;
foreach (Player player in Session.Party.Players)
{
DrawNonCombatPlayerDetails(player, position);
position.X += inActiveCharInfoTexture.Width - 6f;
}
yTextPosition.X = position.X + 5f;
yButtonPosition.X = position.X + 9f;
// Draw Select Button
spriteBatch.Draw(statsTexture, yTextPosition, Color.White);
spriteBatch.Draw(yButtonTexture, yButtonPosition, Color.White);
startTextPosition.X = startingInfoPosition.X -
startButtonTexture.Width - 25f;
startButtonPosition.X = startingInfoPosition.X -
startButtonTexture.Width - 10f;
// Draw Back Button
spriteBatch.Draw(menuTexture, startTextPosition, Color.White);
spriteBatch.Draw(startButtonTexture, startButtonPosition, Color.White);
}
enum PlankState
{
Active,
InActive,
CantUse,
}
///
/// Draws Player Details
///
/// Index of player details to draw
/// Position where to draw
private void DrawCombatPlayerDetails(CombatantPlayer player, Vector2 position)
{
SpriteBatch spriteBatch = screenManager.SpriteBatch;
PlankState plankState;
bool isPortraitActive = false;
bool isCharDead = false;
Color color;
portraitPosition.X = position.X + 7f;
portraitPosition.Y = position.Y + 7f;
namePosition.X = position.X + 84f;
namePosition.Y = position.Y + 12f;
levelPosition.X = position.X + 84f;
levelPosition.Y = position.Y + 39f;
detailPosition.X = position.X + 25f;
detailPosition.Y = position.Y + 66f;
position.X -= 2;
position.Y -= 4;
if (player.IsTurnTaken)
{
plankState = PlankState.CantUse;
isPortraitActive = false;
}
else
{
plankState = PlankState.InActive;
isPortraitActive = true;
}
if (((CombatEngine.HighlightedCombatant == player) && !player.IsTurnTaken) ||
(CombatEngine.PrimaryTargetedCombatant == player) ||
(CombatEngine.SecondaryTargetedCombatants.Contains(player)))
{
plankState = PlankState.Active;
}
if (player.IsDeadOrDying)
{
isCharDead = true;
isPortraitActive = false;
plankState = PlankState.CantUse;
}
// Draw Info Slab
if (plankState == PlankState.Active)
{
color = activeNameColor;
spriteBatch.Draw(activeCharInfoTexture, position, Color.White);
// Draw Brackets
if ((CombatEngine.HighlightedCombatant == player) && !player.IsTurnTaken)
{
spriteBatch.Draw(selectionBracketTexture, position, Color.White);
}
if (isPortraitActive &&
(CombatEngine.HighlightedCombatant == player) &&
(CombatEngine.HighlightedCombatant.CombatAction == null) &&
!CombatEngine.IsDelaying)
{
position.X += activeCharInfoTexture.Width / 2;
position.X -= combatPopupTexture.Width / 2;
position.Y -= combatPopupTexture.Height;
// Draw Action
DrawActionsMenu(position);
}
}
else if (plankState == PlankState.InActive)
{
color = inActiveNameColor;
spriteBatch.Draw(inActiveCharInfoTexture, position, Color.White);
}
else
{
color = Color.Black;
spriteBatch.Draw(cantUseCharInfoTexture, position, Color.White);
}
if (isCharDead)
{
spriteBatch.Draw(deadPortraitTexture, portraitPosition, Color.White);
}
else
{
// Draw Player Portrait
DrawPortrait(player.Player, portraitPosition, plankState);
}
// Draw Player Name
spriteBatch.DrawString(Fonts.PlayerStatisticsFont,
player.Player.Name,
namePosition, color);
color = Color.Black;
// Draw Player Details
spriteBatch.DrawString(Fonts.HudDetailFont,
"Lvl: " + player.Player.CharacterLevel,
levelPosition, color);
spriteBatch.DrawString(Fonts.HudDetailFont,
"HP: " + player.Statistics.HealthPoints +
"/" + player.Player.CharacterStatistics.HealthPoints,
detailPosition, color);
detailPosition.Y += 30f;
spriteBatch.DrawString(Fonts.HudDetailFont,
"MP: " + player.Statistics.MagicPoints +
"/" + player.Player.CharacterStatistics.MagicPoints,
detailPosition, color);
}
///
/// Draws Player Details
///
/// Index of player details to draw
/// Position where to draw
private void DrawNonCombatPlayerDetails(Player player, Vector2 position)
{
SpriteBatch spriteBatch = screenManager.SpriteBatch;
PlankState plankState;
bool isCharDead = false;
Color color;
portraitPosition.X = position.X + 7f;
portraitPosition.Y = position.Y + 7f;
namePosition.X = position.X + 84f;
namePosition.Y = position.Y + 12f;
levelPosition.X = position.X + 84f;
levelPosition.Y = position.Y + 39f;
detailPosition.X = position.X + 25f;
detailPosition.Y = position.Y + 66f;
position.X -= 2;
position.Y -= 4;
plankState = PlankState.Active;
// Draw Info Slab
if (plankState == PlankState.Active)
{
color = activeNameColor;
spriteBatch.Draw(activeCharInfoTexture, position, Color.White);
}
else if (plankState == PlankState.InActive)
{
color = inActiveNameColor;
spriteBatch.Draw(inActiveCharInfoTexture, position, Color.White);
}
else
{
color = Color.Black;
spriteBatch.Draw(cantUseCharInfoTexture, position, Color.White);
}
if (isCharDead)
{
spriteBatch.Draw(deadPortraitTexture, portraitPosition, Color.White);
}
else
{
// Draw Player Portrait
DrawPortrait(player, portraitPosition, plankState);
}
// Draw Player Name
spriteBatch.DrawString(Fonts.PlayerStatisticsFont,
player.Name,
namePosition, color);
color = Color.Black;
// Draw Player Details
spriteBatch.DrawString(Fonts.HudDetailFont,
"Lvl: " + player.CharacterLevel,
levelPosition, color);
spriteBatch.DrawString(Fonts.HudDetailFont,
"HP: " + player.CurrentStatistics.HealthPoints +
"/" + player.CharacterStatistics.HealthPoints,
detailPosition, color);
detailPosition.Y += 30f;
spriteBatch.DrawString(Fonts.HudDetailFont,
"MP: " + player.CurrentStatistics.MagicPoints +
"/" + player.CharacterStatistics.MagicPoints,
detailPosition, color);
}
///
/// Draw the portrait of the given player at the given position.
///
private void DrawPortrait(Player player, Vector2 position,
PlankState plankState)
{
switch (plankState)
{
case PlankState.Active:
screenManager.SpriteBatch.Draw(player.ActivePortraitTexture,
position, Color.White);
break;
case PlankState.InActive:
screenManager.SpriteBatch.Draw(player.InactivePortraitTexture,
position, Color.White);
break;
case PlankState.CantUse:
screenManager.SpriteBatch.Draw(player.UnselectablePortraitTexture,
position, Color.White);
break;
}
}
#endregion
#region Combat Action Menu
///
/// The list of entries in the combat action menu.
///
private string[] actionList = new string[5]
{
"Attack",
"Spell",
"Item",
"Defend",
"Flee",
};
///
/// The currently highlighted item.
///
private int highlightedAction = 0;
///
/// Handle user input to the actions menu.
///
public void UpdateActionsMenu()
{
// cursor up
if (InputManager.IsActionTriggered(InputManager.Action.CursorUp))
{
if (highlightedAction > 0)
{
highlightedAction--;
}
return;
}
// cursor down
if (InputManager.IsActionTriggered(InputManager.Action.CursorDown))
{
if (highlightedAction < actionList.Length - 1)
{
highlightedAction++;
}
return;
}
// select an action
if (InputManager.IsActionTriggered(InputManager.Action.Ok))
{
switch (actionList[highlightedAction])
{
case "Attack":
{
ActionText = "Performing a Melee Attack";
CombatEngine.HighlightedCombatant.CombatAction =
new MeleeCombatAction(CombatEngine.HighlightedCombatant);
CombatEngine.HighlightedCombatant.CombatAction.Target =
CombatEngine.FirstEnemyTarget;
}
break;
case "Spell":
{
SpellbookScreen spellbookScreen = new SpellbookScreen(
CombatEngine.HighlightedCombatant.Character,
CombatEngine.HighlightedCombatant.Statistics);
spellbookScreen.SpellSelected +=
new SpellbookScreen.SpellSelectedHandler(
spellbookScreen_SpellSelected);
Session.ScreenManager.AddScreen(spellbookScreen);
}
break;
case "Item":
{
InventoryScreen inventoryScreen = new InventoryScreen(true);
inventoryScreen.GearSelected +=
new InventoryScreen.GearSelectedHandler(
inventoryScreen_GearSelected);
Session.ScreenManager.AddScreen(inventoryScreen);
}
break;
case "Defend":
{
ActionText = "Defending";
CombatEngine.HighlightedCombatant.CombatAction =
new DefendCombatAction(
CombatEngine.HighlightedCombatant);
CombatEngine.HighlightedCombatant.CombatAction.Start();
}
break;
case "Flee":
CombatEngine.AttemptFlee();
break;
}
return;
}
}
///
/// Recieves the spell from the Spellbook screen and casts it.
///
void spellbookScreen_SpellSelected(Spell spell)
{
if (spell != null)
{
ActionText = "Casting " + spell.Name;
CombatEngine.HighlightedCombatant.CombatAction =
new SpellCombatAction(CombatEngine.HighlightedCombatant, spell);
if (spell.IsOffensive)
{
CombatEngine.HighlightedCombatant.CombatAction.Target =
CombatEngine.FirstEnemyTarget;
}
else
{
CombatEngine.HighlightedCombatant.CombatAction.Target =
CombatEngine.HighlightedCombatant;
}
}
}
///
/// Receives the item back from the Inventory screen and uses it.
///
void inventoryScreen_GearSelected(Gear gear)
{
Item item = gear as Item;
if (item != null)
{
ActionText = "Using " + item.Name;
CombatEngine.HighlightedCombatant.CombatAction =
new ItemCombatAction(CombatEngine.HighlightedCombatant, item);
if (item.IsOffensive)
{
CombatEngine.HighlightedCombatant.CombatAction.Target =
CombatEngine.FirstEnemyTarget;
}
else
{
CombatEngine.HighlightedCombatant.CombatAction.Target =
CombatEngine.HighlightedCombatant;
}
}
}
///
/// Draws the combat action menu.
///
/// The position of the menu.
private void DrawActionsMenu(Vector2 position)
{
ActionText = "Choose an Action";
SpriteBatch spriteBatch = screenManager.SpriteBatch;
Vector2 arrowPosition;
float height = 25f;
spriteBatch.Draw(combatPopupTexture, position, Color.White);
position.Y += 21f;
arrowPosition = position;
arrowPosition.X += 10f;
arrowPosition.Y += 2f;
arrowPosition.Y += height * (int)highlightedAction;
spriteBatch.Draw(actionTexture, arrowPosition, Color.White);
position.Y += 4f;
position.X += 50f;
// Draw Action Text
for (int i = 0; i < actionList.Length; i++)
{
spriteBatch.DrawString(Fonts.GearInfoFont, actionList[i], position,
i == highlightedAction ? selColor : nonSelColor);
position.Y += height;
}
}
#endregion
}
}