209 lines
9.1 KiB
C#
209 lines
9.1 KiB
C#
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<IMyAssembler> assemblers;
|
|
|
|
static readonly List<ComponentQuantity> MISSILE_COMPONENTS = new List<ComponentQuantity>{
|
|
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<string, Ingots> INGOTS_PER_COMPONENT = new Dictionary<string, Ingots>
|
|
{
|
|
["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<IMyAssembler> 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; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Display how many missile can be build with the current ingot stock.
|
|
/// </summary>
|
|
/// <param name="output"></param>
|
|
public void DisplayIngotsStatus(StringBuilder sb)
|
|
{
|
|
var ingots = this.gridTerminal.IngotsFromGridContainers(this.grid);
|
|
|
|
var ingotsMissileStatus = new List<IngotsMissileStatus>();
|
|
var ingotsStatusRest = new List<IngotsStatus>(); // For ingots not needed by missiles.
|
|
|
|
foreach (var ingot in Enum.GetValues(typeof(IngotsEnum)).Cast<IngotsEnum>())
|
|
{
|
|
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));
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// It counts elements in queue in assemblers too.
|
|
/// </summary>
|
|
/// <param name="componentTypes"></param>
|
|
/// <returns></returns>
|
|
List<MyFixedPoint> GetCurrentItemQuantity(IEnumerable<ComponentType> componentTypes)
|
|
{
|
|
var total = new List<MyFixedPoint>(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<IMyAssembler>(grid: this.grid))
|
|
{
|
|
var queue = new List<MyProductionItem>();
|
|
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;
|
|
}
|
|
}
|
|
}
|