Skip to content

Instantly share code, notes, and snippets.

@HeilTec
Created January 9, 2023 16:45
Show Gist options
  • Save HeilTec/e9ad64c8c3fd5b2fe351764ee364909c to your computer and use it in GitHub Desktop.
Save HeilTec/e9ad64c8c3fd5b2fe351764ee364909c to your computer and use it in GitHub Desktop.
Analyzing Space Engineers Conveyor System Connective Properties
using Sandbox.Game.EntityComponents;
using Sandbox.ModAPI.Ingame;
using Sandbox.ModAPI.Interfaces;
using SpaceEngineers.Game.ModAPI.Ingame;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Text;
using VRage;
using VRage.Collections;
using VRage.Game;
using VRage.Game.Components;
using VRage.Game.GUI.TextPanel;
using VRage.Game.ModAPI.Ingame;
using VRage.Game.ModAPI.Ingame.Utilities;
using VRage.Game.ObjectBuilders.Definitions;
using VRageMath;
namespace IngameScript
{
partial class Program : MyGridProgram
{
readonly string LCDTag = "Conveyors LCD";
public Program()
{
Runtime.UpdateFrequency = UpdateFrequency.Update100;
}
public void Main(string argument, UpdateType updateSource)
{
if ((updateSource & UpdateType.Update100) == UpdateType.Update100) {
ScanGrid();
FindConstructions();
FindConveyorConnections();
ShowConstructions();
}
}
readonly List<IMyTerminalBlock> allInventoryBlocks = new List<IMyTerminalBlock>();
readonly List<List<IMyTerminalBlock>> constructs = new List<List<IMyTerminalBlock>>();
readonly List<List<List<IMyInventory>>> inventoryConveyorGroups = new List<List<List<IMyInventory>>>();
readonly StringBuilder _outputText = new StringBuilder();
readonly List<IMyTextPanel> MyLCDs = new List<IMyTextPanel>();
readonly List<List<IMyInventory>> smallPortSegments = new List<List<IMyInventory>>();
readonly MyItemType LargeItem = MyItemType.MakeComponent("LargeTube");
bool HasLCDTag(IMyTerminalBlock TermBlock) =>
TermBlock.CustomName.Contains(LCDTag);
private void FindLCDs()
{
GridTerminalSystem.GetBlocksOfType(MyLCDs, HasLCDTag);
if (MyLCDs.Count == 0)
{
Echo("Warning: Cannot find LCD with group or tag " + LCDTag);
}
}
private void ScanGrid() {
FindLCDs();
GridTerminalSystem.GetBlocksOfType(allInventoryBlocks, block => block.HasInventory);
}
private void FindConstructions() {
foreach (var construct in constructs) construct.Clear();
constructs.Clear(); // ??? is the clearing loop above just a waste of time ???
foreach (var block in allInventoryBlocks)
{
var found = false;
foreach (var construct in constructs)
{
if (block.IsSameConstructAs(construct[0])) {
construct.Add(block);
found = true;
break;
}
}
if (!found)
{
var newConstruct = new List<IMyTerminalBlock> { block };
constructs.Add(newConstruct);
}
}
}
private void FindConveyorConnections()
{
foreach (List<List<IMyInventory>> group in inventoryConveyorGroups)
{
foreach (List<IMyInventory> groupInventory in group)
{
groupInventory.Clear();
}
group.Clear();
}
inventoryConveyorGroups.Clear(); // ??? are the clearing loops above just a waste of time ???
foreach (var construct in constructs)
{
List<List<IMyInventory>> group = new List<List<IMyInventory>>();
inventoryConveyorGroups.Add(group);
foreach (var block in construct)
{
var blockInventory = block.GetInventory();
var found = false;
foreach (List<IMyInventory> groupInventory in group)
{
foreach (IMyInventory inv in groupInventory)
{
if (blockInventory.IsConnectedTo(inv))
{
groupInventory.Add(blockInventory);
found = true;
break;
}
}
if (found) break;
}
if (!found)
{
var newGroupInventory = new List<IMyInventory> { blockInventory };
group.Add(newGroupInventory);
}
}
}
}
private void ShowConstructions()
{
_outputText.Clear();
_outputText.Append("List of constructions:\n---------------------\n");
_outputText.AppendLine();
// Old code kept for reference
//foreach (List<IMyTerminalBlock> construct in constructs)
//{
// _outputText.AppendLine(construct[0].CubeGrid.DisplayName);
// foreach (IMyTerminalBlock block in construct)
// {
// _outputText.AppendLine(block.CustomName);
// }
//}
foreach (List<List<IMyInventory>> group in inventoryConveyorGroups)
{
_outputText.Append("Grid: ");
_outputText.AppendLine(((IMyTerminalBlock)group[0][0].Owner).CubeGrid.DisplayName);
MyCubeSize gridSize = ((IMyTerminalBlock)group[0][0].Owner).CubeGrid.GridSizeEnum;
foreach (List<IMyInventory> groupInventory in group)
{
if (gridSize == MyCubeSize.Large)
{
foreach (var inv in groupInventory)
{
_outputText.Append("||");
_outputText.AppendLine(((IMyCubeBlock)inv.Owner).DisplayNameText);
}
} else
{
smallPortSegments.Clear();
foreach (var inv in groupInventory)
{
bool found = false;
foreach (List<IMyInventory> segment in smallPortSegments)
{
// Detect large or small port connection
bool hasLargePort = inv.CanTransferItemTo(segment[0], LargeItem);
if (hasLargePort)
{
segment.Add(inv);
Echo(((IMyCubeBlock)inv.Owner).DisplayNameText);
found = true;
break;
}
}
if (!found)
{
smallPortSegments.Add(new List<IMyInventory> { inv });
}
}
foreach (var segment in smallPortSegments)
{
foreach (var inv in segment)
{
_outputText.Append(" ||");
_outputText.AppendLine(((IMyCubeBlock)inv.Owner).DisplayNameText);
}
_outputText.AppendLine(" |");
}
}
_outputText.AppendLine();
}
_outputText.AppendLine();
}
foreach (IMyTextPanel LCD in MyLCDs)
{
LCD.ContentType = ContentType.TEXT_AND_IMAGE;
LCD.WriteText(_outputText);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment