Build 0.21.1.0

This commit is contained in:
Markus Isberg
2023-01-13 18:10:35 +02:00
parent 2f7205fb4b
commit 697ec52120
155 changed files with 2423 additions and 1237 deletions
@@ -293,11 +293,11 @@ namespace Barotrauma
GUI.DrawRectangle(spriteBatch,
new Vector2(drawRect.X, -drawRect.Y),
new Vector2(rect.Width, rect.Height),
Color.Blue * alpha, false, (ID % 255) * 0.000001f, (int)Math.Max(1.5f / Screen.Selected.Cam.Zoom, 1.0f));
Color.Blue * alpha, false, (ID % 255) * 0.000001f, (int)Math.Max(MathF.Ceiling(1.5f / Screen.Selected.Cam.Zoom), 1.0f));
GUI.DrawRectangle(spriteBatch,
new Rectangle(drawRect.X, -drawRect.Y, rect.Width, rect.Height),
GUIStyle.Red * ((100.0f - OxygenPercentage) / 400.0f) * alpha, true, 0, (int)Math.Max(1.5f / Screen.Selected.Cam.Zoom, 1.0f));
GUIStyle.Red * ((100.0f - OxygenPercentage) / 400.0f) * alpha, true, 0, (int)Math.Max(MathF.Ceiling(1.5f / Screen.Selected.Cam.Zoom), 1.0f));
if (GameMain.DebugDraw)
{
@@ -515,11 +515,11 @@ namespace Barotrauma
Item targetContainer = null;
bool isShiftDown = PlayerInput.IsShiftDown();
if (!isShiftDown) return null;
if (!isShiftDown) { return null; }
foreach (MapEntity e in mapEntityList)
{
if (!e.SelectableInEditor ||!(e is Item potentialContainer)) { continue; }
if (!e.SelectableInEditor || e is not Item potentialContainer) { continue; }
if (e.IsMouseOn(position))
{
@@ -83,7 +83,10 @@ namespace Barotrauma
{
string errorMsg = "Failed to load sound file \"" + filename + "\" (file not found).";
DebugConsole.ThrowError(errorMsg, e);
GameAnalyticsManager.AddErrorEventOnce("RoundSound.LoadRoundSound:FileNotFound" + filename, GameAnalyticsManager.ErrorSeverity.Error, errorMsg + "\n" + Environment.StackTrace.CleanupStackTrace());
if (!ContentPackageManager.ModsEnabled)
{
GameAnalyticsManager.AddErrorEventOnce("RoundSound.LoadRoundSound:FileNotFound" + filename, GameAnalyticsManager.ErrorSeverity.Error, errorMsg + "\n" + Environment.StackTrace.CleanupStackTrace());
}
return null;
}
catch (System.IO.InvalidDataException e)
@@ -4,26 +4,29 @@ using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Xml.Linq;
using Barotrauma.Items.Components;
namespace Barotrauma
{
class SubmarinePreview : IDisposable
sealed class SubmarinePreview : IDisposable
{
private SpriteRecorder spriteRecorder;
private readonly SubmarineInfo submarineInfo;
private SpriteRecorder spriteRecorder;
private Camera camera;
private Task loadTask;
private (Vector2 Min, Vector2 Max) bounds;
private volatile bool isDisposed;
private GUIFrame previewFrame;
private class HullCollection
private sealed class HullCollection
{
public readonly List<Rectangle> Rects;
public readonly LocalizedString Name;
@@ -186,7 +189,21 @@ namespace Barotrauma
});
recalculateSpecsContainerHeight();
GeneratePreviewMeshes();
TaskPool.Add(nameof(GeneratePreviewMeshes), GeneratePreviewMeshes(), _ =>
{
// Reset the camera's position on the main thread,
// because the Camera class is not thread-safe and
// it's possible for its state to not get updated
// properly if done within a task
camera.Position = (bounds.Min + bounds.Max) * (0.5f, -0.5f);
Vector2 span2d = bounds.Max - bounds.Min;
Vector2 scaledSpan2d = span2d / camera.Resolution.ToVector2();
float scaledSpan = Math.Max(scaledSpan2d.X, scaledSpan2d.Y);
camera.MinZoom = Math.Min(0.1f, 0.4f / scaledSpan);
camera.Zoom = 0.7f / scaledSpan;
camera.StopMovement();
camera.UpdateTransform(interpolate: false, updateListener: false);
});
}
public static void AddToGUIUpdateList()
@@ -207,6 +224,7 @@ namespace Barotrauma
spriteRecorder.Begin(SpriteSortMode.BackToFront);
HashSet<int> toIgnore = new HashSet<int>();
HashSet<int> wires = new HashSet<int>();
foreach (var subElement in submarineInfo.SubmarineElement.Elements())
{
@@ -221,7 +239,7 @@ namespace Barotrauma
ExtractItemContainerIds(component, toIgnore);
break;
case "connectionpanel":
ExtractConnectionPanelLinks(component, toIgnore);
ExtractConnectionPanelLinks(component, wires);
break;
}
}
@@ -231,20 +249,25 @@ namespace Barotrauma
await Task.Yield();
}
var wireNodes = new List<XElement>();
foreach (var subElement in submarineInfo.SubmarineElement.Elements())
{
if (subElement.GetAttributeBool("hiddeningame", false)) { continue; }
switch (subElement.Name.LocalName.ToLowerInvariant())
{
case "structure":
case "item":
if (!toIgnore.Contains(subElement.GetAttributeInt("ID", 0)))
var id = subElement.GetAttributeInt("ID", 0);
if (wires.Contains(id))
{
wireNodes.Add(subElement);
}
else if (!toIgnore.Contains(id))
{
BakeMapEntity(subElement);
}
break;
case "structure":
BakeMapEntity(subElement);
break;
case "hull":
Identifier identifier = subElement.GetAttributeIdentifier("roomname", "");
if (!identifier.IsEmpty)
@@ -261,15 +284,14 @@ namespace Barotrauma
if (isDisposed) { return; }
await Task.Yield();
}
spriteRecorder.End();
camera.Position = (spriteRecorder.Min + spriteRecorder.Max) * 0.5f;
float scaledSpan = (spriteRecorder.Max - spriteRecorder.Min).X / camera.Resolution.X;
camera.Zoom = 0.8f / scaledSpan;
camera.StopMovement();
bounds = (spriteRecorder.Min, spriteRecorder.Max);
wireNodes.ForEach(BakeWireNodes);
spriteRecorder.End();
}
private void ExtractItemContainerIds(XElement component, HashSet<int> ids)
private static void ExtractItemContainerIds(XElement component, HashSet<int> ids)
{
string containedString = component.GetAttributeString("contained", "");
string[] itemIdStrings = containedString.Split(',');
@@ -283,7 +305,7 @@ namespace Barotrauma
}
}
private void ExtractConnectionPanelLinks(XElement component, HashSet<int> ids)
private static void ExtractConnectionPanelLinks(XElement component, HashSet<int> ids)
{
var pins = component.Elements("input").Concat(component.Elements("output"));
foreach (var pin in pins)
@@ -297,6 +319,39 @@ namespace Barotrauma
}
}
private void BakeWireNodes(XElement element)
{
var prefabIdentifier = element.GetAttributeIdentifier("identifier", "");
if (prefabIdentifier.IsEmpty) { return; }
if (!ItemPrefab.Prefabs.TryGet(prefabIdentifier, out var prefab)) { return; }
var prefabWireComponentElement = prefab.ConfigElement.GetChildElement("wire");
if (prefabWireComponentElement is null) { return; }
var wireComponent = element.GetChildElement("wire");
if (wireComponent is null) { return; }
var color = element.GetAttributeColor("spritecolor") ?? Color.White;
var nodes = Wire.ExtractNodes(wireComponent).ToImmutableArray();
var wireSprite = Wire.ExtractWireSprite(prefab.ConfigElement);
var useSpriteDepth = element.GetAttributeBool("usespritedepth", false);
var depth =
useSpriteDepth
? element.GetAttributeFloat("spritedepth", 1.0f)
: wireSprite.Depth;
var width = prefabWireComponentElement.GetAttributeFloat("width", 0.3f);
for (int i = 0; i < nodes.Length - 1; i++)
{
var line = (Start: nodes[i], End: nodes[i + 1]);
var wireSegment = new Wire.WireSection(line.Start, line.End);
wireSegment.Draw(spriteRecorder, wireSprite, color, Vector2.Zero, depth, width);
}
}
private void BakeMapEntity(XElement element)
{
Identifier identifier = element.GetAttributeIdentifier("identifier", Identifier.Empty);
@@ -313,27 +368,27 @@ namespace Barotrauma
float rotation = element.GetAttributeFloat("rotation", 0f);
MapEntityPrefab prefab = null;
if (element.Name.ToString().Equals("item", StringComparison.OrdinalIgnoreCase) &&
ItemPrefab.Prefabs.TryGet(identifier, out ItemPrefab ip))
MapEntityPrefab prefab;
if (element.NameAsIdentifier() == "item"
&& ItemPrefab.Prefabs.TryGet(identifier, out ItemPrefab ip))
{
prefab = ip;
}
else
{
prefab = MapEntityPrefab.List.FirstOrDefault(p => p.Identifier == identifier);
prefab = MapEntityPrefab.FindByIdentifier(identifier);
}
if (prefab == null) { return; }
var texture = prefab.Sprite.Texture;
var srcRect = prefab.Sprite.SourceRect;
flippedX &= prefab.CanSpriteFlipX;
flippedY &= prefab.CanSpriteFlipY;
SpriteEffects spriteEffects = SpriteEffects.None;
if (flippedX && ((prefab as ItemPrefab)?.CanSpriteFlipX ?? true))
if (flippedX)
{
spriteEffects |= SpriteEffects.FlipHorizontally;
}
if (flippedY && ((prefab as ItemPrefab)?.CanSpriteFlipY ?? true))
if (flippedY)
{
spriteEffects |= SpriteEffects.FlipVertically;
}
@@ -419,8 +474,8 @@ namespace Barotrauma
{
float offsetState = 0f;
Vector2 offset = decorativeSprite.GetOffset(ref offsetState, Vector2.Zero) * scale;
if (flippedX && itemPrefab.CanSpriteFlipX) { offset.X = -offset.X; }
if (flippedY && itemPrefab.CanSpriteFlipY) { offset.Y = -offset.Y; }
if (flippedX) { offset.X = -offset.X; }
if (flippedY) { offset.Y = -offset.Y; }
decorativeSprite.Sprite.DrawTiled(spriteRecorder,
new Vector2(spritePos.X + offset.X - rect.Width / 2, -(spritePos.Y + offset.Y + rect.Height / 2)),
rect.Size.ToVector2(), color: color,
@@ -451,8 +506,8 @@ namespace Barotrauma
float rotationState = 0f; float offsetState = 0f;
float rot = decorativeSprite.GetRotation(ref rotationState, 0f);
Vector2 offset = decorativeSprite.GetOffset(ref offsetState, Vector2.Zero) * scale;
if (flippedX && itemPrefab.CanSpriteFlipX) { offset.X = -offset.X; }
if (flippedY && itemPrefab.CanSpriteFlipY) { offset.Y = -offset.Y; }
if (flippedX) { offset.X = -offset.X; }
if (flippedY) { offset.Y = -offset.Y; }
decorativeSprite.Sprite.Draw(spriteRecorder, new Vector2(spritePos.X + offset.X, -(spritePos.Y + offset.Y)), color,
MathHelper.ToRadians(rotation) + rot, decorativeSprite.GetScale(0f) * scale, prefab.Sprite.effects,
depth: Math.Min(depth + (decorativeSprite.Sprite.Depth - prefab.Sprite.Depth), 0.999f));
@@ -472,6 +527,7 @@ namespace Barotrauma
{
overrideSprite = false;
float relativeScale = scale / prefab.Scale;
foreach (var subElement in prefab.ConfigElement.Elements())
{
switch (subElement.Name.LocalName.ToLowerInvariant())
@@ -498,7 +554,6 @@ namespace Barotrauma
relativeBarrelPos,
MathHelper.ToRadians(rotation));
float relativeScale = scale / prefab.Scale;
Vector2 drawPos = new Vector2(rect.X + rect.Width * relativeScale / 2 + transformedBarrelPos.X * relativeScale, rect.Y - rect.Height * relativeScale / 2 - transformedBarrelPos.Y * relativeScale);
drawPos.Y = -drawPos.Y;
@@ -516,20 +571,22 @@ namespace Barotrauma
break;
case "door":
doors.Add(new Door(rect));
var scaledRect = rect with { Size = (rect.Size.ToVector2() * relativeScale).ToPoint() };
doors.Add(new Door(scaledRect));
var doorSpriteElem = subElement.Elements().FirstOrDefault(e => e.Name.LocalName.Equals("sprite", StringComparison.OrdinalIgnoreCase));
if (doorSpriteElem != null)
{
string texturePath = doorSpriteElem.GetAttributeString("texture", "");
Vector2 pos = rect.Location.ToVector2() * new Vector2(1f, -1f);
string texturePath = doorSpriteElem.GetAttributeStringUnrestricted("texture", "");
Vector2 pos = scaledRect.Location.ToVector2() * new Vector2(1f, -1f);
if (subElement.GetAttributeBool("horizontal", false))
{
pos.Y += (float)rect.Height * 0.5f;
pos.Y += (float)scaledRect.Height * 0.5f;
}
else
{
pos.X += (float)rect.Width * 0.5f;
pos.X += (float)scaledRect.Width * 0.5f;
}
Sprite doorSprite = new Sprite(doorSpriteElem, texturePath.Contains("/") ? "" : Path.GetDirectoryName(prefab.FilePath));
spriteRecorder.Draw(doorSprite.Texture, pos,
@@ -555,7 +612,7 @@ namespace Barotrauma
}
}
public void ParseUpgrades(XElement prefabConfigElement, ref float scale)
private void ParseUpgrades(XElement prefabConfigElement, ref float scale)
{
foreach (var upgrade in prefabConfigElement.Elements("Upgrade"))
{