diff --git a/Barotrauma/BarotraumaClient/Source/Map/Levels/BackgroundSprite/BackgroundSpriteManager.cs b/Barotrauma/BarotraumaClient/Source/Map/Levels/BackgroundSprite/BackgroundSpriteManager.cs index bae50b970..814212755 100644 --- a/Barotrauma/BarotraumaClient/Source/Map/Levels/BackgroundSprite/BackgroundSpriteManager.cs +++ b/Barotrauma/BarotraumaClient/Source/Map/Levels/BackgroundSprite/BackgroundSpriteManager.cs @@ -8,7 +8,7 @@ namespace Barotrauma { partial class BackgroundSprite { - public ParticleEmitter ParticleEmitter; + public List ParticleEmitters; public Sound Sound; } @@ -22,10 +22,13 @@ namespace Barotrauma { foreach (BackgroundSprite s in visibleSprites) { - if (s.ParticleEmitter != null) + if (s.ParticleEmitters != null) { - Vector2 emitterPos = s.LocalToWorld(new Vector2(s.Prefab.EmitterPosition.X, s.Prefab.EmitterPosition.Y)); - s.ParticleEmitter.Emit(deltaTime, emitterPos); + for (int i = 0; i < s.ParticleEmitters.Count; i++) + { + Vector2 emitterPos = s.LocalToWorld(s.Prefab.EmitterPositions[i]); + s.ParticleEmitters[i].Emit(deltaTime, emitterPos); + } } if (s.Sound != null) @@ -38,7 +41,7 @@ namespace Barotrauma } else { - s.Sound.UpdatePosition(soundPos); + s.Sound.UpdatePosition(soundPos); } } } diff --git a/Barotrauma/BarotraumaClient/Source/Map/Levels/BackgroundSprite/BackgroundSpritePrefab.cs b/Barotrauma/BarotraumaClient/Source/Map/Levels/BackgroundSprite/BackgroundSpritePrefab.cs index b14c0bac5..997f18f6e 100644 --- a/Barotrauma/BarotraumaClient/Source/Map/Levels/BackgroundSprite/BackgroundSpritePrefab.cs +++ b/Barotrauma/BarotraumaClient/Source/Map/Levels/BackgroundSprite/BackgroundSpritePrefab.cs @@ -1,12 +1,14 @@ -using Microsoft.Xna.Framework; +using Barotrauma.Particles; +using Microsoft.Xna.Framework; +using System.Collections.Generic; using System.Xml.Linq; namespace Barotrauma { partial class BackgroundSpritePrefab { - public readonly Particles.ParticleEmitterPrefab ParticleEmitterPrefab; - public readonly Vector2 EmitterPosition; + public readonly List ParticleEmitterPrefabs; + public readonly List EmitterPositions; public readonly XElement SoundElement; public readonly Vector2 SoundPosition; diff --git a/Barotrauma/BarotraumaShared/Content/BackgroundSprites/BackgroundSpritePrefabs.xml b/Barotrauma/BarotraumaShared/Content/BackgroundSprites/BackgroundSpritePrefabs.xml index e60ee432a..52830aee3 100644 --- a/Barotrauma/BarotraumaShared/Content/BackgroundSprites/BackgroundSpritePrefabs.xml +++ b/Barotrauma/BarotraumaShared/Content/BackgroundSprites/BackgroundSpritePrefabs.xml @@ -107,15 +107,14 @@ - + - - - - + + + + - + - - + + + - + - - + + + \ No newline at end of file diff --git a/Barotrauma/BarotraumaShared/Content/Particles/ParticlePrefabs.xml b/Barotrauma/BarotraumaShared/Content/Particles/ParticlePrefabs.xml index 5033cbb00..6f3b8b869 100644 --- a/Barotrauma/BarotraumaShared/Content/Particles/ParticlePrefabs.xml +++ b/Barotrauma/BarotraumaShared/Content/Particles/ParticlePrefabs.xml @@ -177,6 +177,21 @@ + + + + (); + foreach (ParticleEmitterPrefab emitterPrefab in prefab.ParticleEmitterPrefabs) + { + ParticleEmitters.Add(new ParticleEmitter(emitterPrefab)); + } } if (prefab.SoundElement != null) @@ -172,34 +176,44 @@ namespace Barotrauma spriteCorners[j] += pos.Value + pivotOffset; } + float minX = spriteCorners.Min(c => c.X) - newSprite.Position.Z; + float maxX = spriteCorners.Max(c => c.X) + newSprite.Position.Z; + + float minY = spriteCorners.Min(c => c.Y) - newSprite.Position.Z - level.BottomPos; + float maxY = spriteCorners.Max(c => c.Y) + newSprite.Position.Z - level.BottomPos; + #if CLIENT - if (newSprite.ParticleEmitter != null) + if (newSprite.ParticleEmitters != null) { - Rectangle particleBounds = newSprite.ParticleEmitter.CalculateParticleBounds(pos.Value); - spriteCorners.Add(particleBounds.Location.ToVector2()); - spriteCorners.Add(new Vector2(particleBounds.Right, particleBounds.Bottom)); + foreach (ParticleEmitter emitter in newSprite.ParticleEmitters) + { + Rectangle particleBounds = emitter.CalculateParticleBounds(pos.Value); + minX = Math.Min(minX, particleBounds.X); + maxX = Math.Max(maxX, particleBounds.Right); + minY = Math.Min(minY, particleBounds.Y - level.BottomPos); + maxY = Math.Max(maxY, particleBounds.Bottom - level.BottomPos); + } } #endif sprites.Add(newSprite); - int minX = (int)Math.Floor((spriteCorners.Min(c => c.X) - newSprite.Position.Z) / GridSize); - int maxX = (int)Math.Floor((spriteCorners.Max(c => c.X) + newSprite.Position.Z) / GridSize); + int xStart = (int)Math.Floor(minX / GridSize); + int xEnd = (int)Math.Floor(maxX / GridSize); + if (xEnd < 0 || xStart >= spriteGrid.GetLength(0)) continue; - if (maxX < 0 || minX >= spriteGrid.GetLength(0)) continue; + int yStart = (int)Math.Floor(minY / GridSize); + int yEnd = (int)Math.Floor(maxY / GridSize); + if (yEnd < 0 || yStart >= spriteGrid.GetLength(1)) continue; - 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 (maxY < 0 || minY >= spriteGrid.GetLength(1)) continue; + xStart = Math.Max(xStart, 0); + xEnd = Math.Min(xEnd, spriteGrid.GetLength(0) - 1); + yStart = Math.Max(yStart, 0); + yEnd = Math.Min(yEnd, spriteGrid.GetLength(1) - 1); - minX = Math.Max(minX, 0); - maxX = Math.Min(maxX, spriteGrid.GetLength(0) - 1); - minY = Math.Max(minY, 0); - maxY = Math.Min(maxY, spriteGrid.GetLength(1) - 1); - - for (int x = minX; x <= maxX; x++) + for (int x = xStart; x <= xEnd; x++) { - for (int y = minY; y <= maxY; y++) + for (int y = yStart; y <= yEnd; y++) { if (spriteGrid[x, y] == null) spriteGrid[x, y] = new List(); spriteGrid[x, y].Add(newSprite); diff --git a/Barotrauma/BarotraumaShared/Source/Map/Levels/BackgroundSpritePrefab.cs b/Barotrauma/BarotraumaShared/Source/Map/Levels/BackgroundSpritePrefab.cs index 620dfb804..7e1c07d7a 100644 --- a/Barotrauma/BarotraumaShared/Source/Map/Levels/BackgroundSpritePrefab.cs +++ b/Barotrauma/BarotraumaShared/Source/Map/Levels/BackgroundSpritePrefab.cs @@ -94,8 +94,14 @@ namespace Barotrauma break; #if CLIENT case "particleemitter": - ParticleEmitterPrefab = new Particles.ParticleEmitterPrefab(subElement); - EmitterPosition = ToolBox.GetAttributeVector2(subElement, "position", Vector2.Zero); + if (ParticleEmitterPrefabs == null) + { + ParticleEmitterPrefabs = new List(); + EmitterPositions = new List(); + } + + ParticleEmitterPrefabs.Add(new Particles.ParticleEmitterPrefab(subElement)); + EmitterPositions.Add(ToolBox.GetAttributeVector2(subElement, "position", Vector2.Zero)); break; case "sound": SoundElement = subElement; diff --git a/Barotrauma/BarotraumaShared/Source/Map/Levels/LevelTrigger.cs b/Barotrauma/BarotraumaShared/Source/Map/Levels/LevelTrigger.cs index f988602f4..ce2d48f26 100644 --- a/Barotrauma/BarotraumaShared/Source/Map/Levels/LevelTrigger.cs +++ b/Barotrauma/BarotraumaShared/Source/Map/Levels/LevelTrigger.cs @@ -25,9 +25,11 @@ namespace Barotrauma private float cameraShake; + private Vector2 force; + public Vector2 WorldPosition { - get { return ConvertUnits.ToDisplayUnits(physicsBody.Position); } + get { return physicsBody.Position; } set { physicsBody.SetTransform(ConvertUnits.ToSimUnits(value), physicsBody.Rotation); } } @@ -56,6 +58,8 @@ namespace Barotrauma physicsBody.SetTransform(ConvertUnits.ToSimUnits(position), rotation); cameraShake = ToolBox.GetAttributeFloat(element, "camerashake", 0.0f); + + force = ToolBox.GetAttributeVector2(element, "force", Vector2.Zero); foreach (XElement subElement in element.Elements()) { @@ -110,6 +114,7 @@ namespace Barotrauma public void Update(float deltaTime) { + triggerers.RemoveAll(t => t.Removed); foreach (Entity triggerer in triggerers) { foreach (StatusEffect effect in statusEffects) @@ -133,6 +138,18 @@ namespace Barotrauma } } + if (force != Vector2.Zero) + { + if (triggerer is Character) + { + ((Character)triggerer).AnimController.Collider.ApplyForce(force * deltaTime); + } + else if (triggerer is Submarine) + { + ((Submarine)triggerer).ApplyForce(force * deltaTime); + } + } + if (triggerer == Character.Controlled || triggerer == Character.Controlled?.Submarine) { GameMain.GameScreen.Cam.Shake = Math.Max(GameMain.GameScreen.Cam.Shake, cameraShake); diff --git a/Barotrauma/BarotraumaShared/Source/Physics/PhysicsBody.cs b/Barotrauma/BarotraumaShared/Source/Physics/PhysicsBody.cs index 79dc90406..4bd60463c 100644 --- a/Barotrauma/BarotraumaShared/Source/Physics/PhysicsBody.cs +++ b/Barotrauma/BarotraumaShared/Source/Physics/PhysicsBody.cs @@ -368,15 +368,15 @@ namespace Barotrauma body.ApplyTorque(torque); } - public void SetTransform(Vector2 position, float rotation) + public void SetTransform(Vector2 simPosition, float rotation) { - System.Diagnostics.Debug.Assert(MathUtils.IsValid(position)); - System.Diagnostics.Debug.Assert(Math.Abs(position.X) < 1000000.0f); - System.Diagnostics.Debug.Assert(Math.Abs(position.Y) < 1000000.0f); + System.Diagnostics.Debug.Assert(MathUtils.IsValid(simPosition)); + System.Diagnostics.Debug.Assert(Math.Abs(simPosition.X) < 1000000.0f); + System.Diagnostics.Debug.Assert(Math.Abs(simPosition.Y) < 1000000.0f); - body.SetTransform(position, rotation); - SetPrevTransform(position, rotation); + body.SetTransform(simPosition, rotation); + SetPrevTransform(simPosition, rotation); } public void SetPrevTransform(Vector2 position, float rotation)