/// <summary> /// Resigns the game for the <see cref="WorldState.ActiveFaction"/>, which must be /// controlled by a local human player.</summary> /// <exception cref="PropertyValueException"> /// The current session <see cref="Session.State"/> is not <see cref="SessionState.Human"/>. /// </exception> /// <remarks><para> /// <b>Resign</b> should be called whenever a local human player wishes to resign the game. /// This method performs the following actions: /// </para><list type="number"><item> /// Ask the user to confirm the operation, and immediately return <c>true</c> if the user /// declines. /// </item><item> /// Issue a <see cref="ResignCommand"/> for the <see cref="WorldState.ActiveFaction"/>. /// </item><item> /// Invoke <see cref="EndTurn"/> to immediately end the active faction's turn if command /// execution was successful. /// </item></list><para> /// <b>Resign</b> calls <see cref="Session.Close"/> without confirmation if an error /// occurred, or if a faction controlled by a remote human player was activated. /// </para></remarks> public static void Resign() { CheckSessionState(); WorldState world = Session.Instance.WorldState; string name = world.ActiveFaction.Name; // ask user to confirm resignation MessageBoxResult result = MessageBox.Show(MainWindow.Instance, Global.Strings.DialogResignFaction, name, MessageBoxButton.OKCancel, MessageBoxImage.Question, MessageBoxResult.Cancel); if (result == MessageBoxResult.Cancel) { return; } AsyncAction.BeginRun(delegate { Action postAction; // issue Resign command and end faction's turn if (Session.Instance.Executor.ExecuteResign(world)) { postAction = EndTurn; } else { postAction = () => Session.Close(false); } AsyncAction.BeginInvoke(delegate { postAction(); AsyncAction.EndRun(); }); }); }
/// <summary> /// Ends the turn for the <see cref="WorldState.ActiveFaction"/>, which must be controlled /// by a local human player, and activates subsequent factions.</summary> /// <exception cref="PropertyValueException"> /// The current session <see cref="Session.State"/> is not <see cref="SessionState.Human"/>. /// </exception> /// <remarks><para> /// <b>EndTurn</b> should be called whenever a local human player wishes to end his turn. /// This method performs the following actions: /// </para><list type="number"><item> /// Save the current <see cref="Session.WorldState"/> to the predefined <see /// cref="SessionFileType.Auto"/> session file. /// </item><item> /// Issue an <see cref="EndTurnCommand"/> for the <see cref="WorldState.ActiveFaction"/>. /// </item><item> /// Call <see cref="Session.Dispatch"/> on the current <see cref="Session"/> to dispatch the /// game to the player controlling the faction that was activated in the previous step. /// </item></list><para> /// <b>EndTurn</b> calls <see cref="Session.Close"/> without confirmation if an error /// occurred, or if a faction controlled by a remote human player was activated. /// </para></remarks> public static void EndTurn() { CheckSessionState(); Session session = Session.Instance; // autosave game before executing command string path = FilePaths.GetSessionFile(SessionFileType.Auto).AbsolutePath; session.Save(ref path, false); AsyncAction.BeginRun(delegate { Action postAction; // issue EndTurn command and dispatch game to next player if (session.Executor.ExecuteEndTurn(session.WorldState)) { postAction = session.Dispatch; } else { postAction = () => Session.Close(false); } AsyncAction.BeginInvoke(delegate { postAction(); AsyncAction.EndRun(); }); }); }
/// <summary> /// Completes implicit or explicit target selection with the specified target location. /// </summary> /// <param name="target"> /// The coordinates of the selected target <see cref="Site"/>.</param> /// <returns> /// <c>true</c> if a command was successfully executed; otherwise, <c>false</c>.</returns> /// <remarks><para> /// <b>Complete</b> calls <see cref="Cancel"/> and fails immediately if the specified /// <paramref name="target"/> is not in the <see cref="MapView.SelectedRegion"/> of the /// default <see cref="Session.MapView"/>. /// </para><para> /// Otherwise, if the current <see cref="Session.State"/> equals <see /// cref="SessionState.Human"/>, <b>Complete</b> issues either an <see /// cref="AttackCommand"/> or a <see cref="MoveCommand"/> with the specified <paramref /// name="target"/> site, depending on its contents. <b>Complete</b> then invokes <see /// cref="HumanAction.SelectUnit"/> to cycle to the next active unit. /// </para><para> /// Otherwise, if the current <see cref="Session.State"/> equals <see /// cref="SessionState.Selection"/>, <b>Complete</b> issues the pending command with the /// specified <paramref name="target"/> site. Depending on the pending command, /// <b>Complete</b> then calls <see cref="HumanAction.Build"/> or <see /// cref="HumanAction.ManageEntities"/>, allowing the local human player to continue /// building or placing entities, respectively. /// </para><para> /// The execution of any command implicitly resets the <see cref="Session.State"/> to <see /// cref="SessionState.Human"/> and calls <see cref="Clear"/> to clear all data managed by /// the <see cref="TargetSelection"/> class. Finally, <b>Complete</b> returns the return /// value of the <see cref="Session.Executor"/> method invoked for command execution. /// </para></remarks> public void Complete(PointI target) { // check for valid target if (!Session.MapView.InSelectedRegion(target)) { Cancel(); return; } // remember currently selected entity, if any string id = MainWindow.Instance.SelectedEntity; AsyncAction.BeginRun(delegate { Action action = null; SessionExecutor executor = Session.Instance.Executor; WorldState world = Session.Instance.WorldState; if (Session.State == SessionState.Human) { // issue implicit Attack or Move command, then cycle to next active unit if (this._attackTargets != null && this._attackTargets.Contains(target)) { executor.ExecuteAttack(world, this._attackUnits, target); action = () => HumanAction.SelectUnit(id, false, false); } else if (this._moveTargets != null && this._moveTargets.Contains(target)) { executor.ExecuteMove(world, this._moveUnits, target); action = () => HumanAction.SelectUnit(id, false, false); } } else if (Session.State == SessionState.Selection) { // issue Build or Place command, then let user build or place more entities if (this._commandType == typeof(BuildCommand)) { executor.ExecuteBuildPlace(world, this._entityClass.Id, 1, target); action = HumanAction.Build; } else if (this._commandType == typeof(PlaceCommand)) { executor.ExecutePlace(world, this._entities, target); action = () => HumanAction.ManageEntities(Dialog.ShowEntitiesMode.Unplaced); } } // execute automatic user action, if any if (action == null) { AsyncAction.EndRun(); } else { AsyncAction.BeginInvoke(delegate { action(); AsyncAction.EndRun(); }); } }); }