space_engineers/MechanicalDoor/DoorHinge.cs
2025-02-07 15:25:25 -05:00

82 lines
2.5 KiB
C#

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;
}
}