/// <summary> /// Return 1 if next to a monster /// </summary> /// <returns></returns> private bool IsMonster(int directionX, int directionY) { Dungeon dungeon = Game.Dungeon; Player player = Game.Dungeon.Player; int squareX = player.LocationMap.x + directionX; int squareY = player.LocationMap.y + directionY; Map thisMap = dungeon.Levels[player.LocationLevel]; if (squareX < 0 || squareX >= thisMap.width || squareY < 0 || squareY >= thisMap.height) { return(false); } SquareContents squareContents = dungeon.MapSquareContents(player.LocationLevel, new Point(squareX, squareY)); if (squareContents.monster != null && !squareContents.monster.Charmed) { return(true); } else { return(false); } }
internal static BoardState SetPiece(BoardState state, ulong bitSquare, SquareContents contents) { var bitContents = (ulong)contents; ulong white = state.WhitePieces; ulong black = state.BlackPieces; ulong pawns = state.Pawns; ulong rooks = state.Rooks; ulong knights = state.Knights; ulong bishops = state.Bishops; ulong queens = state.Queens; ulong kings = state.Kings; if ((bitContents & (int)SquareContents.White) != 0) { white |= bitSquare; } else if ((bitContents & (int)SquareContents.Black) != 0) { black |= bitSquare; } if ((bitContents & (int)SquareContents.Pawn) != 0) { pawns |= bitSquare; } else if ((bitContents & (int)SquareContents.Knight) != 0) { knights |= bitSquare; } else if ((bitContents & (int)SquareContents.Bishop) != 0) { bishops |= bitSquare; } else if ((bitContents & (int)SquareContents.Rook) != 0) { rooks |= bitSquare; } else if ((bitContents & (int)SquareContents.Queen) != 0) { queens |= bitSquare; } else if ((bitContents & (int)SquareContents.King) != 0) { kings |= bitSquare; } return(new BoardState( white, black, pawns, knights, bishops, rooks, queens, kings )); }
public Move(char startFile, int startRank, char endFile, int endRank, SquareContents promotedPiece) { StartFile = startFile; StartRank = startRank; EndFile = endFile; EndRank = endRank; PromotedPiece = promotedPiece; }
public void GeneratesExpectedSquares_MatchesCount(string sq, SquareContents piece, int expectedSquares) { var square = MoveParser.ParseSquare(sq); ulong bitSquare = BitTranslator.TranslateToBit(square.File, square.Rank); var board = BoardState.Empty.SetPiece(bitSquare, piece); var game = new Game(board); var validMoves = game.GetValidMoves(square.File, square.Rank); Assert.That(validMoves.Count, Is.EqualTo(expectedSquares)); }
/// <summary> /// Fires the item - probably should be a method /// </summary> /// <param name="target"></param> /// <param name="enemyTarget"></param> /// <returns></returns> public bool FireItem(Point target) { //Should be guaranteed in range by caller Player player = Game.Dungeon.Player; Dungeon dungeon = Game.Dungeon; LogFile.Log.LogEntryDebug("Firing heavy laser", LogDebugLevel.Medium); //The shotgun fires towards its target and does same damage with range //Get all squares in range and within FOV (shotgun needs a straight line route to fire) //Calculate a huge FOV Point projectedLine = Game.Dungeon.GetEndOfLine(player.LocationMap, target, player.LocationLevel); WrappedFOV currentFOV2 = Game.Dungeon.CalculateAbstractFOV(Game.Dungeon.Player.LocationLevel, Game.Dungeon.Player.LocationMap, 80); List <Point> targetSquares = Game.Dungeon.GetPathLinePointsInFOV(Game.Dungeon.Player.LocationLevel, Game.Dungeon.Player.LocationMap, projectedLine, currentFOV2); //Draw attack Screen.Instance.DrawAreaAttackAnimation(targetSquares, ColorPresets.Magenta); //Make firing sound Game.Dungeon.AddSoundEffect(FireSoundMagnitude(), player.LocationLevel, player.LocationMap); //Attack all monsters in the area foreach (Point sq in targetSquares) { SquareContents squareContents = dungeon.MapSquareContents(player.LocationLevel, sq); Monster m = squareContents.monster; //Hit the monster if it's there if (m != null) { int damage = 150; string combatResultsMsg = "PvM (" + m.Representation + ") Laser: Dam: " + damage; LogFile.Log.LogEntryDebug(combatResultsMsg, LogDebugLevel.Medium); //Apply damage player.AttackMonsterRanged(squareContents.monster, damage); } } //Remove 1 ammo Ammo--; return(true); }
public void GeneratesExpectedSquares_OmitsUnexpected(string sq, SquareContents piece, string expectedSquares) { var expected = expectedSquares.Split(',').Select(MoveParser.ParseSquare).ToArray(); var square = MoveParser.ParseSquare(sq); ulong bitSquare = BitTranslator.TranslateToBit(square.File, square.Rank); var board = BoardState.Empty.SetPiece(bitSquare, piece); var game = new Game(board); var validMoves = game.GetValidMoves(square.File, square.Rank).ToArray(); Assert.That(validMoves, Does.Not.Contain(expected[0])); }
public override bool DoSpell(Point target) { Player player = Game.Dungeon.Player; Dungeon dungeon = Game.Dungeon; //Check the target is within FOV //Get the FOV from Dungeon (this also updates the map creature FOV state) CreatureFOV currentFOV = Game.Dungeon.CalculateCreatureFOV(player); //Is the target in FOV if (!currentFOV.CheckTileFOV(target.x, target.y)) { LogFile.Log.LogEntryDebug("Target out of FOV", LogDebugLevel.Medium); Game.MessageQueue.AddMessage("Target is out of sight."); return(false); } //Check there is a monster at target SquareContents squareContents = dungeon.MapSquareContents(player.LocationLevel, target); //Is there no monster here? If so, then slow it if (squareContents.monster != null) { Monster targetM = squareContents.monster; LogFile.Log.LogEntryDebug("Slowing " + targetM.SingleDescription, LogDebugLevel.Medium); Game.MessageQueue.AddMessage("Slow Monster!"); //Check magic resistance bool monsterResisted = CheckMagicResistance(targetM); if (monsterResisted) { return(true); } //Add the slow monster effect int duration = 5 * Creature.turnTicks + Game.Random.Next(10 * Creature.turnTicks); targetM.AddEffect(new MonsterEffects.SlowDown(duration, targetM.Speed / 2)); return(true); } Game.MessageQueue.AddMessage("No target for slow monster."); LogFile.Log.LogEntryDebug("No monster to target for Slow Monster", LogDebugLevel.Medium); return(false); }
/// <summary> /// Updates the board square /// </summary> /// <param name="mouse">the current mouse state</param> /// <returns>true if the player placed an X, false otherwise</returns> public bool Update(MouseState mouse) { // STUDENTS: IF THE MOUSE IS OVER THE SQUARE, THE LEFT MOUSE BUTTON IS PRESSED // AND THE SQUARE CONTENTS IS EMPTY CHANGE THE CONTENTS TO HOLD AN X AND RETURN true. // OTHERWISE, RETURN false if (mouse.LeftButton == ButtonState.Pressed && contents == SquareContents.Empty && drawRectangle.Contains(mouse.X, mouse.Y)) { contents = SquareContents.X; return(true); } else { return(false); } }
public void PlacesPieceOnIntendedSquare(string focusSquare, SquareContents expectedContents, params string[] moveStrings) { var game = new Game(); foreach (var moveString in moveStrings) { var result = game.Move(moveString); Assert.That(result, Is.EqualTo(ErrorCondition.None), "Failed for move: " + moveString); } var targetSquare = MoveParser.ParseSquare(focusSquare); var actualContents = game.GetSquareContents(targetSquare.File, targetSquare.Rank); Assert.That(actualContents, Is.EqualTo(expectedContents)); }
/// <summary> /// Updates the board square /// </summary> /// <param name="mouse">the current mouse state</param> /// <returns>true if the player placed an X, false otherwise</returns> public bool Update(MouseState mouse) { // STUDENTS: IF THE MOUSE IS OVER THE SQUARE, THE LEFT MOUSE BUTTON IS PRESSED // AND THE SQUARE CONTENTS IS EMPTY CHANGE THE CONTENTS TO HOLD AN X AND RETURN true. // OTHERWISE, RETURN false if (drawRectangle.Contains(mouse.X, mouse.Y) && this.Empty && mouse.LeftButton == ButtonState.Pressed) { contents = SquareContents.X; return(true); } else { return(false); } // STUDENTS: REMOVE THE LINE BELOW AFTER UNCOMMENTING AND COMPLETING THE CODE ABOVE //return false; }
public override bool CheckAction(bool isMove, Point deltaMove, bool otherMoveSuccess) { Player player = Game.Dungeon.Player; Dungeon dungeon = Game.Dungeon; //First move is no direction move //Not a move or attack = reset if (!isMove) { moveCounter = 0; return(false); } //First move if (moveCounter == 0) { //Must be no direction if (deltaMove != new Point(0, 0)) { return(false); } //Otherwise we're on moveCounter = 1; LogFile.Log.LogEntryDebug("Burst of Speed started", LogDebugLevel.Medium); return(true); } //Second move if (moveCounter == 1) { //Must be no direction if (deltaMove != new Point(0, 0)) { moveCounter = 0; LogFile.Log.LogEntryDebug("Burst of Speed failed, move on 2", LogDebugLevel.Medium); return(false); } //Otherwise we're on moveCounter = 2; LogFile.Log.LogEntryDebug("Burst of Speed 2", LogDebugLevel.Medium); return(true); } //Second move //Any direction. We skip up to 3 squares unless we get blocked if (moveCounter == 2) { int secondXDelta = deltaMove.x; int secondYDelta = deltaMove.y; Map thisMap = dungeon.Levels[player.LocationLevel]; //We run forward until we find a square to jump to //If we run off the map or can't find a good square, we abort and the move is cancelled int loopCounter = 1; //Worst case we stay where we are squareToMoveTo = player.LocationMap; do { int squareX = player.LocationMap.x + secondXDelta * loopCounter; int squareY = player.LocationMap.y + secondYDelta * loopCounter; //Off the map if (squareX < 0 || squareX > thisMap.width) { break; } if (squareY < 0 || squareY > thisMap.height) { break; } MapTerrain squareTerrain = thisMap.mapSquares[squareX, squareY].Terrain; SquareContents squareContents = dungeon.MapSquareContents(player.LocationLevel, new Point(squareX, squareY)); //Into a wall if (!thisMap.mapSquares[squareX, squareY].Walkable) { break; } //Is there no monster here? If so, then OK square to jump to if (squareContents.monster != null) { break; } //Empty, set this as OK and carry on looping squareToMoveTo = new Point(squareX, squareY); loopCounter++; } while (loopCounter < 3); //Check the status of the evade if (squareToMoveTo == player.LocationMap) { FailBlocked(); return(false); } //Otherwise we are on and will move in DoMove moveCounter = 3; return(true); } LogFile.Log.LogEntryDebug("Burst of speed: moveCounter wrong", LogDebugLevel.Medium); return(false); }
public override bool CheckAction(bool isMove, Point deltaMove, bool otherMoveSuccess) { Player player = Game.Dungeon.Player; Dungeon dungeon = Game.Dungeon; //Not a move or attack = reset if (!isMove) { moveCounter = 0; return(false); } //First move /* * if (moveCounter == 0) * { * //Must be no direction * if (Game.Dungeon.Player.LocationMap != locationAfterMove) * { * return false; * } * * //Otherwise we're on * moveCounter = 1; * LogFile.Log.LogEntryDebug("Charge started", LogDebugLevel.Medium); * * return true; * }*/ //Second move //Any direction without a monster. Subsequent moves needs to be in the same direction Point locationAfterMove = player.LocationMap + deltaMove; if (moveCounter == 0) { //Needs to be no monster in the direction of movement SquareContents squareContents = dungeon.MapSquareContents(player.LocationLevel, locationAfterMove); //Bad terrain if (!dungeon.MapSquareIsWalkable(player.LocationLevel, locationAfterMove)) { FailBlocked(); return(false); } //Monster if (squareContents.monster != null) { FailBlockingMonster(); return(false); } xDelta = locationAfterMove.x - player.LocationMap.x; yDelta = locationAfterMove.y - player.LocationMap.y; if (xDelta == 0 && yDelta == 0) { FailWrongDirection(); return(false); } moveCounter++; LogFile.Log.LogEntryDebug("Charge started", LogDebugLevel.Medium); LogFile.Log.LogEntryDebug("Charge move: " + moveCounter, LogDebugLevel.Medium); return(true); } //Later moves //if(moveCounter > 1) { else { //Needs to be no monster in the direction of movement SquareContents squareContents = dungeon.MapSquareContents(player.LocationLevel, locationAfterMove); int thisxDelta = locationAfterMove.x - player.LocationMap.x; int thisyDelta = locationAfterMove.y - player.LocationMap.y; //Different direction if (thisxDelta != xDelta || thisyDelta != yDelta) { FailWrongDirection(); return(false); } //Bad terrain if (!dungeon.MapSquareIsWalkable(player.LocationLevel, locationAfterMove)) { FailBlocked(); return(false); } //Monster - move is on if (squareContents.monster != null) { //If it's a charmed monster don't attack if (squareContents.monster.Charmed) { FailBlockingMonster(); return(false); } moveReady = true; target = squareContents.monster; return(true); } //Otherwise keep charging moveCounter++; LogFile.Log.LogEntryDebug("Charge move: " + moveCounter, LogDebugLevel.Medium); return(true); } }
/// <summary> /// Updates the board square /// </summary> /// <param name="mouse">the current mouse state</param> /// <returns>true if the player placed an X, false otherwise</returns> public bool Update(MouseState mouse) { // STUDENTS: IF THE MOUSE IS OVER THE SQUARE, THE LEFT MOUSE BUTTON IS PRESSED // AND THE SQUARE CONTENTS IS EMPTY CHANGE THE CONTENTS TO HOLD AN X AND RETURN true. // OTHERWISE, RETURN false if (drawRectangle.Contains(mouse.X, mouse.Y) && mouse.LeftButton == ButtonState.Pressed && contents == SquareContents.Empty) { contents = SquareContents.X; return true; } else { return false; } // STUDENTS: REMOVE THE LINE BELOW AFTER UNCOMMENTING AND COMPLETING THE CODE ABOVE }
public override bool DoSpell(Point target) { Player player = Game.Dungeon.Player; Dungeon dungeon = Game.Dungeon; //Find a nearby location in the dungeon Map thisMap = dungeon.Levels[player.LocationLevel]; bool endLoop = false; int loopCount = 0; int x, y; spellRange = 5 + player.MagicStat / 30; do { loopCount++; //Random location in dungeon x = Game.Random.Next(thisMap.width); y = Game.Random.Next(thisMap.height); //Within range? if (!(Math.Pow(x - player.LocationMap.x, 2) + Math.Pow(y - player.LocationMap.y, 2) < Math.Pow(spellRange, 2))) { continue; } //Not too near - better just to run from the outside in but live with this for now if (!(Math.Pow(x - player.LocationMap.x, 2) + Math.Pow(y - player.LocationMap.y, 2) > 3)) { continue; } //Walkable if (!dungeon.MapSquareIsWalkable(player.LocationLevel, new Point(x, y))) { continue; } //Empty SquareContents sq = dungeon.MapSquareContents(player.LocationLevel, new Point(x, y)); if (!sq.empty) { continue; } //Otherwise OK endLoop = true; } while(!endLoop && loopCount < 1000); //Sanity check if (loopCount == 1000) { LogFile.Log.LogEntryDebug("Failed to find a place to blink to", LogDebugLevel.High); Game.MessageQueue.AddMessage("You feel rooted to the spot."); return(false); } //Otherwise move there Game.MessageQueue.AddMessage("Blink! The world shifts momentarily."); dungeon.MovePCAbsoluteSameLevel(new Point(x, y)); return(true); }
public override bool CheckAction(bool isMove, Point deltaMove, bool otherMoveSuccess) { Player player = Game.Dungeon.Player; Dungeon dungeon = Game.Dungeon; //First move is no direction move //Not a move or attack = reset if (!isMove) { moveCounter = 0; return(false); } //First move if (moveCounter == 0) { //Must be no direction if (deltaMove != new Point(0, 0)) { return(false); } //Must be next to a monster int isMonster = 0; if (IsMonster(-1, -1)) { isMonster++; } if (IsMonster(-1, 0)) { isMonster++; } if (IsMonster(-1, 1)) { isMonster++; } if (IsMonster(0, -1)) { isMonster++; } if (IsMonster(0, 1)) { isMonster++; } if (IsMonster(1, -1)) { isMonster++; } if (IsMonster(1, 0)) { isMonster++; } if (IsMonster(1, 1)) { isMonster++; } if (isMonster == 0) { LogFile.Log.LogEntryDebug("Evade not started - no monster", LogDebugLevel.Medium); return(false); } //Otherwise we're on moveCounter = 1; LogFile.Log.LogEntryDebug("Evade started", LogDebugLevel.Medium); return(true); } //Second move //Any direction with a monster. We skip past it and then one more square in that direction if we can if (moveCounter == 1) { //Needs to be a monster in the direction of movement Point locationAfterMove = player.LocationMap + deltaMove; SquareContents squareContents = dungeon.MapSquareContents(player.LocationLevel, locationAfterMove); //Bad terrain if (!dungeon.MapSquareIsWalkable(player.LocationLevel, locationAfterMove)) { FailBlocked(); return(false); } //No Monster if (squareContents.monster == null) { FailNoMonster(); return(false); } //Charmed monster if (squareContents.monster != null && squareContents.monster.Charmed) { FailNoMonster(); return(false); } //OK, so we have a monster to evade //Check the 2 squares behind it to find one to jump to (adapted from WallVault) int secondXDelta = locationAfterMove.x - player.LocationMap.x; int secondYDelta = locationAfterMove.y - player.LocationMap.y; Map thisMap = dungeon.Levels[player.LocationLevel]; //We run forward until we find a square to jump to //If we run off the map or can't find a good square, we abort and the move is cancelled //Try to jump max of 2 squares, or fall back to one //Start square after monster int loopCounter = 2; //It's not possible to evade 2 monsters in a row, so worse case we stay where we are squareToMoveTo = player.LocationMap; do { int squareX = player.LocationMap.x + secondXDelta * loopCounter; int squareY = player.LocationMap.y + secondYDelta * loopCounter; //Off the map if (squareX < 0 || squareX > thisMap.width) { break; } if (squareY < 0 || squareY > thisMap.height) { break; } MapTerrain squareTerrain = thisMap.mapSquares[squareX, squareY].Terrain; squareContents = dungeon.MapSquareContents(player.LocationLevel, new Point(squareX, squareY)); //Into a wall if (!thisMap.mapSquares[squareX, squareY].Walkable) { break; } //Is there no monster here? If so, then OK square to jump to if (squareContents.monster != null) { break; } //Empty, set this as OK and carry on looping squareToMoveTo = new Point(squareX, squareY); loopCounter++; } while (loopCounter < 4); //Check the status of the evade if (squareToMoveTo == player.LocationMap) { FailBlocked(); return(false); } //Otherwise we are on and will move in DoMove moveCounter = 2; } return(true); }
public override bool DoSpell(Point target) { Player player = Game.Dungeon.Player; Dungeon dungeon = Game.Dungeon; //Check the target is within FOV //Get the FOV from Dungeon (this also updates the map creature FOV state) CreatureFOV currentFOV = Game.Dungeon.CalculateCreatureFOV(player); //Is the target in FOV if (!currentFOV.CheckTileFOV(target.x, target.y)) { LogFile.Log.LogEntryDebug("Target out of FOV", LogDebugLevel.Medium); Game.MessageQueue.AddMessage("Target is out of sight."); return(false); } //Check there is a monster at target SquareContents squareContents = dungeon.MapSquareContents(player.LocationLevel, target); //Is there no monster here? If so, then attack it if (squareContents.monster != null) { LogFile.Log.LogEntryDebug("Firing magic missile", LogDebugLevel.Medium); Game.MessageQueue.AddMessage("Magic Missile!"); Monster monster = squareContents.monster; //Check magic resistance bool monsterResisted = CheckMagicResistance(squareContents.monster); //Draw attack CombatResults results = CombatResults.DefenderDamaged; if (monsterResisted) { results = CombatResults.DefenderUnhurt; } Screen.Instance.DrawMissileAttack(player, monster, results, ColorPresets.Violet); //If monster resisted no damage if (monsterResisted) { return(true); } //Damage base int damageBase; if (player.MagicStat > 120) { damageBase = 8; } else if (player.MagicStat > 60) { damageBase = 6; } else if (player.MagicStat > 30) { damageBase = 5; } else { damageBase = 4; } //Damage done is just the base int damage = Utility.DamageRoll(damageBase); string combatResultsMsg = "PvM Magic Missile: Dam: 1d" + damageBase + " -> " + damage; LogFile.Log.LogEntryDebug(combatResultsMsg, LogDebugLevel.Medium); //Apply damage player.ApplyDamageToMonster(squareContents.monster, damage, true, false); //Graphical effect /* * TCODLineDrawing.InitLine(player.LocationMap.x, player.LocationMap.y, target.x, target.y); * int firstXStep = 0; * int firstYStep = 0; * * TCODLineDrawing.StepLine(ref firstXStep, ref firstYStep);*/ return(true); } Game.MessageQueue.AddMessage("No target for magic missile."); LogFile.Log.LogEntryDebug("No monster to target for Magic Missile", LogDebugLevel.Medium); return(false); }
/// <summary> /// Updates the board square /// </summary> /// <param name="mouse">the current mouse state</param> /// <returns>true if the player placed an X, false otherwise</returns> public bool Update(MouseState mouse) { // STUDENTS: IF THE MOUSE IS OVER THE SQUARE, THE LEFT MOUSE BUTTON IS PRESSED // AND THE SQUARE CONTENTS IS EMPTY CHANGE THE CONTENTS TO HOLD AN X AND RETURN true. // OTHERWISE, RETURN false if ((drawRectangle.Contains(mouse.X, mouse.Y)) && (mouse.LeftButton == ButtonState.Pressed) && (contents == SquareContents.Empty)) { Console.WriteLine("Clicked"); contents = SquareContents.X; return true; } else { return false; } }
public BoardState SetPiece(ulong bitSquare, SquareContents contents) { return(BoardStateMutator.SetPiece(this, bitSquare, contents)); }
public void TryParseMove_ParsesPromotion(string input, string expectedStart, string expectedEnd, PieceColor color, SquareContents piece) { var endSq = MoveParser.ParseSquare(expectedEnd); var startSq = MoveParser.ParseSquare(expectedStart); var pieceColor = color == PieceColor.White ? SquareContents.White : SquareContents.Black; var board = BoardState.Empty.SetPiece(startSq, SquareContents.Pawn | pieceColor); var game = new Game(board, color); var result = game.Move(input); var expectedSquare = game.GetSquareContents(endSq.File, endSq.Rank); Assert.That(result, Is.EqualTo(ErrorCondition.None)); Assert.That(expectedSquare, Is.EqualTo(piece)); }
public override bool CheckAction(bool isMove, Point deltaMove, bool otherMoveSuccess) { Player player = Game.Dungeon.Player; Dungeon dungeon = Game.Dungeon; //First move is pushing off against a wall //Second move is jumping over 0 or more creatures Point locationAfterMove = player.LocationMap + deltaMove; //Not a move or attack = reset if (!isMove) { moveCounter = 0; return(false); } //First move if (moveCounter == 0) { //Must be non-walkable to push off bool pushTerrainWalkable = dungeon.Levels[player.LocationLevel].mapSquares[locationAfterMove.x, locationAfterMove.y].Walkable; if (pushTerrainWalkable) { moveCounter = 0; return(false); } //Is wall //Success moveCounter = 1; //Need to remember the direction of the first push, since we can only vault opposite this xDelta = locationAfterMove.x - player.LocationMap.x; yDelta = locationAfterMove.y - player.LocationMap.y; LogFile.Log.LogEntryDebug("Vault backstab stage 1", LogDebugLevel.Medium); return(true); } //Second move if (moveCounter == 1) { //Only implementing this for player for now! //Check that this direction opposes the initial push int secondXDelta = locationAfterMove.x - player.LocationMap.x; int secondYDelta = locationAfterMove.y - player.LocationMap.y; if (secondXDelta != -xDelta || secondYDelta != -yDelta) { //Reset moveCounter = 0; return(false); } //OK, going in right direction //Need to check what's ahead of the player //Empty squares, can jump 2 Map thisMap = dungeon.Levels[player.LocationLevel]; //We run forward until we find a square to jump to //If we run off the map or can't find a good square, we abort and the move is cancelled //First empty square int loopCounter = 1; do { int squareX = player.LocationMap.x + secondXDelta * loopCounter; int squareY = player.LocationMap.y + secondYDelta * loopCounter; //Off the map if (squareX < 0 || squareX > thisMap.width) { NoWhereToJumpFail(); return(false); } if (squareY < 0 || squareY > thisMap.height) { NoWhereToJumpFail(); return(false); } MapTerrain squareTerrain = thisMap.mapSquares[squareX, squareY].Terrain; SquareContents squareContents = dungeon.MapSquareContents(player.LocationLevel, new Point(squareX, squareY)); //Into a wall if (!thisMap.mapSquares[squareX, squareY].Walkable) { NoWhereToJumpFail(); return(false); } //Adjacent square, must be a monster if (loopCounter == 1 && squareContents.monster == null) { NoMonsterToVaultFail(); return(false); } //Is there no monster here? If so, this is our destination if (squareContents.monster == null) { squareToMoveTo = new Point(squareX, squareY); moveCounter = 2; break; } //Monster here? Keep looping until we hit an empty or something bad loopCounter++; } while (true); LogFile.Log.LogEntryDebug("Vault backstab stage 2", LogDebugLevel.Medium); return(true); } //Third move, has to be attack in the opposite direction to the vault (i.e. same as original push) if (moveCounter == 2) { //Check direction is correct int secondXDelta = locationAfterMove.x - player.LocationMap.x; int secondYDelta = locationAfterMove.y - player.LocationMap.y; if (secondXDelta != xDelta || secondYDelta != yDelta) { //Reset moveCounter = 0; return(false); } //Check there is a monster to attack SquareContents squareContents = dungeon.MapSquareContents(player.LocationLevel, new Point(locationAfterMove.x, locationAfterMove.y)); //Is there a monster here? If so, we will attack it if (squareContents.monster != null && !squareContents.monster.Charmed) { target = squareContents.monster; moveCounter = 3; return(true); } else { //This implies the monster is really fast and going elsewhere which I guess is possible LogFile.Log.LogEntryDebug("VaultBackstab failed due to no-one to stab!", LogDebugLevel.Medium); moveCounter = 0; return(false); } } LogFile.Log.LogEntryDebug("Vault backstab move counter wrong", LogDebugLevel.Medium); return(false); }
public override bool CheckAction(bool isMove, Point deltaMove, bool otherMoveSuccess) { Dungeon dungeon = Game.Dungeon; Player player = Game.Dungeon.Player; //No interruptions if (!isMove) { //FailInterrupted(); return(false); } //Close quarters as part of other attacks are taken care of in their functions, only process if this is not a special move if (otherMoveSuccess) { return(false); } //1 step attack, when single enemy in contact and 3 cardinal directions of target are walls or other unwalkable things //and attack is in cardinal direction firstDeltaX = deltaMove.x; firstDeltaY = deltaMove.y; Point locationAfterMove = player.LocationMap + deltaMove; //Any non-diagonal move //if (firstDeltaX != 0 && firstDeltaY != 0) //{ //FailWrongPattern(); //return; // } //Check it is an attack SquareContents squareContents = dungeon.MapSquareContents(player.LocationLevel, new Point(locationAfterMove.x, locationAfterMove.y)); //Is there a monster here? if (squareContents.monster != null) { //Check for charmed if (squareContents.monster.Charmed) { return(false); } //Check for already dead (maybe from a leap) if (!squareContents.monster.Alive) { return(false); } //Are 3 cardinal directions around the monster unwalkable? Point monsterLoc = squareContents.monster.LocationMap; noCardinals = 0; if (!dungeon.MapSquareIsWalkable(squareContents.monster.LocationLevel, new Point(monsterLoc.x - 1, monsterLoc.y))) { noCardinals++; } if (!dungeon.MapSquareIsWalkable(squareContents.monster.LocationLevel, new Point(monsterLoc.x + 1, monsterLoc.y))) { noCardinals++; } if (!dungeon.MapSquareIsWalkable(squareContents.monster.LocationLevel, new Point(monsterLoc.x, monsterLoc.y + 1))) { noCardinals++; } if (!dungeon.MapSquareIsWalkable(squareContents.monster.LocationLevel, new Point(monsterLoc.x, monsterLoc.y - 1))) { noCardinals++; } if (noCardinals > 1) { target = squareContents.monster; moveCounter = 1; LogFile.Log.LogEntryDebug("CloseQuarters OK. No cards: " + noCardinals, LogDebugLevel.Low); return(true); } LogFile.Log.LogEntryDebug("CloseQuarters: not enough cardinals", LogDebugLevel.Low); } //Otherwise it's not a close quarters attack return(false); }
public override bool DoSpell(Point target) { Player player = Game.Dungeon.Player; Dungeon dungeon = Game.Dungeon; //Check the target is within FOV //Get the FOV from Dungeon (this also updates the map creature FOV state) CreatureFOV currentFOV = Game.Dungeon.CalculateCreatureFOV(player); //Is the target in FOV if (!currentFOV.CheckTileFOV(target.x, target.y)) { LogFile.Log.LogEntryDebug("Target out of FOV", LogDebugLevel.Medium); Game.MessageQueue.AddMessage("Target is out of sight."); return(false); } //Check there is a monster at target SquareContents squareContents = dungeon.MapSquareContents(player.LocationLevel, target); //Is there no monster here? If so, then attack it if (squareContents.monster != null) { LogFile.Log.LogEntryDebug("Firing energy blast", LogDebugLevel.Medium); Game.MessageQueue.AddMessage("Energy Blast!"); //Attack the monster //Check magic resistance bool monsterResisted = CheckMagicResistance(squareContents.monster); //Draw attack CombatResults results = CombatResults.DefenderDamaged; if (monsterResisted) { results = CombatResults.DefenderUnhurt; } Screen.Instance.DrawMissileAttack(player, squareContents.monster, results, ColorPresets.Crimson); //If monster resisted no damage if (monsterResisted) { return(true); } //Damage base int damageBase; if (player.MagicStat > 140) { damageBase = 12; } if (player.MagicStat > 120) { damageBase = 10; } if (player.MagicStat > 100) { damageBase = 8; } else { damageBase = 6; } //Damage done is just the base int damage = Utility.DamageRoll(damageBase) + Utility.DamageRoll(damageBase) + Utility.DamageRoll(damageBase);// +damageBase / 2; string combatResultsMsg = "PvM Energy Blast: Dam: 3d" + damageBase + " -> " + (damage); LogFile.Log.LogEntryDebug(combatResultsMsg, LogDebugLevel.Medium); //Apply damage player.ApplyDamageToMonster(squareContents.monster, damage, true, false); return(true); } Game.MessageQueue.AddMessage("No target for energy blast."); LogFile.Log.LogEntryDebug("No monster to target for Energy Blast", LogDebugLevel.Medium); return(false); }
/// <summary> /// Tells whether or not the given square contents wins on a column /// </summary> /// <param name="contents">the square contents to check</param> /// <returns>true for a win on a column, false otherwise</returns> private bool ColumnWin(SquareContents contents) { return((board[0, 0].Contents == contents && board[1, 0].Contents == contents && board[2, 0].Contents == contents) || (board[0, 1].Contents == contents && board[1, 1].Contents == contents && board[2, 1].Contents == contents) || (board[0, 2].Contents == contents && board[1, 2].Contents == contents && board[2, 2].Contents == contents)); }
public override bool CheckAction(bool isMove, Point deltaMove, bool otherMoveSuccess) { Dungeon dungeon = Game.Dungeon; Player player = Game.Dungeon.Player; Point locationAfterMove = player.LocationMap + deltaMove; //Restore currentTarget reference from ID, in case we have reloaded if (currentTargetID == -1) { target = null; } else { target = Game.Dungeon.GetCreatureByUniqueID(currentTargetID); } //Reset the attack marker extraAttackThisTurn = false; //No interruptions or standing still if (!isMove || locationAfterMove == player.LocationMap) { FailInterrupted(); return(false); } //First move must be an attack if (moveCounter == 0) { int firstDeltaX = locationAfterMove.x - player.LocationMap.x; int firstDeltaY = locationAfterMove.y - player.LocationMap.y; //Set lastDeltaX to something unreasonable so we never repetition fail on the first move lastDeltaX = -50; lastDeltaY = -50; //Reset speed counter //speedInc = 0; //Check it is an attack SquareContents squareContents = dungeon.MapSquareContents(player.LocationLevel, new Point(locationAfterMove.x, locationAfterMove.y)); //Is there a monster here? If so, we will attack it if (squareContents.monster != null && !squareContents.monster.Charmed) { //Set move counter to 1 and drop back, the normal code will do the first attack moveCounter = 1; target = squareContents.monster; currentTargetID = squareContents.monster.UniqueID; LogFile.Log.LogEntryDebug("MultiAttack Begins", LogDebugLevel.Medium); return(true); } else { //Not an attack moveCounter = 0; FailNotAnAttack(); return(false); } } //Any subsequent move can be an attack if //a) it's not the opposite to our last move //b) you are adjacent to a new monster else { int secondXDelta = locationAfterMove.x - player.LocationMap.x; int secondYDelta = locationAfterMove.y - player.LocationMap.y; //Opposite last move if (secondXDelta == -lastDeltaX && secondYDelta == -lastDeltaY) { //Reset FailRepetition(); return(false); } lastDeltaX = secondXDelta; lastDeltaY = secondYDelta; //Check this is a valid location to move into SquareContents squareContents = dungeon.MapSquareContents(player.LocationLevel, locationAfterMove); //Monster if (squareContents.monster != null) { FailBlocked(); return(false); } //Bad terrain if (!dungeon.MapSquareIsWalkable(player.LocationLevel, locationAfterMove)) { FailBlocked(); return(false); } //Check our surrounding squares and make a list of possible targets List <Monster> possibleTargets = new List <Monster>(); squareContents = dungeon.MapSquareContents(player.LocationLevel, new Point(locationAfterMove.x - 1, locationAfterMove.y)); if (squareContents.monster != null && !squareContents.monster.Charmed) { possibleTargets.Add(squareContents.monster); } squareContents = dungeon.MapSquareContents(player.LocationLevel, new Point(locationAfterMove.x + 1, locationAfterMove.y)); if (squareContents.monster != null && !squareContents.monster.Charmed) { possibleTargets.Add(squareContents.monster); } squareContents = dungeon.MapSquareContents(player.LocationLevel, new Point(locationAfterMove.x, locationAfterMove.y + 1)); if (squareContents.monster != null && !squareContents.monster.Charmed) { possibleTargets.Add(squareContents.monster); } squareContents = dungeon.MapSquareContents(player.LocationLevel, new Point(locationAfterMove.x, locationAfterMove.y - 1)); if (squareContents.monster != null && !squareContents.monster.Charmed) { possibleTargets.Add(squareContents.monster); } squareContents = dungeon.MapSquareContents(player.LocationLevel, new Point(locationAfterMove.x - 1, locationAfterMove.y - 1)); if (squareContents.monster != null && !squareContents.monster.Charmed) { possibleTargets.Add(squareContents.monster); } squareContents = dungeon.MapSquareContents(player.LocationLevel, new Point(locationAfterMove.x + 1, locationAfterMove.y - 1)); if (squareContents.monster != null && !squareContents.monster.Charmed) { possibleTargets.Add(squareContents.monster); } squareContents = dungeon.MapSquareContents(player.LocationLevel, new Point(locationAfterMove.x - 1, locationAfterMove.y + 1)); if (squareContents.monster != null && !squareContents.monster.Charmed) { possibleTargets.Add(squareContents.monster); } squareContents = dungeon.MapSquareContents(player.LocationLevel, new Point(locationAfterMove.x + 1, locationAfterMove.y + 1)); if (squareContents.monster != null && !squareContents.monster.Charmed) { possibleTargets.Add(squareContents.monster); } //Does our list of possible targets contain a new monster List <Monster> newMonsters = possibleTargets.FindAll(x => x != target); //Don't count charmed and passives newMonsters = newMonsters.FindAll(x => !x.Passive); newMonsters = newMonsters.FindAll(x => !x.Charmed); if (newMonsters.Count == 0) { FailNoNewMonsters(); return(false); } //Otherwise, pick a random monster to attack this turn target = newMonsters[Game.Random.Next(newMonsters.Count)]; currentTargetID = target.UniqueID; //The effective attack is from the square the player ends up at to the monster. This makes the next move into open square logical attackDeltaX = target.LocationMap.x - (player.LocationMap.x + deltaMove.x); attackDeltaY = target.LocationMap.y - (player.LocationMap.y + deltaMove.y); extraAttackThisTurn = true; moveCounter++; //Will attack it during DoMove return(true); } }
/// <summary> /// Tells whether or not the given square contents wins on a diagonal /// </summary> /// <param name="contents">the square contents to check</param> /// <returns>true for a win on a diagonal, false otherwise</returns> private bool DiagonalWin(SquareContents contents) { return((board[0, 0].Contents == contents && board[1, 1].Contents == contents && board[2, 2].Contents == contents) || (board[2, 0].Contents == contents && board[1, 1].Contents == contents && board[0, 2].Contents == contents)); }
/// <summary> /// Stun grenade - goes through walls /// Should sync with above method /// </summary> /// <param name="item"></param> /// <param name="target"></param> /// <returns></returns> public static Point ThrowItemGrenadeLikeStun(IEquippableItem item, Point target, double size, int damage) { Item itemAsItem = item as Item; LogFile.Log.LogEntryDebug("Throwing " + itemAsItem.SingleItemDescription, LogDebugLevel.Medium); Player player = Game.Dungeon.Player; //Find target List <Point> targetSquares = Game.Dungeon.CalculateTrajectory(target); Monster monster = Game.Dungeon.FirstMonsterInTrajectory(targetSquares); //Find where it landed //Destination will be the last square in trajectory Point destination; if (targetSquares.Count > 0) { destination = targetSquares[targetSquares.Count - 1]; } else { //Threw it on themselves! destination = player.LocationMap; } //Stopped by a monster if (monster != null) { destination = monster.LocationMap; } //Make throwing sound AT target location Game.Dungeon.AddSoundEffect(item.ThrowSoundMagnitude(), Game.Dungeon.Player.LocationLevel, destination); //Work out grenade splash and damage List <Point> grenadeAffects = Game.Dungeon.GetPointsForGrenadeTemplate(destination, Game.Dungeon.Player.LocationLevel, size); //Draw attack Screen.Instance.DrawAreaAttackAnimation(grenadeAffects, ColorPresets.DodgerBlue); //Attack all monsters in the area foreach (Point sq in grenadeAffects) { SquareContents squareContents = Game.Dungeon.MapSquareContents(player.LocationLevel, sq); Monster m = squareContents.monster; //Hit the monster if it's there if (m != null) { string combatResultsMsg = "PvM (" + m.Representation + ") Grenade: Stun: " + damage; LogFile.Log.LogEntryDebug(combatResultsMsg, LogDebugLevel.Medium); //Apply damage player.ApplyStunDamageToMonster(m, damage); } } //Doesn't affect the player return(destination); }
internal BoardState SetPiece(Square square, SquareContents contents) { return(BoardStateMutator.SetPiece(this, BitTranslator.TranslateToBit(square.File, square.Rank), contents)); }
public override bool CheckAction(bool isMove, Point deltaMove, bool otherMoveSuccess) { Dungeon dungeon = Game.Dungeon; Player player = Game.Dungeon.Player; //Restore currentTarget reference from ID, in case we have reloaded if (currentTargetID == -1) { target = null; } else { target = Game.Dungeon.GetCreatureByUniqueID(currentTargetID); } //No interruptions if (!isMove) { FailInterrupted(); return(false); } extraAttackThisTurn = false; Point locationAfterMove = player.LocationMap + deltaMove; //First move must be an attack in a square direction if (moveCounter == 0) { firstDeltaX = deltaMove.x; firstDeltaY = deltaMove.y; //Any non-diagonal move //if (firstDeltaX != 0 && firstDeltaY != 0) //{ //FailWrongPattern(); // return; //} //Check it is an attack SquareContents squareContents = dungeon.MapSquareContents(player.LocationLevel, new Point(locationAfterMove.x, locationAfterMove.y)); //Is there a monster here? If so, we will attack it if (squareContents.monster != null && !squareContents.monster.Charmed) { //Set move counter to 1 and drop back, the normal code will do the first attack moveCounter = 1; target = squareContents.monster; currentTargetID = squareContents.monster.UniqueID; monsterSquare = target.LocationMap; LogFile.Log.LogEntryDebug("OpenSpaceAttack Stage: " + moveCounter, LogDebugLevel.Medium); return(true); } else { //Not an attack moveCounter = 0; FailNotAnAttack(); return(false); } } //Move after an attack if (moveCounter == 1) { //Check this is a valid location to move into SquareContents squareContents = dungeon.MapSquareContents(player.LocationLevel, locationAfterMove); //Monster if (squareContents.monster != null) { FailBlocked(); return(false); } //Bad terrain if (!dungeon.MapSquareIsWalkable(player.LocationLevel, locationAfterMove)) { FailBlocked(); return(false); } //Check the sequence is correct int thisDeltaX = locationAfterMove.x - player.LocationMap.x; int thisDeltaY = locationAfterMove.y - player.LocationMap.y; //South if (firstDeltaX == 0 && firstDeltaY == 1) { if (thisDeltaX != 1 || thisDeltaY != 1) { FailWrongPattern(); return(false); } } //SW attack //Cheat to adopt the normal pattern if (firstDeltaX == -1 && firstDeltaY == 1) { if (thisDeltaX != 0 || thisDeltaY != 1) { FailWrongPattern(); return(false); } thisDeltaX = 1; thisDeltaY = 1; } //NW attack if (firstDeltaX == -1 && firstDeltaY == -1) { if (thisDeltaX != -1 || thisDeltaY != 0) { FailWrongPattern(); return(false); } thisDeltaX = -1; thisDeltaY = 1; } //NE attack if (firstDeltaX == 1 && firstDeltaY == -1) { if (thisDeltaX != 0 || thisDeltaY != -1) { FailWrongPattern(); return(false); } thisDeltaX = -1; thisDeltaY = 1; } //SE attack if (firstDeltaX == 1 && firstDeltaY == 1) { if (thisDeltaX != 1 || thisDeltaY != 0) { FailWrongPattern(); return(false); } thisDeltaX = 1; thisDeltaY = -1; } //East if (firstDeltaX == 1 && firstDeltaY == 0) { if (thisDeltaX != 1 || thisDeltaY != -1) { FailWrongPattern(); return(false); } } //North if (firstDeltaX == 0 && firstDeltaY == -1) { if (thisDeltaX != -1 || thisDeltaY != -1) { FailWrongPattern(); return(false); } } //West if (firstDeltaX == -1 && firstDeltaY == 0) { if (thisDeltaX != -1 || thisDeltaY != 1) { FailWrongPattern(); return(false); } } //Save this move lastDeltaX = thisDeltaX; lastDeltaY = thisDeltaY; //Check there the monster is still in its square and hasn't died //If reaped, we get null from it's id if (target == null) { FailTarget(); return(false); } if (!target.Alive) { FailTarget(); return(false); } if (target.LocationMap != monsterSquare) { FailTarget(); return(false); } //Monster is still alive and in right square - we will attack moveCounter = 2; //Store the delta between the player and the monster attackDeltaX = monsterSquare.x - player.LocationMap.x; attackDeltaY = monsterSquare.y - player.LocationMap.y; extraAttackThisTurn = false; LogFile.Log.LogEntryDebug("OpenSpaceAttack Stage: " + moveCounter, LogDebugLevel.Medium); //Will attack it during DoMove, and move into its square return(true); } //Later moves follow a clockwise box if (moveCounter > 1) { //Check this is a valid location to move into SquareContents squareContents = dungeon.MapSquareContents(player.LocationLevel, locationAfterMove); //Monster if (squareContents.monster != null) { FailBlocked(); return(false); } //Bad terrain if (!dungeon.MapSquareIsWalkable(player.LocationLevel, locationAfterMove)) { FailBlocked(); return(false); } //Check the sequence is correct int thisDeltaX = locationAfterMove.x - player.LocationMap.x; int thisDeltaY = locationAfterMove.y - player.LocationMap.y; //NE if (lastDeltaX == 1 && lastDeltaY == -1) { //SE if (thisDeltaX != 1 || thisDeltaY != 1) { FailWrongPattern(); return(false); } } //SE if (lastDeltaX == 1 && lastDeltaY == 1) { //SW if (thisDeltaX != -1 || thisDeltaY != 1) { FailWrongPattern(); return(false); } } //SW if (lastDeltaX == -1 && lastDeltaY == 1) { //NW if (thisDeltaX != -1 || thisDeltaY != -1) { FailWrongPattern(); return(false); } } //NW if (lastDeltaX == -1 && lastDeltaY == -1) { //NE if (thisDeltaX != 1 || thisDeltaY != -1) { FailWrongPattern(); return(false); } } //Save this move lastDeltaX = thisDeltaX; lastDeltaY = thisDeltaY; //Check there the monster is still in its square and hasn't died //If reaped, we get null from it's id if (target == null) { FailTarget(); return(false); } if (!target.Alive) { FailTarget(); return(false); } if (target.LocationMap != monsterSquare) { FailTarget(); return(false); } //Monster is still alive and in right square moveCounter++; //Store the delta between the player and the monster attackDeltaX = monsterSquare.x - player.LocationMap.x; attackDeltaY = monsterSquare.y - player.LocationMap.y; extraAttackThisTurn = false; LogFile.Log.LogEntryDebug("OpenSpaceAttack Stage: " + moveCounter, LogDebugLevel.Medium); //Will attack it during DoMove, and move into its square return(true); } LogFile.Log.LogEntryDebug("OpenSpaceAttack: moveCounter wrong", LogDebugLevel.Medium); return(false); }
public void Move_UpdatesPiecesWhenCastling(string input, string kingSquare, string rookSquare, SquareContents color) { var king = MoveParser.ParseSquare(kingSquare); var rook = MoveParser.ParseSquare(rookSquare); var game = new Game(); foreach (var move in input.Split(',')) { game.Move(move); } var expectedKing = game.GetSquareContents(king.File, king.Rank); var expectedRook = game.GetSquareContents(rook.File, rook.Rank); Assert.That(expectedKing, Is.EqualTo(SquareContents.King | color)); Assert.That(expectedRook, Is.EqualTo(SquareContents.Rook | color)); }
public override bool CheckAction(bool isMove, Point deltaMove, bool otherMoveSuccess) { Player player = Game.Dungeon.Player; Dungeon dungeon = Game.Dungeon; Point locationAfterMove = player.LocationMap + deltaMove; //First move is pushing off against a wall //Second move is jumping over 0 or more creatures //Not a move or attack = reset if (!isMove) { moveCounter = 0; return(false); } //First move //Must be push off wall if (moveCounter == 0) { //Must be wall MapTerrain pushTerrain = dungeon.Levels[player.LocationLevel].mapSquares[locationAfterMove.x, locationAfterMove.y].Terrain; if (pushTerrain != MapTerrain.Wall && pushTerrain != MapTerrain.ClosedDoor) { moveCounter = 0; return(false); } //Is wall //Success moveCounter = 1; //Need to remember the direction of the first push, since we can only vault opposite this xDelta = locationAfterMove.x - player.LocationMap.x; yDelta = locationAfterMove.y - player.LocationMap.y; LogFile.Log.LogEntryDebug("Wall push stage 1", LogDebugLevel.Medium); return(true); } //Second move //Must be push off same wall if (moveCounter == 1) { int thisDeltaX = locationAfterMove.x - player.LocationMap.x; int thisDeltaY = locationAfterMove.y - player.LocationMap.y; //Must be exactly the same move as last time if (thisDeltaX != xDelta || thisDeltaY != yDelta) { FailPattern(); return(false); } //Success moveCounter = 2; LogFile.Log.LogEntryDebug("Wall push stage 2", LogDebugLevel.Medium); return(true); } //if (moveCounter == 2) else { //Only implementing this for player for now! //Check that this direction opposes the initial push int secondXDelta = locationAfterMove.x - player.LocationMap.x; int secondYDelta = locationAfterMove.y - player.LocationMap.y; if (secondXDelta != -xDelta || secondYDelta != -yDelta) { //Reset FailPattern(); return(false); } //OK, going in right direction //Firstly we need to check that there is a monster to push! SquareContents squareContents = dungeon.MapSquareContents(player.LocationLevel, new Point(locationAfterMove.x, locationAfterMove.y)); if (squareContents.monster == null) { FailNoMonsterToPush(); return(false); } //Need to check what's ahead of the pushed monster Map thisMap = dungeon.Levels[player.LocationLevel]; //We run forward from the monster position until we find a square that will make them stop //Default is to leave them where they are //(Remember to check the creature path finding / AI) //We also set a maximum push-back //Default is not to move the creature anywhere monsterToMove = squareContents.monster; squareToMoveMonsterTo = new Point(locationAfterMove.x, locationAfterMove.y); //Start at the square behind the monster int loopCounter = 1; do { int squareX = locationAfterMove.x + secondXDelta * loopCounter; int squareY = locationAfterMove.y + secondYDelta * loopCounter; //Off the map if (squareX < 0 || squareX > thisMap.width) { break; } if (squareY < 0 || squareY > thisMap.height) { break; } MapTerrain squareTerrain = thisMap.mapSquares[squareX, squareY].Terrain; SquareContents thisContents = dungeon.MapSquareContents(player.LocationLevel, new Point(squareX, squareY)); //Into something non-walkable if (!thisMap.mapSquares[squareX, squareY].Walkable) { break; } //Is there a monster here if (thisContents.monster != null) { break; } //Nothing here, this would be an OK location for the creature to end up squareToMoveMonsterTo = new Point(squareX, squareY); loopCounter++; } while (loopCounter < 6); //Complete move moveCounter = 3; return(true); } }
/// <summary> /// Updates the board square /// </summary> /// <param name="mouse">the current mouse state</param> /// <returns>true if the player placed an X, false otherwise</returns> public bool Update(MouseState mouse) { // STUDENTS: IF THE MOUSE IS OVER THE SQUARE, THE LEFT MOUSE BUTTON IS PRESSED // AND THE SQUARE CONTENTS IS EMPTY CHANGE THE CONTENTS TO HOLD AN X AND RETURN true. // OTHERWISE, RETURN false //if (<students add Boolean expression here>) if(mouse.X > drawRectangle.X && mouse.X < (drawRectangle.X + squareSprite.Width) && mouse.Y > drawRectangle.Y && mouse.Y < (drawRectangle.Y + squareSprite.Height) && mouse.LeftButton == ButtonState.Pressed && this.Empty == true) { contents = SquareContents.X; return true; } else { return false; } // STUDENTS: REMOVE THE LINE BELOW AFTER UNCOMMENTING AND COMPLETING THE CODE ABOVE //return false; }
public override bool DoSpell(Point target) { Player player = Game.Dungeon.Player; Dungeon dungeon = Game.Dungeon; //Check the target is within FOV //Get the FOV from Dungeon (this also updates the map creature FOV state) CreatureFOV currentFOV = Game.Dungeon.CalculateCreatureFOV(player); //Is the target in FOV if (!currentFOV.CheckTileFOV(target.x, target.y)) { LogFile.Log.LogEntryDebug("Target out of FOV", LogDebugLevel.Medium); Game.MessageQueue.AddMessage("Target is out of sight."); return(false); } //Hit monsters around the target Point targetSquare = target; List <Point> splashSquares = new List <Point>(); for (int i = targetSquare.x - spellRange; i < targetSquare.x + spellRange; i++) { for (int j = targetSquare.y - spellRange; j < targetSquare.y + spellRange; j++) { if (Math.Pow(i - targetSquare.x, 2) + Math.Pow(j - targetSquare.y, 2) < Math.Pow(spellRange, 2)) { splashSquares.Add(new Point(i, j)); LogFile.Log.LogEntryDebug("FireBall Added square x: " + i + " y: " + j, LogDebugLevel.Low); } } } //This one is always cast, even without a target Game.MessageQueue.AddMessage("Fire Ball!"); foreach (Point p in splashSquares) { //Is there a monster here? If so, then attack it SquareContents squareContents = dungeon.MapSquareContents(player.LocationLevel, new Point(p.x, p.y)); if (squareContents.monster != null) { HitMonster(player, squareContents.monster); } if (squareContents.player != null) { HitPlayer(); } } //Screen.Instance.DrawFlashSquares(splashSquares, ColorPresets.Red); return(true); }
/// <summary> /// Tells whether or not the given square contents wins on a row /// </summary> /// <param name="contents">the square contents to check</param> /// <returns>true for a win on a row, false otherwise</returns> private bool RowWin(SquareContents contents) { return (board[0, 0].Contents == contents && board[0, 1].Contents == contents && board[0, 2].Contents == contents) || (board[1, 0].Contents == contents && board[1, 1].Contents == contents && board[1, 2].Contents == contents) || (board[2, 0].Contents == contents && board[2, 1].Contents == contents && board[2, 2].Contents == contents); }
public override bool CheckAction(bool isMove, Point deltaMove, bool otherMoveSuccess) { Dungeon dungeon = Game.Dungeon; Player player = Game.Dungeon.Player; Point locationAfterMove = player.LocationMap + deltaMove; //No interruptions if (!isMove) { FailInterrupted(); return(false); } //Something in the square we're trying to enter blocks us SquareContents squareContents = dungeon.MapSquareContents(player.LocationLevel, locationAfterMove); //Monster if (squareContents.monster != null) { FailBlocked(); return(false); } //Bad terrain if (!dungeon.MapSquareIsWalkable(player.LocationLevel, locationAfterMove)) { FailBlocked(); return(false); } int thisDeltaX = locationAfterMove.x - player.LocationMap.x; int thisDeltaY = locationAfterMove.y - player.LocationMap.y; //First move, can be any non diagonal move if (moveCounter == 0) { if (thisDeltaX != 0 && thisDeltaY != 0) { FailWrongPattern(); return(false); } if (thisDeltaX == 0 && thisDeltaY == 0) { FailWrongPattern(); return(false); } //Otherwise OK } else { //Latter moves must be in a clockwise box if (lastDeltaX == -1 && lastDeltaY == 0) { if (thisDeltaX != 0 || thisDeltaY != -1) { FailWrongPattern(); return(false); } } if (lastDeltaX == 0 && lastDeltaY == -1) { if (thisDeltaX != 1 || thisDeltaY != 0) { FailWrongPattern(); return(false); } } if (lastDeltaX == 1 && lastDeltaY == 0) { if (thisDeltaX != 0 || thisDeltaY != 1) { FailWrongPattern(); return(false); } } if (lastDeltaX == 0 && lastDeltaY == 1) { if (thisDeltaX != -1 || thisDeltaY != 0) { FailWrongPattern(); return(false); } } } //OK to increment pattern moveCounter++; LogFile.Log.LogEntryDebug("StunBox OK - point: " + moveCounter.ToString(), LogDebugLevel.Medium); //Save the old deltas lastDeltaX = thisDeltaX; lastDeltaY = thisDeltaY; return(true); }