diff --git a/Subsurface/Content/Items/MiniMap/item.xml b/Subsurface/Content/Items/MiniMap/item.xml index 0d6cee66a..b2aa8fc54 100644 --- a/Subsurface/Content/Items/MiniMap/item.xml +++ b/Subsurface/Content/Items/MiniMap/item.xml @@ -1,5 +1,6 @@  @@ -12,7 +13,9 @@ - + + + \ No newline at end of file diff --git a/Subsurface/Source/GUI/GUI.cs b/Subsurface/Source/GUI/GUI.cs index 658de7752..912f87970 100644 --- a/Subsurface/Source/GUI/GUI.cs +++ b/Subsurface/Source/GUI/GUI.cs @@ -261,6 +261,16 @@ namespace Barotrauma } } + public static void DrawRectangle(SpriteBatch sb, Rectangle rect, Color clr, int thickness, float depth = 0.0f) + { + DrawLine(sb, new Vector2(rect.X, rect.Y), new Vector2(rect.Right, rect.Y), clr, depth, thickness); + DrawLine(sb, new Vector2(rect.X, rect.Bottom-thickness), new Vector2(rect.Right, rect.Bottom-thickness), clr, depth, thickness); + + DrawLine(sb, new Vector2(rect.X+thickness, rect.Y+thickness), new Vector2(rect.X+thickness, rect.Bottom-thickness), clr, depth, thickness); + + DrawLine(sb, new Vector2(rect.Right, rect.Y + thickness), new Vector2(rect.Right, rect.Bottom - thickness), clr, depth, thickness); + } + public static void DrawProgressBar(SpriteBatch sb, Vector2 start, Vector2 size, float progress, Color clr, float depth = 0.0f) { //outlinecolor = "0.5, 0.57, 0.6, 1.0" > diff --git a/Subsurface/Source/Items/Components/Machines/MiniMap.cs b/Subsurface/Source/Items/Components/Machines/MiniMap.cs index 55cef9917..79854e5e1 100644 --- a/Subsurface/Source/Items/Components/Machines/MiniMap.cs +++ b/Subsurface/Source/Items/Components/Machines/MiniMap.cs @@ -2,22 +2,65 @@ using System.Xml.Linq; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; +using System.Collections.Generic; +using System.Linq; namespace Barotrauma.Items.Components { class MiniMap : Powered { + class HullData + { + public float? Oxygen; + public float? Water; + } + + private DateTime resetDataTime; + + bool hasPower; + + [Editable, HasDefaultValue(false, true)] + public bool RequireWaterDetectors + { + get; + set; + } + + [Editable, HasDefaultValue(true, true)] + public bool RequireOxygenDetectors + { + get; + set; + } + + [Editable, HasDefaultValue(false, true)] + public bool ShowHullIntegrity + { + get; + set; + } + + + private Dictionary hullDatas; public MiniMap(Item item, XElement element) : base(item, element) { IsActive = true; + + hullDatas = new Dictionary(); } - - bool hasPower; - + public override void Update(float deltaTime, Camera cam) { + //periodically reset all hull data + //(so that outdated hull info won't be shown if detectors stop sending signals) + if (DateTime.Now > resetDataTime) + { + hullDatas.Clear(); + resetDataTime = DateTime.Now + new TimeSpan(0, 0, 1); + } + currPowerConsumption = powerConsumption; hasPower = voltage > minVoltage; @@ -46,46 +89,150 @@ namespace Barotrauma.Items.Components if (!hasPower) return; - //GUI.DrawRectangle(spriteBatch, new Rectangle(x,y,width,height), Color.Black, true); - Rectangle miniMap = new Rectangle(x + 20, y + 40, width - 40, height - 60); float size = Math.Min((float)miniMap.Width / (float)item.Submarine.Borders.Width, (float)miniMap.Height / (float)item.Submarine.Borders.Height); foreach (Hull hull in Hull.hullList) { - Rectangle hullRect = new Rectangle( + Point topLeft = new Point( miniMap.X + (int)((hull.Rect.X - item.Submarine.HiddenSubPosition.X - item.Submarine.Borders.X) * size), - miniMap.Y - (int)((hull.Rect.Y - item.Submarine.HiddenSubPosition.Y - item.Submarine.Borders.Y) * size), - (int)(hull.Rect.Width * size), - (int)(hull.Rect.Height * size)); + miniMap.Y - (int)((hull.Rect.Y - item.Submarine.HiddenSubPosition.Y - item.Submarine.Borders.Y) * size)); + + Point bottomRight = new Point( + topLeft.X + (int)(hull.Rect.Width * size), + topLeft.Y + (int)(hull.Rect.Height * size)); - float waterAmount = Math.Min(hull.Volume / hull.FullVolume, 1.0f); + topLeft.X = (int)MathUtils.RoundTowardsClosest(topLeft.X, 4); + topLeft.Y = (int)MathUtils.RoundTowardsClosest(topLeft.Y, 4); + bottomRight.X = (int)MathUtils.RoundTowardsClosest(bottomRight.X, 4); + bottomRight.Y = (int)MathUtils.RoundTowardsClosest(bottomRight.Y, 4); - if (hullRect.Height * waterAmount > 1.0f) + Rectangle hullRect = new Rectangle( + topLeft, bottomRight - topLeft); + + HullData hullData; + hullDatas.TryGetValue(hull, out hullData); + + Color borderColor = Color.Green; + + + //hull integrity ----------------------------------- + + float? gapOpenSum = 0.0f; + if (ShowHullIntegrity) { - Rectangle waterRect = new Rectangle( - hullRect.X, - (int)(hullRect.Y + hullRect.Height * (1.0f - waterAmount)), - hullRect.Width, - (int)(hullRect.Height * waterAmount)); - - GUI.DrawRectangle(spriteBatch, waterRect, Color.DarkBlue, true); + gapOpenSum = hull.ConnectedGaps.Where(g => !g.IsRoomToRoom).Sum(g => g.Open); + borderColor = Color.Lerp(borderColor, Color.Red, Math.Min((float)gapOpenSum, 1.0f)); } - GUI.DrawRectangle(spriteBatch, hullRect, Color.White); + //oxygen ----------------------------------- + + float? oxygenAmount = null; + if (RequireOxygenDetectors && (hullData == null || hullData.Oxygen == null)) + { + borderColor *= 0.5f; + } + else + { + oxygenAmount = hullData != null && hullData.Oxygen != null ? (float)hullData.Oxygen : hull.OxygenPercentage; + GUI.DrawRectangle(spriteBatch, hullRect, Color.Lerp(Color.Red * 0.5f, Color.Green * 0.3f, (float)oxygenAmount / 100.0f), true); + } + + //water ----------------------------------- + + float? waterAmount = null; + if (RequireWaterDetectors && (hullData == null || hullData.Water == null)) + { + borderColor *= 0.5f; + } + else + { + waterAmount = hullData != null && hullData.Water != null ? + (float)hullData.Water : + Math.Min(hull.Volume / hull.FullVolume, 1.0f); + + if (hullRect.Height * waterAmount > 3.0f) + { + Rectangle waterRect = new Rectangle( + hullRect.X, + (int)(hullRect.Y + hullRect.Height * (1.0f - waterAmount)), + hullRect.Width, + (int)(hullRect.Height * waterAmount)); + + waterRect.Inflate(-3, -3); + + GUI.DrawRectangle(spriteBatch, waterRect, Color.DarkBlue, true); + GUI.DrawLine(spriteBatch, new Vector2(waterRect.X, waterRect.Y), new Vector2(waterRect.Right, waterRect.Y), Color.LightBlue); + } + } + + if (hullRect.Contains(PlayerInput.MousePosition)) + { + borderColor = Color.White; + + if (gapOpenSum > 0.1f) + { + GUI.DrawString(spriteBatch, + new Vector2(x + 10, y + height - 60), + "Hull breach", Color.Red, Color.Black * 0.5f, 2, GUI.SmallFont); + } + + GUI.DrawString(spriteBatch, + new Vector2(x+10, y+height-40), + oxygenAmount == null ? "Air quality data not available" : "Air quality: "+(int)oxygenAmount+" %", + oxygenAmount == null ? Color.Red : Color.Lerp(Color.Red, Color.LightGreen, (float)oxygenAmount / 100.0f), + Color.Black * 0.5f, 2, GUI.SmallFont); + + GUI.DrawString(spriteBatch, + new Vector2(x + 10, y + height - 20), + waterAmount == null ? "Water level data not available" : "Water level: " + (int)(waterAmount*100.0f) + " %", + waterAmount == null ? Color.Red : Color.Lerp(Color.LightGreen, Color.Red, (float)waterAmount), + Color.Black * 0.5f, 2, GUI.SmallFont); + } + + GUI.DrawRectangle(spriteBatch, hullRect, borderColor, 2); + } + } + + public override void ReceiveSignal(int stepsTaken, string signal, Connection connection, Item sender, float power = 0) + { + base.ReceiveSignal(stepsTaken, signal, connection, sender, power); + + if (sender == null || sender.CurrentHull == null) return; + + Hull senderHull = sender.CurrentHull; + + HullData hullData; + if (!hullDatas.TryGetValue(senderHull, out hullData)) + { + hullData = new HullData(); + hullDatas.Add(senderHull, hullData); } - //foreach (Character c in Character.CharacterList) - //{ - // if (c.AnimController.CurrentHull!=null) continue; + switch (connection.Name) + { + case "water_data_in": + //cheating a bit because water detectors don't actually send the water level + if (sender.GetComponent() == null) + { + hullData.Water = Rand.Range(0.0f, 1.0f); + } + else + { + hullData.Water = Math.Min(senderHull.Volume / senderHull.FullVolume, 1.0f); + } + break; + case "oxygen_data_in": + float oxy = Rand.Range(0.0f, 100.0f); - // Rectangle characterRect = new Rectangle( - // miniMap.X + (int)((c.Position.X - Submarine.Borders.X) * size), - // miniMap.Y - (int)((c.Position.Y - Submarine.Borders.Y) * size), - // 5, 5); + if (!float.TryParse(signal, System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out oxy)) + { + int asdfasdf = 1; + } - // GUI.DrawRectangle(spriteBatch, characterRect, Color.White, true); - //} + hullData.Oxygen = oxy; + break; + } } } diff --git a/Subsurface/Source/Items/Item.cs b/Subsurface/Source/Items/Item.cs index 5fcb8d5df..de112c3d8 100644 --- a/Subsurface/Source/Items/Item.cs +++ b/Subsurface/Source/Items/Item.cs @@ -1549,7 +1549,7 @@ namespace Barotrauma ItemPrefab ip = ep as ItemPrefab; if (ip == null) continue; - if (ip.Name != name) continue; + if (ip.Name != name && (ip.Aliases == null || !ip.Aliases.Contains(name))) continue; if (rect.Width==0 && rect.Height==0) { diff --git a/Subsurface/Source/Items/ItemPrefab.cs b/Subsurface/Source/Items/ItemPrefab.cs index 421aa1f8a..b6de9ec3b 100644 --- a/Subsurface/Source/Items/ItemPrefab.cs +++ b/Subsurface/Source/Items/ItemPrefab.cs @@ -58,6 +58,14 @@ namespace Barotrauma private set; } + //if a matching itemprefab is not found when loading a sub, the game will attempt to find a prefab with a matching alias + //(allows changing item names while keeping backwards compatibility with older sub files) + public string[] Aliases + { + get; + private set; + } + public List DeconstructItems { get; @@ -236,6 +244,12 @@ namespace Barotrauma ImpactTolerance = ToolBox.GetAttributeFloat(element, "impacttolerance", 0.0f); + string aliases = ToolBox.GetAttributeString(element, "aliases", ""); + if (!string.IsNullOrWhiteSpace(aliases)) + { + Aliases = aliases.Split(','); + } + MapEntityCategory category; if (!Enum.TryParse(ToolBox.GetAttributeString(element, "category", "Misc"), true, out category))