Fire & explosion decals

This commit is contained in:
Joonas Rikkonen
2017-07-08 18:30:07 +03:00
parent 4e4983f0a6
commit d4b58e16b9
14 changed files with 155 additions and 71 deletions
@@ -6,9 +6,8 @@ namespace Barotrauma
{
partial class Explosion
{
partial void ExplodeProjSpecific(Vector2 worldPosition,Hull hull)
partial void ExplodeProjSpecific(Vector2 worldPosition, Hull hull)
{
if (shockwave)
{
GameMain.ParticleManager.CreateParticle("shockwave", worldPosition,
@@ -38,6 +37,11 @@ namespace Barotrauma
}
}
if (hull != null && !string.IsNullOrWhiteSpace(decal) && decalSize > 0.0f)
{
hull.AddDecal(decal, worldPosition, decalSize);
}
float displayRange = attack.Range;
if (displayRange < 0.1f) return;
@@ -1,4 +1,5 @@
using Barotrauma.Lights;
using Barotrauma.Particles;
using Microsoft.Xna.Framework;
using System;
using System.Linq;
@@ -78,6 +79,32 @@ namespace Barotrauma
lightSource.Range = Math.Max(size.X, size.Y) * 10.0f / 2.0f;
lightSource.Color = new Color(1.0f, 0.45f, 0.3f) * Rand.Range(0.8f, 1.0f);
lightSource.Position = position + Vector2.UnitY * 30.0f;
if (size.X > 256.0f)
{
if (burnDecals.Count == 0)
{
var newDecal = hull.AddDecal("burnt", WorldPosition + size/2);
if (newDecal != null) burnDecals.Add(newDecal);
}
else if (WorldPosition.X < burnDecals[0].WorldPosition.X - 256.0f)
{
var newDecal = hull.AddDecal("burnt", WorldPosition);
if (newDecal != null) burnDecals.Insert(0, newDecal);
}
else if (WorldPosition.X + size.X > burnDecals[burnDecals.Count-1].WorldPosition.X + 256.0f)
{
var newDecal = hull.AddDecal("burnt", WorldPosition + Vector2.UnitX * size.X);
if (newDecal != null) burnDecals.Add(newDecal);
}
}
foreach (Decal d in burnDecals)
{
//prevent the decals from fading out as long as the firesource is alive
d.FadeTimer = Math.Min(d.FadeTimer, d.FadeInTime);
}
}
}
}
+6 -38
View File
@@ -44,16 +44,18 @@ namespace Barotrauma
!Submarine.RectContains(MathUtils.ExpandRect(WorldRect, -8), position));
}
public void AddDecal(string decalName, Vector2 position, float scale)
public Decal AddDecal(string decalName, Vector2 worldPosition, float scale = 1.0f)
{
if (decals.Count >= MaxDecalsPerHull) return;
if (decals.Count >= MaxDecalsPerHull) return null;
var decal = GameMain.DecalManager.CreateDecal(decalName, scale, position, this);
var decal = GameMain.DecalManager.CreateDecal(decalName, scale, worldPosition, this);
if (decal != null)
{
decals.Add(decal);
}
return decal;
}
partial void UpdateProjSpecific(float deltaTime, Camera cam)
@@ -158,44 +160,10 @@ namespace Barotrauma
{
Rectangle hullDrawRect = rect;
if (Submarine != null) hullDrawRect.Location += Submarine.DrawPosition.ToPoint();
foreach (Decal d in decals)
{
d.Draw(spriteBatch, this);
continue;
Vector2 drawPos = d.Position + rect.Location.ToVector2();
Rectangle drawRect = new Rectangle(
(int)(drawPos.X - d.Sprite.size.X / 2),
(int)(drawPos.Y + d.Sprite.size.Y / 2),
(int)d.Sprite.size.X,
(int)d.Sprite.size.Y);
Rectangle overFlowAmount = new Rectangle(
(int)Math.Max(hullDrawRect.X - drawRect.X, 0.0f),
(int)Math.Max(drawRect.Y - hullDrawRect.Y, 0.0f),
(int)Math.Max(drawRect.Right - hullDrawRect.Right, 0.0f),
(int)Math.Max((hullDrawRect.Y - hullDrawRect.Height) - (drawRect.Y - drawRect.Height), 0.0f));
var clippedSourceRect = new Rectangle(d.Sprite.SourceRect.X + overFlowAmount.X,
d.Sprite.SourceRect.Y + overFlowAmount.Y,
d.Sprite.SourceRect.Width - overFlowAmount.X - overFlowAmount.Width,
d.Sprite.SourceRect.Height - overFlowAmount.Y - overFlowAmount.Height);
drawRect = new Rectangle(
drawRect.X + overFlowAmount.X,
drawRect.Y - overFlowAmount.Y,
drawRect.Width - overFlowAmount.X - overFlowAmount.Width,
drawRect.Height - overFlowAmount.Y - overFlowAmount.Height);
drawPos.Y = -drawPos.Y;
drawRect.Y = -drawRect.Y;
GUI.DrawRectangle(spriteBatch, drawRect, Color.Red);
GUI.DrawRectangle(spriteBatch, drawPos, Vector2.One * 3, Color.Red);
spriteBatch.Draw(d.Sprite.Texture, drawRect, clippedSourceRect, d.Color, 0, Vector2.Zero, SpriteEffects.None, 1.0f);
}
}
@@ -7,26 +7,51 @@ namespace Barotrauma.Particles
class Decal
{
public readonly DecalPrefab Prefab;
public Vector2 Position;
private Vector2 position;
public readonly Sprite Sprite;
private float fadeTimer;
public Color Color
{
get { return Prefab.Color; }
}
public float FadeTimer
{
get { return fadeTimer; }
set { fadeTimer = MathHelper.Clamp(value, 0.0f, LifeTime); }
}
public float FadeInTime
{
get { return Prefab.FadeInTime; }
}
public float FadeOutTime
{
get { return Prefab.FadeOutTime; }
}
public float LifeTime
{
get { return Prefab.LifeTime; }
}
public Color Color
{
get;
set;
}
public Vector2 WorldPosition
{
get
{
return position
+ clippedSourceRect.Size.ToVector2() / 2 * scale
+ hull.Rect.Location.ToVector2()
+ hull.Submarine.DrawPosition;
}
}
private Hull hull;
private float scale;
@@ -36,12 +61,15 @@ namespace Barotrauma.Particles
{
Prefab = prefab;
//transform to hull-relative coordinates so we don't have to worry about the hull moving
Position = worldPosition - hull.WorldRect.Location.ToVector2();
this.hull = hull;
Vector2 drawPos = Position + hull.Rect.Location.ToVector2();
//transform to hull-relative coordinates so we don't have to worry about the hull moving
position = worldPosition - hull.WorldRect.Location.ToVector2();
Vector2 drawPos = position + hull.Rect.Location.ToVector2();
Sprite = prefab.Sprites[Rand.Range(0, prefab.Sprites.Count, Rand.RandSync.Unsynced)];
Color = prefab.Color;
Rectangle drawRect = new Rectangle(
(int)(drawPos.X - Sprite.size.X / 2 * scale),
@@ -61,7 +89,7 @@ namespace Barotrauma.Particles
Sprite.SourceRect.Width - (int)((overFlowAmount.X + overFlowAmount.Width) / scale),
Sprite.SourceRect.Height - (int)((overFlowAmount.Y + overFlowAmount.Height) / scale));
Position -= new Vector2(Sprite.size.X / 2 * scale - overFlowAmount.X, -Sprite.size.Y / 2 * scale + overFlowAmount.Y);
position -= new Vector2(Sprite.size.X / 2 * scale - overFlowAmount.X, -Sprite.size.Y / 2 * scale + overFlowAmount.Y);
this.scale = scale;
}
@@ -71,19 +99,32 @@ namespace Barotrauma.Particles
fadeTimer += deltaTime;
}
public void StopFadeIn()
{
Color *= GetAlpha();
fadeTimer = Prefab.FadeInTime;
}
public void Draw(SpriteBatch spriteBatch, Hull hull)
{
Vector2 drawPos = Position + hull.Rect.Location.ToVector2();
Vector2 drawPos = position + hull.Rect.Location.ToVector2();
drawPos += hull.Submarine.DrawPosition;
drawPos.Y = -drawPos.Y;
float a = 1.0f;
if (fadeTimer > Prefab.LifeTime - Prefab.FadeTime)
{
a = (Prefab.LifeTime - fadeTimer) / Prefab.FadeTime;
}
spriteBatch.Draw(Sprite.Texture, drawPos, clippedSourceRect, Color * a, 0, Vector2.Zero , scale, SpriteEffects.None, 1);
spriteBatch.Draw(Sprite.Texture, drawPos, clippedSourceRect, Color * GetAlpha(), 0, Vector2.Zero, scale, SpriteEffects.None, 1);
}
private float GetAlpha()
{
if (fadeTimer < Prefab.FadeInTime)
{
return fadeTimer / Prefab.FadeInTime;
}
else if (fadeTimer > Prefab.LifeTime - Prefab.FadeOutTime)
{
return (Prefab.LifeTime - fadeTimer) / Prefab.FadeOutTime;
}
return 1.0f;
}
}
}
@@ -14,7 +14,8 @@ namespace Barotrauma.Particles
public readonly Color Color;
public readonly float LifeTime;
public readonly float FadeTime;
public readonly float FadeOutTime;
public readonly float FadeInTime;
public DecalPrefab(XElement element)
{
@@ -33,7 +34,8 @@ namespace Barotrauma.Particles
Color = new Color(ToolBox.GetAttributeVector4(element, "color", Vector4.One));
LifeTime = ToolBox.GetAttributeFloat(element, "lifetime", 10.0f);
FadeTime = Math.Min(LifeTime, ToolBox.GetAttributeFloat(element, "fadetime", 1.0f));
FadeOutTime = Math.Min(LifeTime, ToolBox.GetAttributeFloat(element, "fadeouttime", 1.0f));
FadeInTime = Math.Min(LifeTime - FadeOutTime, ToolBox.GetAttributeFloat(element, "fadeintime", 0.0f));
}
}
}