New project to manage La Mimine frigate

This commit is contained in:
Greg Burri 2025-09-14 17:19:16 +02:00
parent d0be374ca8
commit 3236ccb05f
10 changed files with 873 additions and 0 deletions

209
Mimine/MissileManager.cs Normal file
View file

@ -0,0 +1,209 @@
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;
}
}
}