v1.4.4.1 (Blood in the Water Update)

This commit is contained in:
Regalis11
2024-04-24 18:09:05 +03:00
parent 89b91d1c3e
commit ff1b8951a7
397 changed files with 15250 additions and 6479 deletions
@@ -65,7 +65,7 @@ namespace Barotrauma
bool isEditor = Screen.Selected is { IsEditor: true };
GUILayoutGroup titleHolder = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.3f), listBox.Content.RectTransform));
new GUITextBlock(new RectTransform(Vector2.One, titleHolder.RectTransform), Item.Name, font: GUIStyle.LargeFont)
new GUITextBlock(new RectTransform(Vector2.One, titleHolder.RectTransform), Item.Prefab.Name, font: GUIStyle.LargeFont)
{
TextColor = Color.White,
Color = Color.Black
@@ -84,7 +84,10 @@ namespace Barotrauma
new GUIFrame(new RectTransform(new Vector2(1.0f, 0.02f), listBox.Content.RectTransform), style: "HorizontalLine");
var componentEditor = new SerializableEntityEditor(listBox.Content.RectTransform, ic, inGame: !isEditor, showName: false, titleFont: GUIStyle.SubHeadingFont);
var componentEditor = new SerializableEntityEditor(listBox.Content.RectTransform, ic, inGame: !isEditor, showName: false, titleFont: GUIStyle.SubHeadingFont)
{
Readonly = CircuitBox.Locked
};
fieldCount += componentEditor.Fields.Count;
ic.CreateEditingHUD(componentEditor);
@@ -0,0 +1,184 @@
#nullable enable
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace Barotrauma
{
internal sealed partial class CircuitBoxLabelNode
{
private CircuitBoxLabel headerLabel;
private readonly GUITextBlock bodyLabel;
private const string PromptUserData = "LabelEditPrompt";
public override void DrawHeader(SpriteBatch spriteBatch, RectangleF rect, Color color)
{
GUI.DrawString(spriteBatch, new Vector2(rect.X + CircuitBoxSizes.NodeHeaderTextPadding, rect.Center.Y - headerLabel.Size.Y / 2f), headerLabel.Value, GUIStyle.TextColorNormal, font: GUIStyle.LargeFont);
}
public override void DrawBody(SpriteBatch spriteBatch, RectangleF rect, Color color)
{
bodyLabel.TextOffset = rect.Location - bodyLabel.Rect.Location.ToVector2() + new Vector2(CircuitBoxSizes.NodeBodyTextPadding);
bodyLabel.DrawManually(spriteBatch);
}
public override void OnResized(RectangleF rect)
=> UpdateTextSizes(rect);
private void UpdateTextSizes(RectangleF rect)
{
var size = new Point((int)rect.Width - CircuitBoxSizes.NodeBodyTextPadding * 2, (int)rect.Height - CircuitBoxSizes.NodeBodyTextPadding * 2);
bodyLabel.RectTransform.NonScaledSize = size;
bodyLabel.Text = GetLocalizedText(BodyText);
if (bodyLabel.Font != null)
{
bodyLabel.Text = ToolBox.LimitStringHeight(bodyLabel.WrappedText.Value, bodyLabel.Font!, size.Y);
}
headerLabel = new CircuitBoxLabel(ToolBox.LimitString(GetLocalizedText(HeaderText), GUIStyle.LargeFont, size.X), GUIStyle.LargeFont);
static LocalizedString GetLocalizedText(NetLimitedString text) => TextManager.Get(text.Value).Fallback(text.Value);
}
public void PromptEditText(GUIComponent parent)
{
Color newColor = Color;
CircuitBox.UI?.SetMenuVisibility(false);
GUIFrame backgroundBlocker = new(new RectTransform(Vector2.One, parent.RectTransform), style: "GUIBackgroundBlocker")
{
UserData = PromptUserData
};
GUILayoutGroup mainLayout = new GUILayoutGroup(new RectTransform(new Vector2(0.3f, 0.8f), backgroundBlocker.RectTransform, Anchor.Center), isHorizontal: false, childAnchor: Anchor.TopCenter);
GUILayoutGroup colorLayout = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.1f), mainLayout.RectTransform));
new GUIFrame(new RectTransform(new Vector2(1f, 0.9f), colorLayout.RectTransform)) { IgnoreLayoutGroups = true };
GUILayoutGroup colorArea = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.9f), colorLayout.RectTransform), isHorizontal: true);
GUIFrame labelArea = new(new RectTransform(new Vector2(1f, 0.65f), mainLayout.RectTransform, Anchor.Center));
GUIFrame header = new GUIFrame(new RectTransform(new Vector2(1f, 0.15f), labelArea.RectTransform, Anchor.TopLeft), style: "CircuitBoxTop");
GUIFrame frame = new GUIFrame(new RectTransform(new Vector2(1f, 0.86f), labelArea.RectTransform, Anchor.BottomLeft), style: "CircuitBoxFrame");
header.Color = frame.Color = Color;
GUITextBox headerTextBox = new GUITextBox(new RectTransform(Vector2.One, header.RectTransform, Anchor.Center), text: HeaderText.Value, font: headerLabel.Font, style: "GUITextBoxNoStyle")
{
MaxTextLength = NetLimitedString.MaxLength,
Text = HeaderText.Value
};
GUITextBox bodyTextBox = new GUITextBox(new RectTransform(ToolBox.PaddingSizeParentRelative(frame.RectTransform, 0.95f), frame.RectTransform, Anchor.Center), text: BodyText.Value, font: GUIStyle.Font, style: "GUITextBoxNoStyle", textAlignment: Alignment.TopLeft, wrap: true)
{
MaxTextLength = NetLimitedString.MaxLength
};
bodyTextBox.OnEnterPressed += (textBox, text) =>
{
int caretIndex = textBox.CaretIndex;
textBox.Text = $"{text[..caretIndex]}\n{text[caretIndex..]}";
textBox.CaretIndex = caretIndex + 1;
return true;
};
static void UpdateLabelColor(GUITextBox box)
{
bool found = TextManager.ContainsTag(box.Text);
box.TextColor = found
? GUIStyle.Orange
: GUIStyle.TextColorNormal;
if (found)
{
box.ToolTip = TextManager.GetWithVariable("StringPropertyTranslate", "[translation]", TextManager.Get(box.Text));
}
else
{
box.ToolTip = string.Empty;
}
}
bodyTextBox.OnDeselected += (textBox, _) => UpdateLabelColor(textBox);
headerTextBox.OnDeselected += (textBox, _) => UpdateLabelColor(textBox);
UpdateLabelColor(bodyTextBox);
UpdateLabelColor(headerTextBox);
mainLayout.Recalculate();
headerTextBox.ForceUpdate();
new GUIButton(new RectTransform(new Vector2(0.5f, 0.1f), mainLayout.RectTransform), text: TextManager.Get("confirm"))
{
OnClicked = (_, _) =>
{
CircuitBox.RenameLabel(this, newColor, new NetLimitedString(headerTextBox.Text), new NetLimitedString(bodyTextBox.Text));
RemoveEditPrompt(parent);
return true;
}
};
new GUIButton(new RectTransform(new Vector2(0.5f, 0.1f), mainLayout.RectTransform), text: TextManager.Get("cancel"))
{
OnClicked = (_, _) =>
{
RemoveEditPrompt(parent);
return true;
}
};
LocalizedString[] colorComponentLabels =
{
TextManager.Get("spriteeditor.colorcomponentr"),
TextManager.Get("spriteeditor.colorcomponentg"),
TextManager.Get("spriteeditor.colorcomponentb")
};
for (int i = 0; i <= 2; i++)
{
var element = new GUIFrame(new RectTransform(new Vector2(0.33f, 1), colorArea.RectTransform), style: null);
var colorLabel = new GUITextBlock(new RectTransform(new Vector2(0.3f, 1), element.RectTransform, Anchor.CenterLeft), colorComponentLabels[i],
font: GUIStyle.SubHeadingFont, textAlignment: Alignment.CenterLeft);
var numberInput = new GUINumberInput(new RectTransform(new Vector2(0.7f, 1), element.RectTransform, Anchor.CenterRight), NumberType.Int)
{
Font = GUIStyle.SubHeadingFont,
MinValueInt = 0,
MaxValueInt = 255
};
switch (i)
{
case 0:
colorLabel.TextColor = GUIStyle.Red;
numberInput.IntValue = Color.R;
numberInput.OnValueChanged += numInput =>
{
newColor.R = (byte)numInput.IntValue;
header.Color = frame.Color = newColor;
};
break;
case 1:
colorLabel.TextColor = GUIStyle.Green;
numberInput.IntValue = Color.G;
numberInput.OnValueChanged += numInput =>
{
newColor.G = (byte)numInput.IntValue;
header.Color = frame.Color = newColor;
};
break;
case 2:
colorLabel.TextColor = GUIStyle.Blue;
numberInput.IntValue = Color.B;
numberInput.OnValueChanged += numInput =>
{
newColor.B = (byte)numInput.IntValue;
header.Color = frame.Color = newColor;
};
break;
}
}
}
public void RemoveEditPrompt(GUIComponent parent)
{
if (parent.FindChild(PromptUserData) is not { } promptParent) { return; }
parent.RemoveChild(promptParent);
}
}
}
@@ -1,5 +1,6 @@
#nullable enable
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
@@ -15,7 +16,17 @@ namespace Barotrauma
/// </summary>
internal sealed class CircuitBoxMouseDragSnapshotHandler
{
public IEnumerable<CircuitBoxNode> Nodes => circuitBoxUi.CircuitBox.Components.Union<CircuitBoxNode>(circuitBoxUi.CircuitBox.InputOutputNodes);
public IEnumerable<CircuitBoxNode> Nodes
{
get
{
var cb = circuitBoxUi.CircuitBox;
foreach (var label in cb.Labels) { yield return label; }
foreach (var component in cb.Components) { yield return component; }
foreach (var node in cb.InputOutputNodes) { yield return node; }
}
}
private IReadOnlyList<CircuitBoxWire> Wires => circuitBoxUi.CircuitBox.Wires;
@@ -29,6 +40,8 @@ namespace Barotrauma
// Nodes that should be moved when dragging
moveAffectedComponents = ImmutableHashSet<CircuitBoxNode>.Empty;
public Option<(CircuitBoxResizeDirection, CircuitBoxNode)> LastResizeAffectedNode = Option.None;
public ImmutableHashSet<CircuitBoxNode> GetLastComponentsUnderCursor() => lastNodesUnderCursor;
public ImmutableHashSet<CircuitBoxNode> GetMoveAffectedComponents() => moveAffectedComponents;
@@ -45,6 +58,11 @@ namespace Barotrauma
/// </summary>
public bool IsWiring { get; private set; }
/// <summary>
/// If the user grabbed a side of a node and is resizing a node
/// </summary>
public bool IsResizing { get; private set; }
private Vector2 startClick = Vector2.Zero;
private readonly CircuitBoxUI circuitBoxUi;
@@ -147,6 +165,41 @@ namespace Barotrauma
lastNodesUnderCursor = FindNodesUnderCursor(cursorPos);
LastConnectorUnderCursor = FindConnectorUnderCursor(cursorPos);
LastWireUnderCursor = FindWireUnderCursor(cursorPos);
LastResizeAffectedNode = FindResizeBorderUnderCursor(lastNodesUnderCursor, cursorPos);
}
private static Option<(CircuitBoxResizeDirection, CircuitBoxNode)> FindResizeBorderUnderCursor(ImmutableHashSet<CircuitBoxNode> nodes, Vector2 cursorPos)
{
foreach (var node in nodes)
{
if (!node.IsResizable) { continue; }
const float borderSize = 32f;
var rect = node.Rect;
RectangleF bottomBorder = new(rect.X, rect.Top, rect.Width, borderSize);
RectangleF rightBorder = new(rect.Right - borderSize, rect.Y, borderSize, rect.Height);
RectangleF leftBorder = new(rect.X, rect.Y, borderSize, rect.Height);
bool hoverBottom = bottomBorder.Contains(cursorPos),
hoverRight = rightBorder.Contains(cursorPos),
hoverLeft = leftBorder.Contains(cursorPos);
var dir = CircuitBoxResizeDirection.None;
if (hoverBottom) { dir |= CircuitBoxResizeDirection.Down; }
if (hoverRight) { dir |= CircuitBoxResizeDirection.Right; }
if (hoverLeft) { dir |= CircuitBoxResizeDirection.Left; }
if (dir is CircuitBoxResizeDirection.None)
{
continue;
}
return Option.Some((dir, node));
}
return Option.None;
}
/// <summary>
@@ -193,6 +246,7 @@ namespace Barotrauma
startClick = Vector2.Zero;
IsDragging = false;
IsWiring = false;
IsResizing = false;
lastNodesUnderCursor = ImmutableHashSet<CircuitBoxNode>.Empty;
}
@@ -210,23 +264,34 @@ namespace Barotrauma
IsDragging = false;
}
if (LastResizeAffectedNode.IsNone())
{
IsResizing = false;
}
// startClick is set to zero when the user releases the mouse button, so we should be neither dragging nor wiring in this state
if (startClick == Vector2.Zero)
{
IsDragging = false;
IsWiring = false;
IsResizing = false;
return;
}
bool isDragTresholdExceeded = Vector2.DistanceSquared(startClick, cursorPos) > dragTreshold * dragTreshold;
if (circuitBoxUi.Locked) { return; }
bool isDragThresholdExceeded = Vector2.DistanceSquared(startClick, cursorPos) > dragTreshold * dragTreshold;
if (LastConnectorUnderCursor.IsNone())
if (LastResizeAffectedNode.IsSome())
{
IsDragging |= isDragTresholdExceeded;
IsResizing |= isDragThresholdExceeded;
}
else if (LastConnectorUnderCursor.IsSome())
{
IsWiring |= isDragThresholdExceeded;
}
else
{
IsWiring |= isDragTresholdExceeded;
IsDragging |= isDragThresholdExceeded;
}
}
}
@@ -7,10 +7,10 @@ namespace Barotrauma
{
internal partial class CircuitBoxNode
{
private RectangleF DrawRect,
TopDrawRect;
public RectangleF DrawRect;
private RectangleF TopDrawRect;
private void UpdateDrawRects()
protected void UpdateDrawRects()
{
var drawRect = new RectangleF(Position - Size / 2f, Size);
drawRect.Y = -drawRect.Y;
@@ -26,6 +26,8 @@ namespace Barotrauma
UpdatePositions();
}
public virtual void OnResized(RectangleF drawRect) { }
public void DrawBackground(SpriteBatch spriteBatch, RectangleF drawRect, RectangleF topDrawRect, Color color)
{
CircuitBox.NodeFrameSprite?.Draw(spriteBatch, drawRect, color);
@@ -39,6 +41,7 @@ namespace Barotrauma
DrawBackground(spriteBatch, drawRect, topDrawRect, color);
DrawHeader(spriteBatch, topDrawRect, color);
DrawBody(spriteBatch, drawRect, color);
DrawConnectors(spriteBatch, drawPos);
}
@@ -52,6 +55,7 @@ namespace Barotrauma
}
public virtual void DrawHeader(SpriteBatch spriteBatch, RectangleF rect, Color color) { }
public virtual void DrawBody(SpriteBatch spriteBatch, RectangleF rect, Color color) { }
public void DrawConnectors(SpriteBatch spriteBatch, Vector2 drawPos)
{
@@ -35,6 +35,8 @@ namespace Barotrauma
public List<CircuitBoxWireRenderer> VirtualWires = new();
public bool Locked => CircuitBox.Locked;
public CircuitBoxUI(CircuitBox box)
{
camera = new Camera
@@ -47,7 +49,7 @@ namespace Barotrauma
MouseSnapshotHandler = new CircuitBoxMouseDragSnapshotHandler(this);
}
#region UI
#region UI
public void CreateGUI(GUIFrame parent)
{
@@ -63,7 +65,7 @@ namespace Barotrauma
spriteBatch.End();
spriteBatch.Begin(SpriteSortMode.Deferred, samplerState: GUI.SamplerState, rasterizerState: GameMain.ScissorTestEnable);
DrawHUD(spriteBatch);
DrawHUD(spriteBatch, component.Rect);
spriteBatch.End();
spriteBatch.GraphicsDevice.ScissorRectangle = prevScissorRect;
@@ -82,6 +84,8 @@ namespace Barotrauma
OnClicked = (btn, userdata) =>
{
componentMenuOpen = !componentMenuOpen;
if (Locked) { componentMenuOpen = false; }
foreach (GUIComponent child in btn.Children)
{
child.SpriteEffects = componentMenuOpen ? SpriteEffects.None : SpriteEffects.FlipVertically;
@@ -139,65 +143,68 @@ namespace Barotrauma
};
int buttonHeight = (int)(GUIStyle.ItemFrameMargin.Y * 0.4f);
var settingsIcon = new GUIButton(new RectTransform(new Point(buttonHeight), parent.RectTransform, Anchor.TopLeft) { AbsoluteOffset = new Point(buttonHeight / 4), MinSize = new Point(buttonHeight) },
style: "GUIButtonSettings")
style: "GUIButtonSettings")
{
OnClicked = (btn, userdata) =>
{
OnClicked = (btn, userdata) =>
{
GUIContextMenu.CreateContextMenu(
new ContextMenuOption("circuitboxsetting.resetview", isEnabled: true, onSelected: ResetCamera)
GUIContextMenu.CreateContextMenu(
new ContextMenuOption("circuitboxsetting.resetview", isEnabled: true, onSelected: ResetCamera)
{
Tooltip = TextManager.Get("circuitboxsettingdescription.resetview")
},
new ContextMenuOption("circuitboxsetting.find", isEnabled: true,
new ContextMenuOption("circuitboxsetting.focusinput", isEnabled: true, onSelected: () => FindInputOutput(CircuitBoxInputOutputNode.Type.Input))
{
Tooltip = TextManager.Get("circuitboxsettingdescription.resetview")
Tooltip = TextManager.Get("circuitboxsettingdescription.focusinput")
},
new ContextMenuOption("circuitboxsetting.find", isEnabled: true,
new ContextMenuOption("circuitboxsetting.focusinput", isEnabled: true, onSelected: () => FindInputOuput(CircuitBoxInputOutputNode.Type.Input))
{
Tooltip = TextManager.Get("circuitboxsettingdescription.focusinput")
},
new ContextMenuOption("circuitboxsetting.focusoutput", isEnabled: true, onSelected: () => FindInputOuput(CircuitBoxInputOutputNode.Type.Output))
{
Tooltip = TextManager.Get("circuitboxsettingdescription.focusoutput")
},
new ContextMenuOption("circuitboxsetting.focuscircuits", isEnabled: CircuitBox.Components.Any(), onSelected: FindCircuit)
{
Tooltip = TextManager.Get("circuitboxsettingdescription.focuscircuits")
}));
new ContextMenuOption("circuitboxsetting.focusoutput", isEnabled: true, onSelected: () => FindInputOutput(CircuitBoxInputOutputNode.Type.Output))
{
Tooltip = TextManager.Get("circuitboxsettingdescription.focusoutput")
},
new ContextMenuOption("circuitboxsetting.focuscircuits", isEnabled: CircuitBox.Components.Any(), onSelected: FindCircuit)
{
Tooltip = TextManager.Get("circuitboxsettingdescription.focuscircuits")
}));
void ResetCamera()
{
// Vector2.One because Vector2.Zero means no value
camera.TargetPos = Vector2.One;
}
void FindInputOuput(CircuitBoxInputOutputNode.Type type)
{
var input = CircuitBox.InputOutputNodes.FirstOrDefault(n => n.NodeType == type);
if (input is null) { return; }
camera.TargetPos = input.Position;
}
void FindCircuit()
{
var closestComponent = CircuitBox.Components.MinBy(c => Vector2.DistanceSquared(c.Position, camera.Position));
if (closestComponent is null) { return; }
camera.TargetPos = closestComponent.Position;
}
return true;
void ResetCamera()
{
// Vector2.One because Vector2.Zero means no value
camera.TargetPos = Vector2.One;
}
};
void FindInputOutput(CircuitBoxInputOutputNode.Type type)
{
var input = CircuitBox.InputOutputNodes.FirstOrDefault(n => n.NodeType == type);
if (input is null) { return; }
camera.TargetPos = input.Position;
}
void FindCircuit()
{
var closestComponent = CircuitBox.Components.MinBy(c => Vector2.DistanceSquared(c.Position, camera.Position));
if (closestComponent is null) { return; }
camera.TargetPos = closestComponent.Position;
}
return true;
}
};
MouseSnapshotHandler.UpdateConnections();
// update scales of everything
foreach (var node in CircuitBox.Components) { node.OnUICreated(); }
foreach (var node in CircuitBox.InputOutputNodes) { node.OnUICreated(); }
foreach (var wire in CircuitBox.Wires) { wire.Update(); }
}
private string GetInventoryText()
=> CircuitBox.ComponentContainer is { } container
private string GetInventoryText() =>
CircuitBox.ComponentContainer is { } container
? $"{container.Inventory.AllItems.Count()}/{container.Capacity}"
: "0/0";
@@ -209,7 +216,8 @@ namespace Barotrauma
}
if (componentList is null) { return; }
var playerInventory = CircuitBox.GetSortedCircuitBoxSortedItemsFromPlayer(Character.Controlled);
var playerInventory = CircuitBox.GetSortedCircuitBoxItemsFromPlayer(Character.Controlled);
foreach (GUIComponent child in componentList.Content.Children)
{
@@ -304,9 +312,9 @@ namespace Barotrauma
}
}
#endregion
#endregion
private void DrawHUD(SpriteBatch spriteBatch)
private void DrawHUD(SpriteBatch spriteBatch, Rectangle screenRect)
{
float scale = GUI.Scale / 1.5f;
Vector2 offset = new Vector2(20, 40) * scale;
@@ -352,6 +360,16 @@ namespace Barotrauma
{
n.DrawHUD(spriteBatch, camera);
}
if (Locked)
{
LocalizedString lockedText = TextManager.Get("CircuitBoxLocked")
.Fallback(TextManager.Get("ConnectionLocked"));
Vector2 size = GUIStyle.LargeFont.MeasureString(lockedText);
Vector2 pos = new Vector2(screenRect.Center.X - size.X / 2, screenRect.Top + screenRect.Height * 0.05f);
GUI.DrawString(spriteBatch, pos, lockedText, Color.Red, Color.Black, 8, GUIStyle.LargeFont);
}
}
private void DrawSelection(SpriteBatch spriteBatch, Vector2 pos1, Vector2 pos2, Color color)
@@ -367,6 +385,12 @@ namespace Barotrauma
private static float lineWidth;
public static void DrawRectangleWithBorder(SpriteBatch spriteBatch, RectangleF rect, Color fillColor, Color borderColor)
{
GUI.DrawFilledRectangle(spriteBatch, rect, fillColor);
DrawRectangleOnlyBorder(spriteBatch, rect, borderColor);
}
private static void DrawRectangleOnlyBorder(SpriteBatch spriteBatch, RectangleF rect, Color borderColor)
{
Vector2 topRight = new Vector2(rect.Right, rect.Top),
topLeft = new Vector2(rect.Left, rect.Top),
@@ -375,8 +399,6 @@ namespace Barotrauma
Vector2 offset = new Vector2(0f, lineWidth / 2f);
GUI.DrawFilledRectangle(spriteBatch, rect, fillColor);
spriteBatch.DrawLine(topRight, topLeft, borderColor, thickness: lineWidth);
spriteBatch.DrawLine(topLeft - offset, bottomLeft + offset, borderColor, thickness: lineWidth);
spriteBatch.DrawLine(bottomLeft, bottomRight, borderColor, thickness: lineWidth);
@@ -393,6 +415,16 @@ namespace Barotrauma
Vector2 mousePos = GetCursorPosition();
mousePos.Y = -mousePos.Y;
foreach (var label in CircuitBox.Labels)
{
if (label.IsSelected)
{
label.DrawSelection(spriteBatch, GetSelectionColor(label));
}
label.Draw(spriteBatch, label.Position, label.Color);
}
foreach (CircuitBoxWire wire in CircuitBox.Wires)
{
wire.Renderer.Draw(spriteBatch, GetSelectionColor(wire));
@@ -428,6 +460,7 @@ namespace Barotrauma
Color color = moveable switch
{
CircuitBoxComponent node => node.Item.Prefab.SignalComponentColor,
CircuitBoxLabelNode label => label.Color,
CircuitBoxInputOutputNode ioNode => ioNode.NodeType is CircuitBoxInputOutputNode.Type.Input ? GUIStyle.Green : GUIStyle.Red,
_ => Color.White
};
@@ -435,17 +468,49 @@ namespace Barotrauma
}
}
if (MouseSnapshotHandler.IsResizing && MouseSnapshotHandler.LastResizeAffectedNode.TryUnwrap(out var resize))
{
var (dir, node) = resize;
Vector2 dragOffset = MouseSnapshotHandler.GetDragAmount(GetCursorPosition());
var rect = node.Rect;
rect.Y = -rect.Y;
rect.Y -= rect.Height;
if (dir.HasFlag(CircuitBoxResizeDirection.Down))
{
rect.Height -= dragOffset.Y;
rect.Height = Math.Max(rect.Height, CircuitBoxLabelNode.MinSize.Y + CircuitBoxSizes.NodeHeaderHeight);
}
if (dir.HasFlag(CircuitBoxResizeDirection.Right))
{
rect.Width += dragOffset.X;
rect.Width = Math.Max(rect.Width, CircuitBoxLabelNode.MinSize.X);
}
if (dir.HasFlag(CircuitBoxResizeDirection.Left))
{
float oldWidth = rect.Width;
rect.Width -= dragOffset.X;
rect.Width = Math.Max(rect.Width, CircuitBoxLabelNode.MinSize.X);
float actualResize = rect.Width - oldWidth;
rect.X -= actualResize;
}
DrawRectangleOnlyBorder(spriteBatch, rect, GUIStyle.Yellow);
}
if (DraggedWire.TryUnwrap(out CircuitBoxWireRenderer? draggedWire))
{
draggedWire.Draw(spriteBatch, GUIStyle.Yellow);
}
}
private Color GetSelectionColor(CircuitBoxNode node)
=> GetSelectionColor(node.SelectedBy, node.IsSelectedByMe);
private Color GetSelectionColor(CircuitBoxNode node) => GetSelectionColor(node.SelectedBy, node.IsSelectedByMe);
private Color GetSelectionColor(CircuitBoxWire wire)
=> GetSelectionColor(wire.SelectedBy, wire.IsSelectedByMe);
private Color GetSelectionColor(CircuitBoxWire wire) => GetSelectionColor(wire.SelectedBy, wire.IsSelectedByMe);
private Color GetSelectionColor(ushort selectedBy, bool isSelectedByMe)
{
@@ -489,6 +554,7 @@ namespace Barotrauma
{
node.UpdateEditing(circuitComponent.RectTransform);
}
break;
}
@@ -503,6 +569,7 @@ namespace Barotrauma
{
Character.DisableControls = true;
}
camera.MoveCamera(deltaTime, allowMove: true, allowZoom: isMouseOn, allowInput: isMouseOn, followSub: false);
if (camera.TargetPos != Vector2.Zero && MathUtils.NearlyEqual(camera.Position, camera.TargetPos, 0.01f))
@@ -547,7 +614,7 @@ namespace Barotrauma
}
else
{
DraggedWire = Option.Some(new CircuitBoxWireRenderer(Option.None,start, end, GUIStyle.Red, CircuitBox.WireSprite));
DraggedWire = Option.Some(new CircuitBoxWireRenderer(Option.None, start, end, GUIStyle.Red, CircuitBox.WireSprite));
}
}
else
@@ -562,6 +629,12 @@ namespace Barotrauma
if (PlayerInput.PrimaryMouseButtonClicked())
{
if (MouseSnapshotHandler.IsResizing && MouseSnapshotHandler.LastResizeAffectedNode.TryUnwrap(out var r))
{
var (dir, node) = r;
CircuitBox.ResizeNode(node, dir, MouseSnapshotHandler.GetDragAmount(cursorPos));
}
if (CircuitBox.HeldComponent.TryUnwrap(out ItemPrefab? prefab))
{
CircuitBox.AddComponent(prefab, cursorPos);
@@ -604,22 +677,32 @@ namespace Barotrauma
{
CircuitBox.RemoveComponents(CircuitBox.Components.Where(static node => node.IsSelectedByMe).ToArray());
CircuitBox.RemoveWires(CircuitBox.Wires.Where(static wire => wire.IsSelectedByMe).ToImmutableArray());
CircuitBox.RemoveLabel(CircuitBox.Labels.Where(static label => label.IsSelectedByMe).ToImmutableArray());
}
}
if (componentMenu is { } menu && toggleMenuButton is { } button)
{
componentMenuOpenState = componentMenuOpen ? Math.Min(componentMenuOpenState + deltaTime * 5.0f, 1.0f) : Math.Max(componentMenuOpenState - deltaTime * 5.0f, 0.0f);
button.Enabled = !Locked;
componentMenuOpenState = componentMenuOpen && !Locked ? Math.Min(componentMenuOpenState + deltaTime * 5.0f, 1.0f) : Math.Max(componentMenuOpenState - deltaTime * 5.0f, 0.0f);
menu.RectTransform.ScreenSpaceOffset = Vector2.Lerp(new Vector2(0.0f, menu.Rect.Height - 10), Vector2.Zero, componentMenuOpenState).ToPoint();
button.RectTransform.AbsoluteOffset = new Point(menu.Rect.X + ((menu.Rect.Width / 2) - (button.Rect.Width / 2)), menu.Rect.Y - button.Rect.Height);
}
if (selectedWireFrame is { } wireFrame)
{
wireFrame.Visible = !Locked;
}
camera.Position = Vector2.Clamp(camera.Position,
new Vector2(-CircuitBoxSizes.PlayableAreaSize / 2f),
new Vector2(CircuitBoxSizes.PlayableAreaSize / 2f));
}
public void SetMenuVisibility(bool state)
=> componentMenuOpen = state;
private void UpdateSelection()
{
if (!PlayerInput.IsAltDown() && PlayerInput.PrimaryMouseButtonDown())
@@ -662,35 +745,55 @@ namespace Barotrauma
var wireSelection = CircuitBox.Wires.Where(static w => w.IsSelectedByMe).ToImmutableArray();
var nodeOption = GetTopmostNode(MouseSnapshotHandler.FindNodesUnderCursor(cursorPos));
var nodeSelection = CircuitBox.Components.Where(static n => n.IsSelectedByMe).ToImmutableArray();
var labels = CircuitBox.Labels.Where(static l => l.IsSelectedByMe).ToImmutableArray();
var option = new ContextMenuOption(TextManager.Get("delete"), isEnabled: wireOption.IsSome() || nodeOption is CircuitBoxComponent, () =>
var option = new ContextMenuOption(TextManager.Get("delete"), isEnabled: (wireOption.IsSome() || nodeOption is CircuitBoxComponent or CircuitBoxLabelNode) && !Locked, () =>
{
if (wireOption.TryUnwrap(out var wire))
{
CircuitBox.RemoveWires(wire.IsSelected ? wireSelection : ImmutableArray.Create(wire));
}
if (nodeOption is CircuitBoxComponent node)
switch (nodeOption)
{
CircuitBox.RemoveComponents(node.IsSelected ? nodeSelection : ImmutableArray.Create(node));
case CircuitBoxComponent node:
CircuitBox.RemoveComponents(node.IsSelected ? nodeSelection : ImmutableArray.Create(node));
break;
case CircuitBoxLabelNode label:
CircuitBox.RemoveLabel(label.IsSelected ? labels : ImmutableArray.Create(label));
break;
}
});
var editLabel = new ContextMenuOption(TextManager.Get("circuitboxeditlabel"), isEnabled: nodeOption is CircuitBoxLabelNode && !Locked, () =>
{
if (nodeOption is not CircuitBoxLabelNode label || circuitComponent is null) { return; }
label.PromptEditText(circuitComponent);
});
var addLabelOption = new ContextMenuOption(TextManager.Get("circuitboxaddlabel"), isEnabled: !Locked, () =>
{
CircuitBox.AddLabel(cursorPos);
});
ContextMenuOption[] allOptions = { addLabelOption, editLabel, option };
// show component name in the header to better indicate what is about to be deleted
if (nodeOption is CircuitBoxComponent comp)
{
GUIContextMenu.CreateContextMenu(PlayerInput.MousePosition, comp.Item.Name, comp.Item.Prefab.SignalComponentColor, option);
GUIContextMenu.CreateContextMenu(PlayerInput.MousePosition, comp.Item.Name, comp.Item.Prefab.SignalComponentColor, allOptions);
return;
}
// also check if a wire is being deleted
if (wireOption.TryUnwrap(out var foundWire))
{
GUIContextMenu.CreateContextMenu(PlayerInput.MousePosition, foundWire.UsedItemPrefab.Name, foundWire.Color, option);
GUIContextMenu.CreateContextMenu(PlayerInput.MousePosition, foundWire.UsedItemPrefab.Name, foundWire.Color, allOptions);
return;
}
GUIContextMenu.CreateContextMenu(option);
GUIContextMenu.CreateContextMenu(allOptions);
}
public CircuitBoxNode? GetTopmostNode(ImmutableHashSet<CircuitBoxNode> nodes)