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