From 78c13ddb428f6373f01bc5b3d0928a084b078c75 Mon Sep 17 00:00:00 2001 From: Joonas Rikkonen Date: Mon, 1 Jan 2018 15:04:53 +0200 Subject: [PATCH] Wire selection fixes: - Fixed MathUtils.LineToPointDistance returning NaN if both points of the line are at the same position, preventing from selecting some wire nodes in the wiring mode. - Added an indicator that shows when a node is highlighted. - Wire nodes a higher preference for being highlighted than wire sections. Makes it easier to select nodes that are on top of another wire. Closes #215 --- .../Source/Items/Components/Signal/Wire.cs | 42 +++++++++++++------ .../Source/Items/Components/Signal/Wire.cs | 14 ++----- .../Source/Utils/MathUtils.cs | 5 +++ 3 files changed, 38 insertions(+), 23 deletions(-) diff --git a/Barotrauma/BarotraumaClient/Source/Items/Components/Signal/Wire.cs b/Barotrauma/BarotraumaClient/Source/Items/Components/Signal/Wire.cs index c02fb0254..297a045d0 100644 --- a/Barotrauma/BarotraumaClient/Source/Items/Components/Signal/Wire.cs +++ b/Barotrauma/BarotraumaClient/Source/Items/Components/Signal/Wire.cs @@ -3,6 +3,7 @@ using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; using System.Collections.Generic; +using System.Linq; namespace Barotrauma.Items.Components { @@ -36,6 +37,12 @@ namespace Barotrauma.Items.Components } } + private static Sprite wireSprite; + + private static Wire draggingWire; + private static int? selectedNodeIndex; + private static int? highlightedNodeIndex; + public void Draw(SpriteBatch spriteBatch, bool editing) { if (sections.Count == 0 && !IsActive) @@ -69,7 +76,7 @@ namespace Barotrauma.Items.Components foreach (WireSection section in sections) { - section.Draw(spriteBatch, item.Color, drawOffset, depth, 0.3f); + section.Draw(spriteBatch, item.Submarine == null ? Color.Green : item.Color, drawOffset, depth, 0.3f); } if (IsActive && nodes.Count > 0 && Vector2.Distance(newNodePos, nodes[nodes.Count - 1]) > nodeDistance) @@ -91,14 +98,15 @@ namespace Barotrauma.Items.Components if (item.Submarine != null) drawPos += item.Submarine.Position + item.Submarine.HiddenSubPosition; drawPos.Y = -drawPos.Y; + if ((highlightedNodeIndex == i && item.IsHighlighted) || (selectedNodeIndex == i && item.IsSelected)) + { + GUI.DrawRectangle(spriteBatch, drawPos + new Vector2(-10, -10), new Vector2(20, 20), Color.Red, false, 0.0f); + } + if (item.IsSelected) { GUI.DrawRectangle(spriteBatch, drawPos + new Vector2(-5, -5), new Vector2(10, 10), item.Color, true, 0.0f); - if (highlightedNodeIndex == i) - { - GUI.DrawRectangle(spriteBatch, drawPos + new Vector2(-10, -10), new Vector2(20, 20), Color.Red, false, 0.0f); - } } else { @@ -196,28 +204,36 @@ namespace Barotrauma.Items.Components //check which wire is highlighted with the cursor Wire highlighted = null; - float closestDist = 0.0f; + float closestDist = float.PositiveInfinity; foreach (Wire w in wires) { Vector2 mousePos = GameMain.SubEditorScreen.Cam.ScreenToWorld(PlayerInput.MousePosition); if (w.item.Submarine != null) mousePos -= (w.item.Submarine.Position + w.item.Submarine.HiddenSubPosition); float dist = 0.0f; - if (w.GetClosestNodeIndex(mousePos, highlighted == null ? nodeSelectDist : closestDist, out dist) > -1) + int highlightedNode = w.GetClosestNodeIndex(mousePos, highlighted == null ? nodeSelectDist : closestDist, out dist); + if (highlightedNode > -1) { - highlighted = w; - closestDist = dist; + if (dist < closestDist) + { + highlightedNodeIndex = highlightedNode; + highlighted = w; + closestDist = dist; + } } if (w.GetClosestSectionIndex(mousePos, highlighted == null ? sectionSelectDist : closestDist, out dist) > -1) { - highlighted = w; - closestDist = dist; + //prefer nodes over sections + if (dist + nodeSelectDist * 0.5f < closestDist) + { + highlightedNodeIndex = null; + highlighted = w; + closestDist = dist + nodeSelectDist * 0.5f; + } } - } - if (highlighted != null) { highlighted.item.IsHighlighted = true; diff --git a/Barotrauma/BarotraumaShared/Source/Items/Components/Signal/Wire.cs b/Barotrauma/BarotraumaShared/Source/Items/Components/Signal/Wire.cs index cc44dd0b8..2e4cac0fe 100644 --- a/Barotrauma/BarotraumaShared/Source/Items/Components/Signal/Wire.cs +++ b/Barotrauma/BarotraumaShared/Source/Items/Components/Signal/Wire.cs @@ -30,21 +30,13 @@ namespace Barotrauma.Items.Components const float nodeDistance = 32.0f; const float heightFromFloor = 128.0f; - static Sprite wireSprite; - private List nodes; private List sections; - Connection[] connections; + private Connection[] connections; private Vector2 newNodePos; - - - private static Wire draggingWire; - private static int? selectedNodeIndex; - private static int? highlightedNodeIndex; - public bool Hidden, Locked; public Connection[] Connections @@ -55,12 +47,14 @@ namespace Barotrauma.Items.Components public Wire(Item item, XElement element) : base(item, element) { +#if CLIENT if (wireSprite == null) { wireSprite = new Sprite("Content/Items/wireHorizontal.png", new Vector2(0.5f, 0.5f)); wireSprite.Depth = 0.85f; } - +#endif + nodes = new List(); sections = new List(); diff --git a/Barotrauma/BarotraumaShared/Source/Utils/MathUtils.cs b/Barotrauma/BarotraumaShared/Source/Utils/MathUtils.cs index 92e0a1b16..775b5bbfc 100644 --- a/Barotrauma/BarotraumaShared/Source/Utils/MathUtils.cs +++ b/Barotrauma/BarotraumaShared/Source/Utils/MathUtils.cs @@ -336,6 +336,11 @@ namespace Barotrauma float xDiff = lineB.X - lineA.X; float yDiff = lineB.Y - lineA.Y; + if (xDiff == 0 && yDiff == 0) + { + return Vector2.Distance(lineA, point); + } + return (float)(Math.Abs(xDiff * (lineA.Y - point.Y) - yDiff * (lineA.X - point.X)) / Math.Sqrt(xDiff * xDiff + yDiff * yDiff)); }