#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 BattlescapeScreen.cs * @date Created: 2007/12/30 * @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.Drawing; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Input; using Microsoft.Xna.Framework.Content; using Microsoft.Xna.Framework.Graphics; using Vector3 = Microsoft.Xna.Framework.Vector3; using CeGui; using ProjectXenocide.Utils; using ProjectXenocide.UI.Dialogs; using ProjectXenocide.UI.Scenes.Battlescape; using ProjectXenocide.Model.Battlescape; using ProjectXenocide.Model.Battlescape.Combatants; using Xenocide.Resources; #endregion namespace ProjectXenocide.UI.Screens { /// /// Screen that shows the battlescape /// public partial class BattlescapeScreen : Screen { /// /// Constructor (obviously) /// public BattlescapeScreen() : base("BattlescapeScreen", @"Content\Textures\UI\BasesScreenBackground.png") { Xenocide.AudioSystem.PlayRandomMusic("BaseView"); ChangeState(new StartTurnScreenState(this)); } /// /// Load the Scene's graphic content /// /// content manager that fetches the content /// the display public override void LoadContent(ContentManager content, GraphicsDevice device) { scene.LoadContent(device, battlescape); topLevel = battlescape.Terrain.Levels - 1; } /// /// Perform processing which updates the screen. /// /// snapshot of timing values public override void Update(GameTime gameTime) { state.Update(gameTime); scene.Update(gameTime); } /// /// Render the 3D scene /// /// time interval since last render /// Device to render the globe to public override void Draw(GameTime gameTime, GraphicsDevice device) { scene.Draw(device, sceneWindow.Rect, topLevel, cursorPosition); } #region Create the CeGui widgets /// /// add the buttons to the screen /// protected override void CreateCeguiWidgets() { // Window indicating where the 3D scene is sceneWindow = GuiBuilder.CreateImage(CeguiId + "_viewport"); AddWidget(sceneWindow, 0.00f, 0.00f, 0.745f, 1.00f); // text giving stats for selected combatant combatantStatsTextWindow = AddStaticText(0.0f, 0.0f, 0.745f, 0.065f); combatantStatsTextWindow.Hide(); // other buttons equipmentButton = AddButton("BUTTON_EQUIPMENT", 0.7475f, 0.75f, 0.2275f, 0.04125f); rightHandButton = AddButton("BUTTON_RIGHT_HAND", 0.7475f, 0.80f, 0.2275f, 0.04125f); finishTurnButton = AddButton("BUTTON_FINISH_TURN", 0.7475f, 0.85f, 0.2275f, 0.04125f); topLevelButton = AddButton("BUTTON_TOP_LEVEL", 0.7475f, 0.90f, 0.2275f, 0.04125f); abortButton = AddButton("BUTTON_ABORT_MISSION", 0.7475f, 0.95f, 0.2275f, 0.04125f); // other buttons being pressed equipmentButton.Clicked += new CeGui.GuiEventHandler(OnEquipmentButton); rightHandButton.Clicked += new CeGui.GuiEventHandler(OnRightHandButton); finishTurnButton.Clicked += new CeGui.GuiEventHandler(OnFinishTurnButton); topLevelButton.Clicked += new CeGui.GuiEventHandler(OnTopLevelButton); abortButton.Clicked += new CeGui.GuiEventHandler(OnAbortButton); // mouse activity on screen sceneWindow.MouseMove += new CeGui.MouseEventHandler(OnMouseMoveInScene); sceneWindow.MouseButtonsDown += new CeGui.MouseEventHandler(OnMouseDownInScene); } /// /// CeGui widget that indicates where to draw the 3D scene /// private CeGui.Widgets.StaticImage sceneWindow; private CeGui.Widgets.StaticText combatantStatsTextWindow; private CeGui.Widgets.PushButton equipmentButton; private CeGui.Widgets.PushButton rightHandButton; private CeGui.Widgets.PushButton finishTurnButton; private CeGui.Widgets.PushButton topLevelButton; private CeGui.Widgets.PushButton abortButton; #endregion Create the CeGui widgets #region event handlers /// User has clicked the "Equipment" button /// Not used /// Not used private void OnEquipmentButton(object sender, CeGui.GuiEventArgs e) { state.OnEquipmentButton(); } /// User has clicked the "Right Hand" button /// Not used /// Not used private void OnRightHandButton(object sender, CeGui.GuiEventArgs e) { state.OnHandButton(true); } /// User has clicked the "Finish Turn" button /// Not used /// Not used private void OnFinishTurnButton(object sender, CeGui.GuiEventArgs e) { state.OnFinishTurnButton(); } /// User has clicked the "Top Level" button /// Not used /// Not used private void OnTopLevelButton(object sender, CeGui.GuiEventArgs e) { ToggleTopLevel(); } /// User has clicked the "Abort Mission" button /// Not used /// Not used private void OnAbortButton(object sender, CeGui.GuiEventArgs e) { state.OnAbortButton(); } /// React to user moving the mouse in the 3D scene /// Not used /// Mouse information private void OnMouseMoveInScene(object sender, CeGui.MouseEventArgs e) { Vector3 newPosition = WindowPixelToBattlescapeCell(e.Position.X, e.Position.Y, topLevel); if (cursorPosition != newPosition) { cursorPosition = newPosition; state.OnMouseMoveInScene(cursorPosition); } } /// React to user clicking mouse in the 3D scene /// CeGui widget sending the event /// Mouse information private void OnMouseDownInScene(object sender, CeGui.MouseEventArgs e) { // ignore clicks that are not on the terrain Vector3 newPosition = WindowPixelToBattlescapeCell(e.Position.X, e.Position.Y, topLevel); if (battlescape.Terrain.IsOnTerrain(newPosition)) { if (e.Button == System.Windows.Forms.MouseButtons.Left) { state.OnLeftMouseDownInScene(newPosition); } else { state.OnRightMouseDownInScene(newPosition); } } } #endregion event handlers /// Change the State /// new state private void ChangeState(ScreenState newState) { if (null != state) { state.OnExitState(); } state = newState; if (null != state) { Debug.WriteLine("Entering Battlescape state " + state.GetType().ToString()); state.OnEnterState(); } } /// Change the number of levels of the battlescape being shown private void ToggleTopLevel() { ++topLevel; if (battlescape.Terrain.Levels <= topLevel) { topLevel = 0; } } /// Battlescape is over /// Who won the battle private void FinishMission(BattleFinish finishType) { Mission mission = battlescape.Mission; mission.OnFinish(battlescape, finishType); battlescape.PostMissionCleanup(); Xenocide.GameState.Battlescape = null; ScreenManager.ScheduleScreen(new BattlescapeReportScreen(mission)); } /// /// Convert position of pixel on screen to cell location on battlescape /// /// pixel's column /// pixel's row /// level of the battlescape to find intersection at /// corresponding position, or undefined if not on Battlescape private Vector3 WindowPixelToBattlescapeCell(float X, float Y, int level) { PointF coords2 = sceneWindow.AbsoluteToRelative(new PointF( X - sceneWindow.AbsoluteX, Y - sceneWindow.AbsoluteY)); return scene.WindowToBattlescapeCell(coords2, level); } /// /// Update the combatant stats window with the stats for the currently selected combatant /// /// the selected combatant (null if there isn't one) private void ShowCombatantStats(Combatant combatant) { if (null == combatant) { combatantStatsTextWindow.Hide(); } else { combatantStatsTextWindow.Text = Util.StringFormat(Strings.SCREEN_BATTLESCAPE_COMBATANT_STATS, combatant.Stats[Statistic.TimeUnitsLeft], combatant.Stats[Statistic.TimeUnits], combatant.Stats[Statistic.Health], combatant.Stats[Statistic.InjuryDamage], combatant.Stats[Statistic.StunDamage], combatant.Stats[Statistic.Health] - combatant.Stats[Statistic.InjuryDamage] - combatant.Stats[Statistic.StunDamage] ); combatantStatsTextWindow.Show(); } } #region Fields /// The 3D view shown on the screen private BattlescapeScene scene = new BattlescapeScene(); /// Topmost level of terrain to draw private int topLevel; /// The cell the mouse cursor is currently over private Vector3 cursorPosition = new Vector3(); /// The battlescape private Battle battlescape = Xenocide.GameState.Battlescape; /// State the screen is in private ScreenState state; #endregion Fields } }