/* ========= PATHFINDING METHODS ========= */ /// <summary> /// Return a list of possible moves for the player /// </summary> /// <param name="world">World the player is currently located in</param> /// <param name="location">Location the player is currently at</param> /// <param name="allowUnsafe">Allow possible but unsafe locations</param> /// <returns>A list of new locations the player can move to</returns> public static IEnumerable <Location> GetAvailableMoves(World world, Location location, bool allowUnsafe = false) { List <Location> availableMoves = new List <Location>(); if (IsOnGround(world, location) || IsSwimming(world, location)) { foreach (Direction dir in Enum.GetValues(typeof(Direction))) { if (CanMove(world, location, dir) && (allowUnsafe || IsSafe(world, location.Move(dir)))) { availableMoves.Add(location.Move(dir)); } } } else { foreach (Direction dir in new [] { Direction.East, Direction.West, Direction.North, Direction.South }) { if (CanMove(world, location, dir) && IsOnGround(world, location.Move(dir)) && (allowUnsafe || IsSafe(world, location.Move(dir)))) { availableMoves.Add(location.Move(dir)); } } availableMoves.Add(location.Move(Direction.Down)); } return(availableMoves); }
/* ========= SIMPLE MOVEMENTS ========= */ /// <summary> /// Check if the player can move in the specified direction /// </summary> /// <param name="world">World the player is currently located in</param> /// <param name="location">Location the player is currently at</param> /// <param name="direction">Direction the player is moving to</param> /// <returns>True if the player can move in the specified direction</returns> public static bool CanMove(World world, Location location, Direction direction) { switch (direction) { case Direction.Down: return(!IsOnGround(world, location)); case Direction.Up: return((IsOnGround(world, location) || IsSwimming(world, location)) && !world.GetBlock(location.Move(Direction.Up, 2)).Type.IsSolid()); case Direction.East: case Direction.West: case Direction.South: case Direction.North: return(!world.GetBlock(location.Move(direction)).Type.IsSolid() && !world.GetBlock(location.Move(direction).Move(Direction.Up)).Type.IsSolid()); default: throw new ArgumentException("Unknown direction", "direction"); } }
/// <summary> /// Check if the specified location is safe /// </summary> /// <param name="world">World for performing check</param> /// <param name="location">Location to check</param> /// <returns>True if the destination location won't directly harm the player</returns> public static bool IsSafe(World world, Location location) { return //No block that can harm the player (!world.GetBlock(location).Type.CanHarmPlayers() && !world.GetBlock(location.Move(Direction.Up)).Type.CanHarmPlayers() && !world.GetBlock(location.Move(Direction.Down)).Type.CanHarmPlayers() //No fall from a too high place && (world.GetBlock(location.Move(Direction.Down)).Type.IsSolid() || world.GetBlock(location.Move(Direction.Down, 2)).Type.IsSolid() || world.GetBlock(location.Move(Direction.Down, 3)).Type.IsSolid()) //Not an underwater location && !(world.GetBlock(location.Move(Direction.Up)).Type.IsLiquid())); }
/* ========= LOCATION PROPERTIES ========= */ /// <summary> /// Check if the specified location is on the ground /// </summary> /// <param name="world">World for performing check</param> /// <param name="location">Location to check</param> /// <returns>True if the specified location is on the ground</returns> public static bool IsOnGround(World world, Location location) { return(world.GetBlock(location.Move(Direction.Down)).Type.IsSolid() && (location.Y <= Math.Truncate(location.Y) + 0.0001)); }