diff --git a/Barotrauma/BarotraumaClient/Source/Map/Explosion.cs b/Barotrauma/BarotraumaClient/Source/Map/Explosion.cs index 376c50d95..a2d6f3574 100644 --- a/Barotrauma/BarotraumaClient/Source/Map/Explosion.cs +++ b/Barotrauma/BarotraumaClient/Source/Map/Explosion.cs @@ -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; diff --git a/Barotrauma/BarotraumaClient/Source/Map/FireSource.cs b/Barotrauma/BarotraumaClient/Source/Map/FireSource.cs index dc8d058c9..e144aa7de 100644 --- a/Barotrauma/BarotraumaClient/Source/Map/FireSource.cs +++ b/Barotrauma/BarotraumaClient/Source/Map/FireSource.cs @@ -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); + } } } } diff --git a/Barotrauma/BarotraumaClient/Source/Map/Hull.cs b/Barotrauma/BarotraumaClient/Source/Map/Hull.cs index ee0f53fed..0c6418199 100644 --- a/Barotrauma/BarotraumaClient/Source/Map/Hull.cs +++ b/Barotrauma/BarotraumaClient/Source/Map/Hull.cs @@ -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); } } diff --git a/Barotrauma/BarotraumaClient/Source/Particles/Decal.cs b/Barotrauma/BarotraumaClient/Source/Particles/Decal.cs index ea0907b45..42ead6b92 100644 --- a/Barotrauma/BarotraumaClient/Source/Particles/Decal.cs +++ b/Barotrauma/BarotraumaClient/Source/Particles/Decal.cs @@ -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; } } } diff --git a/Barotrauma/BarotraumaClient/Source/Particles/DecalPrefab.cs b/Barotrauma/BarotraumaClient/Source/Particles/DecalPrefab.cs index 9ee8d0e08..d6005e322 100644 --- a/Barotrauma/BarotraumaClient/Source/Particles/DecalPrefab.cs +++ b/Barotrauma/BarotraumaClient/Source/Particles/DecalPrefab.cs @@ -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)); } } } diff --git a/Barotrauma/BarotraumaShared/BarotraumaShared.projitems b/Barotrauma/BarotraumaShared/BarotraumaShared.projitems index 9c6b52de7..7bd2e0bca 100644 --- a/Barotrauma/BarotraumaShared/BarotraumaShared.projitems +++ b/Barotrauma/BarotraumaShared/BarotraumaShared.projitems @@ -604,9 +604,15 @@ PreserveNewest + + PreserveNewest + PreserveNewest + + PreserveNewest + PreserveNewest diff --git a/Barotrauma/BarotraumaShared/Content/Items/Weapons/explosives.xml b/Barotrauma/BarotraumaShared/Content/Items/Weapons/explosives.xml index 8748c45e6..83ccd80fd 100644 --- a/Barotrauma/BarotraumaShared/Content/Items/Weapons/explosives.xml +++ b/Barotrauma/BarotraumaShared/Content/Items/Weapons/explosives.xml @@ -13,7 +13,7 @@ - + @@ -31,7 +31,7 @@ - + @@ -50,7 +50,7 @@ - + @@ -121,7 +121,7 @@ - + diff --git a/Barotrauma/BarotraumaShared/Content/Items/Weapons/railgun.xml b/Barotrauma/BarotraumaShared/Content/Items/Weapons/railgun.xml index 347498045..1379bf89d 100644 --- a/Barotrauma/BarotraumaShared/Content/Items/Weapons/railgun.xml +++ b/Barotrauma/BarotraumaShared/Content/Items/Weapons/railgun.xml @@ -118,7 +118,7 @@ - + diff --git a/Barotrauma/BarotraumaShared/Content/Particles/DecalPrefabs.xml b/Barotrauma/BarotraumaShared/Content/Particles/DecalPrefabs.xml index 57459dc8a..6eb16e18f 100644 --- a/Barotrauma/BarotraumaShared/Content/Particles/DecalPrefabs.xml +++ b/Barotrauma/BarotraumaShared/Content/Particles/DecalPrefabs.xml @@ -3,9 +3,22 @@ + fadeouttime="20"> + + + + + + diff --git a/Barotrauma/BarotraumaShared/Content/Particles/burnt.png b/Barotrauma/BarotraumaShared/Content/Particles/burnt.png new file mode 100644 index 000000000..ee423867c Binary files /dev/null and b/Barotrauma/BarotraumaShared/Content/Particles/burnt.png differ diff --git a/Barotrauma/BarotraumaShared/Content/Particles/explosiondecal.png b/Barotrauma/BarotraumaShared/Content/Particles/explosiondecal.png new file mode 100644 index 000000000..4ee0f486e Binary files /dev/null and b/Barotrauma/BarotraumaShared/Content/Particles/explosiondecal.png differ diff --git a/Barotrauma/BarotraumaShared/Source/DebugConsole.cs b/Barotrauma/BarotraumaShared/Source/DebugConsole.cs index 820ee0ef9..a27068b56 100644 --- a/Barotrauma/BarotraumaShared/Source/DebugConsole.cs +++ b/Barotrauma/BarotraumaShared/Source/DebugConsole.cs @@ -493,7 +493,7 @@ namespace Barotrauma if (GameMain.Client == null) { Hull.EditFire = !Hull.EditFire; - NewMessage(Hull.EditWater ? "Fire spawning on" : "Fire spawning off", Color.White); + NewMessage(Hull.EditFire ? "Fire spawning on" : "Fire spawning off", Color.White); } break; diff --git a/Barotrauma/BarotraumaShared/Source/Map/Explosion.cs b/Barotrauma/BarotraumaShared/Source/Map/Explosion.cs index e900de839..cd8fe2385 100644 --- a/Barotrauma/BarotraumaShared/Source/Map/Explosion.cs +++ b/Barotrauma/BarotraumaShared/Source/Map/Explosion.cs @@ -17,6 +17,9 @@ namespace Barotrauma private bool sparks, shockwave, flames, smoke; + private string decal; + private float decalSize; + public Explosion(float range, float force, float damage, float structureDamage) { attack = new Attack(damage, structureDamage, 0.0f, range); @@ -37,7 +40,10 @@ namespace Barotrauma flames = ToolBox.GetAttributeBool(element, "flames", true); smoke = ToolBox.GetAttributeBool(element, "smoke", true); - CameraShake = ToolBox.GetAttributeFloat(element, "camerashake", attack.Range*0.1f); + decal = ToolBox.GetAttributeString(element, "decal", ""); + decalSize = ToolBox.GetAttributeFloat(element, "decalSize", 1.0f); + + CameraShake = ToolBox.GetAttributeFloat(element, "camerashake", attack.Range * 0.1f); } public void Explode(Vector2 worldPosition) diff --git a/Barotrauma/BarotraumaShared/Source/Map/FireSource.cs b/Barotrauma/BarotraumaShared/Source/Map/FireSource.cs index 02bc1de08..bf3be9908 100644 --- a/Barotrauma/BarotraumaShared/Source/Map/FireSource.cs +++ b/Barotrauma/BarotraumaShared/Source/Map/FireSource.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using Barotrauma.Networking; #if CLIENT using Barotrauma.Lights; +using Barotrauma.Particles; #endif namespace Barotrauma @@ -22,6 +23,10 @@ namespace Barotrauma private Entity Submarine; +#if CLIENT + private List burnDecals = new List(); +#endif + public Vector2 Position { get { return position; } @@ -110,8 +115,10 @@ namespace Barotrauma //combine overlapping fires for (int i = fireSources.Count - 1; i >= 0; i--) { - for (int j = i-1; j>=0 ; j--) + for (int j = i - 1; j >= 0; j--) { + if (fireSources[i].hull != fireSources[j].hull) continue; + i = Math.Min(i, fireSources.Count - 1); j = Math.Min(j, i - 1); @@ -124,7 +131,12 @@ namespace Barotrauma - leftEdge; fireSources[j].position.X = leftEdge; - + +#if CLIENT + fireSources[j].burnDecals.AddRange(fireSources[i].burnDecals); + fireSources[j].burnDecals.Sort((d1, d2) => { return Math.Sign(d1.WorldPosition.X - d2.WorldPosition.X); }); +#endif + fireSources[i].Remove(); } } @@ -311,6 +323,11 @@ namespace Barotrauma Sounds.SoundManager.Stop(largeSoundIndex); largeSoundIndex = -1; } + + foreach (Decal d in burnDecals) + { + d.StopFadeIn(); + } #endif hull.RemoveFire(this);