private Unit unitSelected; // used to determine what side the unit is on for movement and attack #endregion Fields #region Constructors public Selector(Tile[,] t, Rectangle pos, Texture2D sprite, int X, int Y) { tiles = t; rectPos = new Rectangle(pos.X, pos.Y, pos.Width, pos.Height); texture = sprite; currentGridX = X; currentGridY = Y; curMousePos = new Rectangle(InputManager.CurrentMouseState.X, InputManager.CurrentMouseState.Y, 1, 1); }
protected virtual Stack<PathNode> AStar(Tile source, Tile destination) { List<Tile> closed = new List<Tile>(); List<Tile> toDetermine; List<Tile> toAdd = new List<Tile>(); Stack<PathNode> finalPath = null; MinPriorityQueue<PathNode> open = new MinPriorityQueue<PathNode>(); List<PathNode> openList = new List<PathNode>(); open.Enqueue(new PathNode(source, destination)); openList.Add(open.Peek()); PathNode currentNode = null; bool endReached = false; do { currentNode = open.Dequeue(); openList.Remove(currentNode); if (currentNode.HCost == 0) { endReached = true; finalPath = currentNode.GetPath(); } else { closed.Add(tiles[currentNode.Current.X, currentNode.Current.Y]); toDetermine = getAdjacent(currentNode); foreach (Tile t in toDetermine) { bool remove = false; if (t.Collision > source.Unit.Collision) remove = true; if (t.HasUnit()) if (t.Unit.Army != source.Unit.Army) //added so that AI works remove = true; if (closed.Contains(t)) remove = true; //Add this if I want to have no duplicate pathnodes (currently, //multiple exist with different source nodes /* PathNode temp = new PathNode(t.GridwiseLocation, currentNode, destination.GridwiseLocation); foreach (PathNode p in openList) { if (p.Current == temp.Current) { if (p.GCost > temp.GCost) { p.Source = temp.Source; remove = true; } } }'*/ if (!remove) toAdd.Add(t); } foreach (Tile t in toAdd) { PathNode temp = new PathNode(t.GridwiseLocation, currentNode, destination.GridwiseLocation); open.Enqueue(temp); } toAdd.Clear(); } } while (!endReached); return finalPath; }
//abstract protected void Attack; public abstract void SetTiles(Tile[,] tileArray);
/// <summary> /// /// </summary> /// <param name="player">The player - allows us to give player the array of tiles</param> /// <param name="terrainSheet">The spriteSheet that tiles will load their texture from</param> /// <param name="_armies">An array of armies participating in the battle</param> public Battle(Game1 g, Scenario loadedScenario) { endTurn = false; turn = 0; players = new Player[loadedScenario.ArmyAmount]; pauseMenu = new PauseMenu(3, Game1.GameHeight / 2 - 25, 192); terrainSheet = Game1.GameContent.Load<Texture2D>("Spritesheet"); playerSheet = Game1.GameContent.Load<Texture2D>("selector"); unitSheet = Game1.GameContent.Load<Texture2D>("ArmySpriteSheet"); testArmy = loadedScenario.Armies[0]; g.InfoBar.YMod = 110; g.InfoBar.Visible = false; players[0] = new Human(g.InfoBar,Game1.UpdateBox, playerSheet, loadedScenario.Armies[0]); players[0].RectPos = new Rectangle(64, 64, GV.TileSize, GV.TileSize); players[0].ActualPosition = new Rectangle(64, 64, GV.TileSize, GV.TileSize); for (int i = 1; i < players.Length; i++) { List<Army> allies = new List<Army>(); List<Army> enemies = new List<Army>(); for (int j = 0; j < loadedScenario.ArmyAmount; j++) { if (j != i) { if (loadedScenario.Armies[j].Team == loadedScenario.Armies[i].Team) { allies.Add(loadedScenario.Armies[j]); } else { enemies.Add(loadedScenario.Armies[j]); } } } players[i] = new AI(allies, enemies, loadedScenario.Armies[i]); } g.Camera.Focus = players[0]; DirectoryInfo d = new DirectoryInfo(Environment.CurrentDirectory); while (d.ToString() != "dynasty") d = d.Parent; string path = d.FullName + @"\GameData\Maps\"; XmlReader mapReader = XmlReader.Create(path + loadedScenario.MapFile); int currentRow = 0; int currentCol = 0; mapReader.ReadToFollowing("map"); //read to the first map element available players[0].Position2 = new Point(160, 160); //place the player at a default point for now mapSize = Convert.ToInt32(mapReader.GetAttribute("size")); //get the size of the map (both the length and width of the map are the same, so we use "size") tiles = new Tile[mapSize, mapSize]; //Create a 2D array that holds the required amount of tiles int lastPlaced = 0; currentRow = 0; currentCol = 0; mapReader.ReadToFollowing("tile"); //Read to the first tile elements of the map so we can begin creating tiles do { int length = Convert.ToInt32(mapReader.GetAttribute("length")); //Get the rectangle size of the tile //string[] bound = bounds.Split(','); //Split the values provided into an array //int startX = int.Parse(bound[0]); //our starting x location for creating tiles //int startY = int.Parse(bound[1]); //our starting y location for creating tiles //int endX = int.Parse(bound[2]); //our ending x location for creating tiles //int endY = int.Parse(bound[3]); //our ending y location for creating tiles for (int i = 0; i < length; i++) { tiles[currentRow, currentCol] = new Tile(mapReader.GetAttribute("terrain"), terrainSheet, currentRow, currentCol); currentRow++; if (currentRow >= mapSize) { currentRow = 0; currentCol++; } if ((currentCol == mapSize) && (currentRow == mapSize)) break; } } while (mapReader.ReadToNextSibling("tile")); mapReader.ReadToNextSibling("spawns"); //spawns = new List<Tile>(); mapReader.ReadToFollowing("tile"); do { string bounds = mapReader.GetAttribute("location"); string[] bound = bounds.Split(','); int startX = int.Parse(bound[0]); int startY = int.Parse(bound[1]); int endX = int.Parse(bound[2]); int endY = int.Parse(bound[3]); for (int i = startX; i < endX; i++) { for (int j = startY; j < endY; j++) { //_tiles[i, j].Spawn = true; //spawns.Add(_tiles[i, j]); } } } while (mapReader.ReadToNextSibling("tile")); //head to the next tile element if one exists, otherwise we exit this loop mapReader.Close(); foreach (Player p in players) { p.SetTiles(tiles); foreach (Unit u in p.OwnArmy.Units) { tiles[u.UnitBox.X / GV.TileSize, u.UnitBox.Y / GV.TileSize].Unit = u; u.UnitSprite = unitSheet; u.UnitPic = unitSheet; } } }
public override bool Update(Camera2D camera) { if (mapControl) //Are we moving amongst the map (1st step) { updateBox.TargetUnit = mainSelector.UnitSelected; if (highlightGone == false) //Make sure we no longer are highlighting tiles { secondarySelector.HighlightDelete(); highlightGone = true; } currentTile = mainSelector.Update(ref actualPos, ref currentGridX, ref currentGridY, ref camera, 0, endTurnButton); if (currentTile != null && currentTile.Unit != null && (Game1.Team == int.Parse(currentTile.Unit.Army.ToString()))) //We have selected a tile and it has a unit to select, invoke the infobar and prepare the secondary selector { currentUnit = currentTile.Unit; infoBar.Visible = true; mapControl = false; secondarySelector.UnitSelected = currentUnit; mainSelector.PreviousTile.HighlightCursor = false; secondarySelector.CurrentTile = currentTile; secondarySelector.CurrentGridX = currentGridX; secondarySelector.CurrentGridY = currentGridY; mainSelector.CurrentTile = currentTile; mainSelector.CurrentGridX = currentGridX; mainSelector.CurrentGridY = currentGridY; mainSelector.Tiles[currentGridX, currentGridY].HighlightCursor = true; } } else { if (infoBar.Visible) { updateBox.TargetUnit = currentUnit; if (infoBar.SelectedAction > 0) { selectedAction = infoBar.SelectedAction; infoBar.Visible = false; previousGridX = currentGridX; previousGridY = currentGridY; previousTile = currentTile; previousRectPos = actualPos; } if (InputManager.KeyReady(Keys.Q)) { infoBar.Visible = false; infoBar.SpecialMoveBoxVisible = false; mapControl = true; // The code below may or may not be called based on the option of // whether the player wants cancelling the move to bring them back to // the previous unit selected or if they just want it to keep them // on the current tile. /* mainSelector.CurrentTile = currentTile; mainSelector.CurrentGridX = currentGridX; mainSelector.CurrentGridY = currentGridY; */ } } else { updateBox.TargetUnit = secondarySelector.UnitSelected; if (InputManager.KeyReady(Keys.Q) && !highlightGone) { infoBar.Visible = true; secondarySelector.HighlightDelete(); selectedAction = InfoBar.Action.None; highlightGone = true; mapControl = false; currentTile = previousTile; currentGridX = previousGridX; currentGridY = previousGridY; actualPos = previousRectPos; secondarySelector.CurrentTile = currentTile; secondarySelector.CurrentGridX = currentGridX; secondarySelector.CurrentGridY = currentGridY; mainSelector.CurrentTile = currentTile; mainSelector.CurrentGridX = currentGridX; mainSelector.CurrentGridY = currentGridY; mainSelector.PreviousTile.HighlightCursor = false; foreach (Tile tile in secondarySelector.Tiles) { tile.HighlightCursor = false; } mainSelector.Tiles[currentGridX, currentGridY].HighlightCursor = true; } switch (selectedAction) { case InfoBar.Action.Move: { if (!currentTile.Unit.Bunkered) { if (highlightGone) //Prevent ourselves from highlighting continuously { secondarySelector.HighlightTiles(currentUnit.Movement); highlightGone = false; } selectedTile = secondarySelector.Update(ref actualPos, ref currentGridX, ref currentGridY, ref camera, 0, endTurnButton); if (selectedTile != null && selectedTile.Unit == null && selectedTile.HighlightSpace == true) { //infoBar.SelectedAction = (int)PlayerStatus.None; /* secondarySelector.HighlightTiles(currentUnit.Movement); highlightGone = false; } selectedTile = secondarySelector.Update(ref actualPos, ref currentGridX, ref currentGridY, ref camera, 0/*, endTurnButton); if (selectedTile != null && selectedTile.Unit == null && selectedTile.HighlightSpace == true) {*/ //infoBar.SelectedAction = (int)PlayerStatus.None; //currentUnit.UnitBox.Offset((selectedTile.Location.X - currentUnit.UnitBox.X), (selectedTile.Location.Y - currentUnit.UnitBox.Y)); //currentUnit.UnitPoint = selectedTile.Location.Location; selectedAction = InfoBar.Action.Animate; } } else { Game1.UpdateBox.AddMessage("Unit cannot move \nuntil you \ndeactivate bunker."); highlightGone = false; //Used so we can still q out of method } } break; /*default: mapControl = true; infoBar.Visible = false; break;*/ case InfoBar.Action.Attack: { if (highlightGone) //Prevent ourselves from highlighting continuously { secondarySelector.HighlightEnemies(currentUnit.Range); highlightGone = false; } selectedTile = secondarySelector.Update(ref actualPos, ref currentGridX, ref currentGridY, ref camera, 0, endTurnButton); if (selectedTile != null && selectedTile.Unit != null && selectedTile.Unit.Army != currentTile.Unit.Army && selectedTile.HighlightEnemy) { int dealt, received; Unit attacker = currentTile.Unit; Unit defender = selectedTile.Unit; bool isCounterAttack = false; // MAIN ATTACK int damageDealt = DamageCalculator.doDamage(attacker, defender, isCounterAttack); defender.Health -= damageDealt; dealt = damageDealt; //updateBox.Update(attacker, defender, damageDealt, isCounterAttack); //use isCounterAttack as a parameter in updateBox.Update(...) //if isCounterattack is true, print "attacker did this much damage to defender" //otherwise, print "defender counterattacked attacker with this much damage" // COUNTER ATTACK isCounterAttack = true; damageDealt = DamageCalculator.doDamage(defender, attacker, isCounterAttack); attacker.Health -= damageDealt; received = damageDealt; //updateBox.Update(defender, attacker, damageDealt, isCounterAttack); // Game1.UpdateBox.ReportAttack(dealt, received); Game1.UpdateBox.AddMessage("Player unit attacks, \ndealing " + dealt + " damage!\n\n" + "Enemy unit \ncounterattacks, \ndealing " + received + " damage!"); mapControl = true; infoBar.Visible = false; mainSelector.CurrentTile = currentTile; mainSelector.CurrentGridX = currentGridX; mainSelector.CurrentGridY = currentGridY; //Attacker now knows it has attacked this turn attacker.HasAttacked = true; } } break; case InfoBar.Action.Special: { if (currentTile.Unit.CoolDown == 0) //blocks the use of specials { if (highlightGone) //Prevent ourselves from highlighting continuously { if (infoBar.SelectedSpecialMove.Name == "Frag Grenade") { secondarySelector.HighlightSpecial(infoBar.SelectedSpecialMove.Range, true); highlightGone = false; } else { secondarySelector.HighlightSpecial(infoBar.SelectedSpecialMove.Range, false); highlightGone = false; } } int specialDRange = infoBar.SelectedSpecialMove.AreaOfEffect; selectedTile = secondarySelector.Update(ref actualPos, ref currentGridX, ref currentGridY, ref camera, specialDRange, endTurnButton); if (infoBar.SelectedSpecialMove.NeedsTarget == false || (selectedTile != null && selectedTile.HighlightEnemy)) { Unit attacker = currentTile.Unit; bool isCounterAttack = false; /* secondarySelector.HighlightSpecial(infoBar.SelectedSpecialMove.Range, false); highlightGone = false; } } int specialDRange = infoBar.SelectedSpecialMove.AreaOfEffect; selectedTile = secondarySelector.Update(ref actualPos, ref currentGridX, ref currentGridY, ref camera, specialDRange/*, endTurnButton); if (infoBar.SelectedSpecialMove.NeedsTarget == false || (selectedTile != null && selectedTile.HighlightEnemy)) { Unit attacker = currentTile.Unit; bool isCounterAttack = false; */ /* * TODO: Make a special attack happen here: * get user input for type of attack * string type = user input * SpecialMove s1 = new SpecialMove(type); * Call damage calculator * Use conditional statements based on s1's properties. * * IN THIS CLASS: * "Bunker Down" - Boost defense to unit * "Web Grenade" - Lower enemy move value by 2 * "Frag Grenade" - Secondary selector is on all units, don't allow movement of selector * "Missile" - Doubles the range of helicoptors, but deals 85% damage * "Cripple" - Lowers enemy move value by 2 and deals ~80% damage * "Repair" - Tank attempts to fix some of its parts, returning some lost health * */ if (infoBar.SelectedSpecialMove != null) { SpecialMove s1 = infoBar.SelectedSpecialMove; Random random = new Random(); //Acts upon what type of special is used switch (s1.Name) { case "Bunker Down": if (!attacker.HasAttacked && attacker.Movement == attacker.MaxMovement) { //Going into bunker if (attacker.Bunkered == false) { Game1.UpdateBox.AddMessage("Used Bunker\nDown! Unit's defense \nincreased!"); attacker.Defense += 5; // add 5 defense to unit currently using the move attacker.Attack /= 2; attacker.Movement = 0; // moves all lost! to 0 attacker.HasAttacked = true; // attacked is true, lose a turn attacker.CoolDown = s1.CoolDown; //Sets cooldown for specials } //Leaving bunker else { Game1.UpdateBox.AddMessage("Unit is no \nlonger Bunkered."); attacker.Attack = attacker.OriAttack; attacker.Defense = attacker.OriDefense; attacker.CoolDown = s1.CoolDown; attacker.HasAttacked = true; } } //If conditions aren't met for going or leaving bunker else { Game1.UpdateBox.AddMessage("Can't bunker down\n after moving\n or attacking."); } break; case "Web Grenade": //If we aren't bunkered if (!attacker.Bunkered) { Unit defender = selectedTile.Unit; defender.Movement -= 2; Game1.UpdateBox.AddMessage("Used A Web \nGrenade! Enemy \nunit's move\ndecreased by 2!"); attacker.CoolDown = s1.CoolDown; //Sets cooldown for specials } //If we are bunkered else { Game1.UpdateBox.AddMessage("Must unbunker unit \nto use this special."); } break; case "Frag Grenade": //If we aren't bunkered if (!attacker.Bunkered) { Game1.UpdateBox.AddMessage("Used a Frag\ngrenade!\n...Units took\nsome damage!"); //Each of the five selectable tiles will check if they are not null and if there is a unit present. if (tiles[currentGridX, currentGridY].Unit != null) { // Using Frag Grenade can deal anywhere from 10 to 20 damage. tiles[currentGridX, currentGridY].Unit.Health -= random.Next(10, 20); } if (currentGridX > 0) { if (tiles[currentGridX - 1, currentGridY].Unit != null) { // Using Frag Grenade can deal anywhere from 10 to 20 damage. tiles[currentGridX - 1, currentGridY].Unit.Health -= random.Next(10, 20); } } if (currentGridY > 0) { if (tiles[currentGridX, currentGridY - 1].Unit != null) { // Using Frag Grenade can deal anywhere from 10 to 20 damage. tiles[currentGridX, currentGridY - 1].Unit.Health -= random.Next(10, 20); } } if (currentGridX < Math.Sqrt(tiles.Length - 1)) { if (tiles[currentGridX + 1, currentGridY].Unit != null) { // Using Frag Grenade can deal anywhere from 10 to 20 damage. tiles[currentGridX + 1, currentGridY].Unit.Health -= random.Next(10, 20); } } if (currentGridY < Math.Sqrt(tiles.Length - 1)) { if (tiles[currentGridX, currentGridY + 1].Unit != null) { // Using Frag Grenade can deal anywhere from 10 to 20 damage. tiles[currentGridX, currentGridY + 1].Unit.Health -= random.Next(10, 20); } } attacker.CoolDown = s1.CoolDown; //Sets cooldown for specials } //If we are bunkered else { Game1.UpdateBox.AddMessage("Must unbunker unit \nto use this special."); } break; case "Missile": Unit defending = selectedTile.Unit; defending.Health -= (int).85 * DamageCalculator.doDamage(attacker, defending, false); Game1.UpdateBox.AddMessage("Used A Missile \n...Target Unit \n takes damage"); attacker.CoolDown = s1.CoolDown; //Sets cooldown for specials break; case "Cripple": Unit defend = selectedTile.Unit; defend.Movement -= 2; defend.Health -= (int).806 * DamageCalculator.doDamage(attacker, defend, false); Game1.UpdateBox.AddMessage("Used Cripple \n...Target Unit takes \nsome damage \n and unit's move \ndecreased by 2!"); attacker.CoolDown = s1.CoolDown; //Sets cooldown for specials break; case "Repair": int repair = random.Next(0, 10); //How much we heal for attacker.Health += repair; Game1.UpdateBox.AddMessage("Used Repair \n...Unit healed itself for \n" + repair +" Health."); attacker.CoolDown = s1.CoolDown; //Sets cooldown for specials break; default: break; } infoBar.SelectedSpecialMove = null; } //// MAIN ATTACK //int damageDealt = DamageCalculator.doDamage(attacker, defender, isCounterAttack); //defender.Health -= damageDealt; //dealt = damageDealt; ////updateBox.Update(attacker, defender, damageDealt, isCounterAttack); ////use isCounterAttack as a parameter in updateBox.Update(...) ////if isCounterattack is true, print "attacker did this much damage to defender" ////otherwise, print "defender counterattacked attacker with this much damage" //// COUNTER ATTACK //isCounterAttack = true; //damageDealt = DamageCalculator.doDamage(defender, attacker, isCounterAttack); //attacker.Health -= damageDealt; //received = damageDealt; ////updateBox.Update(defender, attacker, damageDealt, isCounterAttack); //Game1.UpdateBox.ReportAttack(dealt, received); mapControl = true; infoBar.Visible = false; mainSelector.CurrentTile = currentTile; mainSelector.CurrentGridX = currentGridX; mainSelector.CurrentGridY = currentGridY; //Attacker now knows it has attacked this turn attacker.HasAttacked = true; } } else highlightGone = false; //exists so we can q out of a special while we are cooling down. } break; case InfoBar.Action.Animate: //This is where we animate a unit moving AnimateMovement(); break; } } /* if (infoBar.YMod > 105) { currentUnit = null; mapControl = true; infoBar.ItemSelected = (int)PlayerStatus.None; } * */ } if (actualPos.X > ((GV.TileSize * 4) + rectPos.X)) { rectPos.X += GV.TileSize; } else if (actualPos.X < rectPos.X - (GV.TileSize * 4)) { rectPos.X -= GV.TileSize; } if (actualPos.Y > ((GV.TileSize * 4) + rectPos.Y)) { rectPos.Y += GV.TileSize; } else if (actualPos.Y < rectPos.Y - (GV.TileSize * 4)) { rectPos.Y -= GV.TileSize; } //rectPos = tiles[currentGridX, currentGridY].Location //infoBar.SelectedAction = InfoBar.Action.None; if (changeTurn) { foreach (Unit u in ownArmy.Units) u.CoolDown -= 1; changeTurn = false; return true; } return false; }
public Tile Update(ref Rectangle pos, ref int X, ref int Y, ref Camera2D camera, int range, Rectangle endTurnButton) { currentMouseVector = Vector2.Transform(new Vector2(InputManager.CurrentMouseState.X, InputManager.CurrentMouseState.Y), Matrix.Invert(camera.Transform)); if (currentMouseVector.X > 0 && currentMouseVector.Y > 0 && currentMouseVector.X < tiles.GetLength(0) * GV.TileSize - 1 && currentMouseVector.Y < tiles.GetLength(1) * GV.TileSize - 1) { prevMousePos = curMousePos; curMousePos.X = (int)MathHelper.Clamp(currentMouseVector.X, 0f, ((float)Math.Sqrt(tiles.Length - 1) * GV.TileSize)); curMousePos.Y = (int)MathHelper.Clamp(currentMouseVector.Y, 0f, ((float)Math.Sqrt(tiles.Length - 1) * GV.TileSize)); if (!tiles[prevMousePos.X / GV.TileSize, prevMousePos.Y / GV.TileSize].Location.Intersects(curMousePos)) { controlCursorHighlight(prevMousePos.X / GV.TileSize, prevMousePos.Y / GV.TileSize, range, false); } PreviousTile = tiles[curMousePos.X / GV.TileSize, curMousePos.Y / GV.TileSize]; if (currentMouseVector.X > 0 && currentMouseVector.Y > 0 && currentMouseVector.X < tiles.GetLength(0) * GV.TileSize - 1 && currentMouseVector.Y < tiles.GetLength(1) * GV.TileSize - 1) { controlCursorHighlight(curMousePos.X / GV.TileSize, curMousePos.Y / GV.TileSize, range, true); unitSelected = tiles[curMousePos.X / GV.TileSize, curMousePos.Y / GV.TileSize].Unit; } } else { controlCursorHighlight(curMousePos.X / GV.TileSize, curMousePos.Y / GV.TileSize, range, false); } if (InputManager.MouseClicked() && currentMouseVector.X > 0 && currentMouseVector.Y > 0 && currentMouseVector.X < tiles.GetLength(0) * GV.TileSize - 1 && currentMouseVector.Y < tiles.GetLength(1) * GV.TileSize - 1 && !endTurnButton.Contains(new Rectangle(InputManager.CurrentMouseState.X,InputManager.CurrentMouseState.Y,1,1))) { if (currentGridX == curMousePos.X / GV.TileSize && currentGridY == curMousePos.Y / GV.TileSize) { //Mouse.SetPosition(InputManager.CurrentMouseState.X - (int)(camera.Origin.X - camera.Position.X), InputManager.CurrentMouseState.Y - (int)(camera.Origin.Y - camera.Position.Y)); controlCursorHighlight(prevMousePos.X / GV.TileSize, prevMousePos.Y / GV.TileSize, range, false); tiles[currentGridX, currentGridY].HighlightCursor = false; return tiles[currentGridX, currentGridY]; } /* if (new Rectangle(tiles[i, j].Location.X + (int)(camera.Origin.X - camera.Position.X), tiles[i, j].Location.Y + (int)(camera.Origin.Y - camera.Position.Y), tiles[i, j].Location.Width, tiles[i, j].Location.Height).Contains(mousePos)) { PreviousTile = tiles[i, j]; tiles[i, j].HighlightCursor = true; if (InputManager.MouseClicked()) { if (currentGridX == i && currentGridY == j) { return tiles[currentGridX, currentGridY]; } */ currentGridX = curMousePos.X / GV.TileSize; currentGridY = curMousePos.Y / GV.TileSize; } if (InputManager.KeyReady(Keys.W)) { if (currentGridY > 0) currentGridY--; } if (InputManager.KeyReady(Keys.S)) { // -1 is there because sqrt(400) is 20, and array goes 0 - 19 if (currentGridY < Math.Sqrt(tiles.Length) - 1) currentGridY++; } if (InputManager.KeyReady(Keys.A)) { if (currentGridX > 0) currentGridX--; } if (InputManager.KeyReady(Keys.D)) { // -1 is there because sqrt(400) is 20, and array goes 0 - 19 if (currentGridX < Math.Sqrt(tiles.Length) - 1) currentGridX++; } if (InputManager.KeyReady(Keys.Enter)) { return tiles[currentGridX, currentGridY]; //unit.UnitBox.Offset(tiles[currentGridX, currentGridY].Location.X - unit.UnitBox.X, tiles[currentGridX, currentGridY].Location.Y - unit.UnitBox.Y); } X = currentGridX; Y = currentGridY; currentTile = tiles[currentGridX, currentGridY]; pos.X = tiles[currentGridX, currentGridY].Location.X; pos.Y = tiles[currentGridX, currentGridY].Location.Y; return null; }
public override void SetTiles(Tile[,] tileArray) { tiles = tileArray; }
public override void SetTiles(Tile[,] tileArray) { tiles = tileArray; mainSelector.Tiles = tileArray; secondarySelector.Tiles = tileArray; }
private int InvalidTile(Tile movetile, Unit movingUnit) { if (movetile.HasUnit()) { return -10000; } if (movetile.Collision > movingUnit.Collision) { return -10000; } return 0; }
/// <summary> /// Calculates number of nearby enemy units, 'nearby' being defined as /// able to move to the tile. the threatening bool is included as a way /// to differentiate between just nearby (for enemy units able to support enemy units) /// or able to fire on that square (for enemy units nearby AI units) /// </summary> /// <param name="movetile">Tile being weighted</param> /// <param name="threatening">Whether or not ability to attack the tile is the focus, true being yes</param> /// <returns></returns> private int EnemiesNear(Tile movetile, bool threatening) { int x = 0; foreach (Unit enemy in friendlyUnits) { if (threatening) { if (enemy.MaxMovement + enemy.Range >= calculateDistance(enemy.Tile, movetile)) { x++; } } else { if (enemy.MaxMovement >= calculateDistance(enemy.Tile, movetile)) { x++; } } } return x; }
/// <summary> /// Checks whether a given unit can attack any enemies from a given tile. /// </summary> /// <param name="attack">The tile to launch the attack from</param> /// <param name="attacker">The unit that wants to know if it can attack</param> /// <returns>5 for 'true', 0 for 'no', modifier for weighting tiles.</returns> private int CanAttackFrom(Tile attack) { validateAttack(attack.GridwiseLocation.X, attack.GridwiseLocation.Y, currentUnit.Range); foreach (Unit enemy in enemyUnits) { if (enemy.Tile.HighlightSpace) { resetHighlight(); return 5; } } return 0; }
/// <summary> /// Calculates the 'dumb' distance between one tile and another, /// </summary> /// <param name="start">One tile, doesn't matter which</param> /// <param name="end">Other tile, doesn't matter which</param> /// <returns>'dumb' distance, in terms of change in x + change in y on grid.</returns> private int calculateDistance(Tile start, Tile end) { int xDistance = 0; int yDistance = 0; if (start.GridwiseLocation.X >= end.GridwiseLocation.X) { xDistance = start.GridwiseLocation.X - end.GridwiseLocation.X; } else { xDistance = end.GridwiseLocation.X - start.GridwiseLocation.X; } if (start.GridwiseLocation.Y >= end.GridwiseLocation.Y) { yDistance = start.GridwiseLocation.Y - end.GridwiseLocation.Y; } else { yDistance = end.GridwiseLocation.Y - start.GridwiseLocation.Y; } return (xDistance + yDistance); }
/// <summary> /// Calculates number of friendly units (controlled or uncontrolled) nearby. /// 'Nearby' defined as 'can move to this tile in one turn'. /// </summary> /// <param name="movetile">Tile to be judged/weighted</param> /// <returns>Number of friendly (to AI) units able to support tile.</returns> private int AlliesNear(Tile movetile) { int x = 0; foreach (Unit friend in friendlyUnits) { if (friend.MaxMovement >= calculateDistance(friend.Tile, movetile)) { x++; } } foreach (Unit own in ownArmy.Units) { if (own.Movement >= calculateDistance(own.Tile, movetile)) { x++; } } return (x / 2); }