using Sandbox.ModAPI.Ingame; using System.Collections.Generic; using System; namespace IngameScript { public class DoorHinge { public DoorHinge(IMyMotorStator hinge) { Hinge = hinge; } // For these two functions, IMyMotorStator.Angle reports radians, but // IMyMotorStator.RotateToAngle() expects degrees... public void OpenDoorHinge() { Hinge.RotorLock = false; TargetAngle = DegToRad(OpenAngle); Hinge.RotateToAngle(MyRotationDirection.AUTO, OpenAngle, Velocity); } public void CloseDoorHinge() { Hinge.RotorLock = false; TargetAngle = DegToRad(ClosedAngle); Hinge.RotateToAngle(MyRotationDirection.AUTO, ClosedAngle, Velocity); } // Process the hinge's movement. // It will return true when the panel has finished moving. // TODO: Add a mechanism to determine when a door gets stuck or can't reach the target angle. public bool Actuate() { if (Math.Abs(Hinge.Angle - TargetAngle) < 0.1 && Hinge.Angle == LastAngle) { Hinge.RotorLock = true; } LastAngle = Hinge.Angle; return Locked(); } public bool Locked() { return Hinge.RotorLock; } private IMyMotorStator Hinge { get; set; } private float TargetAngle { get; set; } private float LastAngle { 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; } } } // TODO: a utility class or function would be lovely... // In general, the encapsulation feels a little screwy here. private float DegToRad(float degrees) { return degrees * ((float)Math.PI / 180F); } } }