v0.10.5.1

This commit is contained in:
Juan Pablo Arce
2020-09-22 11:31:56 -03:00
parent 44032d0ae0
commit 0002ad2c50
343 changed files with 12276 additions and 5023 deletions
@@ -0,0 +1,167 @@
using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic;
namespace Barotrauma
{
partial class Decal
{
public readonly DecalPrefab Prefab;
private Vector2 position;
private float fadeTimer;
public readonly Sprite Sprite;
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; }
}
private float baseAlpha = 1.0f;
public float BaseAlpha
{
get { return baseAlpha; }
}
public Color Color
{
get;
set;
}
public Vector2 WorldPosition
{
get
{
Vector2 worldPos = position
+ clippedSourceRect.Size.ToVector2() / 2 * Scale
+ hull.Rect.Location.ToVector2();
if (hull.Submarine != null) { worldPos += hull.Submarine.DrawPosition; }
return worldPos;
}
}
public Vector2 Position
{
get { return position; }
}
public Vector2 NonClampedPosition
{
get;
private set;
}
private readonly HashSet<BackgroundSection> affectedSections;
private readonly Hull hull;
public readonly float Scale;
private Rectangle clippedSourceRect;
private bool cleaned = false;
public Decal(DecalPrefab prefab, float scale, Vector2 worldPosition, Hull hull)
{
Prefab = prefab;
this.hull = hull;
//transform to hull-relative coordinates so we don't have to worry about the hull moving
NonClampedPosition = 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),
(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;
foreach (BackgroundSection section in hull.GetBackgroundSectionsViaContaining(new Rectangle((int)position.X, (int)position.Y - drawRect.Height, drawRect.Width, drawRect.Height)))
{
affectedSections ??= new HashSet<BackgroundSection>();
affectedSections.Add(section);
}
}
public void Update(float deltaTime)
{
fadeTimer += deltaTime;
}
public void ForceRefreshFadeTimer(float val)
{
cleaned = false;
fadeTimer = val;
}
public void StopFadeIn()
{
Color *= GetAlpha();
fadeTimer = Prefab.FadeInTime;
}
public bool AffectsSection(BackgroundSection section)
{
return affectedSections != null && affectedSections.Contains(section);
}
public void Clean(float val)
{
cleaned = true;
float sizeModifier = MathHelper.Clamp(Sprite.size.X * Sprite.size.Y * Scale / 10000, 1.0f, 25.0f);
baseAlpha -= val * -1 / sizeModifier;
}
private float GetAlpha()
{
if (fadeTimer < Prefab.FadeInTime && !cleaned)
{
return baseAlpha * fadeTimer / Prefab.FadeInTime;
}
else if (cleaned || fadeTimer > Prefab.LifeTime - Prefab.FadeOutTime)
{
return baseAlpha * Math.Min((Prefab.LifeTime - fadeTimer) / Prefab.FadeOutTime, 1.0f);
}
return baseAlpha;
}
}
}
@@ -0,0 +1,124 @@
using Microsoft.Xna.Framework;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Xml.Linq;
namespace Barotrauma
{
class DecalManager
{
public PrefabCollection<DecalPrefab> Prefabs { get; private set; }
public readonly List<Sprite> GrimeSprites = new List<Sprite>();
private Dictionary<string, List<Sprite>> grimeSpritesByFile = new Dictionary<string, List<Sprite>>();
public DecalManager()
{
Prefabs = new PrefabCollection<DecalPrefab>();
foreach (ContentFile configFile in GameMain.Instance.GetFilesOfType(ContentType.Decals))
{
LoadFromFile(configFile);
}
}
public void LoadFromFile(ContentFile configFile)
{
XDocument doc = XMLExtensions.TryLoadXml(configFile.Path);
if (doc == null) { return; }
if (grimeSpritesByFile.ContainsKey(configFile.Path))
{
foreach (Sprite sprite in grimeSpritesByFile[configFile.Path])
{
sprite.Remove();
GrimeSprites.Remove(sprite);
}
grimeSpritesByFile.Remove(configFile.Path);
}
bool allowOverriding = false;
var mainElement = doc.Root;
if (doc.Root.IsOverride())
{
mainElement = doc.Root.FirstElement();
allowOverriding = true;
}
foreach (XElement sourceElement in mainElement.Elements())
{
var element = sourceElement.IsOverride() ? sourceElement.FirstElement() : sourceElement;
string name = element.Name.ToString().ToLowerInvariant();
switch (name)
{
case "grime":
if (!grimeSpritesByFile.ContainsKey(configFile.Path))
{
grimeSpritesByFile.Add(configFile.Path, new List<Sprite>());
}
var grimeSprite = new Sprite(element);
GrimeSprites.Add(grimeSprite);
grimeSpritesByFile[configFile.Path].Add(grimeSprite);
break;
default:
if (Prefabs.ContainsKey(name))
{
if (allowOverriding || sourceElement.IsOverride())
{
DebugConsole.NewMessage($"Overriding the existing decal prefab '{name}' using the file '{configFile.Path}'", Color.Yellow);
}
else
{
DebugConsole.ThrowError($"Error in '{configFile.Path}': Duplicate decal prefab '{name}' found in '{configFile.Path}'! Each decal prefab must have a unique name. " +
"Use <override></override> tags to override prefabs.");
continue;
}
}
Prefabs.Add(new DecalPrefab(element, configFile), allowOverriding || sourceElement.IsOverride());
break;
}
}
using MD5 md5 = MD5.Create();
foreach (DecalPrefab prefab in Prefabs)
{
prefab.UIntIdentifier = ToolBox.StringToUInt32Hash(prefab.Identifier, md5);
//it's theoretically possible for two different values to generate the same hash, but the probability is astronomically small
var collision = Prefabs.Find(p => p != prefab && p.UIntIdentifier == prefab.UIntIdentifier);
if (collision != null)
{
DebugConsole.ThrowError("Hashing collision when generating uint identifiers for Decals: " + prefab.Identifier + " has the same identifier as " + collision.Identifier + " (" + prefab.UIntIdentifier + ")");
collision.UIntIdentifier++;
}
}
}
public void RemoveByFile(string filePath)
{
Prefabs.RemoveByFile(filePath);
if (grimeSpritesByFile.ContainsKey(filePath))
{
foreach (Sprite sprite in grimeSpritesByFile[filePath])
{
sprite.Remove();
GrimeSprites.Remove(sprite);
}
grimeSpritesByFile.Remove(filePath);
}
}
public Decal CreateDecal(string decalName, float scale, Vector2 worldPosition, Hull hull)
{
if (!Prefabs.ContainsKey(decalName.ToLowerInvariant()))
{
DebugConsole.ThrowError("Decal prefab " + decalName + " not found!");
return null;
}
DecalPrefab prefab = Prefabs[decalName];
return new Decal(prefab, scale, worldPosition, hull);
}
}
}
@@ -0,0 +1,74 @@
using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic;
using System.Xml.Linq;
namespace Barotrauma
{
class DecalPrefab : IPrefab, IDisposable
{
public readonly string Name;
public string OriginalName { get { return Name; } }
public string Identifier
{
get;
private set;
}
/// <summary>
/// Unique identifier that's generated by hashing the prefab's string identifier.
/// Used to reduce the amount of bytes needed to write decal data into network messages in multiplayer.
/// </summary>
public uint UIntIdentifier;
public string FilePath { get; private set; }
public ContentPackage ContentPackage { get; private set; }
public void Dispose()
{
foreach (Sprite spr in Sprites)
{
spr.Remove();
}
Sprites.Clear();
}
public readonly List<Sprite> Sprites;
public readonly Color Color;
public readonly float LifeTime;
public readonly float FadeOutTime;
public readonly float FadeInTime;
public DecalPrefab(XElement element, ContentFile file)
{
Name = element.Name.ToString();
Identifier = Name.ToLowerInvariant();
FilePath = file.Path;
ContentPackage = file.ContentPackage;
Sprites = new List<Sprite>();
foreach (XElement subElement in element.Elements())
{
if (subElement.Name.ToString().Equals("sprite", StringComparison.OrdinalIgnoreCase))
{
Sprites.Add(new Sprite(subElement));
}
}
Color = new Color(element.GetAttributeVector4("color", Vector4.One));
LifeTime = element.GetAttributeFloat("lifetime", 10.0f);
FadeOutTime = Math.Min(LifeTime, element.GetAttributeFloat("fadeouttime", 1.0f));
FadeInTime = Math.Min(LifeTime - FadeOutTime, element.GetAttributeFloat("fadeintime", 0.0f));
}
}
}