Skip to content

Instantly share code, notes, and snippets.

@tomestephens
Created May 26, 2019 17:26
Show Gist options
  • Save tomestephens/926f25134885230afbbb8ec37e85b877 to your computer and use it in GitHub Desktop.
Save tomestephens/926f25134885230afbbb8ec37e85b877 to your computer and use it in GitHub Desktop.
Space Engineers:: Simple Target/Par Stock Inventory Manager
public Program()
{
Runtime.UpdateFrequency = UpdateFrequency.Update100;
}
private static void DisplayText(string text, IMyTextPanel panel) {
panel.WriteText(text);
panel.ShowPublicTextOnScreen();
}
private static bool IsComponent(MyItemType type) {
return type.TypeId.Contains("Component");
}
private static bool IsIngot(MyItemType type) {
return type.ToString().Contains("Ingot");
}
private static string GetItemName(MyItemType type) {
return (string)type.SubtypeId;
}
private static string ToFixedLength(string s, int len) {
// only handling a length under the target...
while(s.Length < len) {
s += " ";
}
return s;
}
private static string GetStockLine(string component, string stock, string par) {
return string.Format("{0} {1} / {2}\n", ToFixedLength(component, 25), ToFixedLength(stock, 7), ToFixedLength(par, 7));
}
public void Main(string argument, UpdateType updateSource) {
// par/target stocks -- place a build order when you're under this
var par = new Dictionary<string, int>();
par.Add("SteelPlate", 1000);
par.Add("Construction", 500);
par.Add("PowerCell", 200);
par.Add("Computer", 200);
par.Add("LargeTube", 200);
par.Add("SmallTube", 200);
par.Add("Motor", 100);
par.Add("InteriorPlate", 200);
//var lcd = (IMyTextPanel) GridTerminalSystem.GetBlockWithName("Explorer-Bridge-LCD-1");
var assembler = (IMyAssembler) GridTerminalSystem.GetBlockWithName("Mobile-Base-Assembler");
// should I be more flexible about which cargo to store in?
var mainCargo = (IMyCargoContainer) GridTerminalSystem.GetBlockWithName("Mobile-Base-Main-Cargo");
MoveAssemblerOutput(mainCargo.GetInventory());
var stock = new Dictionary<string, MyFixedPoint>();
DetermineComponentStock(stock);
var sb = new StringBuilder(GetStockLine("Component", "Stock", "Par"));
foreach(var kvp in stock) {
var parAmt = par.ContainsKey(kvp.Key) ? par[kvp.Key]: 0;
var orderAmount = kvp.Value >= parAmt ? 0 : parAmt - kvp.Value;
sb.Append(GetStockLine(kvp.Key, kvp.Value.ToString(), parAmt.ToString()));
if (orderAmount > 0) {
assembler.AddQueueItem(GetMyDefinitionId(kvp.Key), orderAmount);
}
}
DisplayText(sb.ToString(), lcd);
DisplayIngotCounts();
}
private void DisplayIngotCounts() {
var lcd = (IMyTextPanel) GridTerminalSystem.GetBlockWithName("Explorer-Bridge-LCD-2");
var sb = new StringBuilder("IngotType::Stock\n");
var stock = new Dictionary<string, MyFixedPoint>();
DetermineIngotStock(stock);
foreach(var kvp in stock) {
sb.AppendFormat("{0}::{1}\n", kvp.Key, kvp.Value.ToString());
}
DisplayText(sb.ToString(), lcd);
}
private void MoveAssemblerOutput(IMyInventory dest) {
var assemblers = new List<IMyAssembler>();
GridTerminalSystem.GetBlocksOfType(assemblers);
foreach(var assembler in assemblers) {
MoveInventory(assembler.OutputInventory, dest);
}
}
private static void MoveInventory(IMyInventory src, IMyInventory dest) {
for(int i=0; i<src.ItemCount; i++) {
var item = src.GetItemAt(i);
if (!item.HasValue) continue;
// the destination actually has space...
if(dest.CanItemsBeAdded(item.Value.Amount, item.Value.Type)) {
src.TransferItemTo(dest, item.Value, null);
}
}
}
private void DetermineComponentStock(Dictionary<string, MyFixedPoint> stock) {
var allBlocks = new List<IMyTerminalBlock>();
GridTerminalSystem.GetBlocks(allBlocks);
foreach(var block in allBlocks) {
if (!block.HasInventory) continue;
var inventory = block.GetInventory();
if (inventory == null || inventory.ItemCount == 0) continue;
for(int i=0; i<inventory.ItemCount; i++) {
var item = inventory.GetItemAt(i);
if (!item.HasValue || !IsComponent(item.Value.Type)) continue;
var key = GetItemName(item.Value.Type);
if (stock.ContainsKey(key)) {
stock[key] += item.Value.Amount;
} else {
stock.Add(key, item.Value.Amount);
}
}
}
AddAssemblerQueueToStock(stock);
}
private void DetermineIngotStock(Dictionary<string, MyFixedPoint> stock) {
var allBlocks = new List<IMyTerminalBlock>();
GridTerminalSystem.GetBlocks(allBlocks);
foreach(var block in allBlocks) {
if (!block.HasInventory) continue;
var inventory = block.GetInventory();
if (inventory == null || inventory.ItemCount == 0) continue;
for(int i=0; i<inventory.ItemCount; i++) {
var item = inventory.GetItemAt(i);
if (!item.HasValue || !IsIngot(item.Value.Type)) continue;
var key = GetItemName(item.Value.Type);
if (stock.ContainsKey(key)) {
stock[key] += item.Value.Amount;
} else {
stock.Add(key, item.Value.Amount);
}
}
}
//check ores too?
//AddAssemblerQueueToStock(stock);
}
private void AddAssemblerQueueToStock(Dictionary<string, MyFixedPoint> stock) {
var assemblers = new List<IMyAssembler>();
GridTerminalSystem.GetBlocksOfType(assemblers);
foreach(var assembler in assemblers) {
if (assembler.IsQueueEmpty) continue;
var items = new List<MyProductionItem>();
assembler.GetQueue(items);
foreach(var item in items) {
var key = GetNameFromDefinition(item.BlueprintId);
if (stock.ContainsKey(key)) {
stock[key] += item.Amount;
} else {
stock.Add(key, item.Amount);
}
}
}
}
private static string GetNameFromDefinition(MyDefinitionId def) {
var name = def.SubtypeId.ToString();
switch(name) {
case "ConstructionComponent":
case "ComputerComponent":
case "MotorComponent":
name = name.Replace("Component", "");
break;
}
return name;
}
private static MyDefinitionId GetMyDefinitionId(string item) {
var def = "MyObjectBuilder_BlueprintDefinition/";
switch (item) {
// where we just add "component"
case "Construction":
case "Computer":
case "Motor":
def += item + "Component";
break;
// nothing to change
default:
def += item;
break;
}
return MyDefinitionId.Parse(def);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment