Add an air monitor script and necessary additions to the Sequencer.
This commit is contained in:
parent
85ce54ad1d
commit
1f33b7fbb4
28
AirMonitor/AirMonitor.csproj
Normal file
28
AirMonitor/AirMonitor.csproj
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
<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" />
|
||||||
|
<Import Project="..\Mixins\Sequencer\Sequencer.projitems" Label="shared" />
|
||||||
|
</Project>
|
22
AirMonitor/AirMonitor.mdk.ini
Normal file
22
AirMonitor/AirMonitor.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
AirMonitor/AirMonitor.mdk.local.ini
Normal file
7
AirMonitor/AirMonitor.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
|
22
AirMonitor/AirMonitor.sln
Normal file
22
AirMonitor/AirMonitor.sln
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio Version 17
|
||||||
|
VisualStudioVersion = 17.0.31903.59
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AirMonitor", "AirMonitor.csproj", "{DAD911E6-670F-4AA0-8F00-5D239BC5F732}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Release|Any CPU = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{DAD911E6-670F-4AA0-8F00-5D239BC5F732}.Debug|Any CPU.ActiveCfg = Debug|x64
|
||||||
|
{DAD911E6-670F-4AA0-8F00-5D239BC5F732}.Debug|Any CPU.Build.0 = Debug|x64
|
||||||
|
{DAD911E6-670F-4AA0-8F00-5D239BC5F732}.Release|Any CPU.ActiveCfg = Release|x64
|
||||||
|
{DAD911E6-670F-4AA0-8F00-5D239BC5F732}.Release|Any CPU.Build.0 = Release|x64
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
73
AirMonitor/AirZone.cs
Normal file
73
AirMonitor/AirZone.cs
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
using Sandbox.ModAPI.Ingame;
|
||||||
|
using SpaceEngineers.Game.ModAPI.Ingame;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using VRage.Game.ModAPI.Ingame.Utilities;
|
||||||
|
|
||||||
|
namespace IngameScript {
|
||||||
|
partial class Program {
|
||||||
|
public class AirZone
|
||||||
|
{
|
||||||
|
public bool Triggered = false;
|
||||||
|
|
||||||
|
private MyIni _ini;
|
||||||
|
private List<IMyAirVent> _vents;
|
||||||
|
private PrefixedConsole _console;
|
||||||
|
private Sequencer _sequencer;
|
||||||
|
private const float TriggerLevel = 0.75F;
|
||||||
|
|
||||||
|
public AirZone(string zoneName, MyIni ini, IConsole console)
|
||||||
|
{
|
||||||
|
_ini = ini;
|
||||||
|
_console = new PrefixedConsole(console, zoneName);
|
||||||
|
_sequencer = new Sequencer(zoneName, _console);
|
||||||
|
_vents = new List<IMyAirVent>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddBlock(IMyTerminalBlock block)
|
||||||
|
{
|
||||||
|
if (block is IMyAirVent)
|
||||||
|
{
|
||||||
|
_vents.Add(block as IMyAirVent);
|
||||||
|
} else if (block is IMyDoor) {
|
||||||
|
SequenceableDoor wrapped = SequenceableFactory.MakeSequenceable(block as IMyDoor, _ini, "") as SequenceableDoor;
|
||||||
|
wrapped.Step = 0;
|
||||||
|
wrapped.DeployOpen = false;
|
||||||
|
wrapped.LockOpen = false;
|
||||||
|
wrapped.LockClosed = true;
|
||||||
|
_sequencer.AddBlock(wrapped);
|
||||||
|
} else {
|
||||||
|
_console.Print("Tried to add incompatible block '{block.CustomName}'");
|
||||||
|
}
|
||||||
|
// TODO: support for arbitrary (sub-)sequences here could be powerful
|
||||||
|
}
|
||||||
|
|
||||||
|
// This enumerator should run forever.
|
||||||
|
public IEnumerator<bool> Monitor()
|
||||||
|
{
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
foreach (IMyAirVent vent in _vents)
|
||||||
|
{
|
||||||
|
if (vent.GetOxygenLevel() < TriggerLevel) Triggered = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Triggered == true)
|
||||||
|
{
|
||||||
|
// close the doors
|
||||||
|
IEnumerator<bool> job = _sequencer.RunSequence(true);
|
||||||
|
while (job.MoveNext()) yield return true;
|
||||||
|
|
||||||
|
// noop until manually reset
|
||||||
|
while (Triggered) yield return true;
|
||||||
|
|
||||||
|
// open the doors
|
||||||
|
job = _sequencer.RunSequence(false);
|
||||||
|
while (job.MoveNext()) yield return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
yield return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
5
AirMonitor/Instructions.readme
Normal file
5
AirMonitor/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.
|
96
AirMonitor/Program.cs
Normal file
96
AirMonitor/Program.cs
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
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.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 VRageMath;
|
||||||
|
|
||||||
|
namespace IngameScript
|
||||||
|
{
|
||||||
|
public partial class Program : MyGridProgram
|
||||||
|
{
|
||||||
|
private MyIni _ini;
|
||||||
|
private Console _console;
|
||||||
|
private MyCommandLine _cli;
|
||||||
|
private Dictionary<string, AirZone> _zones;
|
||||||
|
private List<IEnumerator<bool>> _jobs;
|
||||||
|
|
||||||
|
public Program()
|
||||||
|
{
|
||||||
|
_cli = new MyCommandLine();
|
||||||
|
_ini = new MyIni();
|
||||||
|
_console = new Console(this, _ini);
|
||||||
|
_zones = new Dictionary<string, AirZone>();
|
||||||
|
_jobs = new List<IEnumerator<bool>>();
|
||||||
|
|
||||||
|
// Find all tagged objects and build out zones
|
||||||
|
List<IMyTerminalBlock> blocks = new List<IMyTerminalBlock>();
|
||||||
|
GridTerminalSystem.GetBlocksOfType(blocks, block => MyIni.HasSection(block.CustomData, "airMonitor"));
|
||||||
|
foreach (IMyTerminalBlock block in blocks)
|
||||||
|
{
|
||||||
|
_ini.TryParse(block.CustomData);
|
||||||
|
string[] zones = new string[] { };
|
||||||
|
if (_ini.Get("airMonitor", "zones").ToString() != "")
|
||||||
|
{
|
||||||
|
zones = _ini.Get("airMonitor", "zones").ToString().Split(',');
|
||||||
|
}
|
||||||
|
else if (_ini.Get("airMonitor", "zone").ToString() != "")
|
||||||
|
{
|
||||||
|
zones = new string[] { _ini.Get("airMonitor", "zone").ToString() };
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (string zone in zones)
|
||||||
|
{
|
||||||
|
if (!_zones.ContainsKey(zone))
|
||||||
|
{
|
||||||
|
_zones[zone] = new AirZone(zone, _ini, _console);
|
||||||
|
}
|
||||||
|
_zones[zone].AddBlock(block);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (AirZone zone in _zones.Values)
|
||||||
|
{
|
||||||
|
_jobs.Add(zone.Monitor());
|
||||||
|
}
|
||||||
|
Runtime.UpdateFrequency |= UpdateFrequency.Update100;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Main(string argument, UpdateType updateSource)
|
||||||
|
{
|
||||||
|
if (argument != "")
|
||||||
|
{
|
||||||
|
_cli.TryParse(argument);
|
||||||
|
if (_cli.Switch("reset"))
|
||||||
|
{
|
||||||
|
for (int i = 0; i < _cli.ArgumentCount; i++)
|
||||||
|
{
|
||||||
|
if (_zones.ContainsKey(_cli.Argument(i)))
|
||||||
|
{
|
||||||
|
_zones[_cli.Argument(i)].Triggered = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (IEnumerator job in _jobs)
|
||||||
|
{
|
||||||
|
if (job.MoveNext()) continue;
|
||||||
|
_console.Print("WARNING: Monitoring job exited. Zone no longer being monitored.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
BIN
AirMonitor/thumb.png
Normal file
BIN
AirMonitor/thumb.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 389 KiB |
66
Mixins/Sequencer/SequenceableDoor.cs
Normal file
66
Mixins/Sequencer/SequenceableDoor.cs
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
using Sandbox.ModAPI.Ingame;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using VRage.Game.ModAPI.Ingame.Utilities;
|
||||||
|
|
||||||
|
namespace IngameScript
|
||||||
|
{
|
||||||
|
partial class Program
|
||||||
|
{
|
||||||
|
public class SequenceableDoor : ISequenceable
|
||||||
|
{
|
||||||
|
public bool Running { get; }
|
||||||
|
public int Step { get; set; }
|
||||||
|
|
||||||
|
private IMyDoor _door;
|
||||||
|
public bool DeployOpen { get; set; }
|
||||||
|
public bool LockOpen { get; set; }
|
||||||
|
public bool LockClosed { get; set; }
|
||||||
|
|
||||||
|
public SequenceableDoor(
|
||||||
|
IMyDoor door,
|
||||||
|
MyIni ini,
|
||||||
|
string sectionName)
|
||||||
|
{
|
||||||
|
_door = door;
|
||||||
|
|
||||||
|
ini.TryParse(door.CustomData);
|
||||||
|
DeployOpen = ini.Get(sectionName, "deployOpen").ToBoolean(true);
|
||||||
|
LockOpen = ini.Get(sectionName, "lockOpen").ToBoolean(true);
|
||||||
|
LockClosed = ini.Get(sectionName, "lockClosed").ToBoolean(true);
|
||||||
|
Step = ini.Get(sectionName, "step").ToInt32(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerator<bool> Run(bool deploy)
|
||||||
|
{
|
||||||
|
if (deploy && DeployOpen || !deploy && !DeployOpen)
|
||||||
|
{
|
||||||
|
foreach (bool tick in _openDoor()) yield return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
foreach (bool tick in _closeDoor()) yield return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<bool> _openDoor()
|
||||||
|
{
|
||||||
|
_door.Enabled = true;
|
||||||
|
_door.OpenDoor();
|
||||||
|
while (_door.Status != DoorStatus.Open) yield return true;
|
||||||
|
if (LockOpen) {
|
||||||
|
_door.Enabled = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<bool> _closeDoor()
|
||||||
|
{
|
||||||
|
_door.Enabled = true;
|
||||||
|
_door.CloseDoor();
|
||||||
|
while (_door.Status != DoorStatus.Closed) yield return true;
|
||||||
|
if (LockClosed) {
|
||||||
|
_door.Enabled = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -27,6 +27,10 @@ namespace IngameScript
|
||||||
{
|
{
|
||||||
// return new SequenceableMergeBlock(block as IMyShipMergeBlock, step);
|
// return new SequenceableMergeBlock(block as IMyShipMergeBlock, step);
|
||||||
}
|
}
|
||||||
|
if (block is IMyDoor)
|
||||||
|
{
|
||||||
|
return new SequenceableDoor(block as IMyDoor, ini, sectionName);
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user