#region Copyright
/*
--------------------------------------------------------------------------------
This source file is part of Xenocide
by Project Xenocide Team
For the latest info on Xenocide, see http://www.projectxenocide.com/
This work is licensed under the Creative Commons
Attribution-NonCommercial-ShareAlike 2.5 License.
To view a copy of this license, visit
http://creativecommons.org/licenses/by-nc-sa/2.5/
or send a letter to Creative Commons, 543 Howard Street, 5th Floor,
San Francisco, California, 94105, USA.
--------------------------------------------------------------------------------
*/
/*
* @file EquipCraftScreen.cs
* @date Created: 2007/07/14
* @author File creator: David Teviotdale
* @author Credits: none
*/
#endregion
#region Using Statements
using System;
using System.Collections.Generic;
using System.Text;
using CeGui;
using ProjectXenocide.Utils;
using ProjectXenocide.Model.Geoscape;
using ProjectXenocide.Model.Geoscape.Outposts;
using ProjectXenocide.Model.Geoscape.Vehicles;
using ProjectXenocide.Model.StaticData.Items;
using Xenocide.Resources;
#endregion
namespace ProjectXenocide.UI.Screens
{
///
/// This is the screen that allows user set craft's weapons and crew
///
public class EquipCraftScreen : Screen
{
///
/// Constructor (obviously)
///
/// Index to outpost that owns the craft
public EquipCraftScreen(int selectedOutpostIndex)
: base("EquipCraftScreen")
{
this.selectedOutpostIndex = selectedOutpostIndex;
}
#region Create the CeGui widgets
///
/// add the buttons to the screen
///
protected override void CreateCeguiWidgets()
{
// add text giving the name of the selected base
baseNameText = GuiBuilder.CreateText(CeguiId + "_baseNameText");
AddWidget(baseNameText, 0.01f, 0.06f, 0.2275f, 0.04f);
baseNameText.Text = Util.StringFormat(Strings.SCREEN_EQUIP_CRAFT_BASE_NAME,
SelectedOutpost.Name);
// The craft and weapons grids
InitializeCraftGrid();
InitializeWeaponsGrid();
PopulateCraftGrid();
PopulateWeaponsGrid();
// text describing Pod 1
pod1Text = GuiBuilder.CreateText(CeguiId + "_pod1Text");
AddWidget(pod1Text, 0.01f, 0.55f, 0.2275f, 0.16125f);
// text describing Pod 2
pod2Text = GuiBuilder.CreateText(CeguiId + "_pod2Text");
AddWidget(pod2Text, 0.31f, 0.55f, 0.2275f, 0.16125f);
// other buttons
emptyPod1Button = AddButton("BUTTON_EMPTY_POD_1", 0.7475f, 0.75f, 0.2275f, 0.04125f);
emptyPod2Button = AddButton("BUTTON_EMPTY_POD_2", 0.7475f, 0.80f, 0.2275f, 0.04125f);
setPod1Button = AddButton("BUTTON_SET_POD_1", 0.7475f, 0.85f, 0.2275f, 0.04125f);
setPod2Button = AddButton("BUTTON_SET_POD_2", 0.7475f, 0.90f, 0.2275f, 0.04125f);
closeButton = AddButton("BUTTON_CLOSE", 0.7475f, 0.95f, 0.2275f, 0.04125f);
emptyPod1Button.Clicked += new CeGui.GuiEventHandler(OnEmptyPod1Button);
emptyPod2Button.Clicked += new CeGui.GuiEventHandler(OnEmptyPod2Button);
setPod1Button.Clicked += new CeGui.GuiEventHandler(OnSetPod1Button);
setPod2Button.Clicked += new CeGui.GuiEventHandler(OnSetPod2Button);
closeButton.Clicked += new CeGui.GuiEventHandler(OnCloseButton);
weaponsGrid.MouseDoubleClicked += new CeGui.MouseEventHandler(OnWeaponGridMouseDoubleClicked);
}
private CeGui.Widgets.StaticText baseNameText;
private CeGui.Widgets.StaticText pod1Text;
private CeGui.Widgets.StaticText pod2Text;
private CeGui.Widgets.MultiColumnList craftGrid;
private CeGui.Widgets.MultiColumnList weaponsGrid;
private CeGui.Widgets.PushButton emptyPod1Button;
private CeGui.Widgets.PushButton emptyPod2Button;
private CeGui.Widgets.PushButton setPod1Button;
private CeGui.Widgets.PushButton setPod2Button;
private CeGui.Widgets.PushButton closeButton;
///
/// Create the grid that shows the craft
///
private void InitializeCraftGrid()
{
craftGrid = GuiBuilder.CreateGrid("craftGrid");
AddWidget(craftGrid, 0.01f, 0.13f, 0.70f, 0.42f);
craftGrid.AddColumn(Strings.SCREEN_EQUIP_CRAFT_COLUMN_CRAFT_NAME, craftGrid.ColumnCount, 0.20f);
craftGrid.AddColumn(Strings.SCREEN_EQUIP_CRAFT_COLUMN_FUEL, craftGrid.ColumnCount, 0.13f);
craftGrid.AddColumn(Strings.SCREEN_EQUIP_CRAFT_COLUMN_HULL, craftGrid.ColumnCount, 0.13f);
craftGrid.AddColumn(Strings.SCREEN_EQUIP_CRAFT_COLUMN_PODS, craftGrid.ColumnCount, 0.13f);
craftGrid.AddColumn(Strings.SCREEN_EQUIP_CRAFT_COLUMN_AMMO, craftGrid.ColumnCount, 0.13f);
craftGrid.AddColumn(Strings.SCREEN_EQUIP_CRAFT_COLUMN_CREW, craftGrid.ColumnCount, 0.13f);
craftGrid.AddColumn(Strings.SCREEN_EQUIP_CRAFT_COLUMN_HWP, craftGrid.ColumnCount, 0.13f);
craftGrid.SelectionChanged += new WindowEventHandler(OnCraftGridSelectionChanged);
}
///
/// Create MultiColumnListBox which holds weapons
///
private void InitializeWeaponsGrid()
{
weaponsGrid = GuiBuilder.CreateGrid("weaponsGrid");
AddWidget(weaponsGrid, 0.01f, 0.75f, 0.70f, 0.20f);
weaponsGrid.AddColumn(Strings.SCREEN_EQUIP_CRAFT_COLUMN_ITEM, weaponsGrid.ColumnCount, 0.50f);
weaponsGrid.AddColumn(Strings.SCREEN_EQUIP_CRAFT_COLUMN_QUANTITY_IN_BASE, weaponsGrid.ColumnCount, 0.12f);
weaponsGrid.AddColumn(Strings.SCREEN_EQUIP_CRAFT_COLUMN_CLIP_SIZE, weaponsGrid.ColumnCount, 0.13f);
weaponsGrid.AddColumn(Strings.SCREEN_EQUIP_CRAFT_COLUMN_ROUNDS_IN_BASE, weaponsGrid.ColumnCount, 0.23f);
}
///
/// Put the list of craft into the grid
///
private void PopulateCraftGrid()
{
foreach (Craft craft in SelectedOutpost.Fleet)
{
// add craft to grid
Aircraft aircraft = (Aircraft)craft;
CeGui.ListboxTextItem listboxItem = Util.CreateListboxItem(aircraft.Name);
int rowNum = craftGrid.AddRow(listboxItem, 0);
listboxItem.ID = rowNum;
Util.AddNumericElementToGrid(craftGrid, 1, rowNum, aircraft.FuelPercent);
Util.AddNumericElementToGrid(craftGrid, 2, rowNum, aircraft.HullPercent);
Util.AddNumericElementToGrid(craftGrid, 3, rowNum, aircraft.PodCountStatus);
Util.AddNumericElementToGrid(craftGrid, 4, rowNum, aircraft.AmmoStatus);
Util.AddNumericElementToGrid(craftGrid, 5, rowNum, aircraft.SoldierCountStatus);
Util.AddNumericElementToGrid(craftGrid, 6, rowNum, aircraft.XcapCountStatus);
// record craft associated with this line
rowToCraft[rowNum] = aircraft;
}
}
///
/// Put the list of items available equip a craft with on the grid
///
private void PopulateWeaponsGrid()
{
rowToWeapon.Clear();
weaponsGrid.ResetList();
foreach (Item i in SelectedOutpost.Inventory.ListContents())
{
// if the item is a craft weapon, add it to the weaponsGrid
if (i.ItemInfo is CraftWeaponItemInfo)
{
WeaponRow weaponRow = new WeaponRow(i, SelectedOutpost.Inventory);
CeGui.ListboxTextItem listboxItem = Util.CreateListboxItem(weaponRow.Name);
int rowNum = weaponsGrid.AddRow(listboxItem, 0);
listboxItem.ID = rowNum;
Util.AddNumericElementToGrid(weaponsGrid, 1, rowNum, weaponRow.OnHand);
Util.AddNumericElementToGrid(weaponsGrid, 2, rowNum, weaponRow.ClipSize);
Util.AddNumericElementToGrid(weaponsGrid, 3, rowNum, weaponRow.ClipsInBase);
// and record weapon associated with this row
rowToWeapon[rowNum] = weaponRow;
}
}
}
#endregion Create the CeGui widgets
#region event handlers
/// Handle user clicking on the "Empty Pod 1" button
/// Not used
/// Not used
private void OnEmptyPod1Button(object sender, GuiEventArgs e)
{
EmptyPod(1);
}
/// Handle user clicking on the "Empty Pod 2" button
/// Not used
/// Not used
private void OnEmptyPod2Button(object sender, GuiEventArgs e)
{
EmptyPod(2);
}
/// Handle user clicking on the "Set Pod 1" button
/// Not used
/// Not used
private void OnSetPod1Button(object sender, GuiEventArgs e)
{
EquipPod(1);
}
/// Handle user clicking on the "Set Pod 2" button
/// Not used
/// Not used
private void OnSetPod2Button(object sender, GuiEventArgs e)
{
EquipPod(2);
}
///
/// User has double clicked on the weapons grid, assume user wants to arm craft with this weapon
///
/// unused
/// unused
private void OnWeaponGridMouseDoubleClicked(object sender, MouseEventArgs e)
{
TryEquipCraftWithSelectedWeapon();
}
/// React to user pressing the Close button
/// Not used
/// Not used
private void OnCloseButton(object sender, CeGui.GuiEventArgs e)
{
ScreenManager.ScheduleScreen(new BasesScreen(selectedOutpostIndex));
}
/// Handles user clicking on a craft in the grid
/// Not used
/// Not used
private void OnCraftGridSelectionChanged(object sender, WindowEventArgs e)
{
CeGui.Widgets.ListboxItem item = craftGrid.GetFirstSelectedItem();
if (item != null)
{
DrawPodInformation(rowToCraft[item.ID]);
}
}
#endregion event handlers
///
/// Try to equip the selected craft with the selected weapon
///
private void TryEquipCraftWithSelectedWeapon()
{
CeGui.Widgets.ListboxItem selectedRow = GetSelectedCraft();
if (null != selectedRow)
{
Aircraft aircraft = rowToCraft[selectedRow.ID];
for (int podId = 0; podId < aircraft.WeaponPods.Count; ++podId)
{
// can only equip if there's an empty pod to put it in
if (null == aircraft.WeaponPods[podId])
{
EquipPod(podId + 1);
return;
}
}
}
}
///
/// Empty weapon pod of selected craft
///
/// empty Pod 1 or Pod 2
private void EmptyPod(int podId)
{
CeGui.Widgets.ListboxItem selectedRow = GetSelectedCraft();
if (null != selectedRow)
{
Aircraft aircraft = rowToCraft[selectedRow.ID];
// can only empty pod if craft has a pod and it's not empty
if ((podId <= aircraft.WeaponPods.Count) && (null != aircraft.WeaponPods[podId - 1]))
{
// put the weapon in the base, remove from craft & update display
SelectedOutpost.Inventory.Add(aircraft.WeaponPods[podId - 1], false);
aircraft.WeaponPods[podId - 1] = null;
Refresh(selectedRow);
}
}
}
///
/// Put selected weapon into specified pod of selected craft
///
/// empty Pod 1 or Pod 2
private void EquipPod(int podId)
{
CeGui.Widgets.ListboxItem selectedRow = GetSelectedCraft();
if (null != selectedRow)
{
Aircraft aircraft = rowToCraft[selectedRow.ID];
// need to have a weapon selected and craft actually has a pod
WeaponRow weaponRow = GetSelectedWeapon();
if ((null != weaponRow) && (podId <= aircraft.WeaponPods.Count))
{
if (weaponRow.EquipPod(aircraft, podId))
{
Refresh(selectedRow);
}
}
}
}
///
/// Redraw display
///
/// Currently selected row in craftGrid
private void Refresh(CeGui.Widgets.ListboxItem selectedRow)
{
Aircraft aircraft = rowToCraft[selectedRow.ID];
// Update craft grid (pods & ammo)
int row = craftGrid.GetRowIndexOfItem(selectedRow);
CeGui.Widgets.GridReference position = new CeGui.Widgets.GridReference(row, 3);
craftGrid.GetItemAtGridReference(position).Text = aircraft.PodCountStatus;
position.Column = 4;
craftGrid.GetItemAtGridReference(position).Text = aircraft.AmmoStatus;
// Redraw pod info for selected craft
DrawPodInformation(aircraft);
// Redraw weapons available in base
PopulateWeaponsGrid();
}
///
/// Get currently selected Craft from Craft Grid. Give error message if nothing selected
/// or craft is not in an outpost
///
/// selected row of craftGrid
private CeGui.Widgets.ListboxItem GetSelectedCraft()
{
CeGui.Widgets.ListboxItem selectedItem = craftGrid.GetFirstSelectedItem();
if (null == selectedItem)
{
Util.ShowMessageBox(Strings.MSGBOX_NO_CRAFT_SELECTED);
}
else
{
Aircraft aircraft = rowToCraft[selectedItem.ID];
if (!aircraft.InBase)
{
selectedItem = null;
Util.ShowMessageBox(Strings.MSGBOX_CRAFT_NOT_IN_BASE, aircraft.Name);
}
}
return selectedItem;
}
///
/// Get currently selected Weapon from Weapons Grid. Give error message if nothing selected
///
/// currently selected Weapon
private WeaponRow GetSelectedWeapon()
{
CeGui.Widgets.ListboxItem selectedItem = weaponsGrid.GetFirstSelectedItem();
if (null == selectedItem)
{
Util.ShowMessageBox(Strings.MSGBOX_NO_WEAPON_SELECTED);
return null;
}
return rowToWeapon[selectedItem.ID];
}
///
/// Show the information for the weapon pods for a craft
///
/// craft to show weapon pod information
private void DrawPodInformation(Aircraft aircraft)
{
// Start assuming craft has no pods
pod1Text.Hide();
pod2Text.Hide();
// Document Pod 1, if it exists
if (0 < aircraft.WeaponPods.Count)
{
DrawPodInformation(pod1Text, aircraft.WeaponPods[0], 1);
}
// Document Pod 2, if it exists
if (1 < aircraft.WeaponPods.Count)
{
DrawPodInformation(pod2Text, aircraft.WeaponPods[1], 2);
}
}
///
/// Update the details for a specific weapon pod
///
/// Control to write details to
/// Pod to get information for
/// Pod 1 or Pod 2?
private static void DrawPodInformation(CeGui.Widgets.StaticText textControl, WeaponPod pod, int podId)
{
textControl.Show();
StringBuilder info = new StringBuilder(Util.StringFormat(Strings.SCREEN_EQUIP_CRAFT_POD_NAME, podId));
info.Append(Util.Linefeed);
// can't just call pod.PodInformationString(), because pod may be null
info.Append(WeaponPod.PodInformationString(pod));
textControl.Text = info.ToString();
}
///
/// The data backing a row in the weaponsGrid
///
private class WeaponRow
{
///
/// Constructor
///
/// Item to build WeaponRow
/// inventory item will be taken from
public WeaponRow(Item item, OutpostInventory inventory)
{
this.item = item;
this.inventory = inventory;
}
///
/// Equip pod with this weapon
///
/// Aircraft owning the pod
/// Pod 1 or Pod 2?
public bool EquipPod(Aircraft aircraft, int podId)
{
// can only put weapon in pod if pod is empty
if (null == aircraft.WeaponPods[podId - 1])
{
// construct a pod, remove equivelent from inventory and add to craft
WeaponPod pod = (WeaponPod)Weapon.Manufacture();
aircraft.WeaponPods[podId - 1] = pod;
inventory.Remove(pod);
return true;
}
else
{
Util.ShowMessageBox(Strings.MSGBOX_POD_ALREADY_HAS_WEAPON);
return false;
}
}
///
/// Number of weapons of this type on hand
///
public int OnHand { get { return inventory.NumberInInventory(item.ItemInfo); } }
///
/// Number of rounds stored in a full clip
///
public string ClipSize { get { return Weapon.ClipSizeString(); } }
///
/// Number of rounds available in base
///
public string ClipsInBase
{
get
{
if (null == Weapon.Clip)
{
return Strings.SCREEN_EQUIP_CRAFT_IRRELEVANT;
}
else
{
return Util.StringFormat("{0}", inventory.NumberInArmory(Weapon.Clip.Id));
}
}
}
///
/// Name of weapon, to show to user
///
public String Name { get { return item.Name; } }
///
/// Get the weapon details of the item
///
private CraftWeaponItemInfo Weapon { get { return item.ItemInfo as CraftWeaponItemInfo; } }
#region Fields
///
/// Type of item
///
private Item item;
///
/// inventory items are stored in
///
private OutpostInventory inventory;
#endregion Fields
}
#region Fields
///
/// The outpost purchases will be sent to
///
private Outpost SelectedOutpost { get { return Xenocide.GameState.GeoData.Outposts[selectedOutpostIndex]; } }
// index specifying the outpost that items will be taken from
private int selectedOutpostIndex;
///
/// Map rows in weaponsGrid to weapons
///
private Dictionary rowToWeapon = new Dictionary();
///
/// Map row in craftGrid to actual craft
///
private Dictionary rowToCraft = new Dictionary();
#endregion Fields
}
}