space_engineers/MechanicalDoor/DoorHinge.cs

84 lines
2.6 KiB
C#

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