diff --git a/InfoDisplays/InfoDisplays.csproj b/InfoDisplays/InfoDisplays.csproj new file mode 100644 index 0000000..7705310 --- /dev/null +++ b/InfoDisplays/InfoDisplays.csproj @@ -0,0 +1,27 @@ + + + netframework48 + IngameScript + 6 + false + Release;Debug + x64 + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + \ No newline at end of file diff --git a/InfoDisplays/InfoDisplays.mdk.ini b/InfoDisplays/InfoDisplays.mdk.ini new file mode 100644 index 0000000..5add8f4 --- /dev/null +++ b/InfoDisplays/InfoDisplays.mdk.ini @@ -0,0 +1,22 @@ +; This file is project specific and should be checked in to source control. + +[mdk] +; This is a programmable block script project. +; You should not change this. +type=programmableblock + +; Toggle trace (on|off) (verbose output) +trace=off + +; What type of minification to use (none|trim|stripcomments|lite|full) +; none: No minification +; trim: Removes unused types (NOT members). +; stripcomments: trim + removes comments. +; lite: stripcomments + removes leading/trailing whitespace. +; full: lite + renames identifiers to shorter names. +minify=none + +; A list of files and folder to ignore when creating the script. +; This is a comma separated list of glob patterns. +; See https://code.visualstudio.com/docs/editor/glob-patterns +ignores=obj/**/*,MDK/**/*,**/*.debug.cs diff --git a/InfoDisplays/InfoDisplays.mdk.local.ini b/InfoDisplays/InfoDisplays.mdk.local.ini new file mode 100644 index 0000000..4b66820 --- /dev/null +++ b/InfoDisplays/InfoDisplays.mdk.local.ini @@ -0,0 +1,7 @@ +; This file is _local_ to your machine and should not be checked in to source control. + +[mdk] +; Where to output the script to (auto|specific path) +output=auto +; Override the default binary path (auto|specific path) +binarypath=auto \ No newline at end of file diff --git a/InfoDisplays/Instructions.readme b/InfoDisplays/Instructions.readme new file mode 100644 index 0000000..ed30ab7 --- /dev/null +++ b/InfoDisplays/Instructions.readme @@ -0,0 +1,5 @@ +R e a d m e +----------- + +In this file you can include any instructions or other comments you want to have injected onto the +top of your final script. You can safely delete this file if you do not want any such comments. diff --git a/InfoDisplays/OreReport.cs b/InfoDisplays/OreReport.cs new file mode 100644 index 0000000..32644a1 --- /dev/null +++ b/InfoDisplays/OreReport.cs @@ -0,0 +1,113 @@ +// Keeps track of all construction materials (ingots) on the grid +// TODO: also track unprocessed stuff? +using System.Collections.Generic; +using System.Text; +using Sandbox.ModAPI.Ingame; +using VRage; +using VRage.Game.GUI.TextPanel; +using VRage.Game.ModAPI.Ingame; + +namespace IngameScript +{ + partial class Program + { + // TODO: factor out the display code once it is more complex + public class OreReport + { + private Program _program; + private IConsole _console; + private IMyTextSurface _display; + private StringBuilder _builder = new StringBuilder(); + private List _inventories = new List(); + + private Dictionary _ingotTypes = new Dictionary + { + ["Iron"] = MyItemType.MakeIngot("Ingot_Iron"), + ["Silicon"] = MyItemType.MakeIngot("Silicon"), + ["Nickel"] = MyItemType.MakeIngot("Nickel"), + ["Cobalt"] = MyItemType.MakeIngot("Cobalt"), + ["Gold"] = MyItemType.MakeIngot("Gold"), + ["Silver"] = MyItemType.MakeIngot("Silver"), + ["Platinum"] = MyItemType.MakeIngot("Platinum"), + ["Magnesium"] = MyItemType.MakeIngot("Magnesium"), + ["Uranium"] = MyItemType.MakeIngot("Uranium"), + ["Gravel"] = MyItemType.MakeIngot("Gravel"), + }; + private Dictionary _supply = new Dictionary(); + + public OreReport(IMyTextSurface display, Program program) + { + _program = program; + _display = display; + _console = new PrefixedConsole(_program.Console, "OreReport"); + + // Configure display + _display.ContentType = ContentType.TEXT_AND_IMAGE; + _display.WriteText("Initializing..."); + + // initialize the supply map + // initializeIngotTypes(); + foreach (string key in _ingotTypes.Keys) + { + _supply[key] = 0f; + } + + // find all the inventories + List invBlocks = new List(); + program.GridTerminalSystem.GetBlocksOfType(invBlocks, blockFilter); + foreach (IMyTerminalBlock block in invBlocks) + { + IMyInventory inv = block.GetInventory(); + _inventories.Add(inv); + } + + _console.Print($"Scanning {_inventories.Count} inventories."); + } + + public void Update() + { + foreach (string key in _ingotTypes.Keys) + { + _supply[key] = 0f; + } + foreach (IMyInventory inv in _inventories) + { + foreach (KeyValuePair kvp in _ingotTypes) + { + _supply[kvp.Key] += (float)inv.GetItemAmount(kvp.Value); + } + } + } + + // TODO: just text for now; turn this into a nice graphical display eventually + public void Draw() + { + _builder.Clear(); + _builder.AppendLine("INGOT REPORT"); + _builder.AppendLine(); + foreach (string key in _supply.Keys) + { + _builder.Append(key); + _builder.Append(" "); + _builder.Append(_supply[key].ToString()); + _builder.AppendLine(); + } + _display.WriteText(_builder.ToString()); + } + + // private void initializeIngotTypes() + // { + // string[] types = { "Iron", "Silicon", "Nickel", "Cobalt", "Gold", "Silver", "Platinum", "Magnesium", "Uranium", "Gravel" }; + // foreach (string type in types) + // { + // _ingotTypes[type] = new MyItemType("Ingot", type); + // } + // } + + private bool blockFilter(IMyTerminalBlock block) + { + return block.IsSameConstructAs(_program.Me) && block.InventoryCount > 0; + } + } + } +} \ No newline at end of file diff --git a/InfoDisplays/Program.cs b/InfoDisplays/Program.cs new file mode 100644 index 0000000..d463ffc --- /dev/null +++ b/InfoDisplays/Program.cs @@ -0,0 +1,83 @@ +using Sandbox.ModAPI.Ingame; +using System.Collections.Generic; +using VRage.Game.ModAPI.Ingame.Utilities; + +namespace IngameScript +{ + public partial class Program : MyGridProgram, IConsoleProgram + { + public IConsole Console { get; private set; } + public MyIni Ini { get; private set; } + + private OreReport _oreReport = null; + + public Program() + { + Ini = new MyIni(); + Console = new MainConsole(this, "Info Displays"); + + // find displays that are configured to show info, create the necessary objects. + // TODO: currently we only support one display per report, and we just use the first one + List displays = new List(); + GridTerminalSystem.GetBlocksOfType(displays, blockFilter); + foreach (IMyTerminalBlock display in displays) + { + Ini.TryParse(display.CustomData); + List keys = new List(); + Ini.GetKeys("infoDisplay", keys); + foreach (MyIniKey key in keys) + { + switch (key.Name) + { + case "ingotReport": + if (_oreReport != null) break; + int index = Ini.Get(key).ToInt32(); + // extract text surface + if (display is IMyTextSurface) + { + _oreReport = new OreReport(display as IMyTextSurface, this); + Console.Print($"Showing Ore Report on '{display.CustomName}'"); + } + else if (display is IMyTextSurfaceProvider) + { + _oreReport = new OreReport(((IMyTextSurfaceProvider)display).GetSurface(index), this); + Console.Print($"Showing Ore Report on '{display.CustomName}'"); + } + else + { + Console.Print("Tried to configure object without display surface."); + } + break; + default: + Console.Print($"Display type '{key.Name}' not defined."); + break; + } + } + } + + Console.UpdateTickCount(); + if (_oreReport == null) + { + Console.Print("No configured displays found. Shutting down."); + return; + } + Runtime.UpdateFrequency = UpdateFrequency.Update100; + } + + public void Main(string argument, UpdateType updateSource) + { + Console.UpdateTickCount(); + + if (_oreReport != null) + { + _oreReport.Update(); + _oreReport.Draw(); + } + } + + private bool blockFilter(IMyTerminalBlock block) + { + return block.IsSameConstructAs(this.Me) && MyIni.HasSection(block.CustomData, "infoDisplay"); + } + } +} diff --git a/InfoDisplays/thumb.png b/InfoDisplays/thumb.png new file mode 100644 index 0000000..a8dc2ef Binary files /dev/null and b/InfoDisplays/thumb.png differ diff --git a/SpaceEngineers.sln b/SpaceEngineers.sln index 700cf5e..e1bfe91 100644 --- a/SpaceEngineers.sln +++ b/SpaceEngineers.sln @@ -15,6 +15,8 @@ Project("{8A3CDCC5-4B55-4D87-A415-698A0E1FF06F}") = "Console", "Mixins\Console\C EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DockingController", "DockingController\DockingController.csproj", "{FDF834C0-D680-4FFA-8238-FE1FBDCF5B9D}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InfoDisplays", "InfoDisplays\InfoDisplays.csproj", "{4C7C8B10-1E43-453E-A9DA-A3626FE85ACC}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -37,6 +39,10 @@ Global {FDF834C0-D680-4FFA-8238-FE1FBDCF5B9D}.Debug|Any CPU.Build.0 = Debug|x64 {FDF834C0-D680-4FFA-8238-FE1FBDCF5B9D}.Release|Any CPU.ActiveCfg = Release|x64 {FDF834C0-D680-4FFA-8238-FE1FBDCF5B9D}.Release|Any CPU.Build.0 = Release|x64 + {4C7C8B10-1E43-453E-A9DA-A3626FE85ACC}.Debug|Any CPU.ActiveCfg = Debug|x64 + {4C7C8B10-1E43-453E-A9DA-A3626FE85ACC}.Debug|Any CPU.Build.0 = Debug|x64 + {4C7C8B10-1E43-453E-A9DA-A3626FE85ACC}.Release|Any CPU.ActiveCfg = Release|x64 + {4C7C8B10-1E43-453E-A9DA-A3626FE85ACC}.Release|Any CPU.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE