private MenuItem <int> MenuBuildIrrigation() => MenuItem <int> .Create((Map[X, Y] is Forest)? "Change to Plains" : ((Map[X, Y] is Jungle) || (Map[X, Y] is Swamp))? "Change to Grassland" : "Build Irrigation") .SetShortcut("i") .SetEnabled(Map[X, Y].AllowIrrigation() || Map[X, Y].AllowChangeTerrain()) .OnSelect((s, a) => GameTask.Enqueue(Orders.BuildIrrigation(this)));
private GameMenu.Item MenuBuildIrrigation() { GameMenu.Item item; if (Map[X, Y] is Forest) { item = new GameMenu.Item("Change to Plains", "i"); } else if ((Map[X, Y] is Jungle) || (Map[X, Y] is Swamp)) { item = new GameMenu.Item("Change to Grassland", "i"); } else { item = new GameMenu.Item("Build Irrigation", "i"); } item.Selected += (s, a) => GameTask.Enqueue(Orders.BuildIrrigation(this)); return(item); }
internal static void Move(IUnit unit) { Player player = Game.GetPlayer(unit.Owner); if (unit.Owner == 0) { BarbarianMove(unit); return; } if (unit is Settlers) { ITile tile = unit.Tile; bool hasCity = (tile.City != null); bool validCity = (tile is Grassland || tile is River || tile is Plains) && (tile.City == null); bool validIrrigaton = (tile is Grassland || tile is River || tile is Plains || tile is Desert) && (tile.City == null) && (!tile.Mine) && (!tile.Irrigation) && tile.CrossTiles().Any(x => x.IsOcean || x is River || x.Irrigation); bool validMine = (tile is Mountains || tile is Hills) && (tile.City == null) && (!tile.Mine) && (!tile.Irrigation); bool validRoad = (tile.City == null) && tile.Road; int nearestCity = 255; int nearestOwnCity = 255; if (Game.GetCities().Any()) { nearestCity = Game.GetCities().Min(x => Common.DistanceToTile(x.X, x.Y, tile.X, tile.Y)); } if (Game.GetCities().Any(x => x.Owner == unit.Owner)) { nearestOwnCity = Game.GetCities().Where(x => x.Owner == unit.Owner).Min(x => Common.DistanceToTile(x.X, x.Y, tile.X, tile.Y)); } if (validCity && nearestCity > 3) { GameTask.Enqueue(Orders.FoundCity(unit as Settlers)); return; } else if (nearestOwnCity < 3) { switch (Common.Random.Next(5 * nearestOwnCity)) { case 0: if (validRoad) { GameTask.Enqueue(Orders.BuildRoad(unit)); return; } break; case 1: if (validIrrigaton) { GameTask.Enqueue(Orders.BuildIrrigation(unit)); return; } break; case 2: if (validMine) { GameTask.Enqueue(Orders.BuildMines(unit)); return; } break; } } for (int i = 0; i < 1000; i++) { int relX = Common.Random.Next(-1, 2); int relY = Common.Random.Next(-1, 2); if (relX == 0 && relY == 0) { continue; } if (unit.Tile[relX, relY] is Ocean) { continue; } if (unit.Tile[relX, relY].Units.Any(x => x.Owner != unit.Owner)) { continue; } if (!unit.MoveTo(relX, relY)) { continue; } return; } unit.SkipTurn(); return; } else if (unit is Militia || unit is Phalanx || unit is Musketeers || unit is Riflemen || unit is MechInf) { unit.Fortify = true; while (unit.Tile.City != null && unit.Tile.Units.Count(x => x is Militia || x is Phalanx || x is Musketeers || x is Riflemen || x is MechInf) > 2) { IUnit disband = null; IUnit[] units = unit.Tile.Units.Where(x => x != unit).ToArray(); if ((disband = unit.Tile.Units.FirstOrDefault(x => x is Militia)) != null) { Game.DisbandUnit(disband); continue; } if ((disband = unit.Tile.Units.FirstOrDefault(x => x is Phalanx)) != null) { Game.DisbandUnit(disband); continue; } if ((disband = unit.Tile.Units.FirstOrDefault(x => x is Musketeers)) != null) { Game.DisbandUnit(disband); continue; } if ((disband = unit.Tile.Units.FirstOrDefault(x => x is Riflemen)) != null) { Game.DisbandUnit(disband); continue; } if ((disband = unit.Tile.Units.FirstOrDefault(x => x is MechInf)) != null) { Game.DisbandUnit(disband); continue; } } } else { if (unit.Class != UnitClass.Land) { Game.DisbandUnit(unit); } for (int i = 0; i < 1000; i++) { if (unit.Goto.IsEmpty) { int gotoX = Common.Random.Next(-5, 6); int gotoY = Common.Random.Next(-5, 6); if (gotoX == 0 && gotoY == 0) { continue; } if (!player.Visible(unit.X + gotoX, unit.Y + gotoY)) { continue; } unit.Goto = new Point(unit.X + gotoX, unit.Y + gotoY); continue; } if (!unit.Goto.IsEmpty) { int distance = unit.Tile.DistanceTo(unit.Goto); ITile[] tiles = unit.MoveTargets.OrderBy(x => x.DistanceTo(unit.Goto)).ThenBy(x => x.Movement).ToArray(); if (tiles.Length == 0 || tiles[0].DistanceTo(unit.Goto) > distance) { // No valid tile to move to, cancel goto unit.Goto = Point.Empty; continue; } else if (tiles[0].DistanceTo(unit.Goto) == distance) { // Distance is unchanged, 50% chance to cancel goto if (Common.Random.Next(0, 100) < 50) { unit.Goto = Point.Empty; continue; } } if (tiles[0].Units.Any(x => x.Owner != unit.Owner)) { if (unit.Role == UnitRole.Civilian || unit.Role == UnitRole.Settler) { // do not attack with civilian or settler units unit.Goto = Point.Empty; continue; } if (unit.Role == UnitRole.Transport && Common.Random.Next(0, 100) < 67) { // 67% chance of cancelling attack with transport unit unit.Goto = Point.Empty; continue; } if (unit.Attack < tiles[0].Units.Select(x => x.Defense).Max() && Common.Random.Next(0, 100) < 50) { // 50% of attacking cancelling attack of stronger unit unit.Goto = Point.Empty; continue; } } if (!unit.MoveTo(tiles[0].X - unit.X, tiles[0].Y - unit.Y)) { // The code below is to prevent the game from becoming stuck... if (Common.Random.Next(0, 100) < 67) { unit.Goto = Point.Empty; continue; } else if (Common.Random.Next(0, 100) < 67) { unit.SkipTurn(); return; } else { Game.DisbandUnit(unit); return; } } return; } } unit.SkipTurn(); return; } }
private bool KeyDownActiveUnit(KeyboardEventArgs args) { if (Game.ActiveUnit == null || Game.ActiveUnit.Moving) { return(false); } if (args.Key == Key.Space) { Game.ActiveUnit.SkipTurn(); return(true); } else if (Settings.ArrowHelper) { switch (args.Key) { case Key.NumPad1: case Key.End: return(MoveTo(-1, 1)); case Key.NumPad2: return(MoveTo(0, 1)); case Key.NumPad3: case Key.PageDown: return(MoveTo(1, 1)); case Key.NumPad4: return(MoveTo(-1, 0)); case Key.NumPad5: GameTask.Enqueue(Show.Empty); return(true); case Key.NumPad6: return(MoveTo(1, 0)); case Key.NumPad7: case Key.Home: return(MoveTo(-1, -1)); case Key.NumPad8: return(MoveTo(0, -1)); case Key.NumPad9: case Key.PageUp: return(MoveTo(1, -1)); case Key.Escape: _helperDirection = new Point(0, 0); return(true); case Key.Down: _helperDirection.Y++; break; case Key.Up: _helperDirection.Y--; break; case Key.Left: _helperDirection.X--; break; case Key.Right: _helperDirection.X++; break; default: _helperDirection = new Point(0, 0); break; } if (Math.Abs(_helperDirection.X) + Math.Abs(_helperDirection.Y) >= 2) { int x = 0, y = 0; if (_helperDirection.X < 0) { x = -1; } else if (_helperDirection.X > 0) { x = 1; } if (_helperDirection.Y < 0) { y = -1; } else if (_helperDirection.Y > 0) { y = 1; } _helperDirection = new Point(0, 0); return(MoveTo(x, y)); } } else { switch (args.Key) { case Key.NumPad1: case Key.End: return(MoveTo(-1, 1)); case Key.NumPad2: case Key.Down: return(MoveTo(0, 1)); case Key.NumPad3: case Key.PageDown: return(MoveTo(1, 1)); case Key.NumPad4: case Key.Left: return(MoveTo(-1, 0)); case Key.NumPad5: GameTask.Enqueue(Show.Empty); return(true); case Key.NumPad6: case Key.Right: return(MoveTo(1, 0)); case Key.NumPad7: case Key.Home: return(MoveTo(-1, -1)); case Key.NumPad8: case Key.Up: return(MoveTo(0, -1)); case Key.NumPad9: case Key.PageUp: return(MoveTo(1, -1)); } } switch (args.KeyChar) { case 'B': GameTask.Enqueue(Orders.FoundCity(Game.ActiveUnit)); return(true); case 'C': if (Game.ActiveUnit == null) { break; } CenterOnUnit(); return(true); case 'D': if (!args.Shift) { break; } Game.DisbandUnit(Game.ActiveUnit); return(true); case 'H': Game.ActiveUnit.SetHome(); return(true); case 'I': GameTask.Enqueue(Orders.BuildIrrigation(Game.ActiveUnit)); return(true); case 'M': GameTask.Enqueue(Orders.BuildMines(Game.ActiveUnit)); break; case 'R': GameTask.Enqueue(Orders.BuildRoad(Game.ActiveUnit)); break; case 'S': Game.ActiveUnit.Sentry = true; break; case 'F': if (Game.ActiveUnit is Settlers) { GameTask.Enqueue(Orders.BuildFortress(Game.ActiveUnit)); break; } Game.ActiveUnit.Fortify = true; break; case 'U': if (Game.ActiveUnit is IBoardable) { return((Game.ActiveUnit as BaseUnitSea).Unload());; } break; case 'W': GameTask.Enqueue(Orders.Wait(Game.ActiveUnit)); break; } return(false); }
internal static void Move(IUnit unit) { if (unit.Owner == 0) { BarbarianMove(unit); return; } if (unit is Settlers) { ITile tile = unit.Tile; bool hasCity = (tile.City != null); bool validCity = (tile is Grassland || tile is River || tile is Plains) && (tile.City == null); bool validIrrigaton = (tile is Grassland || tile is River || tile is Plains || tile is Desert) && (tile.City == null) && (!tile.Mine) && (!tile.Irrigation) && tile.Cross().Any(x => x.IsOcean || x is River || x.Irrigation); bool validMine = (tile is Mountains || tile is Hills) && (tile.City == null) && (!tile.Mine) && (!tile.Irrigation); bool validRoad = (tile.City == null) && tile.Road; int nearestCity = 255; int nearestOwnCity = 255; if (Game.GetCities().Any()) { nearestCity = Game.GetCities().Min(x => Common.DistanceToTile(x.X, x.Y, tile.X, tile.Y)); } if (Game.GetCities().Any(x => x.Owner == unit.Owner)) { nearestOwnCity = Game.GetCities().Where(x => x.Owner == unit.Owner).Min(x => Common.DistanceToTile(x.X, x.Y, tile.X, tile.Y)); } if (validCity && nearestCity > 3) { GameTask.Enqueue(Orders.FoundCity(unit as Settlers)); return; } else if (nearestOwnCity < 3) { switch (Common.Random.Next(5 * nearestOwnCity)) { case 0: if (validRoad) { GameTask.Enqueue(Orders.BuildRoad(unit)); return; } break; case 1: if (validIrrigaton) { GameTask.Enqueue(Orders.BuildIrrigation(unit)); return; } break; case 2: if (validMine) { GameTask.Enqueue(Orders.BuildMines(unit)); return; } break; } } for (int i = 0; i < 1000; i++) { int relX = Common.Random.Next(-1, 2); int relY = Common.Random.Next(-1, 2); if (relX == 0 && relY == 0) { continue; } if (unit.Tile[relX, relY] is Ocean) { continue; } unit.MoveTo(relX, relY); return; } unit.SkipTurn(); return; } else if (unit is Militia || unit is Phalanx || unit is Musketeers || unit is Riflemen || unit is MechInf) { unit.Fortify = true; while (unit.Tile.City != null && unit.Tile.Units.Count(x => x is Militia || x is Phalanx || x is Musketeers || x is Riflemen || x is MechInf) > 2) { IUnit disband = null; IUnit[] units = unit.Tile.Units.Where(x => x != unit).ToArray(); if ((disband = unit.Tile.Units.FirstOrDefault(x => x is Militia)) != null) { Game.DisbandUnit(disband); continue; } if ((disband = unit.Tile.Units.FirstOrDefault(x => x is Phalanx)) != null) { Game.DisbandUnit(disband); continue; } if ((disband = unit.Tile.Units.FirstOrDefault(x => x is Musketeers)) != null) { Game.DisbandUnit(disband); continue; } if ((disband = unit.Tile.Units.FirstOrDefault(x => x is Riflemen)) != null) { Game.DisbandUnit(disband); continue; } if ((disband = unit.Tile.Units.FirstOrDefault(x => x is MechInf)) != null) { Game.DisbandUnit(disband); continue; } } } else { if (unit.Class != UnitClass.Land) { Game.DisbandUnit(unit); } for (int i = 0; i < 1000; i++) { int relX = Common.Random.Next(-1, 2); int relY = Common.Random.Next(-1, 2); if (relX == 0 && relY == 0) { continue; } if (unit.Tile[relX, relY] is Ocean) { continue; } unit.MoveTo(relX, relY); return; } unit.SkipTurn(); return; } }
private bool KeyDownActiveUnit(KeyboardEventArgs args) { if (Game.ActiveUnit == null || Game.ActiveUnit.Moving) { return(false); } switch (args.Key) { case Key.Space: Game.ActiveUnit.SkipTurn(); return(true); case Key.NumPad1: return(MoveTo(-1, 1)); case Key.NumPad2: case Key.Down: return(MoveTo(0, 1)); case Key.NumPad3: return(MoveTo(1, 1)); case Key.NumPad4: case Key.Left: return(MoveTo(-1, 0)); case Key.NumPad5: GameTask.Enqueue(Show.Empty); return(true); case Key.NumPad6: case Key.Right: return(MoveTo(1, 0)); case Key.NumPad7: return(MoveTo(-1, -1)); case Key.NumPad8: case Key.Up: return(MoveTo(0, -1)); case Key.NumPad9: return(MoveTo(1, -1)); } switch (args.KeyChar) { case 'B': GameTask.Enqueue(Orders.FoundCity(Game.ActiveUnit)); return(true); case 'C': if (Game.ActiveUnit == null) { break; } CenterOnUnit(); return(true); case 'D': if (!args.Shift) { break; } Game.DisbandUnit(Game.ActiveUnit); return(true); case 'H': Game.ActiveUnit.SetHome(); return(true); case 'I': GameTask.Enqueue(Orders.BuildIrrigation(Game.ActiveUnit)); return(true); case 'M': GameTask.Enqueue(Orders.BuildMines(Game.ActiveUnit)); break; case 'R': GameTask.Enqueue(Orders.BuildRoad(Game.ActiveUnit)); break; case 'S': Game.ActiveUnit.Sentry = true; break; case 'F': if (Game.ActiveUnit is Settlers) { GameTask.Enqueue(Orders.BuildFortress(Game.ActiveUnit)); break; } Game.ActiveUnit.Fortify = true; break; case 'U': if (Game.ActiveUnit is IBoardable) { return((Game.ActiveUnit as BaseUnitSea).Unload());; } break; case 'W': GameTask.Enqueue(Orders.Wait(Game.ActiveUnit)); break; } return(false); }