diff --git a/Barotrauma/BarotraumaClient/Source/Characters/BackgroundSprite/BackgroundSpriteManager.cs b/Barotrauma/BarotraumaClient/Source/Characters/BackgroundSprite/BackgroundSpriteManager.cs index 6b6b9d0f9..1bb297d4d 100644 --- a/Barotrauma/BarotraumaClient/Source/Characters/BackgroundSprite/BackgroundSpriteManager.cs +++ b/Barotrauma/BarotraumaClient/Source/Characters/BackgroundSprite/BackgroundSpriteManager.cs @@ -32,13 +32,17 @@ namespace Barotrauma class BackgroundSpriteManager { - const int GridSize = 1000; + const int GridSize = 2000; private List prefabs = new List(); private List[,] sprites; - private float swingTimer; + private List visibleSprites = new List(); + + private Rectangle currentGridIndices; + + private float swingTimer, swingState; public BackgroundSpriteManager(string configPath) { @@ -74,16 +78,8 @@ namespace Barotrauma { sprites = new List[ (int)Math.Ceiling(level.Size.X / GridSize), - (int)Math.Ceiling(level.Size.Y / GridSize)]; - - for (int x = 0; x < sprites.GetLength(0); x++) - { - for (int y = 0; y < sprites.GetLength(1); y++) - { - sprites[x, y] = new List(); - } - } - + (int)Math.Ceiling((level.Size.Y - level.BottomPos) / GridSize)]; + for (int i = 0 ; i < amount; i++) { BackgroundSpritePrefab prefab = GetRandomPrefab(level.GenerationParams.Name); @@ -133,14 +129,15 @@ namespace Barotrauma int maxX = (int)Math.Floor((spriteCorners.Max(c => c.X) + newSprite.Position.Z) / GridSize); if (minX < 0 || maxX >= sprites.GetLength(0)) continue; - int minY = (int)Math.Floor((spriteCorners.Min(c => c.Y) - newSprite.Position.Z) / GridSize); - int maxY = (int)Math.Floor((spriteCorners.Max(c => c.Y) + newSprite.Position.Z) / GridSize); + int minY = (int)Math.Floor((spriteCorners.Min(c => c.Y) - newSprite.Position.Z - level.BottomPos) / GridSize); + int maxY = (int)Math.Floor((spriteCorners.Max(c => c.Y) + newSprite.Position.Z - level.BottomPos) / GridSize); if (minY < 0 || maxY >= sprites.GetLength(1)) continue; for (int x = minX; x <= maxX; x++) { for (int y = minY; y <= maxY; y++) { + if (sprites[x, y] == null) sprites[x, y] = new List(); sprites[x, y].Add(newSprite); } } @@ -156,13 +153,17 @@ namespace Barotrauma Rand.Range(0.0f, level.Size.X, Rand.RandSync.ClientOnly), Rand.Range(0.0f, level.Size.Y, Rand.RandSync.ClientOnly)); - if (!prefab.SpawnOnWalls) return randomPos; + if (prefab.SpawnPos == BackgroundSpritePrefab.SpawnPosType.None) return randomPos; List edges = new List(); List normals = new List(); - var cells = level.GetCells(randomPos); + System.Diagnostics.Debug.Assert(level.ExtraWalls.Length == 1); + List cells = new List(); + if (prefab.SpawnPos.HasFlag(BackgroundSpritePrefab.SpawnPosType.Wall)) cells.AddRange(level.GetCells(randomPos)); + if (prefab.SpawnPos.HasFlag(BackgroundSpritePrefab.SpawnPosType.SeaFloor)) cells.AddRange(level.ExtraWalls[0].Cells); + if (cells.Any()) { VoronoiCell cell = cells[Rand.Int(cells.Count, Rand.RandSync.ClientOnly)]; @@ -197,21 +198,24 @@ namespace Barotrauma normals.Add(normal); } } - - foreach (RuinGeneration.Ruin ruin in Level.Loaded.Ruins) + + if (prefab.SpawnPos.HasFlag(BackgroundSpritePrefab.SpawnPosType.RuinWall)) { - Rectangle expandedArea = ruin.Area; - expandedArea.Inflate(ruin.Area.Width, ruin.Area.Height); - if (!expandedArea.Contains(randomPos)) continue; - - foreach (var ruinShape in ruin.RuinShapes) + foreach (RuinGeneration.Ruin ruin in Level.Loaded.Ruins) { - foreach (var wall in ruinShape.Walls) - { - if (!prefab.Alignment.HasFlag(ruinShape.GetLineAlignment(wall))) continue; + Rectangle expandedArea = ruin.Area; + expandedArea.Inflate(ruin.Area.Width, ruin.Area.Height); + if (!expandedArea.Contains(randomPos)) continue; - edges.Add(new GraphEdge(wall.A, wall.B)); - normals.Add((wall.A + wall.B) / 2.0f - ruinShape.Center); + foreach (var ruinShape in ruin.RuinShapes) + { + foreach (var wall in ruinShape.Walls) + { + if (!prefab.Alignment.HasFlag(ruinShape.GetLineAlignment(wall))) continue; + + edges.Add(new GraphEdge(wall.A, wall.B)); + normals.Add((wall.A + wall.B) / 2.0f - ruinShape.Center); + } } } } @@ -232,6 +236,28 @@ namespace Barotrauma public void Update(float deltaTime) { swingTimer += deltaTime; + swingState = (float)Math.Sin(swingTimer * 0.1f); + + foreach (BackgroundSprite s in visibleSprites) + { + if (s.Prefab.ParticleEmitter != null) + { + Vector2 emitterPos = new Vector2(s.Prefab.EmitterPosition.X, s.Prefab.EmitterPosition.Y); + + if (s.Rotation != 0.0f || s.Prefab.SwingAmount != 0.0f) + { + var ca = (float)Math.Cos(s.Rotation + swingState * s.Prefab.SwingAmount); + var sa = (float)Math.Sin(s.Rotation + swingState * s.Prefab.SwingAmount); + + emitterPos = new Vector2( + ca * emitterPos.X + sa * emitterPos.Y, + -sa * emitterPos.X + ca * emitterPos.Y); + } + + s.Prefab.ParticleEmitter.Emit(deltaTime, new Vector2(s.Position.X, s.Position.Y) + emitterPos); + } + } + } public void DrawSprites(SpriteBatch spriteBatch, Camera cam) @@ -239,12 +265,12 @@ namespace Barotrauma Rectangle indices = Rectangle.Empty; indices.X = (int)Math.Floor(cam.WorldView.X / (float)GridSize); if (indices.X >= sprites.GetLength(0)) return; - indices.Y = (int)Math.Floor((cam.WorldView.Y - cam.WorldView.Height) / (float)GridSize); + indices.Y = (int)Math.Floor((cam.WorldView.Y - cam.WorldView.Height - Level.Loaded.BottomPos) / (float)GridSize); if (indices.Y >= sprites.GetLength(1)) return; indices.Width = (int)Math.Floor(cam.WorldView.Right / (float)GridSize)+1; if (indices.Width < 0) return; - indices.Height = (int)Math.Floor(cam.WorldView.Y / (float)GridSize)+1; + indices.Height = (int)Math.Floor((cam.WorldView.Y - Level.Loaded.BottomPos) / (float)GridSize)+1; if (indices.Height < 0) return; indices.X = Math.Max(indices.X, 0); @@ -252,42 +278,46 @@ namespace Barotrauma indices.Width = Math.Min(indices.Width, sprites.GetLength(0)-1); indices.Height = Math.Min(indices.Height, sprites.GetLength(1)-1); - float swingState = (float)Math.Sin(swingTimer * 0.1f); - - List visibleSprites = new List(); - float z = 0.0f; - for (int x = indices.X; x <= indices.Width; x++) + if (currentGridIndices != indices) { - for (int y = indices.Y; y <= indices.Height; y++) + visibleSprites.Clear(); + + for (int x = indices.X; x <= indices.Width; x++) { - foreach (BackgroundSprite sprite in sprites[x, y]) + for (int y = indices.Y; y <= indices.Height; y++) { - int drawOrderIndex = 0; - for (int i = 0; i < visibleSprites.Count; i++) + if (sprites[x, y] == null) continue; + foreach (BackgroundSprite sprite in sprites[x, y]) { - if (visibleSprites[i] == sprite) + int drawOrderIndex = 0; + for (int i = 0; i < visibleSprites.Count; i++) { - drawOrderIndex = -1; - break; + if (visibleSprites[i] == sprite) + { + drawOrderIndex = -1; + break; + } + + if (visibleSprites[i].Position.Z > sprite.Position.Z) + { + break; + } + else + { + drawOrderIndex = i + 1; + } } - if (visibleSprites[i].Position.Z > sprite.Position.Z) + if (drawOrderIndex >= 0) { - break; + visibleSprites.Insert(drawOrderIndex, sprite); } - else - { - drawOrderIndex = i + 1; - } - } - - if (drawOrderIndex >= 0) - { - visibleSprites.Insert(drawOrderIndex, sprite); } } } + + currentGridIndices = indices; } foreach (BackgroundSprite sprite in visibleSprites) diff --git a/Barotrauma/BarotraumaClient/Source/Characters/BackgroundSprite/BackgroundSpritePrefab.cs b/Barotrauma/BarotraumaClient/Source/Characters/BackgroundSprite/BackgroundSpritePrefab.cs index f3df1563d..5655029d4 100644 --- a/Barotrauma/BarotraumaClient/Source/Characters/BackgroundSprite/BackgroundSpritePrefab.cs +++ b/Barotrauma/BarotraumaClient/Source/Characters/BackgroundSprite/BackgroundSpritePrefab.cs @@ -7,20 +7,32 @@ namespace Barotrauma { class BackgroundSpritePrefab { + [Flags] + public enum SpawnPosType + { + None = 0, + Wall = 1, + RuinWall = 2, + SeaFloor = 4 + } + public readonly Sprite Sprite; public readonly Alignment Alignment; public readonly Vector2 Scale; - public bool SpawnOnWalls; + public SpawnPosType SpawnPos; public readonly bool AlignWithSurface; - + public readonly Vector2 RandomRotation; public readonly Vector2 DepthRange; + public readonly Particles.ParticleEmitter ParticleEmitter; + public readonly Vector2 EmitterPosition; + public readonly float SwingAmount; public readonly int Commonness; @@ -37,8 +49,16 @@ namespace Barotrauma } Commonness = ToolBox.GetAttributeInt(element, "commonness", 1); - - SpawnOnWalls = ToolBox.GetAttributeBool(element, "spawnonwalls", true); + + string[] spawnPosStrs = ToolBox.GetAttributeString(element, "spawnpos", "Wall").Split(','); + foreach (string spawnPosStr in spawnPosStrs) + { + SpawnPosType parsedSpawnPos; + if (Enum.TryParse(spawnPosStr.Trim(), out parsedSpawnPos)) + { + SpawnPos |= parsedSpawnPos; + } + } Scale.X = ToolBox.GetAttributeFloat(element, "minsize", 1.0f); Scale.Y = ToolBox.GetAttributeFloat(element, "maxsize", 1.0f); @@ -69,7 +89,10 @@ namespace Barotrauma OverrideCommonness.Add(levelType, ToolBox.GetAttributeInt(subElement, "commonness", 1)); } break; - + case "particleemitter": + ParticleEmitter = new Particles.ParticleEmitter(subElement); + EmitterPosition = ToolBox.GetAttributeVector2(subElement, "position", Vector2.Zero); + break; } } } diff --git a/Barotrauma/BarotraumaShared/Content/BackgroundSprites/BackgroundSpritePrefabs.xml b/Barotrauma/BarotraumaShared/Content/BackgroundSprites/BackgroundSpritePrefabs.xml index 5b0d56ce4..a9667707b 100644 --- a/Barotrauma/BarotraumaShared/Content/BackgroundSprites/BackgroundSpritePrefabs.xml +++ b/Barotrauma/BarotraumaShared/Content/BackgroundSprites/BackgroundSpritePrefabs.xml @@ -1,102 +1,102 @@  - + - + - + - + - + - + - + - + - + - + - - + + - + - + - + - + - + - + - + - - + + - + - - + + \ No newline at end of file diff --git a/Barotrauma/BarotraumaShared/Source/Map/Levels/Level.cs b/Barotrauma/BarotraumaShared/Source/Map/Levels/Level.cs index a6df9f7a6..86dd29e4f 100644 --- a/Barotrauma/BarotraumaShared/Source/Map/Levels/Level.cs +++ b/Barotrauma/BarotraumaShared/Source/Map/Levels/Level.cs @@ -466,8 +466,6 @@ namespace Barotrauma #if CLIENT renderer.SetBodyVertices(CaveGenerator.GenerateRenderVerticeList(triangles).ToArray(), Color.White); renderer.SetWallVertices(CaveGenerator.GenerateWallShapes(cells), Color.White); - - renderer.PlaceSprites(generationParams.BackgroundSpriteAmount); #endif TopBarrier = BodyFactory.CreateEdge(GameMain.World, @@ -482,6 +480,10 @@ namespace Barotrauma GenerateSeaFloor(); +#if CLIENT + renderer.PlaceSprites(generationParams.BackgroundSpriteAmount); +#endif + foreach (VoronoiCell cell in cells) { foreach (GraphEdge edge in cell.edges)