diff --git a/Subsurface/Barotrauma.csproj b/Subsurface/Barotrauma.csproj
index a798b157a..42058a519 100644
--- a/Subsurface/Barotrauma.csproj
+++ b/Subsurface/Barotrauma.csproj
@@ -320,9 +320,15 @@
PreserveNewest
+
+ PreserveNewest
+
PreserveNewest
+
+ PreserveNewest
+
PreserveNewest
diff --git a/Subsurface/Content/BackgroundSprites/BackgroundSpritePrefabs.xml b/Subsurface/Content/BackgroundSprites/BackgroundSpritePrefabs.xml
index b132e1b6f..be3735b03 100644
--- a/Subsurface/Content/BackgroundSprites/BackgroundSpritePrefabs.xml
+++ b/Subsurface/Content/BackgroundSprites/BackgroundSpritePrefabs.xml
@@ -1,20 +1,34 @@
-
-
+
+
-
+
-
+
-
-
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Subsurface/Content/BackgroundSprites/ice.png b/Subsurface/Content/BackgroundSprites/ice.png
new file mode 100644
index 000000000..9e3b36a02
Binary files /dev/null and b/Subsurface/Content/BackgroundSprites/ice.png differ
diff --git a/Subsurface/Content/BackgroundSprites/vegetation.png b/Subsurface/Content/BackgroundSprites/vegetation.png
index c104f8594..9c4c1937b 100644
Binary files a/Subsurface/Content/BackgroundSprites/vegetation.png and b/Subsurface/Content/BackgroundSprites/vegetation.png differ
diff --git a/Subsurface/Content/BackgroundSprites/vegetation2.png b/Subsurface/Content/BackgroundSprites/vegetation2.png
new file mode 100644
index 000000000..c0383a41d
Binary files /dev/null and b/Subsurface/Content/BackgroundSprites/vegetation2.png differ
diff --git a/Subsurface/Source/Characters/BackgroundSprite/BackgroundSpriteManager.cs b/Subsurface/Source/Characters/BackgroundSprite/BackgroundSpriteManager.cs
index ba2692d94..347453cfb 100644
--- a/Subsurface/Source/Characters/BackgroundSprite/BackgroundSpriteManager.cs
+++ b/Subsurface/Source/Characters/BackgroundSprite/BackgroundSpriteManager.cs
@@ -2,6 +2,7 @@
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Xml.Linq;
@@ -14,21 +15,33 @@ namespace Barotrauma
public readonly BackgroundSpritePrefab Prefab;
public Vector2 Position;
- public BackgroundSprite(BackgroundSpritePrefab prefab, Vector2 position)
+ public float Scale;
+
+ public float Rotation;
+
+ public BackgroundSprite(BackgroundSpritePrefab prefab, Vector2 position, float scale, float rotation = 0.0f)
{
this.Prefab = prefab;
this.Position = position;
+
+ this.Scale = scale;
+
+ this.Rotation = rotation;
}
}
class BackgroundSpriteManager
{
+ const int GridSize = 1000;
+
private List prefabs;
- private List sprites;
+ //private List sprites;
+
+ private List[,] sprites;
public BackgroundSpriteManager(string configPath)
{
- sprites = new List();
+ //sprites = new List[2,2]();
prefabs = new List();
XDocument doc = ToolBox.TryLoadXml(configPath);
@@ -42,82 +55,166 @@ namespace Barotrauma
public void PlaceSprites(Level level, int amount)
{
- sprites.Clear();
+ sprites = new List[
+ (int)Math.Ceiling(level.Size.X / GridSize),
+ (int)Math.Ceiling(level.Size.Y / GridSize)];
- for (int i = 0 ; i ();
+ }
+ }
+
+ for (int i = 0 ; i < amount; i++)
{
BackgroundSpritePrefab prefab = GetRandomPrefab();
- Vector2? pos = FindSpritePosition(level, prefab);
+ GraphEdge selectedEdge = null;
+ Vector2? pos = FindSpritePosition(level, prefab, out selectedEdge);
if (pos == null) continue;
- var newSprite = new BackgroundSprite(prefab, (Vector2)pos);
-
- int n = 0;
-
- while (n < sprites.Count)
+ float rotation = 0.0f;
+ if (prefab.AlignWithSurface)
{
- n++;
+ Vector2 leftPoint = selectedEdge.point2;
+ Vector2 rightPoint = selectedEdge.point1;
- Sprite existingSprite = sprites[n - 1].Prefab.Sprite;
- if (existingSprite == null) continue;
- if (existingSprite.Texture == newSprite.Prefab.Sprite.Texture) break;
+ //if (leftPoint.X > rightPoint.X)
+ //{
+ // leftPoint = selectedEdge.point2;
+ // rightPoint = selectedEdge.point1;
+ //}
+
+ rotation = -MathUtils.VectorToAngle(rightPoint - leftPoint);
}
- sprites.Insert(n, newSprite);
+ 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;
+
+ 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);
}
}
- private Vector2? FindSpritePosition(Level level, BackgroundSpritePrefab prefab)
+ private Vector2? FindSpritePosition(Level level, BackgroundSpritePrefab prefab, out GraphEdge closestEdge)
{
+ closestEdge = null;
+
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;
VoronoiCell cell = cells[Rand.Int(cells.Count, false)];
- GraphEdge bestEdge = null;
+ List edges = new List();
foreach (GraphEdge edge in cell.edges)
{
+ if (!edge.isSolid) continue;
+
if (prefab.Alignment.HasFlag(Alignment.Bottom))
{
- if (bestEdge == null || edge.Center.Y > bestEdge.Center.Y) bestEdge = edge;
+ if (Math.Abs(edge.point1.X - edge.point2.X) < Math.Abs(edge.point1.Y - edge.point2.Y)) continue;
+ if (edge.Center.Y < cell.Center.Y) edges.Add(edge);
}
else if (prefab.Alignment.HasFlag(Alignment.Top))
{
- if (bestEdge == null || edge.Center.Y < bestEdge.Center.Y) bestEdge = edge;
+ if (Math.Abs(edge.point1.X - edge.point2.X) < Math.Abs(edge.point1.Y - edge.point2.Y)) continue;
+ if (edge.Center.Y > cell.Center.Y) edges.Add(edge);
}
else if (prefab.Alignment.HasFlag(Alignment.Left))
{
- if (bestEdge == null || edge.Center.X > bestEdge.Center.X) bestEdge = edge;
+ if (edge.Center.X < cell.Center.X) edges.Add(edge);
}
else if (prefab.Alignment.HasFlag(Alignment.Right))
{
- if (bestEdge == null || edge.Center.X < bestEdge.Center.X) bestEdge = edge;
+ if (edge.Center.X > cell.Center.X) edges.Add(edge);
+ }
+ else
+ {
+ edges.Add(edge);
}
}
- Vector2 dir = Vector2.Normalize(bestEdge.point1 - bestEdge.point2);
- Vector2 pos = bestEdge.Center;
+ if (!edges.Any()) return null;
- if (prefab.Alignment.HasFlag(Alignment.Bottom))
+ closestEdge = edges[Rand.Int(edges.Count,false)];
+
+ float length = Vector2.Distance(closestEdge.point1, closestEdge.point2);
+ Vector2 dir = (closestEdge.point1 - closestEdge.point2) / length;
+ Vector2 pos = closestEdge.Center;
+
+ pos = closestEdge.point2 + dir * Rand.Range(prefab.Sprite.size.X / 2.0f, length - prefab.Sprite.size.X / 2.0f);
+
+ if (prefab.Alignment.HasFlag(Alignment.Top))
{
- pos.Y -= Math.Abs(dir.Y) * prefab.Sprite.size.X/Math.Abs(dir.X);
+ pos.Y -= Math.Abs(dir.Y) * prefab.Sprite.size.X / Math.Abs(dir.X);
}
- else if (prefab.Alignment.HasFlag(Alignment.Top))
+ else if (prefab.Alignment.HasFlag(Alignment.Bottom))
{
- pos.Y += Math.Abs(dir.Y) * prefab.Sprite.size.X/Math.Abs(dir.X);
+ pos.Y += Math.Abs(dir.Y) * prefab.Sprite.size.X / Math.Abs(dir.X);
}
return pos;
}
- public void DrawSprites(SpriteBatch spriteBatch)
+ public void DrawSprites(SpriteBatch spriteBatch, Camera cam)
{
- foreach (BackgroundSprite sprite in sprites)
+ Stopwatch sw = new Stopwatch();
+ sw.Start();
+
+ Rectangle indices = Rectangle.Empty;
+ indices.X = (int)Math.Floor(cam.WorldView.X / (float)GridSize) - 1;
+ if (indices.X >= sprites.GetLength(0)) return;
+
+ indices.Y = (int)Math.Floor((cam.WorldView.Y - cam.WorldView.Height) / (float)GridSize) - 1;
+ if (indices.Y >= sprites.GetLength(1)) return;
+
+
+ indices.Width = (int)Math.Ceiling(cam.WorldView.Right / (float)GridSize) + 1;
+ if (indices.Width < 0) return;
+ indices.Height = (int)Math.Ceiling(cam.WorldView.Y / (float)GridSize) + 1;
+ if (indices.Height < 0) return;
+
+ indices.X = Math.Max(indices.X, 0);
+ indices.Y = Math.Max(indices.Y, 0);
+ indices.Width = Math.Min(indices.Width, sprites.GetLength(0));
+ indices.Height = Math.Min(indices.Height, sprites.GetLength(1));
+
+ float z = 0.0f;
+ for (int x = indices.X; x < indices.Width; x++)
{
- sprite.Prefab.Sprite.Draw(spriteBatch, new Vector2(sprite.Position.X, -sprite.Position.Y));
+ for (int y = indices.Y; y < indices.Height; y++)
+ {
+ foreach (BackgroundSprite sprite in sprites[x, y])
+ {
+ sprite.Prefab.Sprite.Draw(spriteBatch, new Vector2(sprite.Position.X, -sprite.Position.Y), Color.White, sprite.Rotation, sprite.Scale, SpriteEffects.None, z);
+ z += 0.0001f;
+ }
+ }
}
+
+ sw.Stop();
+ Debug.WriteLine(sw.ElapsedMilliseconds + " - "+sw.ElapsedTicks);
}
private BackgroundSpritePrefab GetRandomPrefab()
diff --git a/Subsurface/Source/Characters/BackgroundSprite/BackgroundSpritePrefab.cs b/Subsurface/Source/Characters/BackgroundSprite/BackgroundSpritePrefab.cs
index 7767e727e..8fe9c8021 100644
--- a/Subsurface/Source/Characters/BackgroundSprite/BackgroundSpritePrefab.cs
+++ b/Subsurface/Source/Characters/BackgroundSprite/BackgroundSpritePrefab.cs
@@ -1,4 +1,5 @@
-using System;
+using Microsoft.Xna.Framework;
+using System;
using System.Xml.Linq;
namespace Barotrauma
@@ -9,6 +10,12 @@ namespace Barotrauma
public readonly Alignment Alignment;
+ public readonly Vector2 Scale;
+
+ public readonly bool AlignWithSurface;
+
+ public readonly Vector2 RandomRotation;
+
public readonly int Commonness;
public BackgroundSpritePrefab(XElement element)
@@ -19,6 +26,15 @@ namespace Barotrauma
Commonness = ToolBox.GetAttributeInt(element, "commonness", 1);
+ Scale.X = ToolBox.GetAttributeFloat(element, "minsize", 1.0f);
+ Scale.Y = ToolBox.GetAttributeFloat(element, "maxsize", 1.0f);
+
+ AlignWithSurface = ToolBox.GetAttributeBool(element, "alignwithsurface", false);
+
+ RandomRotation = ToolBox.GetAttributeVector2(element, "randomrotation", Vector2.Zero);
+ RandomRotation.X = MathHelper.ToRadians(RandomRotation.X);
+ RandomRotation.Y = MathHelper.ToRadians(RandomRotation.Y);
+
foreach (XElement subElement in element.Elements())
{
if (subElement.Name.ToString().ToLower() != "sprite") continue;
diff --git a/Subsurface/Source/Map/Levels/CaveGenerator.cs b/Subsurface/Source/Map/Levels/CaveGenerator.cs
index ee789b836..df04cc499 100644
--- a/Subsurface/Source/Map/Levels/CaveGenerator.cs
+++ b/Subsurface/Source/Map/Levels/CaveGenerator.cs
@@ -40,7 +40,9 @@ namespace Barotrauma
{
for (float y = edges.Y + sideInterval; y < edges.W - sideInterval; y += sideInterval)
{
- sites.Add(new Vector2(x, y) + Rand.Vector(sideInterval*0.45f, false));
+ if (Rand.Int(10, false) == 0) continue;
+
+ sites.Add(new Vector2(x, y) + Rand.Vector(sideInterval*0.4f, false));
}
}
@@ -76,6 +78,8 @@ namespace Barotrauma
float closestDist = 0.0f;
foreach (VoronoiCell cell in newCells)
{
+ if (cell.CellType != CellType.Edge) continue;
+
float dist = Vector2.Distance(startPoint, cell.Center);
if (dist < closestDist || startCell == null)
{
@@ -87,27 +91,62 @@ namespace Barotrauma
startCell.CellType = CellType.Path;
List path = new List() {startCell};
- //VoronoiCell pathCell = startCell;
- //for (int i = 0; i < newCells.Count / 2; i++)
- //{
+ VoronoiCell pathCell = startCell;
+ for (int i = 0; i < newCells.Count / 2; i++)
+ {
- // var allowdNextCells = 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;
+ 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;
- // allowdNextCells.Add(adjacent);
- // }
+ allowedNextCells.Add(adjacent);
+ }
+
+ if (allowedNextCells.Count == 0) break;
- // if (allowdNextCells.Count == 0) break;
+ pathCell = allowedNextCells[Rand.Int(allowedNextCells.Count, false)];
+ if (Rand.Int(4,false)==0)
+ {
+ float furthestDist = 0.0f;
+ foreach (VoronoiCell nextCell in allowedNextCells)
+ {
+ float dist = Vector2.Distance(startCell.Center, nextCell.Center);
+ if (dist > furthestDist || furthestDist == 0.0f)
+ {
+ furthestDist = dist;
+ pathCell = nextCell;
+ }
+ }
+ }
- // pathCell = allowdNextCells[Rand.Int(allowdNextCells.Count, false)];
- // path.Add(pathCell);
- //}
+ pathCell.CellType = CellType.Path;
+ path.Add(pathCell);
+ }
+
+ float minPathWidth = 100.0f;
+ for (int i = 0; i < path.Count; i++)
+ {
+ var cell = path[i];
+ foreach (GraphEdge edge in cell.edges)
+ {
+ 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);
+ if (i>0 && (adjacentCell.CellType == CellType.Path || adjacentCell.CellType == CellType.Edge)) continue;
+
+ adjacentCell.CellType = CellType.Path;
+ path.Add(adjacentCell);
+ }
+ }
return path;
}
diff --git a/Subsurface/Source/Map/Levels/Level.cs b/Subsurface/Source/Map/Levels/Level.cs
index c5e99c239..6273ba528 100644
--- a/Subsurface/Source/Map/Levels/Level.cs
+++ b/Subsurface/Source/Map/Levels/Level.cs
@@ -310,47 +310,58 @@ namespace Barotrauma
foreach (VoronoiCell cell in pathCells)
{
+ cell.CellType = CellType.Path;
cells.Remove(cell);
}
- //for (int i = 0; i < 3; i++)
- //{
- // Vector2 startPoint = Vector2.Zero;
- // VoronoiCell startCell = null;
- // while (true)
- // {
- // startCell = cells[Rand.Int(cells.Count, false)];
+ List usedCaveCells = new List();
+ for (int i = 0; i < 3; i++)
+ {
+ Vector2 startPoint = Vector2.Zero;
+ VoronoiCell startCell = null;
- // GraphEdge startEdge =
- // startCell.edges.Find(e => pathCells.Contains(e.AdjacentCell(startCell)));
+ var caveCells = new List();
- // if (startEdge != null)
- // {
- // startPoint = (startEdge.point1 + startEdge.point2) / 2.0f;
- // break;
- // }
- // }
-
- // var caveCells = GetCells(startCell.Center, 1);
+ while (true)
+ {
+ startCell = cells[Rand.Int(cells.Count, false)];
- // List caveSolidCells;
+ GraphEdge startEdge =
+ startCell.edges.Find(e => pathCells.Contains(e.AdjacentCell(startCell)));
- // var cavePathCells = CaveGenerator.CarveCave(caveCells, startPoint, out caveSolidCells);
+ if (startEdge != null)
+ {
+ startPoint = (startEdge.point1 + startEdge.point2) / 2.0f;
+ startPoint += startPoint - startCell.Center;
- // caveCells.ForEach(c => cells.Remove(c));
+ caveCells = GetCells(startCell.Center, 2);
+ caveCells.RemoveAll(c => c.CellType == CellType.Path);
- // //caveSolidCells = CleanCells(cavePathCells);
+ if (usedCaveCells.Any(c => caveCells.Contains(c))) continue;
+ break;
+ }
+ }
- // cells.AddRange(caveSolidCells);
+ usedCaveCells.AddRange(caveCells);
- // foreach (VoronoiCell cell in cavePathCells)
- // {
- // cells.Remove(cell);
- // }
+ List caveSolidCells;
- // pathCells.AddRange(cavePathCells);
- //}
+ var cavePathCells = CaveGenerator.CarveCave(caveCells, startPoint, out caveSolidCells);
+
+ caveCells.ForEach(c => cells.Remove(c));
+
+ //caveSolidCells = CleanCells(cavePathCells);
+
+ cells.AddRange(caveSolidCells);
+
+ foreach (VoronoiCell cell in cavePathCells)
+ {
+ cells.Remove(cell);
+ }
+
+ pathCells.AddRange(cavePathCells);
+ }
for (int x = 0; x < cellGrid.GetLength(0); x++)
{
@@ -376,6 +387,7 @@ namespace Barotrauma
renderer.SetBodyVertices(bodyVertices.ToArray());
renderer.SetWallVertices(CaveGenerator.GenerateWallShapes(cells));
+ renderer.PlaceSprites(1000);
wrappingWalls = new WrappingWall[2, 2];
@@ -442,7 +454,6 @@ namespace Barotrauma
endPosition = temp;
}
- renderer.PlaceSprites(100);
Debug.WriteLine("**********************************************************************************");
Debug.WriteLine("Generated a map with " + sites.Count + " sites in " + sw.ElapsedMilliseconds + " ms");
diff --git a/Subsurface/Source/Map/Levels/LevelRenderer.cs b/Subsurface/Source/Map/Levels/LevelRenderer.cs
index fe526f726..21af54e53 100644
--- a/Subsurface/Source/Map/Levels/LevelRenderer.cs
+++ b/Subsurface/Source/Map/Levels/LevelRenderer.cs
@@ -120,7 +120,7 @@ namespace Barotrauma
SamplerState.LinearWrap, DepthStencilState.Default, null, null,
cam.Transform);
- backgroundSpriteManager.DrawSprites(spriteBatch);
+ backgroundSpriteManager.DrawSprites(spriteBatch, cam);
if (backgroundCreatureManager!=null) backgroundCreatureManager.Draw(spriteBatch);