From 885a8c610cb1b1a534a2922ac817afdfebdabf05 Mon Sep 17 00:00:00 2001 From: Regalis Date: Wed, 22 Mar 2017 23:22:54 +0200 Subject: [PATCH 1/3] Text scale in GUITextBlocks and ItemLabels can be changed, text wrapping fix (words that are too wide for one line shouldn't cause overflows anymore) --- Subsurface/Source/GUI/GUITextBlock.cs | 19 +++++++- .../Source/Items/Components/ItemLabel.cs | 11 +++++ Subsurface/Source/Utils/ToolBox.cs | 46 +++++++++---------- 3 files changed, 50 insertions(+), 26 deletions(-) diff --git a/Subsurface/Source/GUI/GUITextBlock.cs b/Subsurface/Source/GUI/GUITextBlock.cs index 133af328d..54a41ac31 100644 --- a/Subsurface/Source/GUI/GUITextBlock.cs +++ b/Subsurface/Source/GUI/GUITextBlock.cs @@ -10,6 +10,8 @@ namespace Barotrauma protected Alignment textAlignment; + private float textScale; + protected Vector2 textPos; protected Vector2 origin; @@ -88,6 +90,19 @@ namespace Barotrauma get { return textPos; } } + public float TextScale + { + get { return textScale; } + set + { + if (value != textScale) + { + textScale = value; + SetTextPos(); + } + } + } + public Vector2 Origin { get { return origin; } @@ -162,6 +177,8 @@ namespace Barotrauma SetTextPos(); + TextScale = 1.0f; + if (rect.Height == 0 && !string.IsNullOrEmpty(Text)) { this.rect.Height = (int)Font.MeasureString(wrappedText).Y; @@ -267,7 +284,7 @@ namespace Barotrauma Wrap ? wrappedText : text, new Vector2(rect.X, rect.Y) + textPos + offset, textColor * (textColor.A / 255.0f), - 0.0f, origin, 1.0f, + 0.0f, origin, TextScale, SpriteEffects.None, textDepth); } diff --git a/Subsurface/Source/Items/Components/ItemLabel.cs b/Subsurface/Source/Items/Components/ItemLabel.cs index 224c595bf..7452f2f84 100644 --- a/Subsurface/Source/Items/Components/ItemLabel.cs +++ b/Subsurface/Source/Items/Components/ItemLabel.cs @@ -36,6 +36,16 @@ namespace Barotrauma.Items.Components } } + [Editable, HasDefaultValue(1.0f, true)] + public float TextScale + { + get { return textBlock == null ? 1.0f : textBlock.TextScale; } + set + { + if (textBlock != null) textBlock.TextScale = MathHelper.Clamp(value, 0.1f, 10.0f); + } + } + private GUITextBlock TextBlock { get @@ -49,6 +59,7 @@ namespace Barotrauma.Items.Components textBlock.Font = GUI.SmallFont; textBlock.Padding = new Vector4(5.0f, 5.0f, 5.0f, 5.0f); textBlock.TextDepth = item.Sprite.Depth - 0.0001f; + textBlock.TextScale = TextScale; } return textBlock; } diff --git a/Subsurface/Source/Utils/ToolBox.cs b/Subsurface/Source/Utils/ToolBox.cs index eb11099ec..1ac5eae40 100644 --- a/Subsurface/Source/Utils/ToolBox.cs +++ b/Subsurface/Source/Utils/ToolBox.cs @@ -464,44 +464,43 @@ namespace Barotrauma return d[n, m]; } - + public static string WrapText(string text, float lineLength, ScalableFont font) //TODO: could integrate this into the ScalableFont class directly { if (font.MeasureString(text).X < lineLength) return text; text = text.Replace("\n", " \n "); - string[] words = text.Split(' ');//, '\n'); + string[] words = text.Split(' '); StringBuilder wrappedText = new StringBuilder(); float linePos = 0f; float spaceWidth = font.MeasureString(" ").X; for (int i = 0; i < words.Length; ++i) { - if (string.IsNullOrWhiteSpace(words[i]) && words[i]!="\n") continue; + if (string.IsNullOrWhiteSpace(words[i]) && words[i] != "\n") continue; - Vector2 size; - string tempWord = words[i]; - string prevWord = words[i]; - while ((size = font.MeasureString(tempWord)).X > lineLength) + Vector2 size = font.MeasureString(words[i]); + if (size.X > lineLength) { - tempWord = tempWord.Remove(tempWord.Length - 1, 1); - } + while (words[i].Length > 0 && + (size = font.MeasureString((words[i][0]).ToString())).X + linePos < lineLength) + { + wrappedText.Append(words[i][0]); + words[i] = words[i].Remove(0, 1); - words[i] = tempWord; - if (prevWord.Length> tempWord.Length) - { - wrappedText.Append(words[i]); - wrappedText.Append(" \n"); - wrappedText.Append(prevWord.Remove(0, tempWord.Length)); - linePos = lineLength*2.0f; + linePos += size.X; + } + + wrappedText.Append("\n"); + linePos = 0.0f; + i--; continue; - } - + if (linePos + size.X < lineLength) { - wrappedText.Append(words[i]); + wrappedText.Append(words[i]); if (words[i] == "\n") { linePos = 0.0f; @@ -514,13 +513,10 @@ namespace Barotrauma } else { - //if (i>0)wrappedText.Remove(wrappedText.Length - 1, 1); + wrappedText.Append("\n"); + wrappedText.Append(words[i]); - wrappedText.Append("\n"); - wrappedText.Append(words[i]); - - linePos = size.X + spaceWidth; - + linePos = size.X + spaceWidth; } if (i < words.Length - 1) wrappedText.Append(" "); From e9e4e5f9d3af6ffdfbc5dca96b1dc449e400caba Mon Sep 17 00:00:00 2001 From: Regalis Date: Thu, 23 Mar 2017 18:13:28 +0200 Subject: [PATCH 2/3] Level cells that overlap with ruins are removed during level generation (instead of just disabling collisions with them), background sprites can spawn on ruin walls --- .../BackgroundSpriteManager.cs | 83 ++++++++++++------- Subsurface/Source/Map/Levels/Level.cs | 8 +- Subsurface/Source/Map/Levels/Voronoi.cs | 4 +- .../Source/Map/Levels/VoronoiElements.cs | 14 ++-- 4 files changed, 68 insertions(+), 41 deletions(-) diff --git a/Subsurface/Source/Characters/BackgroundSprite/BackgroundSpriteManager.cs b/Subsurface/Source/Characters/BackgroundSprite/BackgroundSpriteManager.cs index f9c42db9d..a8c6007b5 100644 --- a/Subsurface/Source/Characters/BackgroundSprite/BackgroundSpriteManager.cs +++ b/Subsurface/Source/Characters/BackgroundSprite/BackgroundSpriteManager.cs @@ -133,53 +133,74 @@ namespace Barotrauma if (!prefab.SpawnOnWalls) return randomPos; - var cells = level.GetCells(randomPos); - - if (!cells.Any()) return null; - - VoronoiCell cell = cells[Rand.Int(cells.Count, false)]; List edges = new List(); List normals = new List(); - foreach (GraphEdge edge in cell.edges) + + var cells = level.GetCells(randomPos); + + if (cells.Any()) { - if (!edge.isSolid || edge.OutsideLevel) continue; + VoronoiCell cell = cells[Rand.Int(cells.Count, false)]; - Vector2 normal = edge.GetNormal(cell); + foreach (GraphEdge edge in cell.edges) + { + if (!edge.isSolid || edge.OutsideLevel) continue; + + Vector2 normal = edge.GetNormal(cell); - if (prefab.Alignment.HasFlag(Alignment.Bottom) && normal.Y < -0.5f) - { - edges.Add(edge); - } - else if (prefab.Alignment.HasFlag(Alignment.Top) && normal.Y > 0.5f) - { - edges.Add(edge); - } - else if (prefab.Alignment.HasFlag(Alignment.Left) && normal.X < -0.5f) - { - edges.Add(edge); - } - else if (prefab.Alignment.HasFlag(Alignment.Right) && normal.X > 0.5f) - { - edges.Add(edge); - } - else - { - continue; - } + if (prefab.Alignment.HasFlag(Alignment.Bottom) && normal.Y < -0.5f) + { + edges.Add(edge); + } + else if (prefab.Alignment.HasFlag(Alignment.Top) && normal.Y > 0.5f) + { + edges.Add(edge); + } + else if (prefab.Alignment.HasFlag(Alignment.Left) && normal.X < -0.5f) + { + edges.Add(edge); + } + else if (prefab.Alignment.HasFlag(Alignment.Right) && normal.X > 0.5f) + { + edges.Add(edge); + } + else + { + continue; + } - normals.Add(normal); + normals.Add(normal); + } + } + + foreach (RuinGeneration.Ruin ruin in Level.Loaded.Ruins) + { + Rectangle expandedArea = ruin.Area; + expandedArea.Inflate(ruin.Area.Width, ruin.Area.Height); + if (!expandedArea.Contains(randomPos)) continue; + + foreach (var ruinShape in ruin.RuinShapes) + { + foreach (var wall in ruinShape.Walls) + { + if (!prefab.Alignment.HasFlag(ruinShape.GetLineAlignment(wall))) continue; + + edges.Add(new GraphEdge(wall.A, wall.B)); + normals.Add((wall.A + wall.B) / 2.0f - ruinShape.Center); + } + } } if (!edges.Any()) return null; - int index = Rand.Int(edges.Count,false); + int index = Rand.Int(edges.Count, false); closestEdge = edges[index]; edgeNormal = normals[index]; float length = Vector2.Distance(closestEdge.point1, closestEdge.point2); Vector2 dir = (closestEdge.point1 - closestEdge.point2) / length; Vector2 pos = closestEdge.point2 + dir * Rand.Range(prefab.Sprite.size.X / 2.0f, length - prefab.Sprite.size.X / 2.0f, false); - + return pos; } diff --git a/Subsurface/Source/Map/Levels/Level.cs b/Subsurface/Source/Map/Levels/Level.cs index da3c4e9f1..a7be1b181 100644 --- a/Subsurface/Source/Map/Levels/Level.cs +++ b/Subsurface/Source/Map/Levels/Level.cs @@ -732,7 +732,13 @@ namespace Barotrauma { if (MathUtils.GetLineRectangleIntersection(e.point1, e.point2, ruinShape.Rect) != null) { - cell.CellType = CellType.Empty; + cell.CellType = CellType.Removed; + + int x = (int)Math.Floor(cell.Center.X / GridCellSize); + int y = (int)Math.Floor(cell.Center.Y / GridCellSize); + + cellGrid[x, y].Remove(cell); + cells.Remove(cell); break; } } diff --git a/Subsurface/Source/Map/Levels/Voronoi.cs b/Subsurface/Source/Map/Levels/Voronoi.cs index 41a2252fa..2804390e0 100644 --- a/Subsurface/Source/Map/Levels/Voronoi.cs +++ b/Subsurface/Source/Map/Levels/Voronoi.cs @@ -538,10 +538,8 @@ namespace Voronoi2 private void pushGraphEdge( Site leftSite, Site rightSite, Vector2 point1, Vector2 point2 ) { - GraphEdge newEdge = new GraphEdge (); + GraphEdge newEdge = new GraphEdge(point1, point2); allEdges.Add ( newEdge ); - newEdge.point1 = point1; - newEdge.point2 = point2; newEdge.site1 = leftSite; newEdge.site2 = rightSite; diff --git a/Subsurface/Source/Map/Levels/VoronoiElements.cs b/Subsurface/Source/Map/Levels/VoronoiElements.cs index 6755c57f8..4ba871c21 100644 --- a/Subsurface/Source/Map/Levels/VoronoiElements.cs +++ b/Subsurface/Source/Map/Levels/VoronoiElements.cs @@ -155,18 +155,14 @@ namespace Voronoi2 for (int i = 1; i < vertices.Length; i++ ) { - GraphEdge ge = new GraphEdge(); - ge.point1 = vertices[i-1]; - ge.point2 = vertices[i]; + GraphEdge ge = new GraphEdge(vertices[i-1], vertices[i]); System.Diagnostics.Debug.Assert(ge.point1 != ge.point2); edges.Add(ge); } - GraphEdge lastEdge = new GraphEdge(); - lastEdge.point1 = vertices[0]; - lastEdge.point2 = vertices[vertices.Length-1]; + GraphEdge lastEdge = new GraphEdge(vertices[0], vertices[vertices.Length-1]); edges.Add(lastEdge); @@ -208,6 +204,12 @@ namespace Voronoi2 get { return (point1 + point2) / 2.0f; } } + public GraphEdge(Vector2 point1, Vector2 point2) + { + this.point1 = point1; + this.point2 = point2; + } + public VoronoiCell AdjacentCell(VoronoiCell cell) { if (cell1==cell) From 4d19d0afc1c0fc0eff1f3a785cc0c2d400e23022 Mon Sep 17 00:00:00 2001 From: Regalis Date: Thu, 23 Mar 2017 18:55:39 +0200 Subject: [PATCH 3/3] Deconstructors & fabricators drop created items on the floor if there's no more room in the inventory, deconstructor doesn't reset the activation button after deconstructing an item if there are still more items to go --- .../Components/Machines/Deconstructor.cs | 30 ++++++++++++------- .../Items/Components/Machines/Fabricator.cs | 10 ++++++- 2 files changed, 29 insertions(+), 11 deletions(-) diff --git a/Subsurface/Source/Items/Components/Machines/Deconstructor.cs b/Subsurface/Source/Items/Components/Machines/Deconstructor.cs index 5f2b53114..ad0b7d421 100644 --- a/Subsurface/Source/Items/Components/Machines/Deconstructor.cs +++ b/Subsurface/Source/Items/Components/Machines/Deconstructor.cs @@ -30,12 +30,9 @@ namespace Barotrauma.Items.Components public override void Update(float deltaTime, Camera cam) { - if (container == null || !container.Inventory.Items.Any(i=>i!=null)) + if (container == null || container.Inventory.Items.All(i => i == null)) { - progressBar.BarSize = 0.0f; - //activateButton.Enabled = true; - if (container != null) container.Inventory.Locked = false; - IsActive = false; + SetActive(false); return; } @@ -68,15 +65,27 @@ namespace Barotrauma.Items.Components DebugConsole.ThrowError("Tried to deconstruct item \""+targetItem.Name+"\" but couldn't find item prefab \""+deconstructProduct+"\"!"); continue; } - Item.Spawner.QueueItem(itemPrefab, containers[1].Inventory); + + //container full, drop the items outside the deconstructor + if (containers[1].Inventory.Items.All(i => i != null)) + { + Item.Spawner.QueueItem(itemPrefab, item.Position, item.Submarine); + } + else + { + Item.Spawner.QueueItem(itemPrefab, containers[1].Inventory); + } + } container.Inventory.RemoveItem(targetItem); Item.Remover.QueueItem(targetItem); - activateButton.Text = "Deconstruct"; - progressBar.BarSize = 0.0f; - progressTimer = 0.0f; + if (container.Inventory.Items.Any(i => i != null)) + { + progressTimer = 0.0f; + progressBar.BarSize = 0.0f; + } } } @@ -115,6 +124,8 @@ namespace Barotrauma.Items.Components return; } + if (container.Inventory.Items.All(i => i == null)) active = false; + IsActive = active; if (!IsActive) @@ -126,7 +137,6 @@ namespace Barotrauma.Items.Components } else { - if (container.Inventory.Items.All(i => i == null)) return; activateButton.Text = "Cancel"; } diff --git a/Subsurface/Source/Items/Components/Machines/Fabricator.cs b/Subsurface/Source/Items/Components/Machines/Fabricator.cs index f594f22f6..813ce443c 100644 --- a/Subsurface/Source/Items/Components/Machines/Fabricator.cs +++ b/Subsurface/Source/Items/Components/Machines/Fabricator.cs @@ -375,7 +375,15 @@ namespace Barotrauma.Items.Components } } - Item.Spawner.QueueItem(fabricatedItem.TargetItem, containers[1].Inventory); + if (containers[1].Inventory.Items.All(i => i != null)) + { + Item.Spawner.QueueItem(fabricatedItem.TargetItem, item.Position, item.Submarine); + } + else + { + Item.Spawner.QueueItem(fabricatedItem.TargetItem, containers[1].Inventory); + } + CancelFabricating(); }