#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 MoveOrderCombatantScreenState.cs
* @date Created: 2008/02/16
* @author File creator: David Teviotdale
* @author Credits: none
*/
#endregion
#region Using Statements
using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using System.Threading;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using ProjectXenocide.Utils;
using ProjectXenocide.Model;
using ProjectXenocide.Model.Battlescape;
using ProjectXenocide.Model.Battlescape.Combatants;
using ProjectXenocide.Model.StaticData.Items;
using ProjectXenocide.UI.Dialogs;
using ProjectXenocide.UI.Scenes.Battlescape;
#endregion
namespace ProjectXenocide.UI.Screens
{
/*
This file is the screen state, when battlescape is waiting for waiting for player to give or
finish giving a combatant an order
*/
public partial class BattlescapeScreen
{
///
/// Screen behaviour, when player giving a combatant an order to move
///
private class MoveOrderCombatantScreenState : OrderCombatantScreenState
{
///
/// Constructor
///
/// The parent battlescapeScreen
/// Combatant player is giving order to
public MoveOrderCombatantScreenState(BattlescapeScreen battlescapeScreen, Combatant combatant)
: base(battlescapeScreen, combatant)
{
}
/// Called when Screen enters this state
public override void OnEnterState()
{
base.OnEnterState();
BattlescapeScreen.scene.WantedCellCursorColor = Color.Blue;
}
/// React to user moving cursor to new cell of battlescape
/// Cell in battlescape mouse was moved to
public override void OnMouseMoveInScene(Vector3 pos)
{
BattlescapeScreen.scene.ShowPath = false;
// if combatant is dead or stunned, nothing to do
if (!Combatant.CanTakeOrders)
{
return;
}
// draw path, showing how far combatant can move
if (Battlescape.Terrain.IsOnTerrain(pos))
{
List path = new List();
if (Combatant.FindPath(pos, path))
{
// there's a path to destination, see how far along it we can go
int max = (new MoveOrder(Combatant, Battlescape, path)).MaximumPathCells();
if (0 < max)
{
// remove cells beyond move range
if (max < path.Count - 1)
{
path.RemoveRange(max + 1, path.Count - 1 - max);
}
BattlescapeScreen.scene.PathMeshBuilder.Path = path;
BattlescapeScreen.scene.ShowPath = true;
}
}
}
}
/// React to user clicking left mouse button in the 3D battlescape scene
/// Cell in battlescape where mouse was clicked
public override void OnLeftMouseDownInScene(Vector3 pos)
{
// figure out what we do with target cell,
// is there a combatant in the cell?
Combatant target = Battlescape.FindCombatantAt(pos);
if (null != target)
{
switch (target.TeamId)
{
case Team.Aliens:
// if cheat on, give order to alien, otherwise ignore.
if (Xenocide.StaticTables.StartSettings.Cheats.PlayerControlsAliens)
{
BattlescapeScreen.ChangeState(new MoveOrderCombatantScreenState(BattlescapeScreen, target));
}
return;
case Team.XCorp:
// selected a (probably different) X-Corp unit
BattlescapeScreen.ChangeState(new MoveOrderCombatantScreenState(BattlescapeScreen, target));
return;
case Team.Civilians:
// ignore civilians
return;
default:
// should never get here
Debug.Assert(false);
break;
}
}
// if combatant is dead or stunned, nothing to do
if (!Combatant.CanTakeOrders)
{
return;
}
// Assume it's a move command
pos = BattlescapeScene.RoundToCell(pos);
if (Battlescape.Terrain.IsOnTerrain(pos))
{
// check there's a path to the new position
List path = new List();
if (Combatant.FindPath(pos, path))
{
Combatant.Order = new MoveOrder(Combatant, Battlescape, path);
BattlescapeScreen.ChangeState(new CombatantActivityScreenState(BattlescapeScreen, Combatant));
}
}
}
/// React to user clicking right mouse button in the 3D battlescape scene
/// Cell in battlescape where mouse was clicked
/// Right click is a turn command
public override void OnRightMouseDownInScene(Vector3 pos)
{
// if combatant is dead or stunned, nothing to do
if (!Combatant.CanTakeOrders)
{
return;
}
// figure how far to turn
double turn = Combatant.CalcTurnAngle(pos);
// if we're already facing the right quadrant, don't do anything.
if ((MathHelper.PiOver4 - 0.1f) <= (float)Math.Abs(turn))
{
Combatant.Order = new MoveOrder(Combatant, Battlescape, Combatant.Heading + turn);
BattlescapeScreen.ChangeState(new CombatantActivityScreenState(BattlescapeScreen, Combatant));
}
}
#region buttons being clicked
/// User has clicked the equipment button. So bring up equipment screen for selected combatant
public override void OnEquipmentButton()
{
// if combatant is dead or stunned, nothing to do
if (Combatant.CanTakeOrders)
{
BattlescapeScreen.ScreenManager.PushScreen(new EquipSoldierScreen(Combatant, Battlescape, false));
}
}
/// User has clicked the either Right or Left hand button
/// true if it was the "right hand" button
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object)",
Justification="ToDo: String is temporary, to cover case while code under construction, will be removed when problem fixed.")]
public override void OnHandButton(bool right)
{
// if combatant is dead or stunned, nothing to do
if (!Combatant.CanTakeOrders)
{
return;
}
// get item in hand
Item weapon = Combatant.Inventory.ItemAt(right ? 0 : 1, 0);
if (null != weapon)
{
// ToDo: Item can't be used if not researched. Note, some actions (e.g. throw) can be done without needing research
// ToDo: remove this safty check when more actions are implemented
if (0 == weapon.ItemInfo.Actions.Count)
{
Util.ShowMessageBox(String.Format("Sorry, {0} doesn't have any actions yet.", weapon.Name));
return;
}
BattlescapeScreen.ScreenManager.ShowDialog(
new PickActionDialog(BattlescapeScreen, weapon, Combatant, right));
}
}
#endregion buttons being clicked
#region Fields
#endregion Fields
}
}
}