using Sandbox.Game.EntityComponents; using Sandbox.ModAPI.Ingame; using Sandbox.ModAPI.Interfaces; using SpaceEngineers.Game.ModAPI.Ingame; using System.Collections.Generic; using System.Collections; using System.Linq; using System.Text; using System; using VRage.Collections; using VRage.Game.Components; using VRage.Game.ModAPI.Ingame; using VRage.Game.ModAPI.Ingame.Utilities; using VRage.Game.ObjectBuilders.Definitions; using VRage.Game; using VRageMath; namespace IngameScript { partial class Program : MyGridProgram { private Dictionary values = new Dictionary(); private List trackedInventories = new List(); private List assemblers = new List(); private List disassemblers = new List(); public Program() { GetInventories(trackedInventories); GetAssemblers(assemblers, disassemblers); GetStoredLevels(values); UpdateStoredLevels(); } private void UpdateStoredLevels() { MyIni saveFile = new MyIni(); foreach (var kvp in values) { saveFile.Set("Tracked Value", kvp.Key.ToString(), $"{kvp.Value[0]}-{kvp.Value[1]}"); } var current = GetCurrentLevels(); foreach (var kvp in current) { if (!values.ContainsKey(kvp.Key)) { saveFile.Set("Tracked Value", kvp.Key.ToString(), $"{kvp.Value.SerializeString()}-{kvp.Value.SerializeString()}"); values.Add(kvp.Key, new VRage.MyFixedPoint[2] { kvp.Value, kvp.Value }); } } Me.CustomData = saveFile.ToString(); } private void GetInventories(List inventories) { inventories.Clear(); List containers = new List(); GridTerminalSystem.GetBlocksOfType(containers); for (int i = 0; i < containers.Count; i++) { var container = containers[i]; if (container.CustomData.ToLower().Contains("tracked")) { Echo($"Tracking {container.Name} cargo container"); inventories.Add(container.GetInventory()); } } Echo($"Tracking {inventories.Count} inventories"); } private void GetAssemblers(List assemblers, List disassemblers) { assemblers.Clear(); disassemblers.Clear(); List allAssemblers = new List(); GridTerminalSystem.GetBlocksOfType(allAssemblers); for (int i = 0; i < allAssemblers.Count; i++) { var assembler = allAssemblers[i]; var lowerCustomData = assembler.CustomData.ToLower(); if (lowerCustomData.Contains("tracked assembler")) { assemblers.Add(assembler); Echo($"Tracking {assembler.Name} assembler"); } else if (lowerCustomData.Contains("tracked disassembler")) { disassemblers.Add(assembler); Echo($"Tracking {assembler.Name} disassembler"); } } Echo($"Tracking {assemblers.Count} assemblers {disassemblers.Count} disassemblers"); } private Dictionary GetCurrentLevels() { Dictionary retVal = new Dictionary(); GetInventoryLevels(retVal); GetAssemblerLevels(retVal); GetDisassemblerLevels(retVal); return retVal; } private void GetAssemblerLevels(Dictionary levels) { List queue = new List(); for (int i = 0; i < disassemblers.Count; i++) { queue.Clear(); var assembler = disassemblers[i]; assembler.GetQueue(queue); for (int j = 0; j < queue.Count; j++) { var queueItem = queue[j]; if (levels.ContainsKey(queueItem.BlueprintId)) { levels[queueItem.BlueprintId] -= queueItem.Amount; } else { levels.Add(queueItem.BlueprintId, queueItem.Amount); } } } } private void GetDisassemblerLevels(Dictionary levels) { List queue = new List(); for (int i = 0; i < assemblers.Count; i++) { queue.Clear(); var assembler = assemblers[i]; assembler.GetQueue(queue); for (int j = 0; j < queue.Count; j++) { var queueItem = queue[j]; if (levels.ContainsKey(queueItem.BlueprintId)) { levels[queueItem.BlueprintId] += queueItem.Amount; } else { levels.Add(queueItem.BlueprintId, queueItem.Amount); } } } } private void GetInventoryLevels(Dictionary levels) { for (int i = 0; i < trackedInventories.Count; i++) { var inventoryCount = trackedInventories[i].ItemCount; for (int j = 0; j < inventoryCount; j++) { var inventoryItem = trackedInventories[i].GetItemAt(j); if (inventoryItem != null) { if (levels.ContainsKey(inventoryItem.Value.Type)) { levels[inventoryItem.Value.Type] += inventoryItem.Value.Amount; } else { levels.Add(inventoryItem.Value.Type, inventoryItem.Value.Amount); } } } } } private void GetStoredLevels(Dictionary levels) { levels.Clear(); MyIni saveFile = new MyIni(); if (saveFile.TryParse(Me.CustomData)) { var keys = new List(); saveFile.GetKeys("Tracked Value", keys); for (int i = 0; i < keys.Count; i++) { var key = keys[i]; try { var type = MyItemType.Parse(key.Name); var value = saveFile.Get(key); if (!value.IsEmpty) { string[] split = value.ToString().Split('-'); if (split.Length == 2) { VRage.MyFixedPoint min = VRage.MyFixedPoint.DeserializeString(split[0]); VRage.MyFixedPoint max = VRage.MyFixedPoint.DeserializeString(split[1]); if (!levels.ContainsKey(type)) { levels.Add(type, new VRage.MyFixedPoint[] { min, max }); } } } } catch { } } } Echo($"Loaded {levels.Count} values"); } public void Main(string argument, UpdateType updateSource) { var currentLevels = GetCurrentLevels(); CheckValues(currentLevels); } private void CheckValues(Dictionary currentLevels) { if (assemblers.Count > 0 || disassemblers.Count > 0) { foreach (var kvp in values) { MyDefinitionId def; if (MyDefinitionId.TryParse(kvp.Key.TypeId, kvp.Key.SubtypeId, out def)) { Echo($"{def.SubtypeId}-{def.SubtypeName}-{def.TypeId}"); var current = VRage.MyFixedPoint.Zero; if (currentLevels.ContainsKey(kvp.Key)) { current = currentLevels[kvp.Key]; } Echo($"{kvp.Key.SubtypeId} - Current {current} Min {kvp.Value[0]} Max {kvp.Value[1]}"); if (assemblers.Count > 0) { if (kvp.Value.Length > 0) { var min = kvp.Value[0]; if (current < min) { var assembler = GetSmallestQueue(assemblers); assembler.Mode = MyAssemblerMode.Assembly; var amount = min - current; Echo($"{kvp.Key} is down by {amount}"); assembler.InsertQueueItem(0, def, amount); } } } if (disassemblers.Count > 0) { if (kvp.Value.Length > 1) { var max = kvp.Value[1]; if (current > max) { var amount = current - max; Echo($"{kvp.Key} is up by {amount}"); for (int i = 0; i < disassemblers.Count; i++) { var disassembler = disassemblers[i]; disassembler.Mode = MyAssemblerMode.Disassembly; var transfered = FindAndMoveForDisassembly(kvp.Key, amount, disassembler); Echo($"Adding {transfered} {kvp.Key} to {disassembler} queue"); disassembler.InsertQueueItem(0,def, transfered); amount -= transfered; if (amount <= VRage.MyFixedPoint.Zero) { break; } } } } } } } } } private VRage.MyFixedPoint FindAndMoveForDisassembly(MyItemType type, VRage.MyFixedPoint amount, IMyAssembler assembler) { VRage.MyFixedPoint transfered = VRage.MyFixedPoint.Zero; for (int i = 0; i < trackedInventories.Count; i++) { if (trackedInventories[i].CanTransferItemTo(assembler.OutputInventory, type)) { var itemCount = trackedInventories[i].ItemCount; for (int j = 0; j < itemCount; j++) { var item = trackedInventories[i].GetItemAt(j); if (item != null) { if (item.Value.Type == type) { var toTransfer = amount; if (amount > item.Value.Amount) { toTransfer = item.Value.Amount; } if (assembler.OutputInventory.TransferItemFrom(trackedInventories[i], item.Value, toTransfer)) { amount -= toTransfer; transfered += toTransfer; } else { return transfered; } } } if (amount <= VRage.MyFixedPoint.Zero) { return transfered; } } } if (amount <= VRage.MyFixedPoint.Zero) { return transfered; } } return transfered; } private IMyAssembler GetSmallestQueue(List of) { var retVal = of[0]; VRage.MyFixedPoint min = QueueSize(retVal); for (int i = 1; i < of.Count; i++) { var current = QueueSize(retVal); if (current < min) { retVal = of[i]; } } return retVal; } private VRage.MyFixedPoint QueueSize(IMyAssembler assembler) { var queue = new List(); assembler.GetQueue(queue); VRage.MyFixedPoint retVal = VRage.MyFixedPoint.Zero; for (int i = 0; i < queue.Count; i++) { retVal += queue[i].Amount; } return retVal; } } }