diff --git a/Subsurface/Source/Characters/BackgroundSprite/BackgroundSpriteManager.cs b/Subsurface/Source/Characters/BackgroundSprite/BackgroundSpriteManager.cs index 347453cfb..ec3ba6f39 100644 --- a/Subsurface/Source/Characters/BackgroundSprite/BackgroundSpriteManager.cs +++ b/Subsurface/Source/Characters/BackgroundSprite/BackgroundSpriteManager.cs @@ -80,39 +80,21 @@ namespace Barotrauma { Vector2 leftPoint = selectedEdge.point2; Vector2 rightPoint = selectedEdge.point1; - - //if (leftPoint.X > rightPoint.X) - //{ - // leftPoint = selectedEdge.point2; - // rightPoint = selectedEdge.point1; - //} - + rotation = -MathUtils.VectorToAngle(rightPoint - leftPoint); } rotation += Rand.Range(prefab.RandomRotation.X, prefab.RandomRotation.Y, false); - var newSprite = new BackgroundSprite(prefab, (Vector2)pos, Rand.Range(prefab.Scale.X, prefab.Scale.Y), rotation); - - int n = 0; - + var newSprite = new BackgroundSprite(prefab, + (Vector2)pos, Rand.Range(prefab.Scale.X, prefab.Scale.Y, false), rotation); + int x = (int)Math.Floor(((Vector2)pos).X / GridSize); if (x<0 || x >= sprites.GetLength(0)) continue; int y = (int)Math.Floor(((Vector2)pos).Y / GridSize); if (y<0 || 1 >= sprites.GetLength(1)) continue; sprites[x,y].Add(newSprite); - - //while (n < sprites.Count) - //{ - // n++; - - // Sprite existingSprite = sprites[n - 1].Prefab.Sprite; - // if (existingSprite == null) continue; - // if (existingSprite.Texture == newSprite.Prefab.Sprite.Texture) break; - //} - - //sprites.Insert(n, newSprite); } } @@ -120,7 +102,10 @@ namespace Barotrauma { closestEdge = null; - Vector2 randomPos = new Vector2(Rand.Range(0.0f, level.Size.X, false), Rand.Range(0.0f, level.Size.Y, false)); + Vector2 randomPos = new Vector2( + Rand.Range(0.0f, level.Size.X, false), + Rand.Range(0.0f, level.Size.Y, false)); + var cells = level.GetCells(randomPos); if (!cells.Any()) return null; diff --git a/Subsurface/Source/Map/Levels/CaveGenerator.cs b/Subsurface/Source/Map/Levels/CaveGenerator.cs index df04cc499..f66147f43 100644 --- a/Subsurface/Source/Map/Levels/CaveGenerator.cs +++ b/Subsurface/Source/Map/Levels/CaveGenerator.cs @@ -21,7 +21,8 @@ namespace Barotrauma List sites = new List(); - float sideInterval = 400.0f; + float siteInterval = 400.0f; + float siteVariance = siteInterval * 0.4f; Vector4 edges = new Vector4( cells.Min(x => x.edges.Min(e => e.point1.X)), @@ -29,20 +30,20 @@ namespace Barotrauma cells.Max(x => x.edges.Max(e => e.point1.X)), cells.Max(x => x.edges.Max(e => e.point1.Y))); - edges.X -= sideInterval * 2; - edges.Y -= sideInterval * 2; - edges.Z += sideInterval * 2; - edges.W += sideInterval * 2; + edges.X -= siteInterval * 2; + edges.Y -= siteInterval * 2; + edges.Z += siteInterval * 2; + edges.W += siteInterval * 2; Rectangle borders = new Rectangle((int)edges.X, (int)edges.Y, (int)(edges.Z - edges.X), (int)(edges.W - edges.Y)); - for (float x = edges.X + sideInterval; x < edges.Z - sideInterval; x += sideInterval) + for (float x = edges.X + siteInterval; x < edges.Z - siteInterval; x += siteInterval) { - for (float y = edges.Y + sideInterval; y < edges.W - sideInterval; y += sideInterval) + for (float y = edges.Y + siteInterval; y < edges.W - siteInterval; y += siteInterval) { - if (Rand.Int(10, false) == 0) continue; + if (Rand.Int(5, false) == 0) continue; //skip some positions to make the cells more irregular - sites.Add(new Vector2(x, y) + Rand.Vector(sideInterval*0.4f, false)); + sites.Add(new Vector2(x, y) + Rand.Vector(siteVariance, false)); } } @@ -51,9 +52,9 @@ namespace Barotrauma List[,] cellGrid; newCells = GraphEdgesToCells(graphEdges, borders, 1000, out cellGrid); - //remove cells that aren't inside any of the original "base cells" foreach (VoronoiCell cell in newCells) { + //if the cell is at the edge of the graph, remove it if (cell.edges.Any(e => e.point1.X == edges.X || e.point1.X == edges.Z || e.point1.Y == edges.Z || e.point1.Y == edges.W)) @@ -61,10 +62,12 @@ namespace Barotrauma cell.CellType = CellType.Removed; continue; } - + + //remove cells that aren't inside any of the original "base cells" if (cells.Any(c => c.IsPointInside(cell.Center))) continue; foreach (GraphEdge edge in cell.edges) { + //mark all the cells adjacent to the removed cell as edges of the cave var adjacent = edge.AdjacentCell(cell); if (adjacent != null && adjacent.CellType != CellType.Removed) adjacent.CellType = CellType.Edge; } @@ -74,6 +77,7 @@ namespace Barotrauma newCells.RemoveAll(newCell => newCell.CellType == CellType.Removed); + //start carving from the edge cell closest to the startPoint VoronoiCell startCell = null; float closestDist = 0.0f; foreach (VoronoiCell cell in newCells) @@ -94,13 +98,11 @@ namespace Barotrauma VoronoiCell pathCell = startCell; for (int i = 0; i < newCells.Count / 2; i++) { - var allowedNextCells = new List(); foreach (GraphEdge edge in pathCell.edges) { var adjacent = edge.AdjacentCell(pathCell); if (adjacent == null || - //adjacent.CellType == CellType.Path || adjacent.CellType == CellType.Removed || adjacent.CellType == CellType.Edge) continue; @@ -109,8 +111,11 @@ namespace Barotrauma if (allowedNextCells.Count == 0) break; + //randomly pick one of the adjacent cells as the next cell pathCell = allowedNextCells[Rand.Int(allowedNextCells.Count, false)]; - if (Rand.Int(4,false)==0) + + //randomly take steps further away from the startpoint to make the cave expand further + if (Rand.Int(4, false) == 0) { float furthestDist = 0.0f; foreach (VoronoiCell nextCell in allowedNextCells) @@ -128,6 +133,7 @@ namespace Barotrauma path.Add(pathCell); } + //make sure the tunnel is always wider than minPathWidth float minPathWidth = 100.0f; for (int i = 0; i < path.Count; i++) { @@ -137,7 +143,6 @@ namespace Barotrauma if (edge.point1 == edge.point2) continue; if (Vector2.Distance(edge.point1, edge.point2) > minPathWidth) continue; - GraphEdge adjacentEdge = cell.edges.Find(e => e != edge && (e.point1 == edge.point1 || e.point2 == edge.point1)); var adjacentCell = adjacentEdge.AdjacentCell(cell); diff --git a/Subsurface/Source/Map/Levels/Level.cs b/Subsurface/Source/Map/Levels/Level.cs index 6273ba528..dcbcdacd4 100644 --- a/Subsurface/Source/Map/Levels/Level.cs +++ b/Subsurface/Source/Map/Levels/Level.cs @@ -288,22 +288,8 @@ namespace Barotrauma Debug.WriteLine("path: " + sw2.ElapsedMilliseconds + " ms"); sw2.Restart(); - //for (int i = 0; i < 2; i++ ) - //{ - // Vector2 tunnelStart = (i == 0) ? startPosition : endPosition; - - // pathCells.AddRange - // ( - // GeneratePath(rand, tunnelStart, new Vector2(tunnelStart.X, borders.Height), cells, pathBorders, minWidth, 0.1f, mirror) - // ); - //} - - - cells = CleanCells(pathCells); - - - + pathCells.AddRange(CreateBottomHoles(Rand.Range(0.2f,0.8f, false), new Rectangle( (int)(borders.Width * 0.2f), 0, (int)(borders.Width * 0.6f), (int)(borders.Height * 0.3f)))); @@ -313,46 +299,55 @@ namespace Barotrauma cell.CellType = CellType.Path; cells.Remove(cell); } - - + + //generate some narrow caves + int caveAmount = Rand.Int(3, false); List usedCaveCells = new List(); - for (int i = 0; i < 3; i++) + for (int i = 0; i < caveAmount; i++) { Vector2 startPoint = Vector2.Zero; VoronoiCell startCell = null; var caveCells = new List(); - while (true) + int maxTries = 5, tries = 0; + while (tries pathCells.Contains(e.AdjacentCell(startCell))); - + if (startEdge != null) { startPoint = (startEdge.point1 + startEdge.point2) / 2.0f; startPoint += startPoint - startCell.Center; + //get the cells in which the cave will be carved caveCells = GetCells(startCell.Center, 2); + //remove cells that have already been "carved" out caveCells.RemoveAll(c => c.CellType == CellType.Path); + //if any of the cells have already been used as a cave, continue and find some other cells if (usedCaveCells.Any(c => caveCells.Contains(c))) continue; break; } + + tries++; } + //couldn't find a place for a cave -> abort + if (tries >= maxTries) break; + usedCaveCells.AddRange(caveCells); List caveSolidCells; - var cavePathCells = CaveGenerator.CarveCave(caveCells, startPoint, out caveSolidCells); + //remove the large cells used as a "base" for the cave (they've now been replaced with smaller ones) caveCells.ForEach(c => cells.Remove(c)); - - //caveSolidCells = CleanCells(cavePathCells); - + cells.AddRange(caveSolidCells); foreach (VoronoiCell cell in cavePathCells) @@ -361,13 +356,18 @@ namespace Barotrauma } pathCells.AddRange(cavePathCells); + + for (int j = cavePathCells.Count / 2; j < cavePathCells.Count; j+=10) + { + positionsOfInterest.Add(new InterestingPosition(cavePathCells[i].Center, false)); + } } for (int x = 0; x < cellGrid.GetLength(0); x++) { for (int y = 0; y < cellGrid.GetLength(1); y++) { - cellGrid[x, y].Clear(); + cellGrid[x, y] .Clear(); } } @@ -376,8 +376,6 @@ namespace Barotrauma cellGrid[(int)Math.Floor(cell.Center.X / GridCellSize), (int)Math.Floor(cell.Center.Y / GridCellSize)].Add(cell); } - - startPosition.Y = borders.Height; endPosition.Y = borders.Height; @@ -396,7 +394,7 @@ namespace Barotrauma for (int i = 0; i < 2; i++) { wrappingWalls[side, i] = new WrappingWall(pathCells, cells, borders.Height * 0.5f, - (side == 0 ? -1 : 1) * (i == 0 ? 1 : 2)); + (side == 0 ? -1 : 1) * (i + 1)); List wrappingWallVertices; CaveGenerator.GeneratePolygons(wrappingWalls[side, i].Cells, out wrappingWallVertices, false);