gaming-scripts/Space Engineers/acd-firqmod.cs

113 lines
3.9 KiB
C#

/*
* README
* -----------
*
* The AutoCloseDoor-script will monitor and (after a configurated delay) automatically close tagged door for you.
* It will only monitor doors within the same 'construct' (same "mechanical group", not Connectors)
*
* Tag a door with [ACD] (including brackets) in its name to have the AutoCloseDoor-script watch it and automatically close if after 3 seconds.
* Addition by Firq: This behavior can be customized below by setting the values of DefaultTimeout and DoorTag accordingly.
*
* You can also tag it with [ACD 10] to auto-close after 10 seconds (you can write whatever delay you want)
*
* -----------
*
* This version has been slightly modified by Firq. All credit goes to the original author Ninlin (https://steamcommunity.com/sharedfiles/filedetails/?id=2371860127)
*/
/* CUSTOMIZE BEHAVIOR HERE */
const int DefaultTimeout = 3;
const string DoorTag = "ACD";
/* DO NOT CHANGE ANYTHING BELOW THIS LINE */
public Program() {
Runtime.UpdateFrequency = UpdateFrequency.Update100;
}
const string TAG = "[" + DoorTag;
readonly int TAGlen = TAG.Length;
private Dictionary < string, OpenDoor > openDoors = new Dictionary < string, OpenDoor > ();
public void Main(string argument, UpdateType updateSource) {
int iDetectedDoors = 0;
int iOpenDoors = 0;
int iClosedDoors = 0;
var doors = new List < IMyDoor > ();
GridTerminalSystem.GetBlocksOfType < IMyDoor > (doors, (IMyDoor d) => (d.CustomName.Contains(TAG) && d.IsSameConstructAs(Me)));
foreach(var door in doors) {
iDetectedDoors++;
if (door.Status == DoorStatus.Open)
iOpenDoors += handleOpenDoor(door);
}
int iCloseFailed = 0;
var now = DateTime.UtcNow;
List < string > removeNames = null;
foreach(var opendoor in openDoors) {
if (opendoor.Value.Expired) {
var d = GridTerminalSystem.GetBlockWithId(opendoor.Value.ID) as IMyDoor;
if (d != null) {
iClosedDoors++;
d.CloseDoor();
if (removeNames == null)
removeNames = new List < string > ();
removeNames.Add(opendoor.Key);
} else
iCloseFailed++;
}
}
if (removeNames != null)
foreach(var name in removeNames)
openDoors.Remove(name);
var msg = string.Format("\n\nAutoCloseDoors\n----------------------------\nCurrent Time: {0}\n----------------------------\nGuarding {1} {2}",
now.ToLocalTime().ToLongTimeString(), iDetectedDoors, (iDetectedDoors == 1 ? "door" : "doors"));
if (iOpenDoors > 0)
msg += string.Format("\n{0} {1} currently open", iOpenDoors, (iOpenDoors == 1 ? "door is" : "doors are"));
if (iClosedDoors > 0)
msg += string.Format("\n{0} {1} closed", iClosedDoors, (iClosedDoors == 1 ? "door was" : "doors were"));
if (iCloseFailed > 0)
msg += string.Format("\n{0} {1} failed to close", iCloseFailed, (iCloseFailed == 1 ? "door" : "doors"));
var screen = Me.GetSurface(0);
screen.ContentType = ContentType.TEXT_AND_IMAGE;
screen.Alignment = TextAlignment.CENTER;
screen.WriteText(msg, false);
Echo(msg);
}
private class OpenDoor {
public long ID;
public DateTime Timeout;
public OpenDoor(IMyDoor door, int timeout) {
if (timeout <= 0)
timeout = DefaultTimeout;
ID = door.GetId();
Timeout = DateTime.UtcNow.AddSeconds(timeout);
}
public bool Expired => Timeout < DateTime.UtcNow;
}
private int handleOpenDoor(IMyDoor door) {
string tag = door.CustomName.Substring(door.CustomName.IndexOf(TAG) + TAGlen);
int end = tag.IndexOf(']');
if (end < 0) {
return 0;
}
tag = tag.Substring(0, end);
int timeout;
int.TryParse(tag, out timeout);
if (!openDoors.ContainsKey(door.Name)) {
openDoors.Add(door.Name, new OpenDoor(door, timeout));
return 1;
}
return 1;
}