Example #1
0
        /// <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);
            }
        }
Example #2
0
        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
                       ));
        }
Example #3
0
 public Move(char startFile, int startRank, char endFile, int endRank, SquareContents promotedPiece)
 {
     StartFile     = startFile;
     StartRank     = startRank;
     EndFile       = endFile;
     EndRank       = endRank;
     PromotedPiece = promotedPiece;
 }
Example #4
0
        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));
        }
Example #5
0
        /// <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);
        }
Example #6
0
        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]));
        }
Example #7
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);
        }
Example #8
0
 /// <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);
     }
 }
Example #9
0
        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));
        }
Example #10
0
        /// <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;
        }
Example #11
0
        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);
        }
Example #12
0
        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
        }
Example #14
0
        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);
        }
Example #15
0
        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);
        }
Example #16
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 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);
        }
Example #17
0
 /// <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;
     }
 }
Example #18
0
 public BoardState SetPiece(ulong bitSquare, SquareContents contents)
 {
     return(BoardStateMutator.SetPiece(this, bitSquare, contents));
 }
Example #19
0
        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));
        }
Example #20
0
        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);
        }
Example #21
0
        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);
        }
Example #22
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 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);
        }
Example #23
0
 /// <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));
 }
Example #24
0
        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);
            }
        }
Example #25
0
 /// <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));
 }
Example #26
0
        /// <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);
        }
Example #27
0
 internal BoardState SetPiece(Square square, SquareContents contents)
 {
     return(BoardStateMutator.SetPiece(this, BitTranslator.TranslateToBit(square.File, square.Rank), contents));
 }
Example #28
0
        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);
        }
Example #29
0
        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));
        }
Example #30
0
        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);
            }
        }
Example #31
0
        /// <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;
        }
Example #32
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);
            }

            //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);
        }
Example #33
0
 /// <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);
 }
Example #34
0
        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);
        }