public override void Apply(Dungeon dungeon, DungeonFloor floor) { List <DungeonRegion> pruned = new List <DungeonRegion>(); foreach (DungeonRegion region in floor.Regions) { if (region.Size.x < minWidth || region.Size.y < minHeight) { pruned.Add(region); if (region.Neighbors.Count > 0) { DungeonRegion inheritor = region.Neighbors[Random.Range(0, region.Neighbors.Count)]; region.Neighbors.Remove(inheritor); inheritor.Neighbors.Remove(region); foreach (DungeonRegion neighbor in region.Neighbors) { neighbor.Neighbors.Remove(region); inheritor.Neighbors.Add(neighbor); neighbor.Neighbors.Add(inheritor); } } } } floor.Regions.RemoveAll(region => pruned.Contains(region)); }
public override void Apply(Dungeon dungeon, DungeonFloor floor) { List <DungeonRegion> toSplit = new List <DungeonRegion>(floor.Regions); List <DungeonRegion> added = new List <DungeonRegion>(); floor.Regions.Clear(); while (toSplit.Count > 0) { foreach (DungeonRegion reg in toSplit) { if (CanSplitVertically(reg) || CanSplitHorizontally(reg)) { added.AddRange(Split(reg)); } else { floor.Regions.Add(reg); } } toSplit.Clear(); toSplit.AddRange(added); added.Clear(); } }
public override List <RLBaseTile> FindPath(RLBaseTile fromTile, RLBaseTile to, DungeonFloor floor, CanMoveDelegate canMove, PathCostDelegate pathCost) { return(AStarPathfind(floor, fromTile, to, canMove, pathCost)); }
public override void Apply(Dungeon dungeon, DungeonFloor floor) { List <DungeonRegion> unconnected = new List <DungeonRegion>(floor.Regions); Pathfinding pathfinder = new AStarPathfinding(); foreach (DungeonRegion region in floor.Regions) { List <RLBaseTile> floorTiles = new List <RLBaseTile>(); floor.ForTilesInRegion(region, (x, y, tile) => { if (!tile.GetTileType().BlocksMovement) { floorTiles.Add(tile); } return(tile); }); foreach (DungeonRegion neighbor in region.Neighbors) { if (!unconnected.Contains(neighbor)) { List <RLBaseTile> neighborFloorTiles = new List <RLBaseTile>(); floor.ForTilesInRegion(neighbor, (x, y, tile) => { if (!tile.GetTileType().BlocksMovement) { neighborFloorTiles.Add(tile); } return(tile); }); if (floorTiles.Count > 0 && neighborFloorTiles.Count > 0) { List <RLBaseTile> hall = pathfinder.FindPath(floorTiles[Random.Range(0, floorTiles.Count)], neighborFloorTiles[Random.Range(0, neighborFloorTiles.Count)], floor, (from, to) => true, ((from, to) => 1f)); foreach (RLBaseTile tile in hall) { if (tile.GetTileType().BlocksMovement) { floor.Tiles[tile.GetDisplayPosition().x, tile.GetDisplayPosition().y].SetTileType(hallwayFloor); } } } unconnected.Remove(neighbor); } } unconnected.Remove(region); } }
public DungeonFloor CreateFloor(int width, int height, Dungeon dungeon) { DungeonFloor dungeonFloor = new DungeonFloor(width, height, defaultTileType); List <DungeonRegion> dungeonRegions = new List <DungeonRegion>(dungeonFloor.Regions); foreach (GenerationLayer layer in generators) { layer.Apply(dungeon, dungeonFloor); } return(dungeonFloor); }
public override void Apply(Dungeon dungeon, DungeonFloor floor) { foreach (DungeonRegion reg in floor.Regions) { DungeonRegion region = reg; floor.ForTilesInRegion(reg, (x, y, tile) => { if (x == region.Position.x || x == region.Position.x + region.Size.x - 1 || y == region.Position.y || y == region.Position.y + region.Size.y - 1) { tile.SetTileType(wallType); } else { tile.SetTileType(floorType); } return(tile); }); } }
public abstract List <RLBaseTile> GetVisibleTilesFromPosition(Vector2Int fromPosition, int sightRange, DungeonFloor floor);
public override List <RLBaseTile> LineBetween(Vector2Int fromPosition, Vector2Int toPosition, DungeonFloor floor) { float deltaX = toPosition.x - fromPosition.x; float deltaY = toPosition.y - fromPosition.y; if (Mathf.Abs(deltaY) > Mathf.Abs(deltaX)) { return(LineHigh(fromPosition, toPosition, floor)); } else { return(LineLow(fromPosition, toPosition, floor)); } }
private List <RLBaseTile> LineHigh(Vector2Int fromPosition, Vector2Int toPosition, DungeonFloor floor) { List <RLBaseTile> line = new List <RLBaseTile>(); float deltaX = toPosition.x - fromPosition.x; float deltaY = toPosition.y - fromPosition.y; float deltaErr = 0; if (deltaY != 0) { deltaErr = Mathf.Abs(deltaX / deltaY); } float error = 0; int x = fromPosition.x; int i = 0; for (int y = fromPosition.y; i < Mathf.Abs(deltaY); y += ((int)Mathf.Sign(deltaY)), i++) { RLBaseTile tile = floor.GetTileAt(x, y); if (tile == null) { return(line); } line.Add(tile); error += deltaErr; while (error >= .5) { x += ((int)Mathf.Sign(deltaX)); error--; } } return(line); }
public override List <RLBaseTile> GetVisibleTilesFromPosition(Vector2Int fromPosition, int sightRange, DungeonFloor floor) { BresenhamLine bresenhamLine = new BresenhamLine(); List <RLBaseTile> visibleTiles = new List <RLBaseTile>(); List <Vector2Int> outerTiles = new List <Vector2Int>(); for (int i = 0; i < sightRange; i++) { outerTiles.Add(new Vector2Int(fromPosition.x + sightRange, fromPosition.y + i)); outerTiles.Add(new Vector2Int(fromPosition.x + sightRange, fromPosition.y - i)); outerTiles.Add(new Vector2Int(fromPosition.x - sightRange, fromPosition.y + i)); outerTiles.Add(new Vector2Int(fromPosition.x - sightRange, fromPosition.y - i)); outerTiles.Add(new Vector2Int(fromPosition.x + i, fromPosition.y + sightRange)); outerTiles.Add(new Vector2Int(fromPosition.x - i, fromPosition.y + sightRange)); outerTiles.Add(new Vector2Int(fromPosition.x + i, fromPosition.y - sightRange)); outerTiles.Add(new Vector2Int(fromPosition.x - i, fromPosition.y - sightRange)); } outerTiles = outerTiles.Distinct().ToList(); foreach (Vector2Int vision in outerTiles) { List <RLBaseTile> lineTiles = bresenhamLine.LineBetween(fromPosition, vision, floor); foreach (RLBaseTile tile in lineTiles) { if (!visibleTiles.Contains(tile)) { visibleTiles.Add(tile); } if (!CanSeeThrough(tile)) { break; } } } return(visibleTiles); }
public abstract void Apply(Dungeon dungeon, DungeonFloor floor);
public RLSimpleTile(Vector3Int position, RLTileType type, DungeonFloor floor) { Position = position; TileType = type; Floor = floor; }
public abstract List <RLBaseTile> FindPath(RLBaseTile fromTile, RLBaseTile to, DungeonFloor floor, CanMoveDelegate canMove, PathCostDelegate pathCost);
private static List <RLBaseTile> AStarPathfind(DungeonFloor level, RLBaseTile start, RLBaseTile finish, CanMoveDelegate canMove, PathCostDelegate pathCost) { // A* Pathfinding Debug.Log("Connecting " + start.GetDisplayPosition() + " to " + finish.GetDisplayPosition() + " in " + level); List <RLBaseTile> closedSet = new List <RLBaseTile>(); List <RLBaseTile> openSet = new List <RLBaseTile>(); openSet.Add(start); Dictionary <RLBaseTile, RLBaseTile> cameFrom = new Dictionary <RLBaseTile, RLBaseTile>(); Dictionary <RLBaseTile, float> gScore = new Dictionary <RLBaseTile, float>(); gScore[start] = 0; Dictionary <RLBaseTile, float> fScore = new Dictionary <RLBaseTile, float>(); fScore[start] = Mathf.Abs(start.GetDisplayPosition().x - finish.GetDisplayPosition().x) + Mathf.Abs(start.GetDisplayPosition().y - finish.GetDisplayPosition().y); int length = 0; while (openSet.Count > 0) { length++; openSet.Sort((first, second) => { float firstScore; float secondScore; if (!fScore.TryGetValue(first, out firstScore)) { firstScore = float.PositiveInfinity; } if (!fScore.TryGetValue(second, out secondScore)) { secondScore = float.PositiveInfinity; } if (firstScore < secondScore) { return(-1); } else if (firstScore > secondScore) { return(1); } return(0); }); RLBaseTile current = openSet[0]; if (current == finish) { // write and return path List <RLBaseTile> hallTiles = ReconstructPath(current, cameFrom); Debug.Log("Successful path from " + start.GetDisplayPosition() + " to " + finish.GetDisplayPosition()); return(hallTiles); } openSet.Remove(current); closedSet.Add(current); List <RLBaseTile> neighbors = level.GetOrthogonalNeighborTiles(current); neighbors.RemoveAll((tile) => closedSet.Contains(tile) || !canMove(current, tile)); foreach (RLBaseTile neighbor in neighbors) { if (!openSet.Contains(neighbor)) { openSet.Add(neighbor); } float neighborGscore; if (!gScore.TryGetValue(neighbor, out neighborGscore)) { neighborGscore = float.PositiveInfinity; } // currently using 1 as dist_between float tentativeGScore = gScore[current] + pathCost(current, neighbor); if (tentativeGScore >= neighborGscore) { continue; } cameFrom[neighbor] = current; gScore[neighbor] = tentativeGScore; fScore[neighbor] = gScore[neighbor] + Mathf.Abs(neighbor.GetDisplayPosition().x - finish.GetDisplayPosition().x) + Mathf.Abs(neighbor.GetDisplayPosition().y - finish.GetDisplayPosition().y); } } Debug.Log("Connection failed."); return(new List <RLBaseTile>()); }
public abstract List <RLBaseTile> LineBetween(Vector2Int fromPosition, Vector2Int toPosition, DungeonFloor floor);