From 8611c6e597d1e22f7e118bc9c2a32402f6575e04 Mon Sep 17 00:00:00 2001 From: annabunches Date: Tue, 11 Feb 2025 21:43:23 -0500 Subject: [PATCH] Fix rotors and pistons getting stuck and breaking the sequence. --- ActionSequencer/Program.cs | 2 +- AirMonitor/AirZone.cs | 2 +- MechanicalDoor/Program.cs | 2 +- Mixins/Sequencer/SequenceableDoor.cs | 15 +++++-- Mixins/Sequencer/SequenceableFactory.cs | 8 ++-- Mixins/Sequencer/SequenceablePiston.cs | 58 +++++++++++++++++++++++++ Mixins/Sequencer/SequenceableRotor.cs | 29 ++++++------- SpaceEngineers.sln | 6 +++ 8 files changed, 95 insertions(+), 27 deletions(-) create mode 100644 Mixins/Sequencer/SequenceablePiston.cs diff --git a/ActionSequencer/Program.cs b/ActionSequencer/Program.cs index 372c48e..3ce704b 100644 --- a/ActionSequencer/Program.cs +++ b/ActionSequencer/Program.cs @@ -54,7 +54,7 @@ namespace IngameScript if (!_sequences.ContainsKey(id)) _sequences[id] = new Sequencer(this, id); - ISequenceable wrapped = SequenceableFactory.MakeSequenceable(block, Ini, id); + ISequenceable wrapped = SequenceableFactory.MakeSequenceable(this, block, "sequence"); if (wrapped == null) { Console.Print($"Skipping incompatible block '{block.CustomName}'."); diff --git a/AirMonitor/AirZone.cs b/AirMonitor/AirZone.cs index c916516..cf1521e 100644 --- a/AirMonitor/AirZone.cs +++ b/AirMonitor/AirZone.cs @@ -41,8 +41,8 @@ namespace IngameScript { _doors.Add(block as IMyDoor); SequenceableDoor wrapped = SequenceableFactory.MakeSequenceable( + _program, block as IMyDoor, - _program.Ini, "airMonitor") as SequenceableDoor; wrapped.Step = 0; wrapped.DeployOpen = false; diff --git a/MechanicalDoor/Program.cs b/MechanicalDoor/Program.cs index e85eebc..501b35f 100644 --- a/MechanicalDoor/Program.cs +++ b/MechanicalDoor/Program.cs @@ -31,7 +31,7 @@ namespace IngameScript } // Add the part; the Door object handles typing and sequencing. - ISequenceable wrapped = SequenceableFactory.MakeSequenceable(block, Ini, "mechDoor"); + ISequenceable wrapped = SequenceableFactory.MakeSequenceable(this, block, "mechDoor"); if (!(block is IMyShipMergeBlock)) wrapped.Step = 1; // TODO: actually support merge blocks here if (wrapped == null) { Console.Print($"Tried to add incompatible block '{block.CustomName}'"); continue; } _doors[doorName].AddBlock(wrapped); diff --git a/Mixins/Sequencer/SequenceableDoor.cs b/Mixins/Sequencer/SequenceableDoor.cs index 67f5e56..8a1e365 100644 --- a/Mixins/Sequencer/SequenceableDoor.cs +++ b/Mixins/Sequencer/SequenceableDoor.cs @@ -8,7 +8,7 @@ namespace IngameScript { public class SequenceableDoor : ISequenceable { - public bool Running { get; } + public bool Running { get; private set; } = false; public int Step { get; set; } public bool DeployOpen { get; set; } @@ -18,12 +18,13 @@ namespace IngameScript private IMyDoor _door; public SequenceableDoor( + Program _program, IMyDoor door, - MyIni ini, string sectionName) { _door = door; + MyIni ini = _program.Ini; ini.TryParse(door.CustomData); DeployOpen = ini.Get(sectionName, "deployOpen").ToBoolean(true); LockOpen = ini.Get(sectionName, "lockOpen").ToBoolean(true); @@ -33,6 +34,9 @@ namespace IngameScript public IEnumerator Run(bool deploy) { + if (Running) yield break; + Running = true; + if (deploy && DeployOpen || !deploy && !DeployOpen) { foreach (bool tick in _openDoor()) yield return true; @@ -41,6 +45,7 @@ namespace IngameScript { foreach (bool tick in _closeDoor()) yield return true; } + Running = false; } public IEnumerable _openDoor() @@ -48,7 +53,8 @@ namespace IngameScript _door.Enabled = true; _door.OpenDoor(); while (_door.Status != DoorStatus.Open) yield return true; - if (LockOpen) { + if (LockOpen) + { _door.Enabled = false; } } @@ -58,7 +64,8 @@ namespace IngameScript _door.Enabled = true; _door.CloseDoor(); while (_door.Status != DoorStatus.Closed) yield return true; - if (LockClosed) { + if (LockClosed) + { _door.Enabled = false; } } diff --git a/Mixins/Sequencer/SequenceableFactory.cs b/Mixins/Sequencer/SequenceableFactory.cs index 1a45e17..684b928 100644 --- a/Mixins/Sequencer/SequenceableFactory.cs +++ b/Mixins/Sequencer/SequenceableFactory.cs @@ -11,17 +11,17 @@ namespace IngameScript public class SequenceableFactory { public static ISequenceable MakeSequenceable( + Program program, IMyTerminalBlock block, - MyIni ini, string sectionName = "sequence") { if (block is IMyMotorStator) { - return new SequenceableRotor(block as IMyMotorStator, ini, sectionName); + return new SequenceableRotor(program, block as IMyMotorStator, sectionName); } if (block is IMyPistonBase) { - // return new SequenceablePiston(block as IMyPistonBase, step); + return new SequenceablePiston(program, block as IMyPistonBase, sectionName); } if (block is IMyShipMergeBlock) { @@ -29,7 +29,7 @@ namespace IngameScript } if (block is IMyDoor) { - return new SequenceableDoor(block as IMyDoor, ini, sectionName); + return new SequenceableDoor(program, block as IMyDoor, sectionName); } return null; } diff --git a/Mixins/Sequencer/SequenceablePiston.cs b/Mixins/Sequencer/SequenceablePiston.cs new file mode 100644 index 0000000..4336e33 --- /dev/null +++ b/Mixins/Sequencer/SequenceablePiston.cs @@ -0,0 +1,58 @@ +using Sandbox.ModAPI.Ingame; +using System; +using System.Collections.Generic; +using VRage.Game.ModAPI.Ingame.Utilities; + +namespace IngameScript +{ + partial class Program + { + public class SequenceablePiston : ISequenceable + { + public bool Running { get; private set; } = false; + public int Step { get; set; } + + private Program _program; + private IMyPistonBase _piston; + private float _deployPosition; + private float _stowPosition; + private float _velocity; + + public SequenceablePiston(Program program, IMyPistonBase piston, string sectionName) + { + _program = program; + _piston = piston; + + MyIni ini = _program.Ini; + ini.TryParse(piston.CustomData); + + _deployPosition = ini.Get(sectionName, "deployPosition").ToSingle(10F); + _stowPosition = ini.Get(sectionName, "stowPosition").ToSingle(0F); + _velocity = ini.Get(sectionName, "velocity").ToSingle(5F); + Step = ini.Get(sectionName, "step").ToInt32(0); + } + + public IEnumerator Run(bool deploy) + { + if (Running) yield break; + Running = true; + _program.Console.Print("DEBUG: Piston Starting"); + + float targetValue = _stowPosition; + float lastValue = -1; + if (deploy) targetValue = _deployPosition; + _piston.MoveToPosition(targetValue, _velocity); + + while (lastValue != _piston.CurrentPosition) +// Math.Abs(_piston.CurrentPosition - targetValue) > 0.01 || + { + lastValue = _piston.CurrentPosition; + _program.Console.Print(_piston.Status.ToString()); + yield return true; + } + + Running = false; + } + } + } +} \ No newline at end of file diff --git a/Mixins/Sequencer/SequenceableRotor.cs b/Mixins/Sequencer/SequenceableRotor.cs index f60cf1d..240da5a 100644 --- a/Mixins/Sequencer/SequenceableRotor.cs +++ b/Mixins/Sequencer/SequenceableRotor.cs @@ -12,6 +12,7 @@ namespace IngameScript public bool Running { get; private set; } = false; public int Step { get; set; } + private Program _program; private float _velocity; private float _deployAngle; private float _stowAngle; @@ -20,13 +21,16 @@ namespace IngameScript private MyRotationDirection _stowDirection; public SequenceableRotor( + Program program, IMyMotorStator rotor, - MyIni ini, string sectionName) { + _program = program; _rotor = rotor; + MyIni ini = _program.Ini; ini.TryParse(rotor.CustomData); + _deployAngle = ini.Get(sectionName, "deployAngle").ToSingle(90F); _stowAngle = ini.Get(sectionName, "stowAngle").ToSingle(0F); _velocity = ini.Get(sectionName, "velocity").ToSingle(5F); @@ -50,10 +54,15 @@ namespace IngameScript public IEnumerator Run(bool deploy = true) { - float _targetAngle = setup(deploy); + Running = true; + float degAngle = deploy ? _deployAngle : _stowAngle; + MyRotationDirection dir = deploy ? _deployDirection : _stowDirection; - float _lastAngle = _rotor.Angle; - while (Math.Abs(_rotor.Angle - _targetAngle) > 0.1 || _rotor.Angle != _lastAngle) + _rotor.RotorLock = false; + _rotor.RotateToAngle(dir, degAngle, _velocity); + + float _lastAngle = -1; + while (_rotor.Angle != _lastAngle) { _lastAngle = _rotor.Angle; yield return true; @@ -63,18 +72,6 @@ namespace IngameScript Running = false; } - private float setup(bool deploy = true) - { - float degAngle = deploy ? _deployAngle : _stowAngle; - MyRotationDirection dir = deploy ? _deployDirection : _stowDirection; - - _rotor.RotorLock = false; - _rotor.RotateToAngle(dir, degAngle, _velocity); - Running = true; - - return degToRad(degAngle); - } - private float degToRad(float degrees) { return degrees * ((float)Math.PI / 180F); diff --git a/SpaceEngineers.sln b/SpaceEngineers.sln index 2c4992d..8e8967d 100644 --- a/SpaceEngineers.sln +++ b/SpaceEngineers.sln @@ -11,6 +11,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ActionSequencer", "ActionSe EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AirMonitor", "AirMonitor\AirMonitor.csproj", "{40B352CD-100E-4F87-A7A0-FF00F4B8846C}" EndProject +Project("{8a3cdcc5-4b55-4d87-a415-698a0e1ff06f}") = "Sequencer", "Mixins\Sequencer\Sequencer.shproj", "{722a2146-2e38-477c-9587-55075b8fa0e6}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -36,5 +38,9 @@ Global {40B352CD-100E-4F87-A7A0-FF00F4B8846C}.Debug|Any CPU.Build.0 = Debug|x64 {40B352CD-100E-4F87-A7A0-FF00F4B8846C}.Release|Any CPU.ActiveCfg = Release|x64 {40B352CD-100E-4F87-A7A0-FF00F4B8846C}.Release|Any CPU.Build.0 = Release|x64 +# {722a2146-2e38-477c-9587-55075b8fa0e6}.Debug|Any CPU.ActiveCfg = Debug|x64 +# {722a2146-2e38-477c-9587-55075b8fa0e6}.Debug|Any CPU.Build.0 = Debug|x64 +# {722a2146-2e38-477c-9587-55075b8fa0e6}.Release|Any CPU.ActiveCfg = Release|x64 +# {722a2146-2e38-477c-9587-55075b8fa0e6}.Release|Any CPU.Build.0 = Release|x64 EndGlobalSection EndGlobal