/// <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, Game game) { DungeonMap dungeonMap = game.World; Player player = game.Player; FieldOfView monsterFov = new FieldOfView(dungeonMap); // If the monster has not been alerted, compute a field-of-view // Use the monster's 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, 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 commandSystem.MoveMonster(monster, path.StepForward() as Cell); } 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 stay alert // Otherwise the monster will quit chasing the player. if (monster.TurnsAlerted > 15) { monster.TurnsAlerted = null; } } return(true); }