Convert display output to use sprites. Still a work in progress.

This commit is contained in:
Anna Rose 2025-02-13 00:49:18 -05:00
parent 8b740dde71
commit b1d12bad28
3 changed files with 167 additions and 33 deletions

View File

@ -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<MySprite> _staticSprites = new List<MySprite>();
private List<ZoneRow> _rows = new List<ZoneRow>();
private float _scale = 1f;
public AirMonitorDisplay(IMyTextSurface surface, List<AirZone> 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<AirZone> zones = new List<AirZone>();
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<AirZone> 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;
}
}
}
}
}

View File

@ -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<IMyAirVent> Vents { get; } = new List<IMyAirVent>();
private Program _program;

View File

@ -20,7 +20,7 @@ namespace IngameScript
private List<AirDoor> _doors = new List<AirDoor>();
private List<IMyLightingBlock> _lights = new List<IMyLightingBlock>();
private List<IMyTextSurface> _displays = new List<IMyTextSurface>();
private List<AirMonitorDisplay> _displays = new List<AirMonitorDisplay>();
private List<IMyGasTank> _oxygenTanks = new List<IMyGasTank>();
private StringBuilder _displayBuffer = new StringBuilder();
@ -29,6 +29,8 @@ namespace IngameScript
{
Console = new MainConsole(this, "Air Pressure Monitor");
List<IMyTextSurface> surfaces = new List<IMyTextSurface>();
// Find all tagged objects and build out zones
List<IMyTerminalBlock> blocks = new List<IMyTerminalBlock>();
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());
// }
}
}