260 lines
8.7 KiB
C#
260 lines
8.7 KiB
C#
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);
|
|
}
|
|
}
|
|
}
|
|
|