/// <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); }
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); }
//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); }
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); }
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); }
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); }
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); }
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); }
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); }
// 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); }
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); }
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); }
//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); }
// 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); }
/// <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); }
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); }
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); }
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); }
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; }
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); }
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); }
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); }
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); }
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); }
protected ICell GetCell(int x, int y) { DungeonMap map = MainScreen.GameController.CurrentMap; return(map.GetCell(x, y)); }
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"); } } } }
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); }