예제 #1
0
    /// <summary>
    /// Checks to see if a cell is a good candidate for placement of a door.
    /// </summary>
    /// <param name="cell"></param>
    /// <returns></returns>
    private bool IsPotentialDoor(Cell cell)
    {
        if (!cell.IsWalkable)                                                           // If the cell is not walkable then it is a wall and not a good place for a door
        {
            return(false);
        }

        Cell right  = (Cell)map.GetCell(cell.X + 1, cell.Y);                            // Store references to all of the neighboring cells
        Cell left   = (Cell)map.GetCell(cell.X - 1, cell.Y);
        Cell top    = (Cell)map.GetCell(cell.X, cell.Y - 1);
        Cell bottom = (Cell)map.GetCell(cell.X, cell.Y + 1);

        if (map.GetDoor(cell.X, cell.Y) != null ||
            map.GetDoor(right.X, right.Y) != null ||
            map.GetDoor(left.X, left.Y) != null ||
            map.GetDoor(top.X, top.Y) != null ||
            map.GetDoor(bottom.X, bottom.Y) != null)                                    // Make sure there is not already a door here
        {
            return(false);
        }

        if (right.IsWalkable && left.IsWalkable && !top.IsWalkable && !bottom.IsWalkable)// This is a good place for a door on the left or right side of the room
        {
            return(true);
        }

        if (!right.IsWalkable && !left.IsWalkable && top.IsWalkable && bottom.IsWalkable)// This is a good place for a door on the top or bottom of the room
        {
            return(true);
        }
        return(false);
    }
예제 #2
0
        public bool Act(Monster monster, CommandSystem commandSystem)
        {
            DungeonMap  dungeonMap = Game.DungeonMap;
            Player      player     = Game.Player;
            FieldOfView monsterFov = new FieldOfView(dungeonMap);

            if (!monster.TurnsAlerted.HasValue)
            {
                monsterFov.ComputeFov(monster.X, monster.Y, monster.Awareness, true);
                if (monsterFov.IsInFov(player.X, player.Y))
                {
                    Game.MessageLog.Add($"{monster.Name} está em busca do {player.Name} para lutar ");
                    monster.TurnsAlerted = 1;
                }
            }

            if (monster.TurnsAlerted.HasValue)
            {
                dungeonMap.SetIsWalkable(monster.X, monster.Y, true);
                dungeonMap.SetIsWalkable(player.X, player.Y, true);

                PathFinder pathFinder = new PathFinder(dungeonMap);
                Path       path       = null;

                try
                {
                    path = pathFinder.ShortestPath(
                        dungeonMap.GetCell(monster.X, monster.Y),
                        dungeonMap.GetCell(player.X, player.Y));
                }
                catch (PathNotFoundException)
                {
                    Game.MessageLog.Add($"{monster.Name} espera uma oportunidade para avançar");
                }

                dungeonMap.SetIsWalkable(monster.X, monster.Y, false);
                dungeonMap.SetIsWalkable(player.X, player.Y, false);

                if (path != null)
                {
                    try
                    {
                        //TODO: path.SetpFoward() RogueSharo 4.0
                        commandSystem.MoveMonster(monster, path.Steps.First());
                    }
                    catch (NoMoreStepsException)
                    {
                        Game.MessageLog.Add($"{monster.Name} grita em frustração");
                    }
                }

                monster.TurnsAlerted++;

                if (monster.TurnsAlerted > 15)
                {
                    monster.TurnsAlerted = null;
                }
            }
            return(true);
        }
예제 #3
0
        //Checks to see if a cell is a candidate for door placement
        private bool IsPotentialDoor(Cell cell)
        {
            //If cell is a wall it is not a good place for a door
            if (!cell.IsWalkable)
            {
                return(false);
            }

            //Store references to all of the neighboring cells
            Cell right  = _map.GetCell(cell.X + 1, cell.Y);
            Cell left   = _map.GetCell(cell.X - 1, cell.Y);
            Cell top    = _map.GetCell(cell.X, cell.Y - 1);
            Cell bottom = _map.GetCell(cell.X, cell.Y + 1);

            //Check that there is not already a door there
            if (_map.GetDoor(cell.X, cell.Y) != null ||
                _map.GetDoor(right.X, right.Y) != null ||
                _map.GetDoor(left.X, left.Y) != null ||
                _map.GetDoor(top.X, top.Y) != null ||
                _map.GetDoor(bottom.X, bottom.Y) != null)
            {
                return(false);
            }
            //Check if the left or right side is a good spot for the door
            if (right.IsWalkable && left.IsWalkable && !top.IsWalkable && !bottom.IsWalkable)
            {
                return(true);
            }
            //Check if the top or bottom is a good spot for the door
            if (!right.IsWalkable && !left.IsWalkable && top.IsWalkable && bottom.IsWalkable)
            {
                return(true);
            }
            return(false);
        }
        private bool IsPotentialDoor(Cell cell)
        {
            if (!cell.IsWalkable)
            {
                return(false);
            }

            Cell right  = _map.GetCell(cell.X + 1, cell.Y);
            Cell left   = _map.GetCell(cell.X - 1, cell.Y);
            Cell top    = _map.GetCell(cell.X, cell.Y - 1);
            Cell bottom = _map.GetCell(cell.X, cell.Y + 1);

            if (_map.GetDoor(cell.X, cell.Y) != null ||
                _map.GetDoor(right.X, right.Y) != null ||
                _map.GetDoor(left.X, left.Y) != null ||
                _map.GetDoor(top.X, top.Y) != null ||
                _map.GetDoor(bottom.X, bottom.Y) != null)
            {
                return(false);
            }

            if (right.IsWalkable && left.IsWalkable && !top.IsWalkable && !bottom.IsWalkable)
            {
                return(true);
            }
            if (!right.IsWalkable && !left.IsWalkable && top.IsWalkable && bottom.IsWalkable)
            {
                return(true);
            }
            return(false);
        }
예제 #5
0
        public bool Act(Monster monster, CommandSystem commandSystem)
        {
            DungeonMap  dungeonMap = Game.DungeonMap;
            Player      player     = Game.Player;
            FieldOfView monsterFov = new FieldOfView(dungeonMap);

            if (!monster.TurnsAlerted.HasValue)
            {
                monsterFov.ComputeFov(monster.X, monster.Y, monster.Awareness, true);
                if (monsterFov.IsInFov(player.X, player.Y))
                {
                    Game.MessageLog.Add($"{monster.Name} is eager to fight {player.Name}");
                    monster.TurnsAlerted = 1;
                }
            }

            if (monster.TurnsAlerted.HasValue)
            {
                dungeonMap.SetIsWalkable(monster.X, monster.Y, true);
                dungeonMap.SetIsWalkable(player.X, player.Y, true);

                PathFinder pathFinder = new PathFinder(dungeonMap);
                Path       path       = null;

                try
                {
                    path = pathFinder.ShortestPath(
                        dungeonMap.GetCell(monster.X, monster.Y),
                        dungeonMap.GetCell(player.X, player.Y));
                }
                catch (PathNotFoundException)
                {
                    Game.MessageLog.Add($"{monster.Name} waits for turn");
                }

                dungeonMap.SetIsWalkable(monster.X, monster.Y, false);
                dungeonMap.SetIsWalkable(player.X, player.Y, false);

                if (path != null)
                {
                    try
                    {
                        commandSystem.MoveMonster(monster, (Cell)path.Steps.First());
                    }
                    catch (NoMoreStepsException)
                    {
                        Game.MessageLog.Add($"{monster.Name} growls in frustration");
                    }
                }
            }

            monster.TurnsAlerted++;

            if (monster.TurnsAlerted > 15)
            {
                monster.TurnsAlerted = null;
            }
            return(true);
        }
예제 #6
0
        public bool Act(Monster monster, Commands command)
        {
            DungeonMap  DMap   = Facade.DMap;
            FieldOfView mobFov = new FieldOfView(DMap);

            if (!monster.TurnsAlerted.HasValue)
            {
                mobFov.ComputeFov(monster.X, monster.Y, monster.FOVValue, true);
                if (mobFov.IsInFov(Player.GetInstance().X, Player.GetInstance().Y))
                {
                    Facade.Log.Add($"{monster.Name} zauwaza {Player.GetInstance().Name}");
                    monster.TurnsAlerted = 1;
                }
            }
            if (monster.TurnsAlerted.HasValue)
            {
                DMap.SetIsWalkable(monster.X, monster.Y, true);
                DMap.SetIsWalkable(Player.GetInstance().X, Player.GetInstance().Y, true);
                PathFinder pathFinder = new PathFinder(DMap);
                Path       path       = null;
                try
                {
                    path = pathFinder.ShortestPath(
                        DMap.GetCell(monster.X, monster.Y),
                        DMap.GetCell(Player.GetInstance().X, Player.GetInstance().Y));
                }
                catch (PathNotFoundException)
                {
                    Facade.Log.Add($"{monster.Name} czeka na okazje do ataku");
                }
                DMap.SetIsWalkable(monster.X, monster.Y, false);
                DMap.SetIsWalkable(Player.GetInstance().X, Player.GetInstance().Y, false);
                if (path != null)
                {
                    try
                    {
                        command.MoveMob(monster, path.Steps.First());
                    }
                    catch (NoMoreStepsException)
                    {
                        Facade.Log.Add($"{monster.Name} szuka drogi");
                    }
                }

                monster.TurnsAlerted++;

                if (monster.TurnsAlerted > 15)
                {
                    monster.TurnsAlerted = null;
                }
            }
            return(true);
        }
예제 #7
0
 private bool LightAttack(RLKey key)
 {
     if (IsPressed(RLKey.Keypad5))
     {
         ISelfAction action = (ISelfAction)player.Actions.Find(x => x.Name == "Wait");
         return(action.Execute());
     }
     else if (MovementPressed())
     {
         ICellAction action = (ICellAction)player.Actions.Find(x => x.Name == "Punch");
         return(action.Execute(map.GetCell(player.X, player.Y), lastDirection));
     }
     return(false);
 }
예제 #8
0
    public bool RushPlayer(Monster monster, CommandSystem commandSystem, Game game, DungeonMap dungeonMap, Player player, FieldOfView monsterFov)
    {
        // Before we find a path, make sure to make the monster and player Cells walkable
        dungeonMap.SetIsWalkable(monster.X, monster.Y, true);
        dungeonMap.SetIsWalkable(player.X, player.Y, true);

        PathFinder pathFinder = new PathFinder(dungeonMap, 1d);
        Path       path       = null;

        try
        {
            path = pathFinder.ShortestPath(
                dungeonMap.GetCell(monster.X, monster.Y),
                dungeonMap.GetCell(player.X, player.Y));
        }
        catch (PathNotFoundException)
        {
            // The monster can see the player, but cannot find a path to him
            // This could be due to other monsters blocking the way
            // Add a message to the message log that the monster is waiting
            //game.MessageLog.Add(monster.Name + " waits for a turn.");
        }

        // Don't forget to set the walkable status back to false
        dungeonMap.SetIsWalkable(monster.X, monster.Y, false);
        dungeonMap.SetIsWalkable(player.X, player.Y, false);

        // In the case that there was a path, tell the CommandSystem to move the monster
        if (path != null)
        {
            try
            {
                // TODO: This should be path.StepForward() but there is a bug in RogueSharp V3
                // The bug is that a Path returned from a PathFinder does not include the source Cell

                do
                {
                    commandSystem.MoveMonster(monster, path.StepForward() as Cell);
                    monster.MovesCompleted++;
                } while (monster.MovesCompleted < monster.Moves);
            }
            catch (NoMoreStepsException)
            {
                //game.MessageLog.Add(monster.Name + " cannot move.");
            }
        }

        return(true);
    }
예제 #9
0
        public bool Act(Monster monster, CommandSystem commandSystem)
        {
            DungeonMap  dungeonMap = RogueGame.DungeonMap;
            Player      player     = RogueGame.Player;
            FieldOfView monsterFov = new FieldOfView(dungeonMap);

            if (!monster.TurnsAlerted.HasValue)
            {
                monsterFov.ComputeFov(monster.X, monster.Y, monster.Awareness, true);
                if (monsterFov.IsInFov(player.X, player.Y))
                {
                    RogueGame.MessageLog.Add($"{monster.Name} is eager to fight {player.Name}");
                    monster.TurnsAlerted = 1;
                }
            }
            if (monster.TurnsAlerted.HasValue)
            {
                dungeonMap.SetIsWalkable(monster.X, monster.Y, true);
                dungeonMap.SetIsWalkable(player.X, player.Y, true);

                PathFinder pathFinder = new PathFinder(dungeonMap);
                Path       path       = null;

                try
                {
                    path = pathFinder.ShortestPath(dungeonMap.GetCell(monster.X, monster.Y), dungeonMap.GetCell(player.X, player.Y));
                }
                catch (PathNotFoundException)
                {
                    RogueGame.MessageLog.Add($"{monster.Name} waits for a turn");
                }

                dungeonMap.SetIsWalkable(monster.X, monster.Y, false);
                dungeonMap.SetIsWalkable(player.X, player.Y, false);

                if (path != null)
                {
                    try
                    {
                        commandSystem.MoveMonster(monster, path.StepForward());
                    }
                    catch (NoMoreStepsException)
                    {
                        RogueGame.MessageLog.Add($"{monster.Name} waits for a turn");
                    }
                }

                monster.TurnsAlerted++;

                // Lose alerted status every 15 turns. As long as the player is still in FoV the monster will be realerted otherwise the monster will quit chasing the player.
                if (monster.TurnsAlerted > 15)
                {
                    monster.TurnsAlerted = null;
                }
            }
            return(true);
        }
예제 #10
0
        public bool Act(Monster monster, Commands commandSystem)
        {
            DungeonMap  dungeonMap = Game.DungeonMap;
            Player      player     = Game.Player;
            FieldOfView monsterFov = new FieldOfView(dungeonMap);

            if (!monster.TurnsAlerted.HasValue)
            {
                monsterFov.ComputeFov(monster.X, monster.Y, monster.Fov, true);
                if (monsterFov.IsInFov(player.X, player.Y))
                {
                    monster.TurnsAlerted = 1;
                }
            }

            if (monster.TurnsAlerted.HasValue)
            {
                dungeonMap.SetIsWalkable(monster.X, monster.Y, true);
                dungeonMap.SetIsWalkable(player.X, player.Y, true);

                PathFinder pathFinder = new PathFinder(dungeonMap);
                Path       path       = null;

                try
                {
                    path = pathFinder.ShortestPath(dungeonMap.GetCell(monster.X, monster.Y), dungeonMap.GetCell(player.X, player.Y));
                }
                catch (PathNotFoundException)
                {
                }

                dungeonMap.SetIsWalkable(monster.X, monster.Y, false);
                dungeonMap.SetIsWalkable(player.X, player.Y, false);

                if (path != null)
                {
                    try
                    {
                        commandSystem.MoveMonster(monster, path.Steps.First());
                    }
                    catch (NoMoreStepsException)
                    {
                    }
                }

                monster.TurnsAlerted++;

                if (monster.TurnsAlerted > 15)
                {
                    monster.TurnsAlerted = null;
                }
            }

            return(true);
        }
예제 #11
0
        // Revisamos si una celda es una buena candidata para colocar una puerta.
        private bool IsPotencialDoor(Cell cell)
        {
            // Si la celda es no transitable entonces es un pared y no es
            // un buen lugar para colocar una puerta.
            if (!cell.IsWalkable)
            {
                return(false);
            }

            // Almacenamos las referencias a todas las celdas vecinas.
            Cell right = _mazmorra.GetCell(cell.X + 1, cell.Y);
            Cell left  = _mazmorra.GetCell(cell.X - 1, cell.Y);
            Cell top   = _mazmorra.GetCell(cell.X, cell.Y - 1);
            Cell botom = _mazmorra.GetCell(cell.X, cell.Y + 1);

            // Nos aseguramos de que no haya una puerta aquí.
            if (_mazmorra.GetDoor(cell.X, cell.Y) != null ||
                _mazmorra.GetDoor(right.X, right.Y) != null ||
                _mazmorra.GetDoor(left.X, left.Y) != null ||
                _mazmorra.GetDoor(top.X, top.Y) != null ||
                _mazmorra.GetDoor(botom.X, botom.Y) != null)
            {
                return(false);
            }

            // Este es un buen lugar para una puerta y es en la
            // izquierda o derecha de la habitación.
            if (right.IsWalkable && left.IsWalkable && !top.IsWalkable && !botom.IsWalkable)
            {
                return(true);
            }

            // Este es un buen lugar para una puerta y es en la
            // parte de arriba o de abajo de la habitación.
            if (!right.IsWalkable && !left.IsWalkable && top.IsWalkable && botom.IsWalkable)
            {
                return(true);
            }

            return(false);
        }
예제 #12
0
        protected Path GetPath(int startX, int startY, int endX, int endY)
        {
            // Before we find a path, make sure to make the monster and player Cells walkable
            dungeonMap.SetIsWalkable(startX, startY, true);
            dungeonMap.SetIsWalkable(endX, endY, true);

            PathFinder pathFinder = new PathFinder(dungeonMap, 1.41);
            Path       path       = null;

            try
            {
                path = pathFinder.ShortestPath(
                    dungeonMap.GetCell(startX, startY),
                    dungeonMap.GetCell(endX, endY));
            }
            catch (PathNotFoundException)
            {
                //Remove actors from map
                foreach (Monster m in GetMonsters())
                {
                    dungeonMap.SetIsWalkable(m.X, m.Y, true);
                }
                dungeonMap.SetIsWalkable(player.X, player.Y, true);


                path = cleanMapPF.ShortestPath(
                    dungeonMap.GetCell(startX, startY),
                    dungeonMap.GetCell(endX, endY));
            }

            //Put actors back on the map
            foreach (Monster m in GetMonsters())
            {
                dungeonMap.SetIsWalkable(m.X, m.Y, false);
            }
            dungeonMap.SetIsWalkable(player.X, player.Y, false);

            return(path);
        }
예제 #13
0
        public bool Act(Npc villager, CommandSystem commandSystem)
        {
            DungeonMap dungeonMap = Game.DungeonMap;

            ICell NpcCell = dungeonMap.GetCell(villager.X, villager.Y);

            int randomDir = Game.rng.Next(0, 5);

            //randomDir = randomDir / 25;

            commandSystem.MoveVillager(NpcCell, villager, randomDir);
            return(true);
        }
예제 #14
0
        //Checks to see if a cell is a good place for a door
        private bool IsPotentialDoor(ICell cell)
        {
            //If the cell is not walkable
            //then it is a wall and not a good place for a door
            if (!cell.IsWalkable)
            {
                return(false);
            }

            //check all of the neighbouring cells
            ICell right  = _map.GetCell(cell.X + 1, cell.Y);
            ICell left   = _map.GetCell(cell.X - 1, cell.Y);
            ICell top    = _map.GetCell(cell.X, cell.Y - 1);
            ICell bottom = _map.GetCell(cell.X + 1, cell.Y + 1);

            //make sure that a door is not already there
            if (_map.GetDoor(cell.X, cell.Y) != null ||
                _map.GetDoor(right.X, right.Y) != null ||
                _map.GetDoor(left.X, left.Y) != null ||
                _map.GetDoor(top.X, top.Y) != null ||
                _map.GetDoor(bottom.X, bottom.Y) != null)
            {
                return(false);
            }

            //good place for a door on the right or left of the room
            if (right.IsWalkable && left.IsWalkable && !top.IsWalkable && !bottom.IsWalkable)
            {
                return(true);
            }

            //good place for a door on the top or bottom of the room
            if (!right.IsWalkable && !left.IsWalkable && top.IsWalkable && bottom.IsWalkable)
            {
                return(true);
            }
            return(false);
        }
예제 #15
0
        // Creating the final level of the game
        // Killing the final boss will end the game
        // So there is no need to create stairs down
        public DungeonMap CreateFinalLevel(SchedulingSystem schedule)
        {
            map.Initialize(width, height);
            Rectangle playerSpawn = new Rectangle(10, height / 2 - 5, 8, 8);
            Rectangle bossSpawn   = new Rectangle(width / 2, 0, width / 2 - 1, height - 2);

            List <ICell> playerRoom = new List <ICell>();
            List <ICell> bossRoom   = new List <ICell>();

            for (int i = playerSpawn.X; i < playerSpawn.X + playerSpawn.Width; i++)
            {
                for (int j = playerSpawn.Y; j < playerSpawn.Y + playerSpawn.Height; j++)
                {
                    map.SetCellProperties(i, j, true, true, false);
                    playerRoom.Add(map.GetCell(i, j));
                }
            }

            for (int i = bossSpawn.X; i < bossSpawn.X + bossSpawn.Width; i++)
            {
                for (int j = bossSpawn.Y; j < bossSpawn.Y + bossSpawn.Height; j++)
                {
                    map.SetCellProperties(i, j, true, true, false);
                    bossRoom.Add(map.GetCell(i, j));
                }
            }

            for (int i = playerSpawn.Center.X; i < bossSpawn.Center.X; i++)
            {
                map.SetCellProperties(i, playerSpawn.Center.Y, true, true, false);
            }
            map.Rooms.Add(playerRoom);
            map.Rooms.Add(bossRoom);
            PlacePlayer();

            var dragon = Dragon.Create(1);

            dragon.X = bossSpawn.Center.X;
            dragon.Y = bossSpawn.Center.Y;

            map.AddMonster(dragon);
            CreateStairs();
            // Setting the second stairs at 0,0 to avoid exception
            map.StairsDown.X = map.StairsDown.Y = 0;
            return(map);
        }
예제 #16
0
        /// <summary>
        /// Doesn't rely on Rooms to place the player, but instead
        /// places the player in the middle of the map.
        /// </summary>
        private void PlacePlayerInOverworld()
        {
            Player player = Game.Player;

            if (player == null)
            {
                player = new Player();
            }
            // Find a walkable tile near the middle
            int middleX = (int)_map.Width / 2;
            int middleY = (int)_map.Height / 2;

            // If the tile isn't walkable, try another set up
            while (!_map.GetCell(middleX, middleY).IsWalkable)
            {
                if (Dice.Roll("1d2") > 1)
                {
                    ++middleX;
                }
                else
                {
                    ++middleY;
                }
                if (Dice.Roll("1d2") > 1)
                {
                    --middleX;
                }
                else
                {
                    --middleY;
                }
            }
            // Place the player there now that we know it's walkable
            player.X = middleX;
            player.Y = middleY;

            _map.AddPlayer(player);
        }
예제 #17
0
        public bool Act(Monster monster)
        {
            DungeonMap  dungeonMap = Game.DungeonMap;
            Player      player     = Game.Player;
            FieldOfView monsterFov = new FieldOfView(dungeonMap);

            if (!monster.TurnsAlerted.HasValue)
            {
                foreach (Cell cell in monster.AreaControlled.ToArray())
                {
                    monsterFov.ComputeFov(cell.X, cell.Y, monster.Awareness, true);
                    if (monsterFov.IsInFov(player.X, player.Y))
                    {
                        Game.MessageLog.Add($"{monster.Name} is eager to fight {player.Name}");
                        monster.TurnsAlerted = 1;
                        break;
                    }
                }
            }
            if (monster.TurnsAlerted.HasValue)
            {
                foreach (Cell cell in monster.AreaControlled)
                {
                    dungeonMap.SetIsWalkable(cell.X, cell.Y, true);
                }
                dungeonMap.SetIsWalkable(player.X, player.Y, true);
                PathFinder pathFinder = new PathFinder(dungeonMap);
                Path       path       = null;
                // Calculating the path from the central part of the monster
                try
                {
                    path = pathFinder.ShortestPath(monster.AreaControlled[monster.AreaControlled.Count / 2], dungeonMap.GetCell(player.X, player.Y));
                }
                catch
                {
                    if (monster.AreaControlled.Any(c => c.IsInFov))
                    {
                        Game.MessageLog.Add($"{monster.Name} waits for a turn");
                    }
                }
                foreach (Cell cell in monster.AreaControlled)
                {
                    dungeonMap.SetIsWalkable(cell.X, cell.Y, false);
                }
                dungeonMap.SetIsWalkable(player.X, player.Y, false);
                if (path != null)
                {
                    if (path.Steps.First() != null)
                    {
                        CommandSystem.MoveMonster(monster, path.StepForward());
                    }
                    else
                    {
                        Game.MessageLog.Add($"{monster.Name} growls in frustration");
                    }
                    monster.TurnsAlerted++;
                    if (monster.TurnsAlerted > 90)
                    {
                        monster.TurnsAlerted = null;
                    }
                }
            }
            return(true);
        }
예제 #18
0
        public bool Act(Monster monster, CommandSystem commandSystem)
        {
            DungeonMap  dungeonMap = Game.DungeonMap;
            Player      player     = Game.Player;
            FieldOfView monsterFov = new FieldOfView(dungeonMap);

            // If the monster has not been alerted, compute a field-of-view
            // Use the monsters Awareness value for the distance in the FoV check
            // If the player is in the monster's FoV then alert it
            // Add a message to the MessageLog regarding this alerted status
            if (!monster.TurnsAlerted.HasValue)
            {
                monsterFov.ComputeFov(monster.X, monster.Y, monster.Awareness, true);
                if (monsterFov.IsInFov(player.X, player.Y))
                {
                    Game.MessageLog.Add($"{monster.Name} is eager to fight {player.Name}");
                    monster.TurnsAlerted = 1;
                }
            }

            if (monster.TurnsAlerted.HasValue)
            {
                // Before we find a path, make sure to make the monster and player Cells walkable
                dungeonMap.SetIsWalkable(monster.X, monster.Y, true);
                dungeonMap.SetIsWalkable(player.X, player.Y, true);

                PathFinder pathFinder = new PathFinder(dungeonMap);
                Path       path       = null;

                try
                {
                    path = pathFinder.ShortestPath(
                        dungeonMap.GetCell(monster.X, monster.Y),
                        dungeonMap.GetCell(player.X, player.Y));
                }
                catch (PathNotFoundException)
                {
                    // The monster can see the player, but cannot find a path to him
                    // This could be due to other monsters blocking the way
                    // Add a message to the message log that the monster is waiting
                    Game.MessageLog.Add($"{monster.Name} waits for a turn");
                }

                // Don't forget to set the walkable status back to false
                dungeonMap.SetIsWalkable(monster.X, monster.Y, false);
                dungeonMap.SetIsWalkable(player.X, player.Y, false);

                // In the case that there was a path, tell the CommandSystem to move the monster
                if (path != null)
                {
                    try
                    {
                        // TODO: This should be path.StepForward() but there is a bug in RogueSharp V3
                        // The bug is that a path returned from the pathfinder does not include the source Cell
                        commandSystem.MoveMonster(monster, (Cell)path.StepForward());
                    }
                    catch (NoMoreStepsException)
                    {
                        Game.MessageLog.Add($"{monster.Name} growls in frustration");
                    }
                }

                monster.TurnsAlerted++;

                // Lose alerted status every 15 turns.
                // As long as the player is still in FoV the monster will be realerted
                // Otherwise the monster will quit chasing the player.
                if (monster.TurnsAlerted > 15)
                {
                    monster.TurnsAlerted = null;
                }
            }
            return(true);
        }
예제 #19
0
        public bool Act(Monster monster, CommandSystem commandSystem)
        {
            DungeonMap  dungeonMap = Game.DungeonMap;
            Player      player     = Game.Player;
            FieldOfView monsterFov = new FieldOfView(dungeonMap);

            // Si el enemigo no ha sido alertado, calculamos el campo-de-visión.
            // Usamos el valor de {Awareness} del enemigo para cacular la distancia
            // a la cual puede llegar su campo-de-visión.
            // Si el jugador ésta en el campo-de-visión del enemigo, alertamos al enemigo.
            // Añadimos un mensaje en el MessageLog respecto al estado de esta alarma.
            if (!monster.TurnsAlerted.HasValue)
            {
                monsterFov.ComputeFov(monster.X, monster.Y, monster.Awareness, true);
                if (monsterFov.IsInFov(player.X, player.Y))
                {
                    Game.MessageLog.Add($"{monster.Name} está ansioso por luchar con {player.Name}");
                    monster.TurnsAlerted = 1;
                }
            }

            if (monster.TurnsAlerted.HasValue)
            {
                // Antes de encontrar un camino, nos aseguramos que las celdas
                // entre el enemigo y el jugador son transitables.
                dungeonMap.SetIsWalkable(monster.X, monster.Y, true);
                dungeonMap.SetIsWalkable(player.X, player.Y, true);

                PathFinder pathFinder = new PathFinder(dungeonMap);
                Path       path       = null;

                try
                {
                    path = pathFinder.ShortestPath(
                        dungeonMap.GetCell(monster.X, monster.Y),
                        dungeonMap.GetCell(player.X, player.Y));
                }
                catch (PathNotFoundException)
                {
                    // El enemigo puede ver al jugador, pero no puede encontrar una ruta hasta él.
                    // Esto podría deberse a que otros enemigos bloquearon el camino.
                    // Añadimos un mensaje en el MessageLog mencionando que el enemigo espera un turno.
                    Game.MessageLog.Add($"{monster.Name} espera un turno");
                }

                // No se olvide de establecer el estado de las celdas a intransitable.
                dungeonMap.SetIsWalkable(monster.X, monster.Y, false);
                dungeonMap.SetIsWalkable(player.X, player.Y, false);


                // En caso de que encontremos un camino, llamamos a CommandSystem a mover al enemigo.
                if (path != null)
                {
                    try
                    {
                        // TODO: Esto debería de ser path.StepForward(), pero esto es un bug en RogueSharp V3.
                        // El Bug es que un Path devuelve desde un PathFinder no incluye la fuente de celdas.
                        commandSystem.MoveMonster(monster, path.Steps.First());
                    }
                    catch (NoMoreStepsException)
                    {
                        Game.MessageLog.Add($"{monster.Name} ruge de frustración");
                    }
                }

                monster.TurnsAlerted++;

                // Perdemos el estado de alerta después de 15 turnos.
                // Mientras el jugador siga estando en el campo-de-visión del enemigo,
                // esta seguirá estando alerta.
                // De lo contrario el enemigo dejará de perseguir al jugador.
                if (monster.TurnsAlerted > 15)
                {
                    monster.TurnsAlerted = null;
                }
            }

            return(true);
        }
예제 #20
0
        public static void ContinueOldGame(SerializedGame game)
        {
            Check();
            Random   = new DotNetRandom();
            mapLevel = game.mapLevel;
            string ConsoleTitle = $"MagiCave - Level {mapLevel}";

            rootConsole.Title = ConsoleTitle;
            Random.Restore(game.Random);
            steps  = game.steps;
            Player = game.Player;
            for (int i = 0; i < game.Levels.Length; i++)
            {
                SchedulingSystem = new SchedulingSystem();
                DungeonMap levelmap = new DungeonMap();
                levelmap.Restore(game.Levels[i]);
                levelmap.Doors = game.Doors[i].ToList();
                for (int k = 0; k < mapWidth * mapHeight; k++)
                {
                    if ((game.Levels[i].Cells[k] & MapState.CellProperties.Explored) == MapState.CellProperties.Explored)
                    {
                        int l;
                        int j;
                        if (k >= mapWidth)
                        {
                            j = k / mapWidth;
                            l = k - j * mapWidth;
                        }
                        else
                        {
                            l = k;
                            j = 0;
                        }
                        levelmap.SetCellProperties(l, j, levelmap.GetCell(l, j).IsTransparent, levelmap.GetCell(l, j).IsWalkable, true);
                    }
                }
                //levelmap.Rooms = game.Rooms[i].ToList();
                levelmap.Monsters = game.MonstersOnLevel[i].ToList();
                foreach (Monster m in levelmap.Monsters)
                {
                    if (m.Items == null)
                    {
                        m.Items = new List <Interfaces.IItem>();
                    }
                }
                DungeonGenerator gen = new DungeonGenerator(levelmap);
                gen.Restore(SchedulingSystem);
                SchedulingSystems.AddLast(SchedulingSystem);
                Levels.AddLast(levelmap);
                i++;
            }
            CurrentSchedulingSystem = SchedulingSystems.First;
            CurrentLevel            = Levels.First;
            for (int j = 0; j < mapLevel - 1; j++)
            {
                CurrentSchedulingSystem = CurrentSchedulingSystem.Next;
                CurrentLevel            = CurrentLevel.Next;
            }
            SchedulingSystem = CurrentSchedulingSystem.Value;
            DungeonMap       = CurrentLevel.Value;

            MessageLog.Add("Game loaded successfully");

            Player = game.Player;

            DungeonMap.UpdatePlayerFieldOfView();

            ts.Add(game.ts);
            time.Start();

            renderRequired = true;
        }
예제 #21
0
        private void CreateHallways()
        {
            //Initially connect all rooms to closest rooms
            _islands = new List <List <Rectangle> >();
            foreach (Rectangle room1 in _map.Rooms)
            {
                Rectangle closestRoom = new Rectangle();
                double    distance2   = Double.PositiveInfinity;

                foreach (Rectangle room2 in _map.Rooms)
                {
                    if (room2 != room1)
                    {
                        int roomCenterX      = room1.Center.X;
                        int roomCenterY      = room1.Center.Y;
                        int otherRoomCenterX = room2.Center.X;
                        int otherRoomCenterY = room2.Center.Y;

                        double tmp = Math.Sqrt((Math.Pow(roomCenterX - otherRoomCenterX, 2) +
                                                Math.Pow(roomCenterY - otherRoomCenterY, 2)));

                        if (tmp < Math.Sqrt(distance2 * distance2))
                        {
                            distance2   = tmp;
                            closestRoom = room2;
                        }
                    }
                }
                int closestRoomCenterX = closestRoom.Center.X;
                int closestRoomCenterY = closestRoom.Center.Y;
                int currentRoomCenterX = room1.Center.X;
                int currentRoomCenterY = room1.Center.Y;
                if (Game.Random.Next(1, 2) == 1)
                {
                    CreateHorizontalTunnel(closestRoomCenterX, currentRoomCenterX, closestRoomCenterY);
                    CreateVerticalTunnel(closestRoomCenterY, currentRoomCenterY, currentRoomCenterX);
                }
                else
                {
                    CreateVerticalTunnel(closestRoomCenterY, currentRoomCenterY, closestRoomCenterX);
                    CreateHorizontalTunnel(closestRoomCenterX, currentRoomCenterX, currentRoomCenterY);
                }
            }

            _islands = FormIslands();

            //Start connecting closest islands together
            bool allConnected;

            do
            {
                allConnected = true;
                //Temporary islands that will get merged together with each pass
                List <List <Rectangle> > tmpIslands = FormIslands();
                //Connections of rooms closest to one another between islands
                List <List <Rectangle> > connections = new List <List <Rectangle> >();
                foreach (List <Rectangle> island1 in tmpIslands)
                {
                    Rectangle roomA    = new Rectangle();
                    Rectangle roomB    = new Rectangle();
                    double    distance = double.PositiveInfinity;
                    foreach (Rectangle room1 in island1)
                    {
                        foreach (List <Rectangle> island2 in tmpIslands)
                        {
                            if (island1 != island2)
                            {
                                foreach (Rectangle room2 in island2)
                                {
                                    if (room1 != room2)
                                    {
                                        int room1X = room1.Center.X;
                                        int room1Y = room1.Center.Y;
                                        int room2X = room2.Center.X;
                                        int room2Y = room2.Center.Y;

                                        double tmp = Math.Sqrt((Math.Pow(room1X - room2X, 2) +
                                                                Math.Pow(room1Y - room2Y, 2)));

                                        if (tmp < Math.Sqrt(distance * distance))
                                        {
                                            distance = tmp;
                                            roomA    = room1;
                                            roomB    = room2;
                                        }
                                    }
                                }
                            }
                        }
                    }
                    bool alreadyConnected = false;
                    foreach (List <Rectangle> connection in connections)
                    {
                        if (connection.Contains(roomA))
                        {
                            alreadyConnected = true;
                        }
                    }
                    if (!alreadyConnected)
                    {
                        connections.Add(new List <Rectangle>()
                        {
                            roomA, roomB
                        });
                    }
                }

                while (connections.Any())
                {
                    List <Rectangle> connection = connections[0];
                    int room1X = connection[0].Center.X;
                    int room1Y = connection[0].Center.Y;
                    int room2X = connection[1].Center.X;
                    int room2Y = connection[1].Center.Y;
                    if (Game.Random.Next(1, 2) == 1)
                    {
                        CreateHorizontalTunnel(room1X, room2X, room1Y);
                        CreateVerticalTunnel(room1Y, room2Y, room2X);
                    }
                    else
                    {
                        CreateVerticalTunnel(room1Y, room2Y, room1X);
                        CreateHorizontalTunnel(room1X, room2X, room2Y);
                    }
                    connections.Remove(connection);
                }

                //Check if map is interconnected
                foreach (Rectangle room in _map.Rooms)
                {
                    PathFinder pf   = new PathFinder(_map, 1.41);
                    Path       path = null;

                    path = pf.TryFindShortestPath((_map.GetCell(_map.Rooms[0].Center.X, _map.Rooms[0].Center.Y)),
                                                  _map.GetCell(room.Center.X, room.Center.Y));
                    if (path == null)
                    {
                        allConnected = false;
                    }
                }
            } while (!allConnected);
        }
예제 #22
0
        public bool Act(Monster monster, CommandSystem commandSystem)
        {
            DungeonMap  dungeonMap = Game.DungeonMap;
            Player      player     = Game.player;
            FieldOfView monsterFov = new FieldOfView(dungeonMap);

            //if the monster has not been alerted, compute a field of view
            //use the monsters awarness value for the distance in fov check
            //if the player is in the monsters field of view they alert it
            //when it is alerted send a mesage
            if (!monster.TurnsAlerted.HasValue)
            {
                monsterFov.ComputeFov(monster.X, monster.Y, monster.Awareness, true);
                if (monsterFov.IsInFov(player.X, player.Y))
                {
                    Game.messageLog.Add($"{monster.Name} is eager to fight {player.Name}");
                    monster.TurnsAlerted = 1;
                }
            }

            if (monster.TurnsAlerted.HasValue)
            {
                //make the monster and player cells walkable
                dungeonMap.SetIsWalkable(monster.X, monster.Y, true);
                dungeonMap.SetIsWalkable(player.X, player.Y, true);

                PathFinder pathFinder = new PathFinder(dungeonMap);

                Path path = null;

                try
                {
                    //find the shortest path between where the player is and where the monster is
                    path = pathFinder.ShortestPath(dungeonMap.GetCell(monster.X, monster.Y),
                                                   dungeonMap.GetCell(player.X, player.Y));
                }
                catch (PathNotFoundException)
                {
                    //if the monster sees the player but cant get too him send this message
                    Game.messageLog.Add($"{monster.Name} waits for a turn");
                }

                //set walkable status back too false
                dungeonMap.SetIsWalkable(monster.X, monster.Y, false);
                dungeonMap.SetIsWalkable(player.X, player.Y, false);

                //if there is a path tell the command system too move that monster
                if (path != null)
                {
                    try
                    {
                        commandSystem.MoveMonster(monster, path.StepForward());
                    }
                    catch (NoMoreStepsException)
                    {
                        Game.messageLog.Add($"{monster.Name} growls in frustration");
                    }
                }

                monster.TurnsAlerted++;

                //after 15 turns lose alert status as long as the player is still un fov the monster will stay alert
                //otherwise the monster will quit chasing the player
                if (monster.TurnsAlerted > 15)
                {
                    monster.TurnsAlerted = null;
                }
            }
            return(true);
        }
        public bool Act(Monster monster, CommandSystem commandSystem)
        {
            DungeonMap  dungeonMap = Game.DungeonMap;
            Player      player     = Game.Player;
            FieldOfView monsterFov = new FieldOfView(dungeonMap);

            if (!monster.TurnsAlerted.HasValue)
            {
                monsterFov.ComputeFov(monster.X, monster.Y, monster.Awareness, true);
                if (monsterFov.IsInFov(player.X, player.Y))
                {
                    if (monster.GreetMessages != null)
                    {
                        Random random = new Random();
                        int    i      = random.Next(0, monster.GreetMessages.Length);
                        if (monster.IsABoss)
                        {
                            Game.MessageLog.Add($"{monster.GreetMessages[i]}", Swatch.DbBlood);
                        }
                        else
                        {
                            Game.MessageLog.Add($"{monster.GreetMessages[i]}");
                        }
                    }
                    else
                    {
                        Game.MessageLog.Add($"{monster.Name} is eager to fight {player.Name}");
                    }

                    monster.TurnsAlerted = 1;
                }
            }

            if (monster.TurnsAlerted.HasValue)
            {
                dungeonMap.SetIsWalkable(monster.X, monster.Y, true);
                dungeonMap.SetIsWalkable(player.X, player.Y, true);

                PathFinder pathFinder = new PathFinder(dungeonMap);
                Path       path       = null;

                try {
                    path = pathFinder.ShortestPath(
                        dungeonMap.GetCell(monster.X, monster.Y),
                        dungeonMap.GetCell(player.X, player.Y));
                }
                catch (PathNotFoundException) {
                    if (monster.WaitMessages != null)
                    {
                        Random random = new Random();
                        int    i      = random.Next(0, monster.WaitMessages.Length);
                        Game.MessageLog.Add($"{monster.WaitMessages[i]}");
                    }
                    else
                    {
                        Game.MessageLog.Add($"{monster.Name} waits for a turn");
                    }
                }

                dungeonMap.SetIsWalkable(monster.X, monster.Y, false);
                dungeonMap.SetIsWalkable(player.X, player.Y, false);

                if (path != null)
                {
                    try {
                        commandSystem.MoveMonster(monster, path.StepForward());
                    }
                    catch (NoMoreStepsException) {
                        if (monster.WaitMessages != null)
                        {
                            Random random = new Random();
                            int    i      = random.Next(0, monster.WaitMessages.Length);
                            Game.MessageLog.Add($"{monster.WaitMessages[i]}");
                        }
                        else
                        {
                            Game.MessageLog.Add($"{monster.Name} groans in frustration");
                        }
                    }
                }

                monster.TurnsAlerted++;
                if (monster.TurnsAlerted > 15)
                {
                    monster.TurnsAlerted = null;
                }

                if (monster.State != null && monster.State.Name != "None")
                {
                    monster.State.Perform();
                }
            }
            return(true);
        }
예제 #24
0
    private int FloodFill(DungeonMap map, Point start, int fill)
    {
        int nextFill = fill;
        int xMin     = int.MaxValue;
        int yMin     = int.MaxValue;
        int xMax     = 0;
        int yMax     = 0;

        Stack <Point> stack = new Stack <Point>();
        Queue <Point> doors = new Queue <Point>();

        stack.Push(start);

        while (stack.Count > 0)
        {
            Point a = stack.Pop();
            if (a.X < map.floodMap.GetLength(0) && a.X > 0 &&
                a.Y < map.floodMap.GetLength(1) && a.Y > 0)
            {
                if (map.floodMap[a.X, a.Y] == 0 && map.GetCell(a.X, a.Y).IsTransparent)
                {
                    map.floodMap[a.X, a.Y] = fill;
                    stack.Push(new Point(a.X - 1, a.Y));
                    stack.Push(new Point(a.X + 1, a.Y));
                    stack.Push(new Point(a.X, a.Y - 1));
                    stack.Push(new Point(a.X, a.Y + 1));

                    if (a.X < xMin)
                    {
                        xMin = a.X;
                    }
                    if (a.Y < yMin)
                    {
                        yMin = a.Y;
                    }
                    if (a.X > xMax)
                    {
                        xMax = a.X;
                    }
                    if (a.Y > yMax)
                    {
                        yMax = a.Y;
                    }
                }
                else if (map.floodMap[a.X, a.Y] == 0 && map.GetCell(a.X, a.Y).IsWalkable)
                {
                    map.floodMap[a.X, a.Y] = fill;

                    // Include doors in room?
                    //if (a.X < xMin) xMin = a.X;
                    //if (a.Y < yMin) yMin = a.Y;
                    //if (a.X > xMax) xMax = a.X;
                    //if (a.Y > yMax) yMax = a.Y;

                    if (a == start)
                    {
                        stack.Push(new Point(a.X - 1, a.Y));
                        stack.Push(new Point(a.X + 1, a.Y));
                        stack.Push(new Point(a.X, a.Y - 1));
                        stack.Push(new Point(a.X, a.Y + 1));
                    }

                    Point neighbor  = new Point(-1, -1);
                    int   connectID = 0;

                    foreach (Point n in neighbors)
                    {
                        Point temp = a + n;

                        if (temp.X < 0 || temp.Y < 0 || temp.X > map.Width - 1 || temp.Y > map.Height - 1)
                        {
                            continue;
                        }

                        if (!map.GetCell(temp.X, temp.Y).IsTransparent&& map.GetCell(temp.X, temp.Y).IsWalkable)
                        {
                            neighbor = a + n;

                            if (map.floodMap[temp.X, temp.Y] == 0)
                            {
                                doors.Enqueue(neighbor);
                            }
                            else
                            {
                                connectID = map.floodMap[temp.X, temp.Y];
                            }
                        }
                    }

                    map.Doors.Add(new Door(game)
                    {
                        RoomID        = fill,
                        ConnectRoomID = connectID,
                        X             = a.X,
                        Y             = a.Y,
                        connectionX   = neighbor.X,
                        connectionY   = neighbor.Y,
                        IsOpen        = false
                    });
                }
            }
        }

        Room room = new Room(game)
        {
            ID   = fill,
            BBox = new Rectangle()
            {
                X      = xMin,
                Y      = yMin,
                Width  = xMax - xMin,
                Height = yMax - yMin
            }
        };

        room.Map = new Map(room.BBox.Width, room.BBox.Height);

        for (int y = yMin, y1 = 0; y < yMax; y++, y1++)
        {
            for (int x = xMin, x1 = 0; x < xMax; x++, x1++)
            {
                if (map.floodMap[x, y] == fill)
                {
                    room.Map.SetCellProperties(x1, y1, true, true);
                }
            }
        }

        map.Rooms.Add(room);

        while (doors.Count > 0)
        {
            Point door = doors.Dequeue();

            if (map.floodMap[door.X, door.Y] > 0)
            {
                continue;
            }

            nextFill = FloodFill(map, door, ++nextFill);
        }

        return(nextFill);
    }
        public bool Act(Monster monster, CommandSystem commandSystem)
        {
            DungeonMap dungeonMap = Game.DungeonMap;
            Player     player     = Game.Player;
            FieldOfView <DungeonCell> monsterFov = new FieldOfView <DungeonCell>(dungeonMap);

            //if the monster has not been alerted, compute a field of view
            //use the monsters awareness value for the distance in the fov check
            //if the player is in the monsters fov then alert it
            //add a message to the message log regarding this alerted status
            if (!monster.TurnsAlerted.HasValue)
            {
                monsterFov.ComputeFov(monster.X, monster.Y, monster.Awareness, true);
                if (monsterFov.IsInFov(player.X, player.Y))
                {
                    Game.MessageLog.Add($"{monster.Name} is eager to fight {player.Name}");
                    monster.TurnsAlerted = 1;
                }
            }

            if (monster.TurnsAlerted.HasValue)
            {
                //before we find a path, make sure to make the monster and player cells walkable
                dungeonMap.SetIsWalkable(monster.X, monster.Y, true);
                dungeonMap.SetIsWalkable(player.X, player.Y, true);
                PathFinder <DungeonCell> pathFinder = new PathFinder <DungeonCell>(dungeonMap);
                Path path = null;

                try
                {
                    path = pathFinder.ShortestPath(
                        dungeonMap.GetCell(monster.X, monster.Y),
                        dungeonMap.GetCell(player.X, player.Y)
                        );
                }
                catch (PathNotFoundException)
                {
                    //the monster can see a player but cannot find a path to him
                    Game.MessageLog.Add($"{monster.Name} waits for a turn");
                }

                dungeonMap.SetIsWalkable(monster.X, monster.Y, false);
                dungeonMap.SetIsWalkable(player.X, player.Y, false);

                //in the case that there was a path, tell the command system to move the monster
                if (path != null)
                {
                    try
                    {
                        commandSystem.MoveMonster(monster, path.StepForward());
                    }
                    catch (NoMoreStepsException)
                    {
                        Game.MessageLog.Add($"{monster.Name} growls in frustration");
                    }
                }

                monster.TurnsAlerted++;

                //lose alerted status after 15 turns
                if (monster.TurnsAlerted > 15)
                {
                    monster.TurnsAlerted = null;
                }
            }

            return(true);
        }
예제 #26
0
        public bool Act(Monster monster, CommandSystem commandSystem)
        {
            DungeonMap  dungeonMap = Game.DungeonMap;
            Player      player     = Game.Player;
            FieldOfView monsterFov = new FieldOfView(dungeonMap);

            //If the monster has not been alerted, calculate the FOV, use monster's awarenss for the distance in the FOV
            //If the player is in the FOV alert the monster and add a message indicating the alert
            if (!monster.TurnsAlerted.HasValue)
            {
                monsterFov.ComputeFov(monster.X, monster.Y, monster.Awareness, true);
                if (monsterFov.IsInFov(player.X, player.Y))
                {
                    Game.MessageLog.Add($"{monster.Name} is looking to fight {player.Name}");
                    monster.TurnsAlerted = 1;
                }
            }

            if (monster.TurnsAlerted.HasValue)
            {
                //Before finding a path, make the monster and player cells walkable
                dungeonMap.SetIsWalkable(monster.X, monster.Y, true);
                dungeonMap.SetIsWalkable(player.X, player.Y, true);

                PathFinder pathFinder = new PathFinder(dungeonMap);
                Path       path       = null;

                try
                {
                    path = pathFinder.ShortestPath(
                        dungeonMap.GetCell(monster.X, monster.Y),
                        dungeonMap.GetCell(player.X, player.Y));
                }
                catch (PathNotFoundException)
                {
                    //The monster can see the player but cannot find a path to him
                    Game.MessageLog.Add($"{monster.Name} bides its time, waiting to strike");
                }

                dungeonMap.SetIsWalkable(monster.X, monster.Y, false);
                dungeonMap.SetIsWalkable(player.X, player.Y, false);

                //If there is a path available tell the CommandSystem to move the monster
                if (path != null)
                {
                    try
                    {
                        commandSystem.MoveMonster(monster, path.Steps.First());
                    }
                    catch (NoMoreStepsException)
                    {
                        Game.MessageLog.Add($"{monster.Name} roars angrily");
                    }
                }
                monster.TurnsAlerted++;
                //Lose alerted status every 15 turns
                //monster will stay alert as long as the player is in the FOV
                if (monster.TurnsAlerted > 15)
                {
                    monster.TurnsAlerted = null;
                }
            }
            return(true);
        }
예제 #27
0
        public bool Act(Monster monster, CommandSystem commandSystem)
        {
            DungeonMap  dungeonMap = Game.DungeonMap;
            Player      player     = Game.Player;
            FieldOfView monsterFOV = new FieldOfView(dungeonMap);

            // When the monster hasn't been alerted, compute its FOV
            // Use its Awareness value for the distance in the FOV
            // If the player is in the monster's FOV alert it
            // Print the message to messageLog
            if (!monster.TurnsAlerted.HasValue)
            {
                monsterFOV.ComputeFov(monster.X, monster.Y, monster.Awareness, true);
                if (monsterFOV.IsInFov(player.X, player.Y))
                {
                    Game.MessageLog.Add($"{monster.Name} was alerted by {player.Name}!");
                    monster.TurnsAlerted = 1;
                }
            }

            if (monster.TurnsAlerted.HasValue)
            {
                // Before finding a path, make sure to make the monster and player Cells walkable
                dungeonMap.SetIsWalkable(monster.X, monster.Y, true);
                dungeonMap.SetIsWalkable(player.X, player.Y, true);

                PathFinder pathFinder = new PathFinder(dungeonMap);
                Path       path       = null;

                try
                {
                    path = pathFinder.ShortestPath(
                        dungeonMap.GetCell(monster.X, monster.Y),
                        dungeonMap.GetCell(player.X, player.Y));
                }
                catch (PathNotFoundException)
                {
                    // Something made it impossible for the monster to reach the player
                    // It could be the otherm onsters blocking the way
                    Game.MessageLog.Add($"{monster.Name} is wating for a turn.");
                }

                dungeonMap.SetIsWalkable(monster.X, monster.Y, false);
                dungeonMap.SetIsWalkable(player.X, player.Y, false);
                if (path != null)
                {
                    try
                    {
                        // TODO: This should be path.StepForward() but there is a bug in RogueSharp V3
                        // The bug is that a Path returned from a PathFinder does not include the source Cell
                        commandSystem.MoveMonster(monster, (Cell)path.StepForward());
                    }
                    catch (NoMoreStepsException)
                    {
                        Game.MessageLog.Add($"{monster.Name} growls at the {player.Name} in anger!");
                    }
                }

                monster.TurnsAlerted++;

                // Lose alerted status every 15 turns
                // As long as the player is in monster's FOV, the monster will stay alerted
                // Otherwise, the creature will stop chasing the player
                if (monster.TurnsAlerted > 15)
                {
                    monster.TurnsAlerted = null;
                }
            }

            return(true);
        }
예제 #28
0
        protected ICell GetCell(int x, int y)
        {
            DungeonMap map = MainScreen.GameController.CurrentMap;

            return(map.GetCell(x, y));
        }
예제 #29
0
        public void SelectTarget(Point target)
        {
            DungeonMap          map               = Game.DungeonMap;
            Player              player            = Game.Player;
            List <TreasurePile> checkTreasurePile = map.GetItemsAt(target.X, target.Y);
            List <Plant>        checkPlant        = map.GetPlantsAt(target.X, target.Y);
            Monster             currentMonster    = map.GetMonsterAt(target.X, target.Y);

            if (map.GetCell(target.X, target.Y).IsWalkable)
            {
                if (checkTreasurePile != null)
                {
                    for (int i = 0; i < checkTreasurePile.Count; i++)
                    {
                        if (checkTreasurePile[i].Treasure is Trap)
                        {
                            Game.MessageLog.Add($"That is a {checkTreasurePile[i].Treasure.Name}");
                            foreach (ICell cell in Game.DungeonMap.GetCellsInSquare(target.X, target.Y, 1))
                            {
                                if (Game.DungeonMap.CheckForPlayer(cell.X, cell.Y))
                                {
                                    Game.DungeonMap.RemoveTrap(target.X, target.Y);
                                    Game.MessageLog.Add($"You disarm the {checkTreasurePile[i].Treasure.Name}");
                                }
                            }
                        }
                        else if (checkTreasurePile[i].Treasure is HeadEquipment ||
                                 checkTreasurePile[i].Treasure is HandEquipment ||
                                 checkTreasurePile[i].Treasure is FeetEquipment ||
                                 checkTreasurePile[i].Treasure is BodyEquipment)
                        {
                            Game.MessageLog.Add($"That is a {checkTreasurePile[i].Treasure.Name} {checkTreasurePile[i].Treasure.Description}");
                        }
                        else
                        {
                            Game.MessageLog.Add($"That is a {checkTreasurePile[i].Treasure.Name}");
                        }
                    }
                }

                for (int i = 0; i < Game.DungeonMap.Doors.Count; i++)
                {
                    if (Game.DungeonMap.Doors[i].X == target.X && Game.DungeonMap.Doors[i].Y == target.Y)
                    {
                        // We know the door is open because the tile has to be walkable
                        Game.MessageLog.Add("That is an open door");
                    }
                }

                if (Game.DungeonMap.StairsUp != null)
                {
                    if (Game.DungeonMap.StairsUp.X == target.X && Game.DungeonMap.StairsUp.Y == target.Y)
                    {
                        // We know the door is open because the tile has to be walkable
                        Game.MessageLog.Add("That is some stairs leading up.");
                    }
                }

                if (Game.DungeonMap.StairsDown != null)
                {
                    if (Game.DungeonMap.StairsDown.X == target.X && Game.DungeonMap.StairsDown.Y == target.Y)
                    {
                        // We know the door is open because the tile has to be walkable
                        Game.MessageLog.Add("That is some stairs leading down.");
                    }
                }
            }
            else
            {
                if (currentMonster != null)
                {
                    Game.MessageLog.Add($"That is a {currentMonster.Name}");
                    //Game.MessageLog.Add($"That is a {currentMonster.Description}"); // implement me
                }
                if (checkTreasurePile != null)
                {
                    Game.MessageLog.Add("That is an item sitting on a Tree. A programmer blushes in an alternate dimension");
                }
                if (checkPlant != null)
                {
                    for (int i = 0; i < checkPlant.Count; i++)
                    {
                        if (checkPlant[i] is Tree)
                        {
                            Game.MessageLog.Add($"That is a {checkPlant[i].Name}");
                        }
                    }
                }
                for (int i = 0; i < Game.DungeonMap.Doors.Count; i++)
                {
                    if (Game.DungeonMap.Doors[i].X == target.X && Game.DungeonMap.Doors[i].Y == target.Y)
                    {
                        // We know the door is open because the tile has to be walkable
                        Game.MessageLog.Add("That is a closed door");
                    }
                }
            }
        }
예제 #30
0
    public bool Act(Monster monster, CommandSystem commandSystem, Game game)
    {
        DungeonMap  dungeonMap = game.World;
        Player      player     = game.Player;
        FieldOfView monsterFov = new FieldOfView(dungeonMap);

        if (!(monster is Beholder))
        {
            return(false);
        }

        Monster[] beholder = game.beholder;

        if (beholder[0] == null)
        {
            return(false);
        }

        if (!beholder[0].TurnsAlerted.HasValue)
        {
            monsterFov.ComputeFov(beholder[0].X, beholder[0].Y, beholder[0].Awareness, true);
            if (monsterFov.IsInFov(player.X, player.Y))
            {
                game.MessageLog.Add(beholder[0].Name + " wants to eat you.");
                beholder[0].TurnsAlerted = 1;
                game.Player.EngageCombat(beholder[0]);
            }
        }

        if (beholder[0].TurnsAlerted.HasValue)
        {
            // Can attack with main body?
            for (int b = 0; b < 6; b++)
            {
                foreach (Point p in neighbors)
                {
                    if (game.Player.X == beholder[b].X + p.X && game.Player.Y == beholder[b].Y + p.Y)
                    {
                        commandSystem.Attack(beholder[0], game.Player);
                        beholder[0].MovesCompleted = beholder[0].Moves;
                        break; // only attack once with main
                    }
                }
            }

            if ((beholder[0].MovesCompleted < beholder[0].Moves))
            {
                int  closestSectionIndex = 0;
                int  closestSectionDist  = 10000;
                bool tentaclesGone       = true;

                for (int b = 6; b < 9; b++)
                {
                    if (beholder[b] != null)
                    {
                        tentaclesGone = false;
                    }
                }

                for (int b = 0; b < 9; b++)
                {
                    if (beholder[b] == null)
                    {
                        continue;
                    }

                    dungeonMap.SetIsWalkable(beholder[b].X, beholder[b].Y, true);

                    int distToPlayer = Math.Max(Math.Abs(beholder[b].X - player.X), Math.Abs(beholder[b].Y - player.Y));

                    if (distToPlayer < closestSectionDist)
                    {
                        closestSectionIndex = b;
                    }
                }

                dungeonMap.SetIsWalkable(player.X, player.Y, true);

                PathFinder pathFinder = new PathFinder(dungeonMap, 1d);
                Path       path       = null;

                try
                {
                    path = pathFinder.ShortestPath(
                        dungeonMap.GetCell(beholder[closestSectionIndex].X, beholder[closestSectionIndex].Y),
                        dungeonMap.GetCell(player.X, player.Y));
                }
                catch (PathNotFoundException)
                {
                }

                dungeonMap.SetIsWalkable(player.X, player.Y, false);

                if (path != null)
                {
                    try
                    {
                        Cell cell = path.StepForward() as Cell;
                        int  dX   = cell.X - beholder[closestSectionIndex].X;
                        int  dY   = cell.Y - beholder[closestSectionIndex].Y;

                        if (game.World.CanRectFitInRoom(new Rectangle(beholder[0].X + dX, beholder[0].Y + dY, 3, (tentaclesGone) ? 2 : 3)))
                        {
                            for (int b = 0; b < 9; b++)
                            {
                                if (beholder[b] == null)
                                {
                                    continue;
                                }

                                beholder[b].X = beholder[b].X + dX;
                                beholder[b].Y = beholder[b].Y + dY;
                                //game.World.SetIsWalkable(beholder[b].X, beholder[b].Y, false);
                            }
                        }
                    }
                    catch (NoMoreStepsException)
                    {
                        game.MessageLog.Add(beholder[0].Name + " is stuck.");
                    }
                }

                for (int b = 0; b < 9; b++)
                {
                    if (beholder[b] == null)
                    {
                        continue;
                    }

                    dungeonMap.SetIsWalkable(beholder[b].X, beholder[b].Y, false);
                }
            }

            beholder[0].TurnsAlerted++;

            if (monster.TurnsAlerted > 10)
            {
                if (!monsterFov.IsInFov(player.X, player.Y))
                {
                    game.Player.LeaveCombat(beholder[0]);
                }

                beholder[0].TurnsAlerted = null;
            }
        }
        return(true);
    }