131 lines
3.8 KiB
C#
131 lines
3.8 KiB
C#
// Script for opening maintence panels on a ship.
|
|
//
|
|
// Currently this simply opens and closes *all* of the panels attached to hinges
|
|
// whose names start with "Maintenance". Default behavior is to open.
|
|
// Pass the argument -close to close the panels.
|
|
//
|
|
// By default "open" is assumed to be 90 degrees and "closed" is assumed to be 0 degrees.
|
|
// Each hinge can have its behavior configured via custom data. A sample config
|
|
// (with the default values):
|
|
//
|
|
// OpenAngle=90
|
|
// ClosedAngle=0
|
|
// Velocity=5
|
|
|
|
|
|
MyCommandLine cli;
|
|
IEnumerator<bool> state;
|
|
List<Panel> panels;
|
|
|
|
public class Panel {
|
|
public Panel(IMyMotorStator hinge) {
|
|
Hinge = hinge;
|
|
ParseConfig();
|
|
}
|
|
|
|
public void OpenPanel() {
|
|
Hinge.RotorLock = false;
|
|
TargetAngle = OpenAngle;
|
|
Hinge.RotateToAngle(MyRotationDirection.AUTO, TargetAngle, Velocity);
|
|
}
|
|
|
|
public void ClosePanel() {
|
|
Hinge.RotorLock = false;
|
|
TargetAngle = ClosedAngle;
|
|
Hinge.RotateToAngle(MyRotationDirection.AUTO, TargetAngle, Velocity);
|
|
}
|
|
|
|
// Call this function every tick after OpenPanel or ClosePanel.
|
|
// It will return true when the panel has finished moving.
|
|
public bool Monitor() {
|
|
if (Math.Abs(Hinge.Angle - TargetAngle) < 0.01) {
|
|
Hinge.RotorLock = true;
|
|
}
|
|
return Hinge.RotorLock;
|
|
}
|
|
|
|
private IMyMotorStator Hinge { get; set; }
|
|
private float TargetAngle { get; set; }
|
|
private float OpenAngle { get; set; } = 90F;
|
|
private float ClosedAngle { get; set; } = 0F;
|
|
private float Velocity { get; set; } = 5F;
|
|
|
|
private void ParseConfig() {
|
|
string[] lines = Hinge.CustomData.Split('\n');
|
|
foreach (string line in lines) {
|
|
string[] tokens = line.Split('=');
|
|
if (tokens.Length != 2) continue;
|
|
switch(tokens[0]) {
|
|
case "OpenAngle":
|
|
OpenAngle = float.Parse(tokens[1]);
|
|
break;
|
|
case "ClosedAngle":
|
|
ClosedAngle = float.Parse(tokens[1]);
|
|
break;
|
|
case "Velocity":
|
|
Velocity = float.Parse(tokens[1]);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public Program() {
|
|
cli = new MyCommandLine();
|
|
state = null;
|
|
|
|
panels = new List<Panel>();
|
|
List<IMyMotorStator> allHinges = new List<IMyMotorStator>();
|
|
foreach(IMyMotorStator hinge in allHinges) {
|
|
if (hinge.CustomName.StartsWith("Maintenance")) {
|
|
panels.Add(new Panel(hinge));
|
|
}
|
|
}
|
|
|
|
Echo($"Found {panels.Length} panels.");
|
|
}
|
|
|
|
public void Main(string argument, UpdateType updateSource) {
|
|
if (state == null) {
|
|
cli.TryParse(argument);
|
|
if (cli.Switch("close")) state = ClosePanels();
|
|
else state = OpenPanels();
|
|
Runtime.UpdateFrequency = UpdateFrequency.Update1;
|
|
return;
|
|
}
|
|
|
|
if (!state.MoveNext()) {
|
|
state.Dispose();
|
|
state = null;
|
|
Runtime.UpdateFrequency = UpdateFrequency.None;
|
|
}
|
|
}
|
|
|
|
private IEnumerator<bool> OpenPanels() {
|
|
Echo("Opening panels.");
|
|
foreach (Panel panel in panels) {
|
|
panel.OpenPanel();
|
|
}
|
|
return MonitorPanels();
|
|
}
|
|
|
|
private IEnumerator<bool> ClosePanels() {
|
|
Echo("Closing panels.");
|
|
foreach (Panel panel in panels) {
|
|
panel.ClosePanel();
|
|
}
|
|
return MonitorPanels();
|
|
}
|
|
|
|
private IEnumerator<bool> MonitorPanels() {
|
|
while (true) {
|
|
Echo("Monitoring panels.");
|
|
bool done = true; // assume we've finished, then falsify it below
|
|
foreach (Panel panel in panels) {
|
|
if (!panel.Monitor()) done = false;
|
|
}
|
|
if (done) yield break;
|
|
yield return true;
|
|
}
|
|
}
|