diff --git a/Barotrauma/BarotraumaClient/Source/Characters/Attack.cs b/Barotrauma/BarotraumaClient/Source/Characters/Attack.cs index 0a54164d0..243154813 100644 --- a/Barotrauma/BarotraumaClient/Source/Characters/Attack.cs +++ b/Barotrauma/BarotraumaClient/Source/Characters/Attack.cs @@ -8,7 +8,7 @@ namespace Barotrauma { private Sound sound; - private ParticleEmitterPrefab particleEmitterPrefab; + private ParticleEmitter particleEmitterPrefab; partial void InitProjSpecific(XElement element) { @@ -23,18 +23,18 @@ namespace Barotrauma switch (subElement.Name.ToString().ToLowerInvariant()) { case "particleemitter": - particleEmitterPrefab = new ParticleEmitterPrefab(subElement); + particleEmitterPrefab = new ParticleEmitter(subElement); break; } } } - partial void DamageParticles(Vector2 worldPosition) + partial void DamageParticles(float deltaTime, Vector2 worldPosition) { if (particleEmitterPrefab != null) { - particleEmitterPrefab.Emit(worldPosition); + particleEmitterPrefab.Emit(deltaTime, worldPosition); } if (sound != null) diff --git a/Barotrauma/BarotraumaClient/Source/Map/Lights/LightManager.cs b/Barotrauma/BarotraumaClient/Source/Map/Lights/LightManager.cs index 56b9478d3..e1b24db9e 100644 --- a/Barotrauma/BarotraumaClient/Source/Map/Lights/LightManager.cs +++ b/Barotrauma/BarotraumaClient/Source/Map/Lights/LightManager.cs @@ -159,7 +159,7 @@ namespace Barotrauma.Lights lightEffect.World = Matrix.CreateTranslation(offset) * transform; - GameMain.ParticleManager.Draw(spriteBatch, false, Particles.ParticleBlendState.Additive); + GameMain.ParticleManager.Draw(spriteBatch, false, null, Particles.ParticleBlendState.Additive); if (Character.Controlled != null) { diff --git a/Barotrauma/BarotraumaClient/Source/Particles/Particle.cs b/Barotrauma/BarotraumaClient/Source/Particles/Particle.cs index fdd027ab3..401331b33 100644 --- a/Barotrauma/BarotraumaClient/Source/Particles/Particle.cs +++ b/Barotrauma/BarotraumaClient/Source/Particles/Particle.cs @@ -73,6 +73,11 @@ namespace Barotrauma.Particles get { return velocity; } set { velocity = value; } } + + public Hull CurrentHull + { + get { return currentHull; } + } public void Init(ParticlePrefab prefab, Vector2 position, Vector2 speed, float rotation, Hull hullGuess = null) { diff --git a/Barotrauma/BarotraumaClient/Source/Particles/ParticleEmitter.cs b/Barotrauma/BarotraumaClient/Source/Particles/ParticleEmitter.cs index 4b17c0104..ea6f2b13e 100644 --- a/Barotrauma/BarotraumaClient/Source/Particles/ParticleEmitter.cs +++ b/Barotrauma/BarotraumaClient/Source/Particles/ParticleEmitter.cs @@ -4,7 +4,7 @@ using System.Xml.Linq; namespace Barotrauma.Particles { - class ParticleEmitterPrefab + class ParticleEmitter { public readonly string Name; @@ -15,10 +15,14 @@ namespace Barotrauma.Particles public readonly float VelocityMin, VelocityMax; public readonly float ScaleMin, ScaleMax; + + public readonly int ParticleAmount; - public readonly float ParticleAmount; + public readonly float ParticlesPerSecond; + + private float emitTimer; - public ParticleEmitterPrefab(XElement element) + public ParticleEmitter(XElement element) { Name = element.Name.ToString(); @@ -60,22 +64,40 @@ namespace Barotrauma.Particles VelocityMax = VelocityMin; } - ParticleAmount = ToolBox.GetAttributeInt(element, "particleamount", 1); + ParticlesPerSecond = ToolBox.GetAttributeInt(element, "particlespersecond", 0); + ParticleAmount = ToolBox.GetAttributeInt(element, "particleamount", 0); } - public void Emit(Vector2 position, Hull hullGuess = null) + public void Emit(float deltaTime, Vector2 position, Hull hullGuess = null) { + emitTimer += deltaTime; + + if (ParticlesPerSecond > 0) + { + float emitInterval = 1.0f / ParticlesPerSecond; + while (emitTimer > emitInterval) + { + Emit(position, hullGuess); + emitTimer -= emitInterval; + } + } + for (int i = 0; i= MaxParticles) return null; + //endPos = x + vt + 1/2 * at^2 + Vector2 particleEndPos = position + speed * prefab.LifeTime + 0.5f * prefab.VelocityChange * prefab.LifeTime * prefab.LifeTime; + + 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)); + + Rectangle expandedViewRect = MathUtils.ExpandRect(cam.WorldView, MaxOutOfViewDist); + + if (minPos.X > expandedViewRect.Right || maxPos.X < expandedViewRect.X) return null; + if (minPos.Y > expandedViewRect.Y || maxPos.Y < expandedViewRect.Y - expandedViewRect.Height) return null; + if (particles[particleCount] == null) particles[particleCount] = new Particle(); particles[particleCount].Init(prefab, position, speed, rotation, hullGuess); particleCount++; - return particles[particleCount-1]; - + return particles[particleCount - 1]; } public ParticlePrefab FindPrefab(string prefabName) @@ -131,7 +138,7 @@ namespace Barotrauma.Particles } } - public void Draw(SpriteBatch spriteBatch, bool inWater, ParticleBlendState blendState) + public void Draw(SpriteBatch spriteBatch, bool inWater, bool? inSub, ParticleBlendState blendState) { ParticlePrefab.DrawTargetType drawTarget = inWater ? ParticlePrefab.DrawTargetType.Water : ParticlePrefab.DrawTargetType.Air; @@ -139,6 +146,7 @@ namespace Barotrauma.Particles { if (particles[i].BlendState != blendState) continue; if (!particles[i].DrawTarget.HasFlag(drawTarget)) continue; + if (inSub.HasValue && (particles[i].CurrentHull == null) == inSub.Value) continue; particles[i].Draw(spriteBatch); } diff --git a/Barotrauma/BarotraumaClient/Source/Screens/GameScreen.cs b/Barotrauma/BarotraumaClient/Source/Screens/GameScreen.cs index 41e4055dc..0e58721e7 100644 --- a/Barotrauma/BarotraumaClient/Source/Screens/GameScreen.cs +++ b/Barotrauma/BarotraumaClient/Source/Screens/GameScreen.cs @@ -134,6 +134,27 @@ namespace Barotrauma Level.Loaded.DrawBack(graphics, spriteBatch, cam, BackgroundCreatureManager); } +#if LINUX + spriteBatch.Begin(SpriteSortMode.Deferred, + BlendState.NonPremultiplied, + null, DepthStencilState.DepthRead, null, null, + cam.Transform); +#else + spriteBatch.Begin(SpriteSortMode.Deferred, + BlendState.AlphaBlend, + null, DepthStencilState.DepthRead, null, null, + cam.Transform); +#endif + GameMain.ParticleManager.Draw(spriteBatch, true, false, Particles.ParticleBlendState.AlphaBlend); + spriteBatch.End(); + + spriteBatch.Begin(SpriteSortMode.Deferred, + BlendState.Additive, + null, DepthStencilState.Default, null, null, + cam.Transform); + GameMain.ParticleManager.Draw(spriteBatch, true, false, Particles.ParticleBlendState.Additive); + spriteBatch.End(); + spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend, null, null, null, null, @@ -181,14 +202,14 @@ namespace Barotrauma null, DepthStencilState.DepthRead, null, null, cam.Transform); #endif - GameMain.ParticleManager.Draw(spriteBatch, true, Particles.ParticleBlendState.AlphaBlend); + GameMain.ParticleManager.Draw(spriteBatch, true, true, Particles.ParticleBlendState.AlphaBlend); spriteBatch.End(); spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.Additive, null, DepthStencilState.Default, null, null, cam.Transform); - GameMain.ParticleManager.Draw(spriteBatch, true, Particles.ParticleBlendState.Additive); + GameMain.ParticleManager.Draw(spriteBatch, true, true, Particles.ParticleBlendState.Additive); spriteBatch.End(); //---------------------------------------------------------------------------------------- @@ -211,14 +232,14 @@ namespace Barotrauma cam.Transform); #endif - GameMain.ParticleManager.Draw(spriteBatch, false, Particles.ParticleBlendState.AlphaBlend); + GameMain.ParticleManager.Draw(spriteBatch, false, null, Particles.ParticleBlendState.AlphaBlend); spriteBatch.End(); spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.Additive, null, DepthStencilState.DepthRead, null, null, cam.Transform); - GameMain.ParticleManager.Draw(spriteBatch, false, Particles.ParticleBlendState.Additive); + GameMain.ParticleManager.Draw(spriteBatch, false, null, Particles.ParticleBlendState.Additive); spriteBatch.End(); if (Character.Controlled != null && GameMain.LightManager.LosEnabled) diff --git a/Barotrauma/BarotraumaShared/Content/Items/Tools/tools.xml b/Barotrauma/BarotraumaShared/Content/Items/Tools/tools.xml index cc5f710f6..674134f40 100644 --- a/Barotrauma/BarotraumaShared/Content/Items/Tools/tools.xml +++ b/Barotrauma/BarotraumaShared/Content/Items/Tools/tools.xml @@ -270,8 +270,8 @@ - - + + diff --git a/Barotrauma/BarotraumaShared/Source/Characters/Attack.cs b/Barotrauma/BarotraumaShared/Source/Characters/Attack.cs index 73c906e60..6dd580b3e 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/Attack.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/Attack.cs @@ -143,7 +143,7 @@ namespace Barotrauma public AttackResult DoDamage(IDamageable attacker, IDamageable target, Vector2 worldPosition, float deltaTime, bool playSound = true) { - DamageParticles(worldPosition); + DamageParticles(deltaTime, worldPosition); var attackResult = target.AddDamage(attacker, worldPosition, this, deltaTime, playSound); @@ -168,6 +168,6 @@ namespace Barotrauma return attackResult; } - partial void DamageParticles(Vector2 worldPosition); + partial void DamageParticles(float deltaTime, Vector2 worldPosition); } } diff --git a/Barotrauma/BarotraumaShared/Source/Characters/StatusEffect.cs b/Barotrauma/BarotraumaShared/Source/Characters/StatusEffect.cs index cebeb9e1e..10c73a8e0 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/StatusEffect.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/StatusEffect.cs @@ -23,7 +23,7 @@ namespace Barotrauma private List requiredItems; #if CLIENT - private List particleEmitters; + private List particleEmitters; private Sound sound; #endif @@ -77,7 +77,7 @@ namespace Barotrauma requiredItems = new List(); #if CLIENT - particleEmitters = new List(); + particleEmitters = new List(); #endif IEnumerable attributes = element.Attributes(); @@ -179,7 +179,7 @@ namespace Barotrauma break; #if CLIENT case "particleemitter": - particleEmitters.Add(new ParticleEmitterPrefab(subElement)); + particleEmitters.Add(new ParticleEmitter(subElement)); break; #endif } @@ -280,9 +280,9 @@ namespace Barotrauma } #if CLIENT - foreach (ParticleEmitterPrefab emitter in particleEmitters) + foreach (ParticleEmitter emitter in particleEmitters) { - emitter.Emit(entity.WorldPosition, hull); + emitter.Emit(deltaTime, entity.WorldPosition, hull); } #endif } @@ -331,8 +331,8 @@ namespace Barotrauma } else { - DebugConsole.ThrowError("Couldn't apply value "+value.ToString()+" ("+type+") to property \""+property.Name+"\" ("+property.GetValue().GetType()+")! " - +"Make sure the type of the value set in the config files matches the type of the property."); + DebugConsole.ThrowError("Couldn't apply value " + value.ToString() + " (" + type + ") to property \"" + property.Name + "\" (" + property.GetValue().GetType() + ")! " + + "Make sure the type of the value set in the config files matches the type of the property."); } }