diff --git a/Subsurface/Barotrauma.csproj b/Subsurface/Barotrauma.csproj
index 117d4b36c..7da1f6e51 100644
--- a/Subsurface/Barotrauma.csproj
+++ b/Subsurface/Barotrauma.csproj
@@ -60,6 +60,7 @@
Icon.ico
+
@@ -850,12 +851,18 @@
PreserveNewest
+
+ PreserveNewest
+
PreserveNewest
PreserveNewest
+
+ PreserveNewest
+
PreserveNewest
diff --git a/Subsurface/Content/Particles/FlameRoundParticleSheet.png b/Subsurface/Content/Particles/FlameRoundParticleSheet.png
new file mode 100644
index 000000000..8b6c84a46
Binary files /dev/null and b/Subsurface/Content/Particles/FlameRoundParticleSheet.png differ
diff --git a/Subsurface/Content/Particles/ParticlePrefabs.xml b/Subsurface/Content/Particles/ParticlePrefabs.xml
index 7182505bc..36fbedd31 100644
--- a/Subsurface/Content/Particles/ParticlePrefabs.xml
+++ b/Subsurface/Content/Particles/ParticlePrefabs.xml
@@ -111,19 +111,20 @@
-
-
+ velocitychange="0.0, 2.5"
+ animduration="1.2"
+ loopanim="false">
+
-
+ collisionradius="80.0"
+ velocitychange="0.0, 2.5"
+ animduration="4"
+ restitution="0.98"
+ loopanim="false">
+
hullGaps;
+
+ private float animState;
+ private int animFrame;
public ParticlePrefab.DrawTargetType DrawTarget
{
@@ -77,6 +80,9 @@ namespace Barotrauma.Particles
spriteIndex = Rand.Int(prefab.Sprites.Count);
+ animState = 0;
+ animFrame = 0;
+
currentHull = Hull.FindHull(position, hullGuess);
this.position = position;
@@ -166,6 +172,13 @@ namespace Barotrauma.Particles
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);
+ }
if (prefab.DeleteOnCollision || prefab.CollidesWithWalls)
{
@@ -317,11 +330,25 @@ namespace Barotrauma.Particles
drawSize *= ((totalLifeTime - lifeTime) / prefab.GrowTime);
}
- 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);
+ 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);
+ }
+
+
}
}
}
diff --git a/Subsurface/Source/Particles/ParticlePrefab.cs b/Subsurface/Source/Particles/ParticlePrefab.cs
index c0af6a518..47c9d29c5 100644
--- a/Subsurface/Source/Particles/ParticlePrefab.cs
+++ b/Subsurface/Source/Particles/ParticlePrefab.cs
@@ -13,6 +13,9 @@ namespace Barotrauma.Particles
public readonly List Sprites;
+ public readonly float AnimDuration;
+ public readonly bool LoopAnim;
+
public readonly float AngularVelocityMin, AngularVelocityMax;
public readonly float StartRotationMin, StartRotationMax;
@@ -53,11 +56,21 @@ namespace Barotrauma.Particles
foreach (XElement subElement in element.Elements())
{
- if (subElement.Name.ToString().ToLowerInvariant() != "sprite") continue;
-
- Sprites.Add(new Sprite(subElement));
+ 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);
@@ -134,7 +147,9 @@ namespace Barotrauma.Particles
DeleteOnCollision = ToolBox.GetAttributeBool(element, "deleteoncollision", false);
CollidesWithWalls = ToolBox.GetAttributeBool(element, "collideswithwalls", false);
- CollisionRadius = ToolBox.GetAttributeFloat(element, "collisionradius", Sprites[0].SourceRect.Width/2.0f);
+ CollisionRadius = ToolBox.GetAttributeFloat(element,
+ "collisionradius",
+ Sprites.Count > 0 ? 1 : Sprites[0].SourceRect.Width / 2.0f);
ColorChange = ToolBox.GetAttributeVector4(element, "colorchange", Vector4.Zero);
diff --git a/Subsurface/Source/Sprite.cs b/Subsurface/Source/Sprite.cs
index 0788538fd..236a7b102 100644
--- a/Subsurface/Source/Sprite.cs
+++ b/Subsurface/Source/Sprite.cs
@@ -14,15 +14,15 @@ namespace Barotrauma
//if two sprites use the same file, they share the same texture
string file;
- Texture2D texture;
+ protected Texture2D texture;
//the area in the texture that is supposed to be drawn
Rectangle sourceRect;
//the offset used when drawing the sprite
- Vector2 offset;
+ protected Vector2 offset;
- private Vector2 origin;
+ protected Vector2 origin;
//the size of the drawn sprite, if larger than the source,
//the sprite is tiled to fill the target size
@@ -32,7 +32,7 @@ namespace Barotrauma
public SpriteEffects effects;
- float depth;
+ protected float depth;
public Rectangle SourceRect
{
@@ -202,7 +202,7 @@ namespace Barotrauma
this.Draw(spriteBatch, pos, color, origin, rotate, new Vector2(scale, scale), spriteEffect, depth);
}
- public void Draw(SpriteBatch spriteBatch, Vector2 pos, Color color, Vector2 origin, float rotate, Vector2 scale, SpriteEffects spriteEffect = SpriteEffects.None, float? depth = null)
+ public virtual void Draw(SpriteBatch spriteBatch, Vector2 pos, Color color, Vector2 origin, float rotate, Vector2 scale, SpriteEffects spriteEffect = SpriteEffects.None, float? depth = null)
{
//for (int x = -1; x <= 1; x += 2)
//{
diff --git a/Subsurface/Source/SpriteSheet.cs b/Subsurface/Source/SpriteSheet.cs
new file mode 100644
index 000000000..eadc93492
--- /dev/null
+++ b/Subsurface/Source/SpriteSheet.cs
@@ -0,0 +1,55 @@
+using Microsoft.Xna.Framework;
+using System;
+using System.Xml.Linq;
+using Microsoft.Xna.Framework.Graphics;
+
+namespace Barotrauma
+{
+ class SpriteSheet : Sprite
+ {
+ private Rectangle[] sourceRects;
+
+ public int FrameCount
+ {
+ get { return sourceRects.Length; }
+ }
+
+ public SpriteSheet(XElement element, string path = "", string file = "")
+ : base(element, path, file)
+ {
+ int columnCount = Math.Max(ToolBox.GetAttributeInt(element, "columns", 1), 1);
+ int rowCount = Math.Max(ToolBox.GetAttributeInt(element, "rows", 1), 1);
+
+ sourceRects = new Rectangle[rowCount * columnCount];
+
+ int cellWidth = SourceRect.Width / columnCount;
+ int cellHeight = SourceRect.Height / rowCount;
+
+ for (int x = 0; x < columnCount; x++)
+ {
+ for (int y = 0; y < rowCount; y++)
+ {
+ sourceRects[x + y * columnCount] = new Rectangle(x * cellWidth, y * cellHeight, cellWidth, cellHeight);
+ }
+ }
+
+ origin = ToolBox.GetAttributeVector2(element, "origin", new Vector2(0.5f, 0.5f));
+ origin.X = origin.X * cellWidth;
+ origin.Y = origin.Y * cellHeight;
+ }
+
+ public override void Draw(SpriteBatch spriteBatch, Vector2 pos, Color color, Vector2 origin, float rotate, Vector2 scale, SpriteEffects spriteEffect = SpriteEffects.None, float? depth = default(float?))
+ {
+ if (texture == null) return;
+
+ spriteBatch.Draw(texture, pos + offset, sourceRects[0], color, rotation + rotate, origin, scale, spriteEffect, depth == null ? this.depth : (float)depth);
+ }
+
+ public void Draw(SpriteBatch spriteBatch, int spriteIndex, Vector2 pos, Color color, Vector2 origin, float rotate, Vector2 scale, SpriteEffects spriteEffect = SpriteEffects.None, float? depth = default(float?))
+ {
+ if (texture == null) return;
+
+ spriteBatch.Draw(texture, pos + offset, sourceRects[spriteIndex], color, rotation + rotate, origin, scale, spriteEffect, depth == null ? this.depth : (float)depth);
+ }
+ }
+}