Renamed project folders from Subsurface to Barotrauma
This commit is contained in:
@@ -0,0 +1,381 @@
|
||||
using FarseerPhysics;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Barotrauma.Particles
|
||||
{
|
||||
class Particle
|
||||
{
|
||||
private ParticlePrefab prefab;
|
||||
|
||||
public delegate void OnChangeHullHandler(Vector2 position, Hull currentHull);
|
||||
public OnChangeHullHandler OnChangeHull;
|
||||
|
||||
private Vector2 position;
|
||||
private Vector2 prevPosition;
|
||||
|
||||
private Vector2 velocity;
|
||||
|
||||
private float rotation;
|
||||
private float prevRotation;
|
||||
|
||||
private float angularVelocity;
|
||||
|
||||
private Vector2 size;
|
||||
private Vector2 sizeChange;
|
||||
|
||||
private Color color;
|
||||
private float alpha;
|
||||
|
||||
private int spriteIndex;
|
||||
|
||||
private float totalLifeTime;
|
||||
private float lifeTime;
|
||||
|
||||
private Vector2 velocityChange;
|
||||
|
||||
private Vector2 drawPosition;
|
||||
private float drawRotation;
|
||||
|
||||
private Hull currentHull;
|
||||
|
||||
private List<Gap> hullGaps;
|
||||
|
||||
private float animState;
|
||||
private int animFrame;
|
||||
|
||||
public ParticlePrefab.DrawTargetType DrawTarget
|
||||
{
|
||||
get { return prefab.DrawTarget; }
|
||||
}
|
||||
|
||||
public ParticleBlendState BlendState
|
||||
{
|
||||
get { return prefab.BlendState; }
|
||||
}
|
||||
|
||||
public Vector2 Size
|
||||
{
|
||||
get { return size; }
|
||||
set { size = value; }
|
||||
}
|
||||
|
||||
public Vector2 VelocityChange
|
||||
{
|
||||
get { return velocityChange; }
|
||||
set { velocityChange = value; }
|
||||
}
|
||||
|
||||
public Vector2 Velocity
|
||||
{
|
||||
get { return velocity; }
|
||||
set { velocity = value; }
|
||||
}
|
||||
|
||||
public void Init(ParticlePrefab prefab, Vector2 position, Vector2 speed, float rotation, Hull hullGuess = null)
|
||||
{
|
||||
this.prefab = prefab;
|
||||
|
||||
spriteIndex = Rand.Int(prefab.Sprites.Count);
|
||||
|
||||
animState = 0;
|
||||
animFrame = 0;
|
||||
|
||||
currentHull = Hull.FindHull(position, hullGuess);
|
||||
|
||||
this.position = position;
|
||||
prevPosition = position;
|
||||
|
||||
drawPosition = position;
|
||||
|
||||
velocity = MathUtils.IsValid(speed) ? speed : Vector2.Zero;
|
||||
|
||||
if (currentHull != null && currentHull.Submarine != null)
|
||||
{
|
||||
velocity += ConvertUnits.ToDisplayUnits(currentHull.Submarine.Velocity);
|
||||
}
|
||||
|
||||
this.rotation = rotation + Rand.Range(prefab.StartRotationMin, prefab.StartRotationMax);
|
||||
prevRotation = rotation;
|
||||
|
||||
angularVelocity = prefab.AngularVelocityMin + (prefab.AngularVelocityMax - prefab.AngularVelocityMin) * Rand.Range(0.0f, 1.0f);
|
||||
|
||||
totalLifeTime = prefab.LifeTime;
|
||||
lifeTime = prefab.LifeTime;
|
||||
|
||||
size = prefab.StartSizeMin + (prefab.StartSizeMax - prefab.StartSizeMin) * Rand.Range(0.0f, 1.0f);
|
||||
|
||||
sizeChange = prefab.SizeChangeMin + (prefab.SizeChangeMax - prefab.SizeChangeMin) * Rand.Range(0.0f, 1.0f);
|
||||
|
||||
color = new Color(prefab.StartColor, 1.0f);
|
||||
alpha = prefab.StartAlpha;
|
||||
|
||||
velocityChange = prefab.VelocityChange;
|
||||
|
||||
OnChangeHull = null;
|
||||
|
||||
if (prefab.DeleteOnCollision || prefab.CollidesWithWalls)
|
||||
{
|
||||
hullGaps = currentHull == null ? new List<Gap>() : currentHull.ConnectedGaps;
|
||||
}
|
||||
|
||||
if (prefab.RotateToDirection)
|
||||
{
|
||||
this.rotation = MathUtils.VectorToAngle(new Vector2(velocity.X, -velocity.Y));
|
||||
|
||||
prevRotation = rotation;
|
||||
}
|
||||
}
|
||||
|
||||
public bool Update(float deltaTime)
|
||||
{
|
||||
prevPosition = position;
|
||||
prevRotation = rotation;
|
||||
|
||||
//over 3 times faster than position += velocity * deltatime
|
||||
position.X += velocity.X * deltaTime;
|
||||
position.Y += velocity.Y * deltaTime;
|
||||
|
||||
if (prefab.RotateToDirection)
|
||||
{
|
||||
if (velocityChange != Vector2.Zero || angularVelocity != 0.0f)
|
||||
{
|
||||
rotation = MathUtils.VectorToAngle(new Vector2(velocity.X, -velocity.Y));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rotation += angularVelocity * deltaTime;
|
||||
}
|
||||
|
||||
if (prefab.WaterDrag > 0.0f &&
|
||||
(currentHull == null || (currentHull.Submarine != null && position.Y - currentHull.Submarine.DrawPosition.Y < currentHull.Surface)))
|
||||
{
|
||||
ApplyDrag(prefab.WaterDrag, deltaTime);
|
||||
}
|
||||
else if (prefab.Drag > 0.0f)
|
||||
{
|
||||
ApplyDrag(prefab.Drag, deltaTime);
|
||||
}
|
||||
|
||||
velocity.X += velocityChange.X * deltaTime;
|
||||
velocity.Y += velocityChange.Y * deltaTime;
|
||||
|
||||
size.X += sizeChange.X * deltaTime;
|
||||
size.Y += sizeChange.Y * deltaTime;
|
||||
|
||||
alpha += prefab.ColorChange.W * deltaTime;
|
||||
|
||||
color = new Color(
|
||||
color.R / 255.0f + prefab.ColorChange.X * deltaTime,
|
||||
color.G / 255.0f + prefab.ColorChange.Y * deltaTime,
|
||||
color.B / 255.0f + prefab.ColorChange.Z * deltaTime);
|
||||
|
||||
if (prefab.Sprites[spriteIndex] is SpriteSheet)
|
||||
{
|
||||
animState += deltaTime;
|
||||
int frameCount = ((SpriteSheet)prefab.Sprites[spriteIndex]).FrameCount;
|
||||
animFrame = (int)Math.Min(Math.Floor(animState / prefab.AnimDuration * frameCount), frameCount - 1);
|
||||
}
|
||||
|
||||
lifeTime -= deltaTime;
|
||||
if (lifeTime <= 0.0f || alpha <= 0.0f || size.X <= 0.0f || size.Y <= 0.0f) return false;
|
||||
|
||||
if (!prefab.DeleteOnCollision && !prefab.CollidesWithWalls) return true;
|
||||
|
||||
if (currentHull == null)
|
||||
{
|
||||
Hull collidedHull = Hull.FindHull(position);
|
||||
if (collidedHull != null)
|
||||
{
|
||||
if (prefab.DeleteOnCollision) return false;
|
||||
OnWallCollisionOutside(collidedHull);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
Vector2 collisionNormal = Vector2.Zero;
|
||||
if (velocity.Y < 0.0f && position.Y - prefab.CollisionRadius * size.Y < currentHull.WorldRect.Y - currentHull.WorldRect.Height)
|
||||
{
|
||||
if (prefab.DeleteOnCollision) return false;
|
||||
collisionNormal = new Vector2(0.0f, 1.0f);
|
||||
}
|
||||
else if (velocity.Y > 0.0f && position.Y + prefab.CollisionRadius * size.Y > currentHull.WorldRect.Y)
|
||||
{
|
||||
if (prefab.DeleteOnCollision) return false;
|
||||
collisionNormal = new Vector2(0.0f, -1.0f);
|
||||
}
|
||||
else if (velocity.X < 0.0f && position.X - prefab.CollisionRadius * size.X < currentHull.WorldRect.X)
|
||||
{
|
||||
if (prefab.DeleteOnCollision) return false;
|
||||
collisionNormal = new Vector2(1.0f, 0.0f);
|
||||
}
|
||||
else if (velocity.X > 0.0f && position.X + prefab.CollisionRadius * size.X > currentHull.WorldRect.Right)
|
||||
{
|
||||
if (prefab.DeleteOnCollision) return false;
|
||||
collisionNormal = new Vector2(-1.0f, 0.0f);
|
||||
}
|
||||
|
||||
if (collisionNormal != Vector2.Zero)
|
||||
{
|
||||
bool gapFound = false;
|
||||
foreach (Gap gap in hullGaps)
|
||||
{
|
||||
if (gap.isHorizontal != (collisionNormal.X != 0.0f)) continue;
|
||||
|
||||
if (gap.isHorizontal)
|
||||
{
|
||||
if (gap.WorldRect.Y < position.Y || gap.WorldRect.Y - gap.WorldRect.Height > position.Y) continue;
|
||||
int gapDir = Math.Sign(gap.WorldRect.Center.X - currentHull.WorldRect.Center.X);
|
||||
if (Math.Sign(velocity.X) != gapDir || Math.Sign(position.X - currentHull.WorldRect.Center.X) != gapDir) continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gap.WorldRect.X > position.X || gap.WorldRect.Right < position.X) continue;
|
||||
float hullCenterY = currentHull.WorldRect.Y - currentHull.WorldRect.Height / 2;
|
||||
int gapDir = Math.Sign(gap.WorldRect.Y - hullCenterY);
|
||||
if (Math.Sign(velocity.Y) != gapDir || Math.Sign(position.Y - hullCenterY) != gapDir) continue;
|
||||
}
|
||||
|
||||
gapFound = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!gapFound)
|
||||
{
|
||||
OnWallCollisionInside(currentHull, collisionNormal);
|
||||
}
|
||||
else
|
||||
{
|
||||
Hull newHull = Hull.FindHull(position);
|
||||
if (newHull != currentHull)
|
||||
{
|
||||
currentHull = newHull;
|
||||
hullGaps = currentHull == null ? new List<Gap>() : currentHull.ConnectedGaps;
|
||||
OnChangeHull?.Invoke(position, currentHull);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void ApplyDrag(float dragCoefficient, float deltaTime)
|
||||
{
|
||||
if (Math.Abs(velocity.X) < 0.0001f && Math.Abs(velocity.Y) < 0.0001f) return;
|
||||
float speed = velocity.Length();
|
||||
|
||||
velocity -= (velocity / speed) * Math.Min(speed * speed * dragCoefficient * deltaTime, 1.0f);
|
||||
}
|
||||
|
||||
private void OnWallCollisionInside(Hull prevHull, Vector2 collisionNormal)
|
||||
{
|
||||
Rectangle prevHullRect = prevHull.WorldRect;
|
||||
|
||||
Vector2 subVel = ConvertUnits.ToDisplayUnits(prevHull.Submarine.Velocity);
|
||||
velocity -= subVel;
|
||||
|
||||
if (Math.Abs(collisionNormal.X) > Math.Abs(collisionNormal.Y))
|
||||
{
|
||||
if (collisionNormal.X > 0.0f)
|
||||
{
|
||||
position.X = Math.Max(position.X, prevHullRect.X + prefab.CollisionRadius * size.X);
|
||||
}
|
||||
else
|
||||
{
|
||||
position.X = Math.Min(position.X, prevHullRect.Right - prefab.CollisionRadius * size.X);
|
||||
}
|
||||
velocity.X = Math.Sign(collisionNormal.X) * Math.Abs(velocity.X) * prefab.Restitution;
|
||||
velocity.Y *= (1.0f - prefab.Friction);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (collisionNormal.Y > 0.0f)
|
||||
{
|
||||
position.Y = Math.Max(position.Y, prevHullRect.Y - prevHullRect.Height + prefab.CollisionRadius * size.Y);
|
||||
}
|
||||
else
|
||||
{
|
||||
position.Y = Math.Min(position.Y, prevHullRect.Y - prefab.CollisionRadius * size.Y);
|
||||
|
||||
}
|
||||
velocity.X *= (1.0f - prefab.Friction);
|
||||
velocity.Y = Math.Sign(collisionNormal.Y) * Math.Abs(velocity.Y) * prefab.Restitution;
|
||||
}
|
||||
|
||||
velocity += subVel;
|
||||
}
|
||||
|
||||
|
||||
private void OnWallCollisionOutside(Hull collisionHull)
|
||||
{
|
||||
Rectangle hullRect = collisionHull.WorldRect;
|
||||
|
||||
if (position.Y < hullRect.Y - hullRect.Height)
|
||||
{
|
||||
position.Y = hullRect.Y - hullRect.Height - prefab.CollisionRadius;
|
||||
velocity.Y = -velocity.Y;
|
||||
}
|
||||
else if (position.Y > hullRect.Y)
|
||||
{
|
||||
position.Y = hullRect.Y + prefab.CollisionRadius;
|
||||
velocity.X = Math.Abs(velocity.Y) * Math.Sign(velocity.X);
|
||||
velocity.Y = -velocity.Y;
|
||||
}
|
||||
|
||||
if (position.X < hullRect.X)
|
||||
{
|
||||
position.X = hullRect.X - prefab.CollisionRadius;
|
||||
velocity.X = -velocity.X;
|
||||
}
|
||||
else if (position.X > hullRect.X + hullRect.Width)
|
||||
{
|
||||
position.X = hullRect.X + hullRect.Width + prefab.CollisionRadius;
|
||||
velocity.X = -velocity.X;
|
||||
}
|
||||
|
||||
velocity *= prefab.Restitution;
|
||||
}
|
||||
|
||||
public void UpdateDrawPos()
|
||||
{
|
||||
drawPosition = Timing.Interpolate(prevPosition, position);
|
||||
drawRotation = Timing.Interpolate(prevRotation, rotation);
|
||||
|
||||
prevPosition = position;
|
||||
prevRotation = rotation;
|
||||
}
|
||||
|
||||
public void Draw(SpriteBatch spriteBatch)
|
||||
{
|
||||
Vector2 drawSize = size;
|
||||
|
||||
if (prefab.GrowTime > 0.0f && totalLifeTime - lifeTime < prefab.GrowTime)
|
||||
{
|
||||
drawSize *= ((totalLifeTime - lifeTime) / prefab.GrowTime);
|
||||
}
|
||||
|
||||
if (prefab.Sprites[spriteIndex] is SpriteSheet)
|
||||
{
|
||||
((SpriteSheet)prefab.Sprites[spriteIndex]).Draw(
|
||||
spriteBatch, animFrame,
|
||||
new Vector2(drawPosition.X, -drawPosition.Y),
|
||||
color * alpha,
|
||||
prefab.Sprites[spriteIndex].Origin, drawRotation,
|
||||
drawSize, SpriteEffects.None, prefab.Sprites[spriteIndex].Depth);
|
||||
}
|
||||
else
|
||||
{
|
||||
prefab.Sprites[spriteIndex].Draw(spriteBatch,
|
||||
new Vector2(drawPosition.X, -drawPosition.Y),
|
||||
color * alpha,
|
||||
prefab.Sprites[spriteIndex].Origin, drawRotation,
|
||||
drawSize, SpriteEffects.None, prefab.Sprites[spriteIndex].Depth);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
using System.Xml.Linq;
|
||||
using Microsoft.Xna.Framework;
|
||||
using FarseerPhysics;
|
||||
using System;
|
||||
|
||||
namespace Barotrauma.Particles
|
||||
{
|
||||
class ParticleEmitterPrefab
|
||||
{
|
||||
public readonly string Name;
|
||||
|
||||
public readonly ParticlePrefab particlePrefab;
|
||||
|
||||
public readonly float AngleMin, AngleMax;
|
||||
|
||||
public readonly float VelocityMin, VelocityMax;
|
||||
|
||||
public readonly float ScaleMin, ScaleMax;
|
||||
|
||||
public readonly float ParticleAmount;
|
||||
|
||||
public ParticleEmitterPrefab(XElement element)
|
||||
{
|
||||
Name = element.Name.ToString();
|
||||
|
||||
particlePrefab = GameMain.ParticleManager.FindPrefab(ToolBox.GetAttributeString(element, "particle", ""));
|
||||
|
||||
if (element.Attribute("startrotation") == null)
|
||||
{
|
||||
AngleMin = ToolBox.GetAttributeFloat(element, "anglemin", 0.0f);
|
||||
AngleMax = ToolBox.GetAttributeFloat(element, "anglemax", 0.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
AngleMin = ToolBox.GetAttributeFloat(element, "angle", 0.0f);
|
||||
AngleMax = AngleMin;
|
||||
}
|
||||
|
||||
AngleMin = MathHelper.ToRadians(AngleMin);
|
||||
AngleMax = MathHelper.ToRadians(AngleMax);
|
||||
|
||||
if (element.Attribute("scalemin")==null)
|
||||
{
|
||||
ScaleMin = 1.0f;
|
||||
ScaleMax = 1.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
ScaleMin = ToolBox.GetAttributeFloat(element,"scalemin",1.0f);
|
||||
ScaleMax = Math.Max(ScaleMin, ToolBox.GetAttributeFloat(element, "scalemax", 1.0f));
|
||||
}
|
||||
|
||||
if (element.Attribute("velocity") == null)
|
||||
{
|
||||
VelocityMin = ToolBox.GetAttributeFloat(element, "velocitymin", 0.0f);
|
||||
VelocityMax = ToolBox.GetAttributeFloat(element, "velocitymax", 0.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
VelocityMin = ToolBox.GetAttributeFloat(element, "velocity", 0.0f);
|
||||
VelocityMax = VelocityMin;
|
||||
}
|
||||
|
||||
ParticleAmount = ToolBox.GetAttributeInt(element, "particleamount", 1);
|
||||
}
|
||||
|
||||
public void Emit(Vector2 position, Hull hullGuess = null)
|
||||
{
|
||||
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);
|
||||
|
||||
var particle = GameMain.ParticleManager.CreateParticle(particlePrefab, position, velocity, 0.0f, hullGuess);
|
||||
|
||||
if (particle!=null)
|
||||
{
|
||||
particle.Size *= Rand.Range(ScaleMin, ScaleMax);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Xml.Linq;
|
||||
using FarseerPhysics;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
|
||||
namespace Barotrauma.Particles
|
||||
{
|
||||
enum ParticleBlendState
|
||||
{
|
||||
AlphaBlend, Additive, Distortion
|
||||
}
|
||||
|
||||
class ParticleManager
|
||||
{
|
||||
public static int particleCount;
|
||||
|
||||
private const int MaxOutOfViewDist = 500;
|
||||
|
||||
private const int MaxParticles = 1500;
|
||||
private Particle[] particles;
|
||||
|
||||
private Dictionary<string, ParticlePrefab> prefabs;
|
||||
|
||||
Camera cam;
|
||||
|
||||
public ParticleManager(string configFile, Camera cam)
|
||||
{
|
||||
this.cam = cam;
|
||||
|
||||
particles = new Particle[MaxParticles];
|
||||
|
||||
XDocument doc = ToolBox.TryLoadXml(configFile);
|
||||
if (doc == null || doc.Root == null) return;
|
||||
|
||||
prefabs = new Dictionary<string, ParticlePrefab>();
|
||||
|
||||
foreach (XElement element in doc.Root.Elements())
|
||||
{
|
||||
if (prefabs.ContainsKey(element.Name.ToString()))
|
||||
{
|
||||
DebugConsole.ThrowError("Error in " + configFile + "! Each particle prefab must have a unique name.");
|
||||
continue;
|
||||
}
|
||||
prefabs.Add(element.Name.ToString(), new ParticlePrefab(element));
|
||||
}
|
||||
}
|
||||
|
||||
public Particle CreateParticle(string prefabName, Vector2 position, float angle, float speed, Hull hullGuess = null)
|
||||
{
|
||||
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)
|
||||
{
|
||||
ParticlePrefab prefab = FindPrefab(prefabName);
|
||||
|
||||
if (prefab == null)
|
||||
{
|
||||
DebugConsole.ThrowError("Particle prefab \"" + prefabName+"\" not found!");
|
||||
return null;
|
||||
}
|
||||
|
||||
return CreateParticle(prefab, position, speed, rotation, hullGuess);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (particles[particleCount] == null) particles[particleCount] = new Particle();
|
||||
|
||||
particles[particleCount].Init(prefab, position, speed, rotation, hullGuess);
|
||||
|
||||
particleCount++;
|
||||
|
||||
return particles[particleCount-1];
|
||||
|
||||
}
|
||||
|
||||
public ParticlePrefab FindPrefab(string prefabName)
|
||||
{
|
||||
ParticlePrefab prefab;
|
||||
prefabs.TryGetValue(prefabName, out prefab);
|
||||
|
||||
if (prefab == null)
|
||||
{
|
||||
DebugConsole.ThrowError("Particle prefab " + prefabName + " not found!");
|
||||
return null;
|
||||
}
|
||||
|
||||
return prefab;
|
||||
}
|
||||
|
||||
private void RemoveParticle(int index)
|
||||
{
|
||||
particleCount--;
|
||||
|
||||
Particle swap = particles[index];
|
||||
particles[index] = particles[particleCount];
|
||||
particles[particleCount] = swap;
|
||||
}
|
||||
|
||||
public void Update(float deltaTime)
|
||||
{
|
||||
for (int i = 0; i < particleCount; i++)
|
||||
{
|
||||
bool remove = false;
|
||||
try
|
||||
{
|
||||
remove = !particles[i].Update(deltaTime);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
DebugConsole.ThrowError("Particle update failed", e);
|
||||
remove = true;
|
||||
}
|
||||
|
||||
if (remove) RemoveParticle(i);
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateTransforms()
|
||||
{
|
||||
for (int i = 0; i < particleCount; i++)
|
||||
{
|
||||
particles[i].UpdateDrawPos();
|
||||
}
|
||||
}
|
||||
|
||||
public void Draw(SpriteBatch spriteBatch, bool inWater, ParticleBlendState blendState)
|
||||
{
|
||||
ParticlePrefab.DrawTargetType drawTarget = inWater ? ParticlePrefab.DrawTargetType.Water : ParticlePrefab.DrawTargetType.Air;
|
||||
|
||||
for (int i = 0; i < particleCount; i++)
|
||||
{
|
||||
if (particles[i].BlendState != blendState) continue;
|
||||
if (!particles[i].DrawTarget.HasFlag(drawTarget)) continue;
|
||||
|
||||
particles[i].Draw(spriteBatch);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,181 @@
|
||||
using System.Xml.Linq;
|
||||
using Microsoft.Xna.Framework;
|
||||
using FarseerPhysics;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Barotrauma.Particles
|
||||
{
|
||||
class ParticlePrefab
|
||||
{
|
||||
public enum DrawTargetType { Air = 1, Water = 2, Both = 3 }
|
||||
|
||||
public readonly string Name;
|
||||
|
||||
public readonly List<Sprite> Sprites;
|
||||
|
||||
public readonly float AnimDuration;
|
||||
public readonly bool LoopAnim;
|
||||
|
||||
public readonly float AngularVelocityMin, AngularVelocityMax;
|
||||
|
||||
public readonly float StartRotationMin, StartRotationMax;
|
||||
|
||||
public readonly Vector2 StartSizeMin, StartSizeMax;
|
||||
public readonly Vector2 SizeChangeMin, SizeChangeMax;
|
||||
|
||||
public readonly float Drag, WaterDrag;
|
||||
|
||||
public readonly Color StartColor;
|
||||
public readonly float StartAlpha;
|
||||
|
||||
public readonly Vector4 ColorChange;
|
||||
|
||||
public readonly float LifeTime;
|
||||
|
||||
public readonly float GrowTime;
|
||||
|
||||
public readonly float CollisionRadius;
|
||||
public readonly bool DeleteOnCollision;
|
||||
public readonly bool CollidesWithWalls;
|
||||
|
||||
public readonly float Friction;
|
||||
public readonly float Restitution;
|
||||
|
||||
public readonly Vector2 VelocityChange;
|
||||
|
||||
public readonly DrawTargetType DrawTarget;
|
||||
|
||||
public readonly ParticleBlendState BlendState;
|
||||
|
||||
public readonly bool RotateToDirection;
|
||||
|
||||
public ParticlePrefab(XElement element)
|
||||
{
|
||||
Name = element.Name.ToString();
|
||||
|
||||
Sprites = new List<Sprite>();
|
||||
|
||||
foreach (XElement subElement in element.Elements())
|
||||
{
|
||||
switch (subElement.Name.ToString().ToLowerInvariant())
|
||||
{
|
||||
case "sprite":
|
||||
Sprites.Add(new Sprite(subElement));
|
||||
break;
|
||||
case "spritesheet":
|
||||
case "animatedsprite":
|
||||
Sprites.Add(new SpriteSheet(subElement));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
AnimDuration = ToolBox.GetAttributeFloat(element, "animduration", 1.0f);
|
||||
LoopAnim = ToolBox.GetAttributeBool(element, "loopanim", true);
|
||||
|
||||
if (element.Attribute("angularvelocity") == null)
|
||||
{
|
||||
AngularVelocityMin = ToolBox.GetAttributeFloat(element, "angularvelocitymin", 0.0f);
|
||||
AngularVelocityMax = ToolBox.GetAttributeFloat(element, "angularvelocitymax", 0.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
AngularVelocityMin = ToolBox.GetAttributeFloat(element, "angularvelocity", 0.0f);
|
||||
AngularVelocityMax = AngularVelocityMin;
|
||||
}
|
||||
|
||||
if (element.Attribute("startsize") == null)
|
||||
{
|
||||
StartSizeMin = ToolBox.GetAttributeVector2(element, "startsizemin", Vector2.One);
|
||||
StartSizeMax = ToolBox.GetAttributeVector2(element, "startsizemax", Vector2.One);
|
||||
}
|
||||
else
|
||||
{
|
||||
StartSizeMin = ToolBox.GetAttributeVector2(element, "startsize", Vector2.One);
|
||||
StartSizeMax = StartSizeMin;
|
||||
}
|
||||
|
||||
if (element.Attribute("sizechange") == null)
|
||||
{
|
||||
SizeChangeMin = ToolBox.GetAttributeVector2(element, "sizechangemin", Vector2.Zero);
|
||||
SizeChangeMax = ToolBox.GetAttributeVector2(element, "sizechangemax", Vector2.Zero);
|
||||
}
|
||||
else
|
||||
{
|
||||
SizeChangeMin = ToolBox.GetAttributeVector2(element, "sizechange", Vector2.Zero);
|
||||
SizeChangeMax = SizeChangeMin;
|
||||
}
|
||||
|
||||
Drag = ToolBox.GetAttributeFloat(element, "drag", 0.0f);
|
||||
WaterDrag = ToolBox.GetAttributeFloat(element, "waterdrag", 0.0f);
|
||||
|
||||
Friction = ToolBox.GetAttributeFloat(element, "friction", 0.5f);
|
||||
Restitution = ToolBox.GetAttributeFloat(element, "restitution", 0.5f);
|
||||
|
||||
switch (ToolBox.GetAttributeString(element, "blendstate", "alphablend"))
|
||||
{
|
||||
case "alpha":
|
||||
case "alphablend":
|
||||
BlendState = ParticleBlendState.AlphaBlend;
|
||||
break;
|
||||
case "add":
|
||||
case "additive":
|
||||
BlendState = ParticleBlendState.Additive;
|
||||
break;
|
||||
case "distort":
|
||||
case "distortion":
|
||||
BlendState = ParticleBlendState.Distortion;
|
||||
break;
|
||||
}
|
||||
|
||||
GrowTime = ToolBox.GetAttributeFloat(element, "growtime", 0.0f);
|
||||
|
||||
if (element.Attribute("startrotation") == null)
|
||||
{
|
||||
StartRotationMin = ToolBox.GetAttributeFloat(element, "startrotationmin", 0.0f);
|
||||
StartRotationMax = ToolBox.GetAttributeFloat(element, "startrotationmax", 0.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
StartRotationMin = ToolBox.GetAttributeFloat(element, "startrotation", 0.0f);
|
||||
StartRotationMax = StartRotationMin;
|
||||
}
|
||||
|
||||
StartRotationMin = MathHelper.ToRadians(StartRotationMin);
|
||||
StartRotationMax = MathHelper.ToRadians(StartRotationMax);
|
||||
|
||||
StartColor = new Color(ToolBox.GetAttributeVector4(element, "startcolor", Vector4.One));
|
||||
StartAlpha = ToolBox.GetAttributeFloat(element, "startalpha", 1.0f);
|
||||
|
||||
DeleteOnCollision = ToolBox.GetAttributeBool(element, "deleteoncollision", false);
|
||||
CollidesWithWalls = ToolBox.GetAttributeBool(element, "collideswithwalls", false);
|
||||
|
||||
CollisionRadius = ToolBox.GetAttributeFloat(element,
|
||||
"collisionradius",
|
||||
Sprites.Count > 0 ? 1 : Sprites[0].SourceRect.Width / 2.0f);
|
||||
|
||||
ColorChange = ToolBox.GetAttributeVector4(element, "colorchange", Vector4.Zero);
|
||||
|
||||
LifeTime = ToolBox.GetAttributeFloat(element, "lifetime", 5.0f);
|
||||
|
||||
VelocityChange = ToolBox.GetAttributeVector2(element, "velocitychange", Vector2.Zero);
|
||||
VelocityChange = ConvertUnits.ToDisplayUnits(VelocityChange);
|
||||
|
||||
RotateToDirection = ToolBox.GetAttributeBool(element, "rotatetodirection", false);
|
||||
|
||||
switch (ToolBox.GetAttributeString(element, "drawtarget", "air").ToLowerInvariant())
|
||||
{
|
||||
case "air":
|
||||
default:
|
||||
DrawTarget = DrawTargetType.Air;
|
||||
break;
|
||||
case "water":
|
||||
DrawTarget = DrawTargetType.Water;
|
||||
break;
|
||||
case "both":
|
||||
DrawTarget = DrawTargetType.Both;
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user