using Sandbox.ModAPI.Ingame; using System.Collections.Generic; using System; namespace IngameScript { public class DoorHinge { public DoorHinge(MyGridProgram p, IMyMotorStator hinge) { _p = p; _hinge = hinge; parseConfig(); } // 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 { get { return _hinge.RotorLock; } } 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; } } } private float degToRad(float degrees) { return degrees * ((float)Math.PI / 180F); } private MyGridProgram _p; private IMyMotorStator _hinge; private float _targetAngle; private float _lastAngle; private float _openAngle = 90F; private float _closedAngle = 0F; private float _velocity = 5F; } }