Decal system (TODO: add decals for explosions and fire), moved some of the client-specific Hull update logic to the client project
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using System;
|
||||
|
||||
namespace Barotrauma.Particles
|
||||
{
|
||||
class Decal
|
||||
{
|
||||
public readonly DecalPrefab Prefab;
|
||||
public Vector2 Position;
|
||||
|
||||
public readonly Sprite Sprite;
|
||||
|
||||
private float fadeTimer;
|
||||
|
||||
public Color Color
|
||||
{
|
||||
get { return Prefab.Color; }
|
||||
}
|
||||
|
||||
public float FadeTimer
|
||||
{
|
||||
get { return fadeTimer; }
|
||||
}
|
||||
|
||||
public float LifeTime
|
||||
{
|
||||
get { return Prefab.LifeTime; }
|
||||
}
|
||||
|
||||
private float scale;
|
||||
|
||||
private Rectangle clippedSourceRect;
|
||||
|
||||
public Decal(DecalPrefab prefab, float scale, Vector2 worldPosition, Hull hull)
|
||||
{
|
||||
Prefab = prefab;
|
||||
|
||||
//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)];
|
||||
|
||||
Rectangle drawRect = new Rectangle(
|
||||
(int)(drawPos.X - Sprite.size.X / 2 * scale),
|
||||
(int)(drawPos.Y + Sprite.size.Y / 2 * scale),
|
||||
(int)(Sprite.size.X * scale),
|
||||
(int)(Sprite.size.Y * scale));
|
||||
|
||||
Rectangle overFlowAmount = new Rectangle(
|
||||
(int)Math.Max(hull.Rect.X - drawRect.X, 0.0f),
|
||||
(int)Math.Max(drawRect.Y - hull.Rect.Y, 0.0f),
|
||||
(int)Math.Max(drawRect.Right - hull.Rect.Right, 0.0f),
|
||||
(int)Math.Max((hull.Rect.Y - hull.Rect.Height) - (drawRect.Y - drawRect.Height), 0.0f));
|
||||
|
||||
clippedSourceRect = new Rectangle(
|
||||
Sprite.SourceRect.X + (int)(overFlowAmount.X / scale),
|
||||
Sprite.SourceRect.Y + (int)(overFlowAmount.Y / scale),
|
||||
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);
|
||||
|
||||
this.scale = scale;
|
||||
}
|
||||
|
||||
public void Update(float deltaTime)
|
||||
{
|
||||
fadeTimer += deltaTime;
|
||||
}
|
||||
|
||||
public void Draw(SpriteBatch spriteBatch, Hull hull)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using System.Collections.Generic;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Barotrauma.Particles
|
||||
{
|
||||
class DecalManager
|
||||
{
|
||||
private Dictionary<string, DecalPrefab> prefabs;
|
||||
|
||||
public DecalManager(string configFile)
|
||||
{
|
||||
XDocument doc = ToolBox.TryLoadXml(configFile);
|
||||
if (doc == null || doc.Root == null) return;
|
||||
|
||||
prefabs = new Dictionary<string, DecalPrefab>();
|
||||
|
||||
foreach (XElement element in doc.Root.Elements())
|
||||
{
|
||||
if (prefabs.ContainsKey(element.Name.ToString()))
|
||||
{
|
||||
DebugConsole.ThrowError("Error in " + configFile + "! Each decal prefab must have a unique name.");
|
||||
continue;
|
||||
}
|
||||
prefabs.Add(element.Name.ToString(), new DecalPrefab(element));
|
||||
}
|
||||
}
|
||||
|
||||
public Decal CreateDecal(string decalName, float scale, Vector2 worldPosition, Hull hull)
|
||||
{
|
||||
DecalPrefab prefab;
|
||||
prefabs.TryGetValue(decalName, out prefab);
|
||||
|
||||
if (prefab == null)
|
||||
{
|
||||
DebugConsole.ThrowError("Decal prefab " + decalName + " not found!");
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Decal(prefab, scale, worldPosition, hull);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Barotrauma.Particles
|
||||
{
|
||||
class DecalPrefab
|
||||
{
|
||||
public readonly string Name;
|
||||
|
||||
public readonly List<Sprite> Sprites;
|
||||
|
||||
public readonly Color Color;
|
||||
|
||||
public readonly float LifeTime;
|
||||
public readonly float FadeTime;
|
||||
|
||||
public DecalPrefab(XElement element)
|
||||
{
|
||||
Name = element.Name.ToString();
|
||||
|
||||
Sprites = new List<Sprite>();
|
||||
|
||||
foreach (XElement subElement in element.Elements())
|
||||
{
|
||||
if (subElement.Name.ToString().ToLowerInvariant() == "sprite")
|
||||
{
|
||||
Sprites.Add(new Sprite(subElement));
|
||||
}
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user