public override void Update(GameTime gameTime) { if (FIRSTLOAD) { //must put some first loading code here, since when states are added to the stack they have their content load/initialize functions called immediately. // This would result in some strange behaviour with units being removed from the grid when they shouldn't be if this was put in load/initialize. if (useAiOpponent) { //the following variable is used for displaying the outcome of the ai round at the end of the round. moneyAtRoundStart = playerToCheckWinCondition.Money; //remove the other player's units this turn only otherPlayer = players.Where(player => player.Id != nonAiPlayerId).First(); grid.MoveUnitsOffGridTemporarily(otherPlayer.Id); //add the ai opponents units to the grid. Random random = new Random(); foreach (Unit unit in aiRoundUnits) { //find an unoccupied tile in the opponents half (Note their units have been removed temporarily this round) Vector3 location = Vector3.Zero; bool occupied = true; while (occupied) { location = otherPlayer.GetRandomPositionInHalf(); if (!grid.IsTileOccupied(location)) { occupied = false; } } //add the ai unit at the random location. unit.AddToGrid(grid, location); } } FIRSTLOAD = false; } helpButton.Update(gameTime); //check that the round has not finished. i.e. only one side's units are left. int oneSidesUnitCount = grid.Units.Where(unit => unit.OwnerId == playerToCheckWinCondition.Id).ToList().Count; if (oneSidesUnitCount == 0 || oneSidesUnitCount == grid.Units.Count) { EndBattle(); } else { //each time the timer resets... if (timer == stepTimeInterval) { //get the next unit to update //unitsToUpdate list stores the units that haven't been updated in order by their speed for each step if (unitsToUpdate == null) { //get a new list if its hasn't been defined //(Note: order by descending, higher speed => move first) unitsToUpdate = grid.Units.OrderByDescending(unit => unit.Stats.Speed.Value).ToList(); } else if (unitsToUpdate.Count == 0) { //... or has been emptied. unitsToUpdate = grid.Units.OrderByDescending(unit => unit.Stats.Speed.Value).ToList(); } if (unitsToUpdate.Count != 0) { //first get information about the next move a unit will make so it can be displayed //to the player before being committed. //check that list is not empty before trying to update the unit. pendingUpdateUnit = unitsToUpdate.First(); //get the fastest unit and store it to commit changes later. if (pendingUpdateUnit.IsAlive()) { pendingAction = pendingUpdateUnit.Update(players, grid, false); //... and update it - not commiting changes (get pending action info) } } } //decrement the timer by time elapsed. timer -= (float)gameTime.ElapsedGameTime.TotalSeconds; //commit changes if the interval has elapsed (gives time for update to be shown to player) if (timer <= 0) { if (pendingUpdateUnit != null && pendingAction != null) { ActionArgs action = pendingUpdateUnit.Update(players, grid, true); //update the unit, comitting changes actionLog.AddEntry(action); //add result of update to the action log (the action performed) //then remove it from units needing to be updated for this step. unitsToUpdate.RemoveAll(match => match.id == pendingUpdateUnit.id); //remove any units thay may have fainted as a result of an action to stop them from trying to update this step. unitsToUpdate.RemoveAll(match => match.IsAlive() == false); //and finally reset the interval timer. timer = stepTimeInterval; } } } }