First stab (currently untested) for a dock loading/unloading script.
This commit is contained in:
parent
e739b4e64d
commit
3727cf8f20
118
DockLoader/Dock.cs
Normal file
118
DockLoader/Dock.cs
Normal file
|
@ -0,0 +1,118 @@
|
|||
using Sandbox.ModAPI.Ingame;
|
||||
using SpaceEngineers.Game.ModAPI.Ingame;
|
||||
using System.Collections.Generic;
|
||||
using VRage.Game.ModAPI.Ingame.Utilities;
|
||||
|
||||
namespace IngameScript
|
||||
{
|
||||
partial class Program
|
||||
{
|
||||
// We don't really do anything with the modes other than Loading right now,
|
||||
// but they are nice for consistency.
|
||||
// TODO: we could have displays that print the current mode...
|
||||
public enum DockMode
|
||||
{
|
||||
Loading,
|
||||
Unloading,
|
||||
Off,
|
||||
}
|
||||
|
||||
public class Dock
|
||||
{
|
||||
public string Id { get; private set; }
|
||||
public DockMode Mode { get; private set; } = DockMode.Off;
|
||||
|
||||
public bool Functional
|
||||
{
|
||||
get
|
||||
{
|
||||
return _ports.Count > 0 && _inputSorter != null && _outputSorter != null;
|
||||
}
|
||||
}
|
||||
|
||||
private IMyConveyorSorter _inputSorter;
|
||||
private IMyConveyorSorter _outputSorter;
|
||||
private List<IMyShipConnector> _ports = new List<IMyShipConnector>();
|
||||
private bool _wasDocked = false; // Records whether a ship was docked last time we checked for one.
|
||||
private IConsole _console;
|
||||
|
||||
public Dock(string id, IConsole console)
|
||||
{
|
||||
Id = id;
|
||||
_console = new PrefixedConsole(console, id);
|
||||
}
|
||||
|
||||
// Check and update the state of the Dock.
|
||||
// In particular, this checks whether a ship has undocked since our last check,
|
||||
// and if so it turns off the loading/unloading mechanism and releases the lock.
|
||||
public void Update()
|
||||
{
|
||||
bool isDocked = false;
|
||||
foreach (IMyShipConnector port in _ports)
|
||||
{
|
||||
if (port.IsConnected)
|
||||
{
|
||||
isDocked = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (_wasDocked && !isDocked) Reset();
|
||||
|
||||
_wasDocked = isDocked;
|
||||
}
|
||||
|
||||
|
||||
public void StartLoading()
|
||||
{
|
||||
Mode = DockMode.Loading;
|
||||
_outputSorter.Enabled = false;
|
||||
_inputSorter.Enabled = true;
|
||||
}
|
||||
|
||||
public void StartUnloading()
|
||||
{
|
||||
Mode = DockMode.Unloading;
|
||||
_inputSorter.Enabled = false;
|
||||
_outputSorter.Enabled = true;
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
Mode = DockMode.Off;
|
||||
_inputSorter.Enabled = false;
|
||||
_outputSorter.Enabled = false;
|
||||
}
|
||||
|
||||
public void AddBlock(IMyTerminalBlock block, MyIni ini)
|
||||
{
|
||||
if (block is IMyConveyorSorter)
|
||||
{
|
||||
string direction = ini.Get("dockLoader", "direction").ToString();
|
||||
switch (direction)
|
||||
{
|
||||
case "input":
|
||||
_inputSorter = block as IMyConveyorSorter;
|
||||
_inputSorter.Enabled = false;
|
||||
break;
|
||||
case "output":
|
||||
_outputSorter = block as IMyConveyorSorter;
|
||||
_outputSorter.Enabled = false;
|
||||
break;
|
||||
default:
|
||||
_console.Print($"Invalid direction for '{block.CustomName}'");
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (block is IMyShipConnector)
|
||||
{
|
||||
_ports.Add(block as IMyShipConnector);
|
||||
}
|
||||
else
|
||||
{
|
||||
_console.Print($"Can't add block '{block.CustomName}'");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
27
DockLoader/DockLoader.csproj
Normal file
27
DockLoader/DockLoader.csproj
Normal file
|
@ -0,0 +1,27 @@
|
|||
<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.11">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Mal.Mdk2.PbPackager" Version="2.1.1">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Mal.Mdk2.References" Version="2.2.4" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Remove="Instructions.readme" />
|
||||
<AdditionalFiles Include="Instructions.readme" />
|
||||
<AdditionalFiles Include="thumb.png" />
|
||||
</ItemGroup>
|
||||
<Import Project="..\Mixins\Console\Console.projitems" Label="shared" />
|
||||
</Project>
|
22
DockLoader/DockLoader.mdk.ini
Normal file
22
DockLoader/DockLoader.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
DockLoader/DockLoader.mdk.local.ini
Normal file
7
DockLoader/DockLoader.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
|
5
DockLoader/Instructions.readme
Normal file
5
DockLoader/Instructions.readme
Normal file
|
@ -0,0 +1,5 @@
|
|||
R e a d m e
|
||||
-----------
|
||||
|
||||
In this file you can include any instructions or other comments you want to have injected onto the
|
||||
top of your final script. You can safely delete this file if you do not want any such comments.
|
124
DockLoader/Program.cs
Normal file
124
DockLoader/Program.cs
Normal file
|
@ -0,0 +1,124 @@
|
|||
using System.Collections.Generic;
|
||||
using Sandbox.ModAPI.Ingame;
|
||||
using VRage.Game.ModAPI.Ingame.Utilities;
|
||||
using System.Linq;
|
||||
|
||||
namespace IngameScript
|
||||
{
|
||||
public partial class Program : MyGridProgram, IConsoleProgram
|
||||
{
|
||||
public MyIni Ini { get; private set; }
|
||||
public IConsole Console { get; private set; }
|
||||
|
||||
private MyCommandLine _cli = new MyCommandLine();
|
||||
private Warehouse _warehouse;
|
||||
private Dictionary<string, Dock> _docks = new Dictionary<string, Dock>();
|
||||
|
||||
public Program()
|
||||
{
|
||||
Ini = new MyIni();
|
||||
Console = new MainConsole(this, "Dock Loader");
|
||||
_warehouse = new Warehouse(Console);
|
||||
|
||||
// Find all the blocks with a [dockLoader] config
|
||||
List<IMyTerminalBlock> blocks = new List<IMyTerminalBlock>();
|
||||
GridTerminalSystem.GetBlocksOfType(blocks, blockFilter);
|
||||
foreach (IMyTerminalBlock block in blocks)
|
||||
{
|
||||
Ini.TryParse(block.CustomData);
|
||||
if (Ini.Get("dockLoader", "warehouse").ToBoolean(false)) _warehouse.AddBlock(block, Ini);
|
||||
else
|
||||
{
|
||||
string id = Ini.Get("dockLoader", "id").ToString();
|
||||
if (id == "")
|
||||
{
|
||||
Console.Print($"Ignoring invalid block '{block.CustomName}'");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!_docks.ContainsKey(id)) _docks[id] = new Dock(id, Console);
|
||||
_docks[id].AddBlock(block, Ini);
|
||||
}
|
||||
}
|
||||
|
||||
// Remove any non-functional docks.
|
||||
foreach (Dock dock in _docks.Values.ToList())
|
||||
{
|
||||
if (!dock.Functional)
|
||||
{
|
||||
Console.Print($"Dock '{dock.Id}' not fully configured, ignoring.");
|
||||
_docks.Remove(dock.Id);
|
||||
}
|
||||
}
|
||||
|
||||
Console.Print($"Found {_docks.Count} docks to manage.");
|
||||
|
||||
Runtime.UpdateFrequency |= UpdateFrequency.Update100;
|
||||
}
|
||||
|
||||
public void Main(string argument, UpdateType updateSource)
|
||||
{
|
||||
handleInput(argument);
|
||||
|
||||
// Check on loading state
|
||||
int loadingCount = 0;
|
||||
bool timeout = _warehouse.Timeout;
|
||||
foreach (Dock dock in _docks.Values)
|
||||
{
|
||||
dock.Update();
|
||||
if (dock.Mode == DockMode.Loading)
|
||||
{
|
||||
if (timeout) dock.Reset();
|
||||
else loadingCount++;
|
||||
}
|
||||
}
|
||||
|
||||
// This will decrement any loading timer, and switch to unloading mode when we do timeout.
|
||||
// It will also switch to unloading mode if we pass it a 0.
|
||||
if (updateSource.HasFlag(UpdateType.Update100)) _warehouse.Update(loadingCount);
|
||||
}
|
||||
|
||||
private bool blockFilter(IMyTerminalBlock block)
|
||||
{
|
||||
return block.IsSameConstructAs(this.Me) && MyIni.HasSection(block.CustomData, "dockLoader");
|
||||
}
|
||||
|
||||
private void handleInput(string argument)
|
||||
{
|
||||
if (argument == "") return;
|
||||
_cli.TryParse(argument);
|
||||
if (_cli.ArgumentCount != 2)
|
||||
{
|
||||
Console.Print("Must call script with exactly 2 arguments.");
|
||||
return;
|
||||
}
|
||||
|
||||
string command = _cli.Argument(0).Trim().ToLower();
|
||||
string dockId = _cli.Argument(1).Trim().ToLower();
|
||||
|
||||
if (!_docks.ContainsKey(dockId))
|
||||
{
|
||||
Console.Print($"Unknown dock '{dockId}'");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (command)
|
||||
{
|
||||
case "load":
|
||||
_docks[dockId].StartLoading();
|
||||
_warehouse.StartLoading();
|
||||
break;
|
||||
case "unload":
|
||||
_docks[dockId].StartUnloading();
|
||||
break;
|
||||
case "reset":
|
||||
_docks[dockId].Reset();
|
||||
break;
|
||||
default:
|
||||
Console.Print($"Unknown command '{command}'");
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
72
DockLoader/Warehouse.cs
Normal file
72
DockLoader/Warehouse.cs
Normal file
|
@ -0,0 +1,72 @@
|
|||
using Sandbox.ModAPI.Ingame;
|
||||
using VRage.Game.ModAPI.Ingame.Utilities;
|
||||
|
||||
namespace IngameScript
|
||||
{
|
||||
partial class Program
|
||||
{
|
||||
public class Warehouse
|
||||
{
|
||||
public bool Timeout
|
||||
{
|
||||
get
|
||||
{
|
||||
return _timeoutTicks == 0;
|
||||
}
|
||||
}
|
||||
|
||||
private IMyConveyorSorter _inputSorter;
|
||||
private IMyConveyorSorter _outputSorter;
|
||||
private IConsole _console;
|
||||
private uint _timeoutTicks = 0;
|
||||
|
||||
public Warehouse(IConsole console)
|
||||
{
|
||||
_console = new PrefixedConsole(console, "warehouse");
|
||||
}
|
||||
|
||||
public void Update(int loadingCount)
|
||||
{
|
||||
if (_timeoutTicks > 0)
|
||||
{
|
||||
_timeoutTicks--;
|
||||
if (_timeoutTicks == 0 || loadingCount == 0)
|
||||
{
|
||||
_timeoutTicks = 0;
|
||||
_outputSorter.Enabled = false;
|
||||
_inputSorter.Enabled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// A dock has requested loading
|
||||
public void StartLoading()
|
||||
{
|
||||
_inputSorter.Enabled = false;
|
||||
_outputSorter.Enabled = true;
|
||||
_timeoutTicks = 75; // This is approximately 2 minutes.
|
||||
}
|
||||
|
||||
public void AddBlock(IMyTerminalBlock block, MyIni ini)
|
||||
{
|
||||
if (!(block is IMyConveyorSorter))
|
||||
{
|
||||
_console.Print($"Ignoring incompatible block '{block.CustomName}'");
|
||||
return;
|
||||
}
|
||||
switch (ini.Get("dockLoader", "direction").ToString())
|
||||
{
|
||||
case "input":
|
||||
_inputSorter = block as IMyConveyorSorter;
|
||||
break;
|
||||
case "output":
|
||||
_outputSorter = block as IMyConveyorSorter;
|
||||
break;
|
||||
default:
|
||||
_console.Print($"Invalid direction for '{block.CustomName}'");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
BIN
DockLoader/thumb.png
Normal file
BIN
DockLoader/thumb.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 389 KiB |
35
ScriptTemplate.cs
Normal file
35
ScriptTemplate.cs
Normal file
|
@ -0,0 +1,35 @@
|
|||
using Sandbox.ModAPI.Ingame;
|
||||
using VRage.Game.ModAPI.Ingame.Utilities;
|
||||
|
||||
namespace IngameScript
|
||||
{
|
||||
public partial class Program : MyGridProgram, IConsoleProgram
|
||||
{
|
||||
public MyIni Ini { get; private set; }
|
||||
public IConsole Console { get; private set; }
|
||||
|
||||
private MyCommandLine _cli = new MyCommandLine();
|
||||
|
||||
public Program()
|
||||
{
|
||||
Ini = new MyIni();
|
||||
Console = new MainConsole(this, "Program Name");
|
||||
}
|
||||
|
||||
public void Main(string argument, UpdateType updateSource)
|
||||
{
|
||||
handleInput(argument);
|
||||
}
|
||||
|
||||
private bool blockFilter(IMyTerminalBlock block)
|
||||
{
|
||||
return block.IsSameConstructAs(this.Me);
|
||||
}
|
||||
|
||||
private void handleInput(string argument)
|
||||
{
|
||||
if (argument == "") return;
|
||||
_cli.TryParse(argument);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -17,6 +17,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DockingController", "Dockin
|
|||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InfoDisplays", "InfoDisplays\InfoDisplays.csproj", "{4C7C8B10-1E43-453E-A9DA-A3626FE85ACC}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DockLoader", "DockLoader\DockLoader.csproj", "{A4D9F936-93B2-423A-BD76-A97A084BD605}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
@ -43,6 +45,10 @@ Global
|
|||
{4C7C8B10-1E43-453E-A9DA-A3626FE85ACC}.Debug|Any CPU.Build.0 = Debug|x64
|
||||
{4C7C8B10-1E43-453E-A9DA-A3626FE85ACC}.Release|Any CPU.ActiveCfg = Release|x64
|
||||
{4C7C8B10-1E43-453E-A9DA-A3626FE85ACC}.Release|Any CPU.Build.0 = Release|x64
|
||||
{A4D9F936-93B2-423A-BD76-A97A084BD605}.Debug|Any CPU.ActiveCfg = Debug|x64
|
||||
{A4D9F936-93B2-423A-BD76-A97A084BD605}.Debug|Any CPU.Build.0 = Debug|x64
|
||||
{A4D9F936-93B2-423A-BD76-A97A084BD605}.Release|Any CPU.ActiveCfg = Release|x64
|
||||
{A4D9F936-93B2-423A-BD76-A97A084BD605}.Release|Any CPU.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
113
docking.cs
113
docking.cs
|
@ -1,113 +0,0 @@
|
|||
// Docking controller script; handles docking and undocking.
|
||||
// Specifically, when you activate the script it will:
|
||||
// * Connect any Connectors whose names start with "Docking Port" that are ready to connect.
|
||||
// * Turn off all engines.
|
||||
// * Set all O2 and Hydrogen tanks to Stockpile.
|
||||
//
|
||||
// Recharging batteries needs to be done manually, since the script can't finish with the
|
||||
// batteries disabled.
|
||||
//
|
||||
// When you activate the script with "-undock" it will reverse all of these actions.
|
||||
//
|
||||
// TODO: None of the below switches work yet.
|
||||
// You can selectively disable some functionality with switches.
|
||||
// * "-no-refuel" to disable refueling
|
||||
|
||||
MyCommandLine cli;
|
||||
IEnumerator<bool> state;
|
||||
|
||||
List<IMyShipConnector> dockingPorts;
|
||||
List<IMyThrust> thrusters;
|
||||
List<IMyGasTank> tanks;
|
||||
|
||||
public Program() {
|
||||
cli = new MyCommandLine();
|
||||
state = null;
|
||||
|
||||
dockingPorts = new List<IMyShipConnector>();
|
||||
List<IMyShipConnector> allConnectors = new List<IMyShipConnector>();
|
||||
GridTerminalSystem.GetBlocksOfType(allConnectors);
|
||||
foreach(IMyShipConnector connector in allConnectors) {
|
||||
if (connector.CustomName.StartsWith("Docking Port")) {
|
||||
dockingPorts.Add(connector);
|
||||
}
|
||||
}
|
||||
|
||||
thrusters = new List<IMyThrust>();
|
||||
GridTerminalSystem.GetBlocksOfType(thrusters);
|
||||
|
||||
tanks = new List<IMyGasTank>();
|
||||
GridTerminalSystem.GetBlocksOfType(tanks);
|
||||
|
||||
Echo($"Found {dockingPorts.Count} docking ports.");
|
||||
Echo($"Found {thrusters.Count} thrusters");
|
||||
Echo($"Found {tanks.Count} tanks");
|
||||
}
|
||||
|
||||
public void Main(string argument, UpdateType updateSource) {
|
||||
if (state == null) {
|
||||
cli.TryParse(argument);
|
||||
if (cli.Switch("undock")) state = Undock();
|
||||
else state = Dock();
|
||||
Runtime.UpdateFrequency = UpdateFrequency.Update100;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!state.MoveNext()) {
|
||||
Runtime.UpdateFrequency = UpdateFrequency.None;
|
||||
state.Dispose();
|
||||
state = null;
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerator<bool> Dock() {
|
||||
Echo("Initiating docking operation.");
|
||||
|
||||
foreach (IMyShipConnector dockingPort in dockingPorts) {
|
||||
if (dockingPort.Status == MyShipConnectorStatus.Connectable) {
|
||||
dockingPort.Connect();
|
||||
}
|
||||
}
|
||||
|
||||
bool docked = false;
|
||||
while (!docked) {
|
||||
yield return true;
|
||||
foreach (IMyShipConnector dockingPort in dockingPorts) {
|
||||
if (dockingPort.Status == MyShipConnectorStatus.Connected) {
|
||||
docked = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Echo("Docking clamp engaged. Shutting down systems.");
|
||||
|
||||
foreach (IMyThrust thruster in thrusters) {
|
||||
thruster.Enabled = false;
|
||||
}
|
||||
|
||||
foreach (IMyGasTank tank in tanks) {
|
||||
tank.Stockpile = true;
|
||||
}
|
||||
|
||||
yield return false;
|
||||
}
|
||||
|
||||
private IEnumerator<bool> Undock() {
|
||||
Echo("Initiating undocking operation.");
|
||||
foreach (IMyGasTank tank in tanks) {
|
||||
tank.Stockpile = false;
|
||||
}
|
||||
|
||||
foreach (IMyThrust thruster in thrusters) {
|
||||
thruster.Enabled = true;
|
||||
}
|
||||
|
||||
foreach (IMyShipConnector dockingPort in dockingPorts) {
|
||||
if (dockingPort.Status == MyShipConnectorStatus.Connected) {
|
||||
dockingPort.Disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
yield return false;
|
||||
}
|
Loading…
Reference in New Issue
Block a user