diff --git a/Barotrauma/BarotraumaClient/Source/Characters/BackgroundSprite/BackgroundSpriteManager.cs b/Barotrauma/BarotraumaClient/Source/Characters/BackgroundSprite/BackgroundSpriteManager.cs index dca8c393c..8cef2d9b8 100644 --- a/Barotrauma/BarotraumaClient/Source/Characters/BackgroundSprite/BackgroundSpriteManager.cs +++ b/Barotrauma/BarotraumaClient/Source/Characters/BackgroundSprite/BackgroundSpriteManager.cs @@ -31,7 +31,10 @@ namespace Barotrauma this.Rotation = rotation; - this.ParticleEmitter = new ParticleEmitter(prefab.ParticleEmitterPrefab); + if (prefab.ParticleEmitterPrefab != null) + { + this.ParticleEmitter = new ParticleEmitter(prefab.ParticleEmitterPrefab); + } } } @@ -107,7 +110,7 @@ namespace Barotrauma //calculate the positions of the corners of the rotated sprite Vector2 halfSize = newSprite.Prefab.Sprite.size * newSprite.Scale / 2; - var spriteCorners = new Vector2[] + var spriteCorners = new List { -halfSize, new Vector2(-halfSize.X, halfSize.Y), halfSize, new Vector2(halfSize.X, -halfSize.Y) @@ -125,11 +128,16 @@ namespace Barotrauma (float)(spriteCorners[j].X * Math.Cos(-rotation) - spriteCorners[j].Y * Math.Sin(-rotation)), (float)(spriteCorners[j].X * Math.Sin(-rotation) + spriteCorners[j].Y * Math.Cos(-rotation))); - spriteCorners[j] += (Vector2)pos + pivotOffset; + spriteCorners[j] += pos.Value + pivotOffset; } - //newSprite.spriteCorners = spriteCorners; - + if (newSprite.ParticleEmitter != null) + { + Rectangle particleBounds = newSprite.ParticleEmitter.CalculateParticleBounds(pos.Value); + spriteCorners.Add(particleBounds.Location.ToVector2()); + spriteCorners.Add(new Vector2(particleBounds.Right, particleBounds.Bottom)); + } + 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); if (minX < 0 || maxX >= sprites.GetLength(0)) continue; diff --git a/Barotrauma/BarotraumaClient/Source/Particles/ParticleEmitter.cs b/Barotrauma/BarotraumaClient/Source/Particles/ParticleEmitter.cs index 93c0b15ca..48ebd825d 100644 --- a/Barotrauma/BarotraumaClient/Source/Particles/ParticleEmitter.cs +++ b/Barotrauma/BarotraumaClient/Source/Particles/ParticleEmitter.cs @@ -17,6 +17,7 @@ namespace Barotrauma.Particles public ParticleEmitter(ParticleEmitterPrefab prefab) { + System.Diagnostics.Debug.Assert(prefab != null, "The prefab of a particle emitter cannot be null"); Prefab = prefab; } @@ -52,6 +53,27 @@ namespace Barotrauma.Particles particle.Size *= Rand.Range(Prefab.ScaleMin, Prefab.ScaleMax); } } + + public Rectangle CalculateParticleBounds(Vector2 startPosition) + { + Rectangle bounds = new Rectangle((int)startPosition.X, (int)startPosition.Y, (int)startPosition.X, (int)startPosition.Y); + + for (float angle = Prefab.AngleMin; angle <= Prefab.AngleMax; angle += 0.1f) + { + Vector2 velocity = new Vector2((float)Math.Cos(angle), (float)Math.Sin(angle)) * Prefab.VelocityMax; + Vector2 endPosition = Prefab.ParticlePrefab.CalculateEndPosition(startPosition, velocity); + + bounds = new Rectangle( + (int)Math.Min(bounds.X, endPosition.X), + (int)Math.Min(bounds.Y, endPosition.Y), + (int)Math.Max(bounds.X, endPosition.X), + (int)Math.Max(bounds.Y, endPosition.Y)); + } + + bounds = new Rectangle(bounds.X, bounds.Y, bounds.Width - bounds.X, bounds.Height - bounds.Y); + + return bounds; + } } class ParticleEmitterPrefab @@ -86,8 +108,8 @@ namespace Barotrauma.Particles AngleMax = AngleMin; } - AngleMin = MathHelper.ToRadians(AngleMin); - AngleMax = MathHelper.ToRadians(AngleMax); + AngleMin = MathHelper.ToRadians(MathHelper.Clamp(AngleMin, -360.0f, 360.0f)); + AngleMax = MathHelper.ToRadians(MathHelper.Clamp(AngleMax, -360.0f, 360.0f)); if (element.Attribute("scalemin")==null) { diff --git a/Barotrauma/BarotraumaClient/Source/Particles/ParticleManager.cs b/Barotrauma/BarotraumaClient/Source/Particles/ParticleManager.cs index ac4bfff64..880ca990e 100644 --- a/Barotrauma/BarotraumaClient/Source/Particles/ParticleManager.cs +++ b/Barotrauma/BarotraumaClient/Source/Particles/ParticleManager.cs @@ -51,7 +51,7 @@ namespace Barotrauma.Particles return CreateParticle(prefabName, position, new Vector2((float)Math.Cos(angle), (float)-Math.Sin(angle)) * speed, angle, hullGuess); } - public Particle CreateParticle(string prefabName, Vector2 position, Vector2 speed, float rotation=0.0f, Hull hullGuess = null) + public Particle CreateParticle(string prefabName, Vector2 position, Vector2 velocity, float rotation=0.0f, Hull hullGuess = null) { ParticlePrefab prefab = FindPrefab(prefabName); @@ -61,15 +61,14 @@ namespace Barotrauma.Particles return null; } - return CreateParticle(prefab, position, speed, rotation, hullGuess); + return CreateParticle(prefab, position, velocity, rotation, hullGuess); } - public Particle CreateParticle(ParticlePrefab prefab, Vector2 position, Vector2 speed, float rotation = 0.0f, Hull hullGuess = null) + public Particle CreateParticle(ParticlePrefab prefab, Vector2 position, Vector2 velocity, float rotation = 0.0f, Hull hullGuess = null) { - if (particleCount >= MaxParticles) return null; + if (particleCount >= MaxParticles || prefab == null) return null; - //endPos = x + vt + 1/2 * at^2 - Vector2 particleEndPos = position + speed * prefab.LifeTime + 0.5f * prefab.VelocityChange * prefab.LifeTime * prefab.LifeTime; + Vector2 particleEndPos = prefab.CalculateEndPosition(position, velocity); Vector2 minPos = new Vector2(Math.Min(position.X, particleEndPos.X), Math.Min(position.Y, particleEndPos.Y)); Vector2 maxPos = new Vector2(Math.Max(position.X, particleEndPos.X), Math.Max(position.Y, particleEndPos.Y)); @@ -81,7 +80,7 @@ namespace Barotrauma.Particles if (particles[particleCount] == null) particles[particleCount] = new Particle(); - particles[particleCount].Init(prefab, position, speed, rotation, hullGuess); + particles[particleCount].Init(prefab, position, velocity, rotation, hullGuess); particleCount++; diff --git a/Barotrauma/BarotraumaClient/Source/Particles/ParticlePrefab.cs b/Barotrauma/BarotraumaClient/Source/Particles/ParticlePrefab.cs index ef13959c3..12e0905fa 100644 --- a/Barotrauma/BarotraumaClient/Source/Particles/ParticlePrefab.cs +++ b/Barotrauma/BarotraumaClient/Source/Particles/ParticlePrefab.cs @@ -83,6 +83,9 @@ namespace Barotrauma.Particles AngularVelocityMax = AngularVelocityMin; } + AngularVelocityMin = MathHelper.ToRadians(AngularVelocityMin); + AngularVelocityMax = MathHelper.ToRadians(AngularVelocityMax); + if (element.Attribute("startsize") == null) { StartSizeMin = ToolBox.GetAttributeVector2(element, "startsizemin", Vector2.One); @@ -177,5 +180,11 @@ namespace Barotrauma.Particles } } + + public Vector2 CalculateEndPosition(Vector2 startPosition, Vector2 velocity) + { + //endPos = x + vt + 1/2 * at^2 + return startPosition + velocity * LifeTime + 0.5f * VelocityChange * LifeTime * LifeTime; + } } }