diff --git a/AirMonitor/AirMonitorDisplay.cs b/AirMonitor/AirMonitorDisplay.cs new file mode 100644 index 0000000..47e362b --- /dev/null +++ b/AirMonitor/AirMonitorDisplay.cs @@ -0,0 +1,109 @@ +using Sandbox.ModAPI.Ingame; +using System; +using System.Collections.Generic; +using VRage.Game.GUI.TextPanel; +using VRageMath; + +namespace IngameScript +{ + partial class Program + { + public class AirMonitorDisplay + { + private class ZoneRow + { + public AirZone Zone { get; private set; } + public MySprite Name { get; private set; } + public MySprite Level; // { get; private set; } + public MySprite Triggered { get; private set; } + + public ZoneRow(RectangleF viewport, AirZone zone, float yPosition, float scale) + { + float xIncrement = viewport.Size.X / 3; + Zone = zone; + Name = new MySprite(SpriteType.TEXT, Zone.Name, new Vector2(0, yPosition) + viewport.Position, null, Color.White, "Debug", TextAlignment.LEFT, scale); + Level = new MySprite(SpriteType.TEXT, "----", new Vector2(xIncrement, yPosition) + viewport.Position, null, Color.White, "Debug", TextAlignment.LEFT, scale); + Triggered = new MySprite(SpriteType.TEXTURE, "Danger", new Vector2(xIncrement * 2, yPosition) + viewport.Position, new Vector2(32f, 32f), Color.White, null, TextAlignment.CENTER, 0f); + } + } + + private IMyTextSurface _surface; + private List _staticSprites = new List(); + private List _rows = new List(); + private float _scale = 1f; + + public AirMonitorDisplay(IMyTextSurface surface, List zones) + { + // Setup draw surface + _surface = surface; + _surface.ScriptBackgroundColor = new Color(0, 0, 0, 255); + _surface.ContentType = ContentType.SCRIPT; + _surface.Script = ""; + buildSprites(zones); + } + + public void Draw() + { + if (_surface.FontSize != _scale) { + _scale = _surface.FontSize; + + // Is it worth it to save this list? Maybe, but we don't anticipate + // this changing often at all. + List zones = new List(); + foreach (ZoneRow row in _rows) { + zones.Add(row.Zone); + } + buildSprites(zones); + } + + MySpriteDrawFrame frame = _surface.DrawFrame(); + + foreach (MySprite sprite in _staticSprites) + { + frame.Add(sprite); + } + + // for (int i=0; i < _rows.Count; i++) + foreach (ZoneRow row in _rows) + { + + frame.Add(row.Name); + row.Level.Data = row.Zone.OxygenLevel.ToString("P2"); + frame.Add(row.Level); + if (row.Zone.Triggered) frame.Add(row.Triggered); + } + frame.Dispose(); + } + + private void buildSprites(List zones) + { + RectangleF viewport = new RectangleF( + (_surface.TextureSize - _surface.SurfaceSize) / 2f, + _surface.SurfaceSize + ); + + // build static sprites + float yPosition = 0f; + float xIncrement = viewport.Size.X / 3; +// float scale = 500 / Math.Min(viewport.Size.X, viewport.Size.Y); + + _staticSprites.Clear(); + + _staticSprites.Add(new MySprite(SpriteType.TEXT, "OXYGEN REPORT", new Vector2(viewport.Size.X / 2, yPosition) + viewport.Position, null, Color.White, "Debug", TextAlignment.CENTER, 1.25f * _scale)); // title + yPosition += 30f; + _staticSprites.Add(new MySprite(SpriteType.TEXT, "ZONE", new Vector2(0, yPosition) + viewport.Position, null, Color.Blue, "Debug", TextAlignment.LEFT, 1.2f * _scale)); // title + _staticSprites.Add(new MySprite(SpriteType.TEXT, "O2 LEVEL", new Vector2(xIncrement, yPosition) + viewport.Position, null, Color.Blue, "Debug", TextAlignment.LEFT, 1.2f * _scale)); // title + _staticSprites.Add(new MySprite(SpriteType.TEXT, "STATUS", new Vector2(xIncrement * 2, yPosition) + viewport.Position, null, Color.Blue, "Debug", TextAlignment.LEFT, 1.2f * _scale)); // title + yPosition += 30f; + + // build dynamic sprites + _rows.Clear(); + foreach (AirZone zone in zones) + { + _rows.Add(new ZoneRow(viewport, zone, yPosition, _scale)); + yPosition += 30f; + } + } + } + } +} \ No newline at end of file diff --git a/AirMonitor/AirZone.cs b/AirMonitor/AirZone.cs index df91bb7..4588f37 100644 --- a/AirMonitor/AirZone.cs +++ b/AirMonitor/AirZone.cs @@ -22,6 +22,20 @@ namespace IngameScript return false; } } + + public float OxygenLevel + { + get + { + float ret = 100F; + foreach (IMyAirVent vent in Vents) + { + if (vent.GetOxygenLevel() < ret) ret = vent.GetOxygenLevel(); + } + return ret; + } + } + public List Vents { get; } = new List(); private Program _program; diff --git a/AirMonitor/Program.cs b/AirMonitor/Program.cs index b5e493a..183fcbb 100644 --- a/AirMonitor/Program.cs +++ b/AirMonitor/Program.cs @@ -20,7 +20,7 @@ namespace IngameScript private List _doors = new List(); private List _lights = new List(); - private List _displays = new List(); + private List _displays = new List(); private List _oxygenTanks = new List(); private StringBuilder _displayBuffer = new StringBuilder(); @@ -29,6 +29,8 @@ namespace IngameScript { Console = new MainConsole(this, "Air Pressure Monitor"); + List surfaces = new List(); + // Find all tagged objects and build out zones List blocks = new List(); GridTerminalSystem.GetBlocksOfType(blocks, block => MyIni.HasSection(block.CustomData, "airMonitor")); @@ -41,10 +43,6 @@ namespace IngameScript { zones = Ini.Get("airMonitor", "zones").ToString().Split(','); } - else if (Ini.Get("airMonitor", "zone").ToString() != "") - { - zones = new string[] { Ini.Get("airMonitor", "zone").ToString() }; - } foreach (string zone in zones) { if (!_zones.ContainsKey(zone)) _zones[zone] = new AirZone(this, zone); @@ -59,7 +57,7 @@ namespace IngameScript { // TODO: behave differently if zone is defined Console.Print($"Adding monitoring display '{block.CustomName}'"); - _displays.Add(block as IMyTextSurface); + surfaces.Add(block as IMyTextSurface); } else if (Ini.Get("airMonitor", "display").ToString() != "") @@ -73,7 +71,7 @@ namespace IngameScript } else { - _displays.Add(provider.GetSurface(displayIndex)); + surfaces.Add(provider.GetSurface(displayIndex)); } } @@ -107,6 +105,11 @@ namespace IngameScript _jobs.Add(zone.Monitor()); } + foreach (IMyTextSurface surface in surfaces) + { + _displays.Add(new AirMonitorDisplay(surface, _zones.Values.ToList())); + } + Runtime.UpdateFrequency = UpdateFrequency.Update100; Console.UpdateTickCount(); } @@ -139,36 +142,44 @@ namespace IngameScript updateDisplays(); } - // write diagnostics to any configured display screens private void updateDisplays() { - if (_displays.Count == 0) return; - - _displayBuffer.Clear(); - _displayBuffer.Append("AIR PRESSURE REPORT\n\n"); - foreach (AirZone zone in _zones.Values) + foreach (AirMonitorDisplay display in _displays) { - _displayBuffer.Append(zone.Name); - _displayBuffer.Append(": "); - _displayBuffer.Append(zone.Triggered ? "ALARM TRIPPED " : "nominal "); - foreach (IMyAirVent vent in zone.Vents) - { - _displayBuffer.Append((int)(vent.GetOxygenLevel() * 100F)); - _displayBuffer.Append("% "); - } - - _displayBuffer.Append("\n"); + display.Draw(); } - - _displayBuffer.Append("\n"); - _displayBuffer.Append("OXYGEN TANK LEVELS\n"); - foreach (IMyGasTank tank in _oxygenTanks) - { - _displayBuffer.Append((int)(tank.FilledRatio * 100)); - _displayBuffer.Append("% "); - } - - foreach (IMyTextSurface display in _displays) display.WriteText(_displayBuffer.ToString()); } + + // write diagnostics to any configured display screens + // private void updateDisplays() + // { + // if (_displays.Count == 0) return; + + // _displayBuffer.Clear(); + // _displayBuffer.Append("AIR PRESSURE REPORT\n\n"); + // foreach (AirZone zone in _zones.Values) + // { + // _displayBuffer.Append(zone.Name); + // _displayBuffer.Append(": "); + // _displayBuffer.Append(zone.Triggered ? "ALARM TRIPPED " : "nominal "); + // foreach (IMyAirVent vent in zone.Vents) + // { + // _displayBuffer.Append((int)(vent.GetOxygenLevel() * 100F)); + // _displayBuffer.Append("% "); + // } + + // _displayBuffer.Append("\n"); + // } + + // _displayBuffer.Append("\n"); + // _displayBuffer.Append("OXYGEN TANK LEVELS\n"); + // foreach (IMyGasTank tank in _oxygenTanks) + // { + // _displayBuffer.Append((int)(tank.FilledRatio * 100)); + // _displayBuffer.Append("% "); + // } + + // foreach (IMyTextSurface display in _displays) display.WriteText(_displayBuffer.ToString()); + // } } }