New project to manage La Mimine frigate
This commit is contained in:
parent
d0be374ca8
commit
3236ccb05f
10 changed files with 873 additions and 0 deletions
127
Mimine/AmmoManager.cs
Normal file
127
Mimine/AmmoManager.cs
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
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 AmmoManager
|
||||
{
|
||||
readonly IMyGridTerminalSystem gridTerminal;
|
||||
readonly IMyCubeGrid grid;
|
||||
readonly Output output;
|
||||
readonly IList<IMyAssembler> assemblers;
|
||||
|
||||
public AmmoManager(IMyGridTerminalSystem gridTerminal, IMyCubeGrid grid, Output output, IList<IMyAssembler> assemblers)
|
||||
{
|
||||
this.gridTerminal = gridTerminal;
|
||||
this.grid = grid;
|
||||
this.output = output;
|
||||
this.assemblers = assemblers;
|
||||
}
|
||||
|
||||
public class AmmoStatus
|
||||
{
|
||||
public MyFixedPoint NbOfCannonShell { get; set; }
|
||||
public MyFixedPoint NbOfArtilleryShell { get; set; }
|
||||
public MyFixedPoint NbOfGatlingAmmo { get; set; }
|
||||
|
||||
public AmmoStatus Copy()
|
||||
{
|
||||
return this.MemberwiseClone() as AmmoStatus;
|
||||
}
|
||||
}
|
||||
|
||||
public void BuildAmmo(AmmoStatus status)
|
||||
{
|
||||
if (this.assemblers.Count == 0)
|
||||
return;
|
||||
|
||||
var mainAssembler = this.assemblers[0];
|
||||
|
||||
var statusWithAssemblerQueues = status.Copy();
|
||||
|
||||
// Add the current Queue.
|
||||
foreach (var assembler in this.gridTerminal.GetBlocks<IMyAssembler>(grid: this.grid))
|
||||
{
|
||||
var queue = new List<MyProductionItem>();
|
||||
assembler.GetQueue(queue);
|
||||
|
||||
foreach (var item in queue)
|
||||
{
|
||||
if (item.BlueprintId == Constants.CANNON_SHELL_BLUEPRINT_ID)
|
||||
statusWithAssemblerQueues.NbOfCannonShell += item.Amount;
|
||||
else if (item.BlueprintId == Constants.ARTILLERY_SHELL_BLUEPRINT_ID)
|
||||
statusWithAssemblerQueues.NbOfArtilleryShell += item.Amount;
|
||||
else if (item.BlueprintId == Constants.GATLING_AMMO_BLUEPRINT_ID)
|
||||
statusWithAssemblerQueues.NbOfGatlingAmmo += item.Amount;
|
||||
}
|
||||
}
|
||||
|
||||
if (statusWithAssemblerQueues.NbOfCannonShell < Constants.NUMBER_OF_CANNON_SHELL)
|
||||
{
|
||||
var toBuild = Constants.NUMBER_OF_CANNON_SHELL - statusWithAssemblerQueues.NbOfCannonShell;
|
||||
this.output.Print($"Requesting {toBuild} of {Constants.CANNON_SHELL_BLUEPRINT_ID.SubtypeName}");
|
||||
mainAssembler.AddQueueItem(Constants.CANNON_SHELL_BLUEPRINT_ID, toBuild);
|
||||
}
|
||||
|
||||
if (statusWithAssemblerQueues.NbOfArtilleryShell < Constants.NUMBER_OF_ARTILLERY_SHELL)
|
||||
{
|
||||
var toBuild = Constants.NUMBER_OF_ARTILLERY_SHELL - statusWithAssemblerQueues.NbOfArtilleryShell;
|
||||
this.output.Print($"Requesting {toBuild} of {Constants.ARTILLERY_SHELL_BLUEPRINT_ID.SubtypeName}");
|
||||
mainAssembler.AddQueueItem(Constants.ARTILLERY_SHELL_BLUEPRINT_ID, toBuild);
|
||||
}
|
||||
|
||||
if (statusWithAssemblerQueues.NbOfGatlingAmmo < Constants.NUMBER_OF_GATLING_AMMO)
|
||||
{
|
||||
var toBuild = Constants.NUMBER_OF_GATLING_AMMO - statusWithAssemblerQueues.NbOfGatlingAmmo;
|
||||
this.output.Print($"Requesting {toBuild} of {Constants.GATLING_AMMO_BLUEPRINT_ID.SubtypeName}");
|
||||
mainAssembler.AddQueueItem(Constants.GATLING_AMMO_BLUEPRINT_ID, toBuild);
|
||||
}
|
||||
}
|
||||
|
||||
public void DisplayAmmoStatus(StringBuilder sb, AmmoStatus status)
|
||||
{
|
||||
var assaultConnonShell = "Assault Cannon Shell:";
|
||||
sb.Append(assaultConnonShell);
|
||||
sb.AppendLine($"{status.NbOfCannonShell}".PadLeft(Constants.CONSOLE_LINE_LENGTH - assaultConnonShell.Length));
|
||||
|
||||
var artilleryShell = "Artillery Shell:";
|
||||
sb.Append(artilleryShell);
|
||||
sb.AppendLine($"{status.NbOfArtilleryShell}".PadLeft(Constants.CONSOLE_LINE_LENGTH - artilleryShell.Length));
|
||||
|
||||
var gatlingAmmo = "Gatling Ammo Box";
|
||||
sb.Append(gatlingAmmo);
|
||||
sb.AppendLine($"{status.NbOfGatlingAmmo}".PadLeft(Constants.CONSOLE_LINE_LENGTH - gatlingAmmo.Length));
|
||||
}
|
||||
|
||||
public AmmoStatus GetAmmoStatus()
|
||||
{
|
||||
var status = new AmmoStatus();
|
||||
|
||||
foreach (var inventory in this.gridTerminal.GetAllInventories(grid))
|
||||
{
|
||||
var items = new List<MyInventoryItem>();
|
||||
inventory.GetItems(items);
|
||||
foreach (var item in items)
|
||||
{
|
||||
if (item.Type.SubtypeId == "MediumCalibreAmmo")
|
||||
status.NbOfCannonShell += item.Amount;
|
||||
else if (item.Type.SubtypeId == "LargeCalibreAmmo")
|
||||
status.NbOfArtilleryShell += item.Amount;
|
||||
else if (item.Type.SubtypeId == "NATO_25x184mm")
|
||||
status.NbOfGatlingAmmo += item.Amount;
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
}
|
||||
}
|
||||
37
Mimine/Components.cs
Normal file
37
Mimine/Components.cs
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using VRage;
|
||||
using VRage.Game;
|
||||
using VRage.Game.ModAPI.Ingame;
|
||||
|
||||
namespace IngameScript
|
||||
{
|
||||
class ComponentType
|
||||
{
|
||||
public readonly MyItemType ItemType;
|
||||
public readonly MyDefinitionId BlueprintId;
|
||||
|
||||
public ComponentType(MyItemType itemType, MyDefinitionId blueprintId)
|
||||
{
|
||||
this.ItemType = itemType;
|
||||
this.BlueprintId = blueprintId;
|
||||
}
|
||||
}
|
||||
|
||||
class ComponentQuantity
|
||||
{
|
||||
public readonly ComponentType ComponentType;
|
||||
public readonly MyFixedPoint Quantity;
|
||||
|
||||
public ComponentQuantity(MyItemType itemType, MyDefinitionId blueprintId, MyFixedPoint quantity)
|
||||
{
|
||||
|
||||
this.ComponentType = new ComponentType(itemType, blueprintId);
|
||||
this.Quantity = quantity;
|
||||
}
|
||||
}
|
||||
}
|
||||
29
Mimine/Constants.cs
Normal file
29
Mimine/Constants.cs
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using VRage.Game;
|
||||
|
||||
namespace IngameScript
|
||||
{
|
||||
internal static class Constants
|
||||
{
|
||||
public const int NUMBER_OF_MISSILES = 3; // The quantity of components will be created to build this quantity of missiles.
|
||||
|
||||
public const int NUMBER_OF_CANNON_SHELL = 200;
|
||||
public const int NUMBER_OF_ARTILLERY_SHELL = 50;
|
||||
public const int NUMBER_OF_GATLING_AMMO = 500;
|
||||
|
||||
public const int CONSOLE_NB_LINES = 14;
|
||||
public const int CONSOLE_LINE_LENGTH = 50;
|
||||
public const string GRID_PREFIX = "[Mimine]";
|
||||
|
||||
public static readonly MyDefinitionId CANNON_SHELL_BLUEPRINT_ID = MyDefinitionId.Parse("MyObjectBuilder_BlueprintDefinition/Position0110_MediumCalibreAmmo");
|
||||
public static readonly MyDefinitionId ARTILLERY_SHELL_BLUEPRINT_ID = MyDefinitionId.Parse("MyObjectBuilder_BlueprintDefinition/Position0120_LargeCalibreAmmo");
|
||||
public static readonly MyDefinitionId GATLING_AMMO_BLUEPRINT_ID = MyDefinitionId.Parse("MyObjectBuilder_BlueprintDefinition/Position0080_NATO_25x184mmMagazine");
|
||||
|
||||
public const float EPSILON = 0.05f;
|
||||
}
|
||||
}
|
||||
144
Mimine/Ingots.cs
Normal file
144
Mimine/Ingots.cs
Normal file
|
|
@ -0,0 +1,144 @@
|
|||
using System;
|
||||
using System.CodeDom;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Sandbox.ModAPI.Ingame;
|
||||
|
||||
using VRage;
|
||||
using VRage.Game;
|
||||
using VRage.Game.ModAPI.Ingame;
|
||||
|
||||
namespace IngameScript
|
||||
{
|
||||
enum IngotsEnum
|
||||
{
|
||||
Iron = 0,
|
||||
Nickel = 1,
|
||||
Cobalt = 2,
|
||||
Magnesium = 3,
|
||||
Silicon = 4,
|
||||
Silver = 5,
|
||||
Gold = 6,
|
||||
Platinum = 7,
|
||||
Uranium = 8,
|
||||
Gravel = 9, // Named 'Stone' in the API.
|
||||
}
|
||||
|
||||
class IngotException : Exception
|
||||
{
|
||||
public IngotException(string mess) :
|
||||
base(mess)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
class Ingot
|
||||
{
|
||||
public static MyItemType FromEnum(IngotsEnum ingot)
|
||||
{
|
||||
var name = "";
|
||||
switch (ingot)
|
||||
{
|
||||
case IngotsEnum.Iron: name = "Iron"; break;
|
||||
case IngotsEnum.Nickel: name = "Nickel"; break;
|
||||
case IngotsEnum.Cobalt: name = "Cobalt"; break;
|
||||
case IngotsEnum.Magnesium: name = "Magnesium"; break;
|
||||
case IngotsEnum.Silicon: name = "Silicon"; break;
|
||||
case IngotsEnum.Silver: name = "Silver"; break;
|
||||
case IngotsEnum.Gold: name = "Gold"; break;
|
||||
case IngotsEnum.Platinum: name = "Platinum"; break;
|
||||
case IngotsEnum.Uranium: name = "Uranium"; break;
|
||||
case IngotsEnum.Gravel: name = "Stone"; break;
|
||||
}
|
||||
return MyItemType.MakeIngot(name);
|
||||
}
|
||||
|
||||
public static IngotsEnum FromSubTypeId(string id)
|
||||
{
|
||||
IngotsEnum enumValue = IngotsEnum.Iron;
|
||||
switch (id)
|
||||
{
|
||||
case "Iron": enumValue = IngotsEnum.Iron; break;
|
||||
case "Nickel": enumValue = IngotsEnum.Nickel; break;
|
||||
case "Cobalt": enumValue = IngotsEnum.Cobalt; break;
|
||||
case "Magnesium": enumValue = IngotsEnum.Magnesium; break;
|
||||
case "Silicon": enumValue = IngotsEnum.Silicon; break;
|
||||
case "Silver": enumValue = IngotsEnum.Silver; break;
|
||||
case "Gold": enumValue = IngotsEnum.Gold; break;
|
||||
case "Platinum": enumValue = IngotsEnum.Platinum; break;
|
||||
case "Uranium": enumValue = IngotsEnum.Uranium; break;
|
||||
case "Stone": enumValue = IngotsEnum.Gravel; break;
|
||||
default: throw new IngotException($"Unknown ingot id: {id}");
|
||||
}
|
||||
return enumValue;
|
||||
}
|
||||
}
|
||||
|
||||
internal class Ingots
|
||||
{
|
||||
readonly float[] ingots = new float[10];
|
||||
|
||||
public Ingots(float iron = 0, float nickel = 0, float cobalt = 0, float magnesium = 0, float silicon = 0, float silver = 0, float gold = 0, float platinum = 0, float uranium = 0, float gravel = 0)
|
||||
{
|
||||
ingots[(int)IngotsEnum.Iron] = iron;
|
||||
ingots[(int)IngotsEnum.Nickel] = nickel;
|
||||
ingots[(int)IngotsEnum.Cobalt] = cobalt;
|
||||
ingots[(int)IngotsEnum.Magnesium] = magnesium;
|
||||
ingots[(int)IngotsEnum.Silicon] = silicon;
|
||||
ingots[(int)IngotsEnum.Silver] = silver;
|
||||
ingots[(int)IngotsEnum.Gold] = gold;
|
||||
ingots[(int)IngotsEnum.Platinum] = platinum;
|
||||
ingots[(int)IngotsEnum.Uranium] = uranium;
|
||||
ingots[(int)IngotsEnum.Gravel] = gravel;
|
||||
}
|
||||
|
||||
public float this[IngotsEnum ingot]
|
||||
{
|
||||
get { return ingots[(int)ingot]; }
|
||||
set { ingots[(int)ingot] = value; }
|
||||
}
|
||||
|
||||
public static Ingots operator +(Ingots a, Ingots b)
|
||||
{
|
||||
var result = new Ingots();
|
||||
for (int i = 0; i < result.ingots.Length; i++)
|
||||
result.ingots[i] = a.ingots[i] + b.ingots[i];
|
||||
return result;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
foreach (var ingot in Enum.GetValues(typeof(IngotsEnum)).Cast<IngotsEnum>())
|
||||
{
|
||||
sb.AppendLine($"{ingot}: {this[ingot]}");
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
static class IngotsUtils
|
||||
{
|
||||
public static Ingots IngotsFromGridContainers(this IMyGridTerminalSystem gridTerminal, IMyCubeGrid grid)
|
||||
{
|
||||
var ingots = new Ingots();
|
||||
|
||||
foreach (var inventory in gridTerminal.GetAllInventories(grid))
|
||||
{
|
||||
var items = new List<MyInventoryItem>();
|
||||
inventory.GetItems(items);
|
||||
|
||||
foreach (var item in items)
|
||||
if (item.Type.TypeId == "MyObjectBuilder_Ingot")
|
||||
ingots[Ingot.FromSubTypeId(item.Type.SubtypeId)] += (float)item.Amount;
|
||||
}
|
||||
|
||||
return ingots;
|
||||
}
|
||||
}
|
||||
}
|
||||
34
Mimine/Mimine.csproj
Normal file
34
Mimine/Mimine.csproj
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netframework48</TargetFramework>
|
||||
<RootNamespace>IngameScript</RootNamespace>
|
||||
<LangVersion>6</LangVersion>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<Configurations>Release;Debug</Configurations>
|
||||
<Platforms>x64</Platforms>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Mal.Mdk2.PbAnalyzers" Version="2.1.13">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Mal.Mdk2.PbPackager" Version="2.1.5">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Mal.Mdk2.References" Version="2.2.4">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="Instructions.readme" />
|
||||
<AdditionalFiles Include="Instructions.readme" />
|
||||
</ItemGroup>
|
||||
|
||||
<Import Project="..\SECommon\SECommon.projitems" Label="Shared" />
|
||||
|
||||
</Project>
|
||||
22
Mimine/Mimine.mdk.ini
Normal file
22
Mimine/Mimine.mdk.ini
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
; This file is project specific and should be checked in to source control.
|
||||
|
||||
[mdk]
|
||||
; This is a programmable block script project.
|
||||
; You should not change this.
|
||||
type=programmableblock
|
||||
|
||||
; Toggle trace (on|off) (verbose output)
|
||||
trace=off
|
||||
|
||||
; What type of minification to use (none|trim|stripcomments|lite|full)
|
||||
; none: No minification
|
||||
; trim: Removes unused types (NOT members).
|
||||
; stripcomments: trim + removes comments.
|
||||
; lite: stripcomments + removes leading/trailing whitespace.
|
||||
; full: lite + renames identifiers to shorter names.
|
||||
minify=none
|
||||
|
||||
; A list of files and folder to ignore when creating the script.
|
||||
; This is a comma separated list of glob patterns.
|
||||
; See https://code.visualstudio.com/docs/editor/glob-patterns
|
||||
ignores=obj/**/*,MDK/**/*,**/*.debug.cs
|
||||
7
Mimine/Mimine.mdk.local.ini
Normal file
7
Mimine/Mimine.mdk.local.ini
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
; This file is _local_ to your machine and should not be checked in to source control.
|
||||
|
||||
[mdk]
|
||||
; Where to output the script to (auto|specific path)
|
||||
output=auto
|
||||
; Override the default binary path (auto|specific path)
|
||||
binarypath=auto
|
||||
209
Mimine/MissileManager.cs
Normal file
209
Mimine/MissileManager.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
260
Mimine/Program.cs
Normal file
260
Mimine/Program.cs
Normal file
|
|
@ -0,0 +1,260 @@
|
|||
using Sandbox.Game;
|
||||
using Sandbox.Game.EntityComponents;
|
||||
using Sandbox.ModAPI.Ingame;
|
||||
using Sandbox.ModAPI.Interfaces;
|
||||
|
||||
using SpaceEngineers.Game.ModAPI.Ingame;
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using VRage;
|
||||
using VRage.Collections;
|
||||
using VRage.Game;
|
||||
using VRage.Game.Components;
|
||||
using VRage.Game.GUI.TextPanel;
|
||||
using VRage.Game.ModAPI.Ingame;
|
||||
using VRage.Game.ModAPI.Ingame.Utilities;
|
||||
using VRage.Game.ObjectBuilders.Definitions;
|
||||
using VRage.Game.VisualScripting;
|
||||
using VRage.GameServices;
|
||||
using VRage.ObjectBuilders;
|
||||
|
||||
using VRageMath;
|
||||
|
||||
namespace IngameScript
|
||||
{
|
||||
partial class Program : MyGridProgram
|
||||
{
|
||||
enum State
|
||||
{
|
||||
IDLE,
|
||||
BUILD_COMPONENTS_MISSILES,
|
||||
}
|
||||
|
||||
State currentState = State.IDLE;
|
||||
|
||||
readonly IMyCubeGrid grid;
|
||||
|
||||
readonly Output output;
|
||||
|
||||
readonly Output leftPanel;
|
||||
readonly Output rightPanel;
|
||||
|
||||
readonly List<IMyAssembler> assemblers = new List<IMyAssembler>(); // First one is the main assembler.
|
||||
|
||||
readonly MissileManager missileManager;
|
||||
readonly AmmoManager ammoManager;
|
||||
|
||||
public Program()
|
||||
{
|
||||
this.grid = this.Me.CubeGrid;
|
||||
|
||||
var cockpitPilot = this.GridTerminalSystem.GetBlock<IMyCockpit>("[Mimine] Control Seat Main");
|
||||
var cockpitCopilot = this.GridTerminalSystem.GetBlock<IMyCockpit>("[Mimine] Control Seat Copilot");
|
||||
|
||||
var output = this.Me.GetSurface(0);
|
||||
this.output = new Output(output, Constants.CONSOLE_NB_LINES);
|
||||
|
||||
this.output.Print("Mimine system starting...");
|
||||
|
||||
this.leftPanel = new Output(new List<IMyTextSurface> { this.GridTerminalSystem.GetBlock<IMyTextPanel>("[Mimine] LCD Panel 01", this.grid), cockpitCopilot.GetSurface(1), cockpitPilot.GetSurface(1) });
|
||||
this.rightPanel = new Output(new List<IMyTextSurface> { this.GridTerminalSystem.GetBlock<IMyTextPanel>("[Mimine] LCD Panel 02", this.grid), cockpitCopilot.GetSurface(0), cockpitPilot.GetSurface(0) });
|
||||
|
||||
foreach (var assembler in this.GridTerminalSystem.GetBlocks<IMyAssembler>(grid: this.grid))
|
||||
{
|
||||
if (assembler.BlockDefinition.SubtypeName == "LargeAssembler")
|
||||
{
|
||||
if (assembler.CooperativeMode)
|
||||
this.assemblers.Add(assembler);
|
||||
else
|
||||
this.assemblers.Insert(0, assembler);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Not very useful to inform about ignored assemblers -> commented out.
|
||||
//this.output.Print($"Assembler Ignored, not a large assembler:");
|
||||
//this.output.Print($" {assembler.CustomName}");
|
||||
}
|
||||
}
|
||||
|
||||
if (this.assemblers.Count == 0)
|
||||
this.output.PrintError("No assembler found");
|
||||
else
|
||||
this.output.Print($"Main assembler: {this.assemblers[0].CustomName}");
|
||||
|
||||
this.missileManager = new MissileManager(this.GridTerminalSystem, this.grid, this.output, this.assemblers);
|
||||
this.ammoManager = new AmmoManager(this.GridTerminalSystem, this.grid, this.output, this.assemblers);
|
||||
|
||||
Runtime.UpdateFrequency = UpdateFrequency.Update100;
|
||||
}
|
||||
|
||||
public void Save()
|
||||
{
|
||||
}
|
||||
|
||||
public void Main(string argument, UpdateType updateSource)
|
||||
{
|
||||
if ((updateSource & UpdateType.Update100) != 0)
|
||||
{
|
||||
this.UpdateState();
|
||||
}
|
||||
else if ((updateSource & (UpdateType.Terminal | UpdateType.Trigger)) != 0)
|
||||
{
|
||||
switch (argument)
|
||||
{
|
||||
case "BUILD":
|
||||
this.currentState = State.BUILD_COMPONENTS_MISSILES;
|
||||
break;
|
||||
|
||||
case "STOP":
|
||||
this.currentState = State.IDLE;
|
||||
break;
|
||||
|
||||
default:
|
||||
this.output.Print($"Uknown command: {argument}");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateState()
|
||||
{
|
||||
var ammoStatus = this.ammoManager.GetAmmoStatus();
|
||||
|
||||
if (this.currentState == State.BUILD_COMPONENTS_MISSILES)
|
||||
{
|
||||
this.missileManager.BuildComponentForMissiles();
|
||||
this.ammoManager.BuildAmmo(ammoStatus);
|
||||
}
|
||||
|
||||
this.DisplayStatus();
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
this.missileManager.DisplayIngotsStatus(sb);
|
||||
sb.AppendLine(new string('-', Constants.CONSOLE_LINE_LENGTH));
|
||||
this.ammoManager.DisplayAmmoStatus(sb, ammoStatus);
|
||||
this.rightPanel.Display(sb.ToString());
|
||||
}
|
||||
|
||||
void DisplayStatus()
|
||||
{
|
||||
var cargoSpace = this.GetCargoSpace();
|
||||
var energyState = this.GetEnergyState();
|
||||
var hydrogenVolume = this.GetHydrogenVolume();
|
||||
var oxygenVolume = this.GetOxygenVolume();
|
||||
|
||||
this.leftPanel.Display(
|
||||
$@"
|
||||
{cargoSpace.ToString("Cargo volume", "kL")}
|
||||
|
||||
{energyState.ToString("Energy", "MWh")}
|
||||
|
||||
{hydrogenVolume.ToString("Hydrogen", "L")}
|
||||
|
||||
{oxygenVolume.ToString("Oxygen", "L")}"
|
||||
);
|
||||
}
|
||||
|
||||
struct Quantity
|
||||
{
|
||||
public Quantity(double current, double total)
|
||||
{
|
||||
this.Current = current;
|
||||
this.Total = total;
|
||||
}
|
||||
|
||||
public readonly double Current;
|
||||
public readonly double Total;
|
||||
|
||||
public string ToString(string name, string unit)
|
||||
{
|
||||
var firstLine = new StringBuilder();
|
||||
firstLine.Append(name).Append(": ");
|
||||
var values = $"{this.Current:N1} {unit} / {this.Total:N1} {unit}";
|
||||
firstLine.Append(values.PadLeft(Constants.CONSOLE_LINE_LENGTH - firstLine.Length));
|
||||
|
||||
var secondLine = new StringBuilder();
|
||||
secondLine.Append("[");
|
||||
var ratio = this.Current / this.Total;
|
||||
var percentStr = $"{ratio * 100.0,8:N1}%";
|
||||
// "-2" because of the starting and ending characters: '[', ']'.
|
||||
var gaugeSize = Constants.CONSOLE_LINE_LENGTH - percentStr.Length - 2;
|
||||
var n = (int)((double)gaugeSize * ratio);
|
||||
secondLine.Append(new string('|', n));
|
||||
secondLine.Append(new string(' ', gaugeSize - n)).Append("]");
|
||||
secondLine.Append(percentStr);
|
||||
|
||||
return $"{firstLine}\n{secondLine}";
|
||||
}
|
||||
}
|
||||
|
||||
Quantity GetCargoSpace()
|
||||
{
|
||||
var containers = this.GridTerminalSystem.GetBlocks<IMyCargoContainer>(grid: this.grid);
|
||||
|
||||
double currentVolume = 0;
|
||||
double totalVolume = 0;
|
||||
|
||||
foreach (var container in containers)
|
||||
{
|
||||
var inventory = container.GetInventory();
|
||||
currentVolume += (double)inventory.CurrentVolume;
|
||||
totalVolume += (double)inventory.MaxVolume;
|
||||
}
|
||||
|
||||
return new Quantity(currentVolume, totalVolume);
|
||||
}
|
||||
|
||||
Quantity GetEnergyState()
|
||||
{
|
||||
double currentkWh = 0;
|
||||
double maxkWh = 0;
|
||||
var batteries = this.GridTerminalSystem.GetBlocks<IMyBatteryBlock>(grid: this.grid);
|
||||
|
||||
foreach (var battery in batteries)
|
||||
{
|
||||
currentkWh += (double)battery.CurrentStoredPower;
|
||||
maxkWh += (double)battery.MaxStoredPower;
|
||||
}
|
||||
|
||||
return new Quantity(currentkWh, maxkWh);
|
||||
}
|
||||
|
||||
Quantity GetHydrogenVolume()
|
||||
{
|
||||
double currentVolume = 0;
|
||||
double totalVolume = 0;
|
||||
var tanks = this.GridTerminalSystem.GetBlocks<IMyGasTank>(grid: this.grid, filter: tank => tank.CustomName.Contains("Hydrogen"));
|
||||
|
||||
foreach (var tank in tanks)
|
||||
{
|
||||
currentVolume += (double)tank.Capacity * (double)tank.FilledRatio;
|
||||
totalVolume += (double)tank.Capacity;
|
||||
}
|
||||
|
||||
return new Quantity(currentVolume, totalVolume);
|
||||
}
|
||||
|
||||
Quantity GetOxygenVolume()
|
||||
{
|
||||
double currentVolume = 0;
|
||||
double totalVolume = 0;
|
||||
var tanks = this.GridTerminalSystem.GetBlocks<IMyGasTank>(grid: this.grid, filter: tank => tank.CustomName.Contains("Oxygen"));
|
||||
|
||||
foreach (var tank in tanks)
|
||||
{
|
||||
currentVolume += (double)tank.Capacity * (double)tank.FilledRatio;
|
||||
totalVolume += (double)tank.Capacity;
|
||||
}
|
||||
|
||||
return new Quantity(currentVolume, totalVolume);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
4
Mimine/packages.config
Normal file
4
Mimine/packages.config
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Mal.Mdk2.PbPackager" version="2.0.0-alpha073" targetFramework="net48" />
|
||||
</packages>
|
||||
Loading…
Add table
Add a link
Reference in a new issue