/// <summary> /// Calculates what damage a unit will receive from lasers at a given location. /// </summary> /// <param name="map">The game map.</param> /// <param name="location">Where the unit is located.</param> /// <returns>The amount of damage. Will be 0 or 1.</returns> public static int CalcLaserDamage(GameMap map, BoardLocation location) { int damage = 0; damage += _CalcLaserDamage(map, location.MapPosition, 0, -1, MapSquare.DIRECTION.SOUTH, MapSquare.SIDE.NORTH, MapSquare.SIDE.SOUTH); damage += _CalcLaserDamage(map, location.MapPosition, 0, 1, MapSquare.DIRECTION.NORTH, MapSquare.SIDE.SOUTH, MapSquare.SIDE.NORTH); damage += _CalcLaserDamage(map, location.MapPosition, -1, 0, MapSquare.DIRECTION.EAST, MapSquare.SIDE.WEST, MapSquare.SIDE.EAST); damage += _CalcLaserDamage(map, location.MapPosition, 1, 0, MapSquare.DIRECTION.WEST, MapSquare.SIDE.EAST, MapSquare.SIDE.WEST); return damage; }
/// <summary> /// Destination for a movement. Ignores all robots on the map but does take into account walls, conveyor belts and gears. Returns /// every step of the move. /// </summary> /// <param name="map">The game map.</param> /// <param name="startLocation">Where the unit starts.</param> /// <param name="cards">The cards to apply.</param> /// <returns>Every step of the move.</returns> public static List<MovePoint> CardPath(GameMap map, BoardLocation startLocation, IEnumerable<Card> cards) { // if we can't move, we end up where we started List<MovePoint> points = new List<MovePoint> {new MovePoint(startLocation)}; foreach (Card cardOn in cards) { // move robot MovePoint endLocation = Move(map, startLocation, cardOn.Move); if (endLocation.Dead) { points.Add(endLocation); return points; } if (! endLocation.Location.Equals(startLocation)) { startLocation = endLocation.Location; points.Add(new MovePoint(startLocation)); } // conveyor belt - may cause a 1/4 turn. MapSquare sq = map.GetSquare(startLocation.MapPosition); for (int speed=1; (sq.Conveyor != null) && (speed <= sq.Conveyor.Speed); speed++) { endLocation = Move(map, startLocation.MapPosition, sq.Conveyor.Direction); BoardLocation locMove = new BoardLocation(endLocation.Location.MapPosition, startLocation.Direction); sq = map.GetSquare(endLocation.Location.MapPosition); if (sq.Conveyor != null) { MapSquare.DIRECTION dirEnter = MoveDirection(startLocation.MapPosition, endLocation.Location.MapPosition); locMove = locMove.Rotate((int)sq.Conveyor.Direction - (int)dirEnter); } startLocation = locMove; points.Add(new MovePoint(startLocation)); } // gears if (sq.Type == MapSquare.TYPE.ROTATE_CLOCKWISE) { startLocation = startLocation.Rotate(1); points.Add(new MovePoint(startLocation)); } if (sq.Type == MapSquare.TYPE.ROTATE_COUNTERCLOCKWISE) { startLocation = startLocation.Rotate(-1); points.Add(new MovePoint(startLocation)); } // damage int damage = CalcLaserDamage(map, startLocation); if (damage != 0) points[points.Count - 1].Damage = damage; } return points; }
/// <summary> /// Destination for a movement. Ignores all robots on the map but does take into account walls, conveyor belts and gears. Returns /// the final location of the move. /// </summary> /// <param name="map">The game map.</param> /// <param name="startLocation">Where the unit starts.</param> /// <param name="cards">The cards to apply.</param> /// <returns>The final location of the move.</returns> public static MovePoint CardDestination(GameMap map, BoardLocation startLocation, IEnumerable<Card> cards) { List<MovePoint> points = CardPath(map, startLocation, cards); if ((points == null) || (points.Count == 0)) { Trap.trap(); return null; } return points[points.Count - 1]; }
/// <summary> /// Destination for a movement. Ignores all robots on the map but does take into account walls, conveyor belts and gears. Returns /// the final location of the move. /// </summary> /// <param name="map">The game map.</param> /// <param name="startLocation">Where the unit starts.</param> /// <param name="cards">The cards to apply.</param> /// <returns>The final location of the move.</returns> public static MovePoint CardDestination(GameMap map, BoardLocation startLocation, Card[] cards) { MovePoint[] points = CardPath(map, startLocation, cards); if ((points == null) || (points.Length == 0)) { Trap.trap(); return null; } return points[points.Length - 1]; }
/// <summary> /// Create a new Robot object. /// </summary> /// <param name="location">The unit is at this location on the map.</param> /// <param name="bitmap">The bitmaps for this robot facing. Index using DIRECTION.</param> public Robot(BoardLocation location, Bitmap bitmap) : base(location) { Bitmaps = new Bitmap[4]; Bitmaps[(int)MapSquare.DIRECTION.NORTH] = bitmap; Bitmaps[(int)MapSquare.DIRECTION.EAST] = new Bitmap(bitmap); Bitmaps[(int)MapSquare.DIRECTION.EAST].RotateFlip(RotateFlipType.Rotate90FlipNone); Bitmaps[(int)MapSquare.DIRECTION.SOUTH] = new Bitmap(bitmap); Bitmaps[(int)MapSquare.DIRECTION.SOUTH].RotateFlip(RotateFlipType.Rotate180FlipNone); Bitmaps[(int)MapSquare.DIRECTION.WEST] = new Bitmap(bitmap); Bitmaps[(int)MapSquare.DIRECTION.WEST].RotateFlip(RotateFlipType.Rotate270FlipNone); }
/// <summary> /// Create the object. /// </summary> /// <param name="location">The unit is at this location on the map.</param> protected CombatUnit(BoardLocation location) { Location = location; }
/// <summary> /// Create the object. No damage. /// </summary> /// <param name="location">The location of the move result.</param> /// <param name="dead">true if the move caused death.</param> public MovePoint(BoardLocation location, bool dead) { Location = location; Dead = dead; }
/// <summary> /// Create the object. Not dead. /// </summary> /// <param name="location">The location of the move result.</param> /// <param name="damage">The damage level from this move.</param> public MovePoint(BoardLocation location, int damage) { Location = location; Damage = damage; }
/// <summary> /// Create the object. No damage and not dead. /// </summary> /// <param name="location">The location of the move result.</param> public MovePoint(BoardLocation location) { Location = location; Damage = 0; Dead = false; }
/// <summary> /// Move a unit one square in the requested direction. Ignores all robots on the map but does take into account walls, conveyor belts and gears. /// </summary> /// <param name="map">The game map.</param> /// <param name="position">The map square to start the move from.</param> /// <param name="direction">The direction to move.</param> /// <returns>The final location of the move.</returns> public static MovePoint Move(GameMap map, Point position, MapSquare.DIRECTION direction) { // watch for wall in this direction MapSquare.SIDE sideExit = sideMoveOut[(int) direction]; MapSquare.SIDE sideEnter = sideMoveIn[(int) direction]; BoardLocation location = new BoardLocation(position, direction); // can we exit this square? MapSquare sq = map.GetSquare(position); if ((sq.Walls & sideExit) != 0) return new MovePoint(location); BoardLocation moveTo = location.Move(1); // did we go off the board? if ((moveTo.MapPosition.X < 0) || (map.Width <= moveTo.MapPosition.X) || (moveTo.MapPosition.Y < 0) || (map.Height <= moveTo.MapPosition.Y)) return new MovePoint(location, true); // did we go into a pit? if (map.GetSquare(moveTo.MapPosition).Type == MapSquare.TYPE.PIT) return new MovePoint(moveTo, true); // can we enter the new square? sq = map.GetSquare(moveTo.MapPosition); if ((sq.Walls & sideEnter) != 0) return new MovePoint(location); return new MovePoint(moveTo); }
/// <summary> /// Move a unit one card move. Ignores all robots on the map but does take into account walls, conveyor belts and gears. /// </summary> /// <param name="map">The game map.</param> /// <param name="startLocation">Where the unit starts.</param> /// <param name="move">The move to apply.</param> /// <returns>The final location of the move.</returns> public static MovePoint Move(GameMap map, BoardLocation startLocation, Card.ROBOT_MOVE move) { int steps = 0; switch (move) { case Card.ROBOT_MOVE.BACKWARD_ONE: steps = -1; break; case Card.ROBOT_MOVE.FORWARD_ONE: steps = 1; break; case Card.ROBOT_MOVE.FORWARD_TWO: steps = 2; break; case Card.ROBOT_MOVE.FORWARD_THREE: steps = 3; break; case Card.ROBOT_MOVE.ROTATE_LEFT: return new MovePoint(startLocation.Rotate(-1)); case Card.ROBOT_MOVE.ROTATE_RIGHT: return new MovePoint(startLocation.Rotate(1)); case Card.ROBOT_MOVE.ROTATE_UTURN: return new MovePoint(startLocation.Rotate(2)); } MapSquare.DIRECTION dir = steps >= 0 ? startLocation.Direction : startLocation.Rotate(2).Direction; Point position = startLocation.MapPosition; while (steps != 0) { MovePoint mp = Move(map, position, dir); if (mp.Dead) return new MovePoint(new BoardLocation(mp.Location.MapPosition, startLocation.Direction), true); position = mp.Location.MapPosition; int singleStep = Math.Max(-1, Math.Min(1, steps)); steps -= singleStep; } return new MovePoint(new BoardLocation(position, startLocation.Direction)); }
/// <summary> /// Create a new laser object. /// </summary> /// <param name="location">The unit is at this location on the map.</param> /// <param name="numSquares">The number of squares the laser shoots over, including the one it is on. (The Laser is ended by a wall.)</param> public Laser(BoardLocation location, int numSquares) : base(location) { NumSquares = numSquares; }
/// <summary> /// Copy constructor. /// </summary> /// <param name="src">Initialize with the values in this struct.</param> public BoardLocation(BoardLocation src) { _mapPosition = src.MapPosition; _direction = src.Direction; }
private bool FireLaser(BoardLocation location, Player firingPlayer) { LaserMove lm = laserMove[(int) location.Direction]; int x = location.MapPosition.X; int y = location.MapPosition.Y; bool firstSquare = true; bool fired = false; while ((0 <= x) && (x < MainMap.Width) && (0 <= y) && (y < MainMap.Height)) { MapSquare sq = MainMap.Squares[x][y]; // can we move into this square? if ((!firstSquare) && ((sq.Walls & lm.wallEnter) != 0)) break; // robot to hit? (can be us if isLaser is true) Point pt = new Point(x, y); Player plyrTargetRobot = Players.Where(pl => (pl.IsVisible) && (pl.Robot.Location.MapPosition == pt)).FirstOrDefault(); if ((plyrTargetRobot != null) && ((firingPlayer == null) || (!firstSquare))) { // call this before IncreaseDamage because if it's killed it is moved to -1, -1 Explosion expl = new Explosion(framework.frameTicks, plyrTargetRobot.Robot.Location.MapPosition); framework.sprites.Add(expl); framework.laserBeams.Add(new LaserBeam(location.MapPosition, plyrTargetRobot.Robot.Location.MapPosition, firingPlayer == null)); plyrTargetRobot.IncreaseDamage(); fired = true; if (firingPlayer != null) firingPlayer.Score += 1; Trace.WriteLine(string.Format(" laser - Player: {0} at {1} hit by laser at {2}, damage {3}, lives {4}", plyrTargetRobot.Name, plyrTargetRobot.Robot.Location, location, plyrTargetRobot.Damage, plyrTargetRobot.Lives)); if (plyrTargetRobot.Mode == Player.MODE.DEAD) framework.mainWindow.StatusMessage(string.Format("Player {0} has been killed", plyrTargetRobot.Name)); ValidateData(); break; } // can we move out of this square? if ((sq.Walls & lm.wallExit) != 0) break; x += lm.xAdd; y += lm.yAdd; firstSquare = false; } return fired; }
// board (conveyor and gear) movement. private void ExecuteMoveBoard() { Trace.WriteLine("Conveyor and gear moves:"); // We move if the dest is a conveyor or it's unoccupied. // bugbug - The unoccupied test works for the one map we have - the one conveyor exit square has a wall after it. List<Player> plyrMoveBelt = Players.Where(playerInternal => playerInternal.IsVisible).ToList(); for (int level = 2; level > 0; level--) foreach (Player plyrOn in plyrMoveBelt) { // needs to be on a belt - and we do the 2 move, then all MapSquare sq = MainMap.GetSquare(plyrOn.Robot.Location.MapPosition); if ((sq.Conveyor == null) || (sq.Conveyor.Speed < level)) continue; Utilities.MovePoint mp = Utilities.Move(MainMap, plyrOn.Robot.Location.MapPosition, sq.Conveyor.Direction); MapSquare sqDest = MainMap.GetSquare(mp.Location.MapPosition); if (sqDest.Type == MapSquare.TYPE.CONVEYOR_BELT) { // the turn is based on the direction entered and the exit direction MapSquare.DIRECTION dirEnter = Utilities.MoveDirection(plyrOn.Robot.Location.MapPosition, mp.Location.MapPosition); BoardLocation dest = new BoardLocation(mp.Location.MapPosition, plyrOn.Robot.Location.Direction); dest = dest.Rotate((int)sqDest.Conveyor.Direction - (int)dirEnter); Trace.WriteLine(string.Format(" conveyor - Player: {0} at {1} moved to {2}", plyrOn.Name, plyrOn.Robot.Location, dest)); plyrOn.Robot.Location = dest; continue; } // we're going off the belt Player plyrDestRobot = Players.Where(pl => (pl.IsVisible) && (pl.Robot.Location.MapPosition == mp.Location.MapPosition)).FirstOrDefault(); if (plyrDestRobot != null) { Trace.WriteLine(string.Format(" conveyor - Player: {0} at {1} cannot be moved", plyrOn.Name, plyrOn.Robot.Location)); continue; } BoardLocation location = new BoardLocation(mp.Location.MapPosition, plyrOn.Robot.Location.Direction); Trace.WriteLine(string.Format(" conveyor - Player: {0} at {1} moved off the belt to {2}", plyrOn.Name, plyrOn.Robot.Location, location)); Trap.trap(location.Direction != plyrOn.Robot.Location.Direction); plyrOn.Robot.Location = location; } // have to validate after because we move on top of each other handling the conveyor belt ValidateData(); List<Player> plyrMoveGears = (from plyrOn in Players where plyrOn.IsVisible let sq = MainMap.GetSquare(plyrOn.Robot.Location.MapPosition) where ((sq.Type == MapSquare.TYPE.ROTATE_CLOCKWISE) || (sq.Type == MapSquare.TYPE.ROTATE_COUNTERCLOCKWISE)) select plyrOn).ToList(); foreach (Player plyrOn in plyrMoveGears) { MapSquare sq = MainMap.GetSquare(plyrOn.Robot.Location.MapPosition); plyrOn.Robot.Location = plyrOn.Robot.Location.Rotate(sq.Type == MapSquare.TYPE.ROTATE_CLOCKWISE ? 1 : -1); Trace.WriteLine(string.Format(" gear - Player: {0} turned to {1}", plyrOn.Name, plyrOn.Robot.Location)); ValidateData(); } }
public void PlayerSetArchive(Player player, BoardLocation location) { player.Robot.Location = location; if (!Players.Any(pl => pl.Robot.Location.IsNull && pl.TcpGuid != null)) phaseOn = PHASE.GET_TURN; }