- The emission rate of ParticleEmitters can be set as particles per second (instead of particles per frame).
- Particles that are outside the sub aren't visible inside hulls even if they overlap with the sub. - ParticleManager takes the movement of the particles into account when determining which particles to cull. For example, a particle that will move upwards can be emitted even if it's below the camera view.
This commit is contained in:
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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<ParticleAmount; i++)
|
||||
{
|
||||
float angle = Rand.Range(AngleMin, AngleMax);
|
||||
Vector2 velocity = new Vector2((float)Math.Cos(angle), (float)Math.Sin(angle)) * Rand.Range(VelocityMin, VelocityMax);
|
||||
Emit(position, hullGuess);
|
||||
}
|
||||
}
|
||||
|
||||
var particle = GameMain.ParticleManager.CreateParticle(particlePrefab, position, velocity, 0.0f, hullGuess);
|
||||
private void Emit(Vector2 position, Hull hullGuess = null)
|
||||
{
|
||||
float angle = Rand.Range(AngleMin, AngleMax);
|
||||
Vector2 velocity = new Vector2((float)Math.Cos(angle), (float)Math.Sin(angle)) * Rand.Range(VelocityMin, VelocityMax);
|
||||
|
||||
if (particle!=null)
|
||||
{
|
||||
particle.Size *= Rand.Range(ScaleMin, ScaleMax);
|
||||
}
|
||||
var particle = GameMain.ParticleManager.CreateParticle(particlePrefab, position, velocity, 0.0f, hullGuess);
|
||||
|
||||
if (particle != null)
|
||||
{
|
||||
particle.Size *= Rand.Range(ScaleMin, ScaleMax);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,19 +66,26 @@ namespace Barotrauma.Particles
|
||||
|
||||
public Particle CreateParticle(ParticlePrefab prefab, Vector2 position, Vector2 speed, float rotation = 0.0f, Hull hullGuess = null)
|
||||
{
|
||||
if (!Submarine.RectContains(MathUtils.ExpandRect(cam.WorldView, MaxOutOfViewDist), position)) return null;
|
||||
//if (!cam.WorldView.Contains(position)) return null;
|
||||
|
||||
if (particleCount >= 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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user