#region File Description
//-----------------------------------------------------------------------------
// StoreBuyScreen.cs
//
// Microsoft XNA Community Game Platform
// Copyright (C) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#endregion
#region Using Statements
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
using RolePlayingGameData;
#endregion
namespace RolePlaying
{
///
/// Displays the gear from a particular store and allows the user to purchase them.
///
class StoreBuyScreen : ListScreen
{
#region Graphics Data
///
/// The left-facing quantity arrow.
///
private Texture2D leftQuantityArrow;
///
/// The right-facing quantity arrow.
///
private Texture2D rightQuantityArrow;
#endregion
#region Columns
private string nameColumnText = "Name";
private const int nameColumnInterval = 80;
private string powerColumnText = "Power (min, max)";
private const int powerColumnInterval = 270;
private string quantityColumnText = "Qty";
private const int quantityColumnInterval = 340;
private string priceColumnText = "Price";
private const int priceColumnInterval = 120;
#endregion
#region Data Access
///
/// The store whose goods are being displayed.
///
private Store store;
///
/// The index of the current StoreCategory.
///
private int currentCategoryIndex = 0;
///
/// Get the list that this screen displays.
///
public override ReadOnlyCollection GetDataList()
{
return
store.StoreCategories[currentCategoryIndex].AvailableGear.AsReadOnly();
}
///
/// The selected quantity of the current entry.
///
private int selectedQuantity = 0;
///
/// The maximum quantity of the current entry.
///
private int maximumQuantity = 0;
///
/// Resets the selected quantity to the maximum value for the selected entry.
///
private void ResetQuantities()
{
// check the indices before recalculating
if ((currentCategoryIndex < 0) ||
(currentCategoryIndex > store.StoreCategories.Count) ||
(SelectedIndex < 0) || (SelectedIndex >=
store.StoreCategories[currentCategoryIndex].AvailableGear.Count))
{
return;
}
// get the value of the selected gear
Gear gear =
store.StoreCategories[currentCategoryIndex].AvailableGear[SelectedIndex];
if ((gear == null) || (gear.GoldValue <= 0))
{
selectedQuantity = maximumQuantity = 0;
}
selectedQuantity = 1;
maximumQuantity = (int)Math.Floor(Session.Party.PartyGold /
(gear.GoldValue * store.BuyMultiplier));
}
#endregion
#region List Navigation
///
/// Move the current selection up one entry.
///
protected override void MoveCursorUp()
{
int oldIndex = SelectedIndex;
base.MoveCursorUp();
if (SelectedIndex != oldIndex)
{
ResetQuantities();
}
}
///
/// Move the current selection down one entry.
///
protected override void MoveCursorDown()
{
int oldIndex = SelectedIndex;
base.MoveCursorDown();
if (SelectedIndex != oldIndex)
{
ResetQuantities();
}
}
///
/// Decrease the selected quantity by one.
///
protected override void MoveCursorLeft()
{
if (maximumQuantity > 0)
{
// decrement the quantity, looping around if necessary
selectedQuantity = (selectedQuantity > 1) ?
selectedQuantity - 1 : maximumQuantity;
}
}
///
/// Increase the selected quantity by one.
///
protected override void MoveCursorRight()
{
if (maximumQuantity > 0)
{
// loop to one if the selected quantity is already at maximum.
selectedQuantity = selectedQuantity < maximumQuantity ?
selectedQuantity + 1 : 1;
}
}
#endregion
#region Initialization
///
/// Creates a new StoreBuyScreen object for the given store.
///
public StoreBuyScreen(Store store)
: base()
{
// check the parameter
if ((store == null) || (store.StoreCategories.Count <= 0))
{
throw new ArgumentNullException("store");
}
this.store = store;
// configure the menu text
selectButtonText = "Purchase";
backButtonText = "Back";
xButtonText = String.Empty;
yButtonText = String.Empty;
ResetMenu();
ResetQuantities();
}
///
/// Load the graphics content from the content manager.
///
public override void LoadContent()
{
base.LoadContent();
ContentManager content = ScreenManager.Game.Content;
leftQuantityArrow =
content.Load(@"Textures\Buttons\QuantityArrowLeft");
rightQuantityArrow =
content.Load(@"Textures\Buttons\QuantityArrowRight");
}
#endregion
#region Input Handling
///
/// Respond to the triggering of the Select action.
///
protected override void SelectTriggered(Gear entry)
{
if (entry == null)
{
return;
}
// purchase the items if possible
int totalPrice = (int)Math.Floor(entry.GoldValue * selectedQuantity *
store.BuyMultiplier);
if (totalPrice <= Session.Party.PartyGold)
{
Session.Party.PartyGold -= totalPrice;
Session.Party.AddToInventory(entry, selectedQuantity);
}
// reset the quantities - either gold has gone down or the total was bad
ResetQuantities();
}
///
/// Switch to the previous store category.
///
protected override void PageScreenLeft()
{
currentCategoryIndex--;
if (currentCategoryIndex < 0)
{
currentCategoryIndex = store.StoreCategories.Count - 1;
}
ResetMenu();
ResetQuantities();
}
///
/// Switch to the next store category.
///
protected override void PageScreenRight()
{
currentCategoryIndex++;
if (currentCategoryIndex >= store.StoreCategories.Count)
{
currentCategoryIndex = 0;
}
ResetMenu();
ResetQuantities();
}
///
/// Reset the menu title and trigger button text for the current store category.
///
private void ResetMenu()
{
// update the title the title
titleText = store.StoreCategories[currentCategoryIndex].Name;
// get the left trigger text
int index = currentCategoryIndex - 1;
if (index < 0)
{
index = store.StoreCategories.Count - 1;
}
leftTriggerText = store.StoreCategories[index].Name;
// get the right trigger text
index = currentCategoryIndex + 1;
if (index >= store.StoreCategories.Count)
{
index = 0;
}
rightTriggerText = store.StoreCategories[index].Name;
}
#endregion
#region Drawing
///
/// Draw the entry at the given position in the list.
///
/// The entry to draw.
/// The position to draw the entry at.
/// If true, this item is selected.
protected override void DrawEntry(Gear entry, Vector2 position,
bool isSelected)
{
// check the parameter
if (entry == null)
{
throw new ArgumentNullException("entry");
}
SpriteBatch spriteBatch = ScreenManager.SpriteBatch;
Vector2 drawPosition = position;
// draw the icon
spriteBatch.Draw(entry.IconTexture, drawPosition + iconOffset, Color.White);
// draw the name
Color color = isSelected ? Fonts.HighlightColor : Fonts.DisplayColor;
drawPosition.Y += listLineSpacing / 4;
drawPosition.X += nameColumnInterval;
spriteBatch.DrawString(Fonts.GearInfoFont, entry.Name, drawPosition, color);
// draw the power
drawPosition.X += powerColumnInterval;
string powerText = entry.GetPowerText();
Vector2 powerTextSize = Fonts.GearInfoFont.MeasureString(powerText);
Vector2 powerPosition = drawPosition;
powerPosition.Y -= (float)Math.Ceiling((powerTextSize.Y - 30f) / 2);
spriteBatch.DrawString(Fonts.GearInfoFont, powerText,
powerPosition, color);
// draw the quantity
drawPosition.X += quantityColumnInterval;
int priceSingle = (int)Math.Floor(entry.GoldValue * store.BuyMultiplier);
if (isSelected)
{
if (priceSingle <= Session.Party.PartyGold)
{
Vector2 quantityPosition = drawPosition;
// draw the left selection arrow
quantityPosition.X -= leftQuantityArrow.Width;
spriteBatch.Draw(leftQuantityArrow,
new Vector2(quantityPosition.X, quantityPosition.Y - 4),
Color.White);
quantityPosition.X += leftQuantityArrow.Width;
// draw the selected quantity ratio
string quantityText = selectedQuantity.ToString() + "/" +
maximumQuantity.ToString();
spriteBatch.DrawString(Fonts.GearInfoFont, quantityText,
quantityPosition, color);
quantityPosition.X +=
Fonts.GearInfoFont.MeasureString(quantityText).X;
// draw the right selection arrow
spriteBatch.Draw(rightQuantityArrow,
new Vector2(quantityPosition.X, quantityPosition.Y - 4),
Color.White);
quantityPosition.X += rightQuantityArrow.Width;
// draw the purchase button
selectButtonText = "Purchase";
}
else
{
// turn off the purchase button
selectButtonText = String.Empty;
}
}
// draw the price
drawPosition.X += priceColumnInterval;
string priceText = String.Empty;
if (isSelected)
{
int totalPrice = (int)Math.Floor(entry.GoldValue * store.BuyMultiplier) *
selectedQuantity;
priceText = totalPrice.ToString();
}
else
{
priceText = ((int)Math.Floor(entry.GoldValue *
store.BuyMultiplier)).ToString();
}
spriteBatch.DrawString(Fonts.GearInfoFont, priceText,
drawPosition, color);
}
///
/// Draw the description of the selected item.
///
protected override void DrawSelectedDescription(Gear entry)
{
// check the parameter
if (entry == null)
{
throw new ArgumentNullException("entry");
}
SpriteBatch spriteBatch = ScreenManager.SpriteBatch;
Vector2 position = descriptionTextPosition;
// draw the description
// -- it's up to the content owner to fit the description
string text = entry.Description;
if (!String.IsNullOrEmpty(text))
{
spriteBatch.DrawString(Fonts.DescriptionFont, text, position,
Fonts.DescriptionColor);
position.Y += Fonts.DescriptionFont.LineSpacing;
}
// draw the modifiers
Equipment equipment = entry as Equipment;
if (equipment != null)
{
text = equipment.OwnerBuffStatistics.GetModifierString();
if (!String.IsNullOrEmpty(text))
{
spriteBatch.DrawString(Fonts.DescriptionFont, text, position,
Fonts.DescriptionColor);
position.Y += Fonts.DescriptionFont.LineSpacing;
}
}
// draw the restrictions
text = entry.GetRestrictionsText();
if (!String.IsNullOrEmpty(text))
{
spriteBatch.DrawString(Fonts.DescriptionFont, text, position,
Fonts.DescriptionColor);
position.Y += Fonts.DescriptionFont.LineSpacing;
}
}
///
/// Draw the column headers above the list.
///
protected override void DrawColumnHeaders()
{
SpriteBatch spriteBatch = ScreenManager.SpriteBatch;
Vector2 position = listEntryStartPosition;
position.X += nameColumnInterval;
if (!String.IsNullOrEmpty(nameColumnText))
{
spriteBatch.DrawString(Fonts.CaptionFont, nameColumnText, position,
Fonts.CaptionColor);
}
position.X += powerColumnInterval;
if (!String.IsNullOrEmpty(powerColumnText))
{
spriteBatch.DrawString(Fonts.CaptionFont, powerColumnText, position,
Fonts.CaptionColor);
}
position.X += quantityColumnInterval;
if (!String.IsNullOrEmpty(quantityColumnText))
{
spriteBatch.DrawString(Fonts.CaptionFont, quantityColumnText, position,
Fonts.CaptionColor);
}
position.X += priceColumnInterval;
if (!String.IsNullOrEmpty(priceColumnText))
{
spriteBatch.DrawString(Fonts.CaptionFont, priceColumnText, position,
Fonts.CaptionColor);
}
}
#endregion
}
}