using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Sandbox.ModAPI.Ingame; using VRage; using VRage.Game; using VRage.Game.ModAPI.Ingame; namespace IngameScript { internal class MissileManager { readonly IMyGridTerminalSystem gridTerminal; readonly IMyCubeGrid grid; readonly Output output; readonly IList assemblers; static readonly List MISSILE_COMPONENTS = new List{ new ComponentQuantity(MyItemType.MakeComponent("SteelPlate"), MyDefinitionId.Parse("MyObjectBuilder_BlueprintDefinition/SteelPlate"), 254), new ComponentQuantity(MyItemType.MakeComponent("Construction"), MyDefinitionId.Parse("MyObjectBuilder_BlueprintDefinition/ConstructionComponent"), 172), new ComponentQuantity(MyItemType.MakeComponent("Motor"), MyDefinitionId.Parse("MyObjectBuilder_BlueprintDefinition/MotorComponent"), 18), new ComponentQuantity(MyItemType.MakeComponent("InteriorPlate"), MyDefinitionId.Parse("MyObjectBuilder_BlueprintDefinition/InteriorPlate"), 43), new ComponentQuantity(MyItemType.MakeComponent("Computer"), MyDefinitionId.Parse("MyObjectBuilder_BlueprintDefinition/ComputerComponent"), 53), new ComponentQuantity(MyItemType.MakeComponent("PowerCell"), MyDefinitionId.Parse("MyObjectBuilder_BlueprintDefinition/PowerCell"), 2), new ComponentQuantity(MyItemType.MakeComponent("Display"), MyDefinitionId.Parse("MyObjectBuilder_BlueprintDefinition/Display"), 1), new ComponentQuantity(MyItemType.MakeComponent("SmallTube"), MyDefinitionId.Parse("MyObjectBuilder_BlueprintDefinition/SmallTube"), 27), new ComponentQuantity(MyItemType.MakeComponent("MetalGrid"), MyDefinitionId.Parse("MyObjectBuilder_BlueprintDefinition/MetalGrid"), 48), new ComponentQuantity(MyItemType.MakeComponent("LargeTube"), MyDefinitionId.Parse("MyObjectBuilder_BlueprintDefinition/LargeTube"), 16), new ComponentQuantity(MyItemType.MakeComponent("Detector"), MyDefinitionId.Parse("MyObjectBuilder_BlueprintDefinition/DetectorComponent"), 14), new ComponentQuantity(MyItemType.MakeComponent("RadioCommunication"), MyDefinitionId.Parse("MyObjectBuilder_BlueprintDefinition/RadioCommunicationComponent"), 22), new ComponentQuantity(MyItemType.MakeComponent("Girder"), MyDefinitionId.Parse("MyObjectBuilder_BlueprintDefinition/GirderComponent"), 11), new ComponentQuantity(MyItemType.MakeComponent("Explosives"), MyDefinitionId.Parse("MyObjectBuilder_BlueprintDefinition/ExplosivesComponent"), 22), }; // In kg. static readonly Dictionary INGOTS_PER_COMPONENT = new Dictionary { ["SteelPlate"] = new Ingots(iron: 21), ["Construction"] = new Ingots(iron: 8), ["Motor"] = new Ingots(iron: 20, nickel: 5), ["InteriorPlate"] = new Ingots(iron: 3), ["Computer"] = new Ingots(iron: 0.5f, silicon: 0.2f), ["PowerCell"] = new Ingots(iron: 10, nickel: 2, silicon: 1), ["Display"] = new Ingots(iron: 1, silicon: 5), ["SmallTube"] = new Ingots(iron: 5), ["MetalGrid"] = new Ingots(iron: 12, nickel: 5, cobalt: 3), ["LargeTube"] = new Ingots(iron: 30), ["Detector"] = new Ingots(iron: 5, nickel: 15), ["RadioCommunication"] = new Ingots(iron: 8, silicon: 1), ["Girder"] = new Ingots(iron: 6), ["Explosives"] = new Ingots(silicon: 0.5f, magnesium: 2), }; static readonly Ingots INGOTS_PER_MISSILE; static MissileManager() { INGOTS_PER_MISSILE = new Ingots(); foreach (var component in MISSILE_COMPONENTS) { INGOTS_PER_MISSILE += INGOTS_PER_COMPONENT[component.ComponentType.ItemType.SubtypeId]; } } public MissileManager(IMyGridTerminalSystem gridTerminal, IMyCubeGrid grid, Output output, IList assemblers) { this.gridTerminal = gridTerminal; this.grid = grid; this.output = output; this.assemblers = assemblers; } public void BuildComponentForMissiles() { if (this.assemblers.Count == 0) return; var existingAmounts = this.GetCurrentItemQuantity(MISSILE_COMPONENTS.Select(quantity => quantity.ComponentType)); int i = 0; foreach (var missileComponent in MISSILE_COMPONENTS) { var existing = existingAmounts[i]; //this.output.Print($"{missileComponent.ItemType}: {existing}"); var desired = missileComponent.Quantity * Constants.NUMBER_OF_MISSILES; if (existing < desired) { var toBuild = desired - existing; this.output.Print($"Requesting {toBuild} of {missileComponent.ComponentType.BlueprintId.SubtypeName}"); this.assemblers[0].AddQueueItem(missileComponent.ComponentType.BlueprintId, toBuild); } i += 1; } } struct IngotsMissileStatus { public string Name { get; set; } public float Amount { get; set; } public float NbOfMissiles { get; set; } } struct IngotsStatus { public string Name { get; set; } public float Amount { get; set; } } /// /// Display how many missile can be build with the current ingot stock. /// /// public void DisplayIngotsStatus(StringBuilder sb) { var ingots = this.gridTerminal.IngotsFromGridContainers(this.grid); var ingotsMissileStatus = new List(); var ingotsStatusRest = new List(); // For ingots not needed by missiles. foreach (var ingot in Enum.GetValues(typeof(IngotsEnum)).Cast()) { var amount = ingots[ingot]; var amountNeeded = INGOTS_PER_MISSILE[ingot]; if (amountNeeded != 0f) ingotsMissileStatus.Add(new IngotsMissileStatus { Name = ingot.ToString(), Amount = amount, NbOfMissiles = amount / amountNeeded }); else ingotsStatusRest.Add(new IngotsStatus { Name = ingot.ToString(), Amount = amount }); } ingotsMissileStatus.Sort((a, b) => b.NbOfMissiles.CompareTo(a.NbOfMissiles)); sb.AppendLine(); sb.AppendLine($"Nb of missiles buildable: {(int)ingotsMissileStatus.Last().NbOfMissiles}"); sb.AppendLine(new string('-', Constants.CONSOLE_LINE_LENGTH)); foreach (var ingotMissileStatus in ingotsMissileStatus) { var name = $"{ingotMissileStatus.Name} ({(int)ingotMissileStatus.NbOfMissiles}):"; sb.Append(name); var value = $"{ingotMissileStatus.Amount:N2} kg"; sb.AppendLine(value.PadLeft(Constants.CONSOLE_LINE_LENGTH - name.Length)); } sb.AppendLine(new string('-', Constants.CONSOLE_LINE_LENGTH)); foreach (var ingotStatus in ingotsStatusRest) { var name = $"{ingotStatus.Name}:"; sb.Append(name); var value = $"{ingotStatus.Amount:N2} kg"; sb.AppendLine(value.PadLeft(Constants.CONSOLE_LINE_LENGTH - name.Length)); } } /// /// It counts elements in queue in assemblers too. /// /// /// List GetCurrentItemQuantity(IEnumerable componentTypes) { var total = new List(new MyFixedPoint[componentTypes.Count()]); foreach (var inventory in this.gridTerminal.GetAllInventories(grid)) { int i = 0; foreach (var componentType in componentTypes) { var items = inventory.FindItem(componentType.ItemType); if (items.HasValue) total[i] += items.Value.Amount; i += 1; } } // Special case for assemblers: check the current queue. foreach (var assembler in this.gridTerminal.GetBlocks(grid: this.grid)) { var queue = new List(); assembler.GetQueue(queue); int i = 0; foreach (var componentType in componentTypes) { foreach (var item in queue) { if (item.BlueprintId == componentType.BlueprintId) total[i] += item.Amount; } i += 1; } } return total; } } }