Advertisement
Guest User

Untitled

a guest
Apr 24th, 2019
115
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 66.35 KB | None | 0 0
  1.  
  2. /*************************************************
  3. * Automatic Air-Lock Script - by Syntak *
  4. *************************************************/
  5. //1.14
  6.  
  7.  
  8.  
  9.  
  10. public Program()
  11. {
  12. //ReadUserOptions();
  13. AirLockList = new List<AirLock>();
  14. airLockCount = CacheBlockLists();
  15. lastUpdateTime = System.DateTime.Now;
  16. Runtime.UpdateFrequency = UpdateFrequency.Update10;
  17. Echo("Hello World");
  18. //if (Me.CustomData.Length == 0)
  19. //{
  20. // WriteUserOptions();
  21. //}
  22. }
  23.  
  24. //OPTIONS
  25. static bool LOCKDOORS = true; //LOCK DOORS TO PREVENT OPENING BEFORE DE/PRESSURISING
  26. static bool AUTOOPENDOORS = true; //OPEN DOORS AUTOMATICALLY AFTER DE/PRESSURISING
  27. static bool AUTOCLOSEDOORS = true; //CLOSE DOORS AUTOMATICALLY WHEN NOT NEAR AIRLOCK
  28. static float DOORCLOSEDELAY = 5000f; //miliseconds, autoclose delay for sensorless doors
  29. static string DISABLED_VENT = "OFF"; //behaviour of AL vents when AL disabled, OFF|DEPRESSURISE|PRESSURISE
  30.  
  31. //SOUND
  32. static bool ENABLE_SOUNDS = true;
  33. static string EQUALISING_SOUND = "Alert 2"; //sound to play while airlock is equalising
  34. static string READY_SOUND = "Alert 1"; //sound to play when airlock is ready
  35. static float LOOP_PERIOD_EQ = 20; // Loop period for equalising sound, set to something longer that the time to cycle airlock
  36. static float LOOP_PERIOD_READY = 0.5f; // Loop period for ready sound, set to something short
  37.  
  38. //PERFORMANCE
  39. static int CACHE_INTERVAL = 10; //seconds, time between searching for blocks. lower numbers impact performance
  40. static int UPDATE_INTERVAL = 50; //miliseconds, time between updating
  41. static double INSTRUCTION_LIMIT = 0.9; //Portion of instruction limit to use (lower for better performance)
  42.  
  43. //BLOCK TAGS
  44. //static string AL_TAG_PREFIX = "AL1";
  45. static string AL_VENT_TAG = "AL1V"; //TAG FOR AIR LOCK VENTS
  46. static string AL_SEN_TAG = "AL1S"; /*TAG FOR INTRA AIR LOCK SENSOR;
  47. SHOULD COVER AREA INSIDE AIRLOCK*/
  48. static string AL_IVENT_TAG = "AL1I"; //TAG FOR INSIDE AIR VENT
  49. static string AL_IDOOR_TAG = "AL1I"; //TAG FOR INNER DOOR
  50. static string AL_ISEN_TAG = "AL1I"; /*TAG FOR INNER SENSOR;
  51. SHOULD COVER AREA EITHER SIDE OF INNER DOOR
  52. CAN'T OVERLAP WITH OUTER SENSOR AREA*/
  53. static string AL_ILCD_TAG = "AL1I"; //TAG FOR INNER STATUS LCD
  54. static string AL_ILIGHT_TAG = "AL1I"; //TAG FOR INNER STATUS LIGHT
  55. static string AL_ODOOR_TAG = "AL1O"; //TAG FOR OUTER DOOR
  56. static string AL_OSEN_TAG = "AL1O"; /*TAG FOR OUTER SENSOR;
  57. SHOULD COVER AREA EITHER SIDE OF OUTER DOOR
  58. CAN'T OVERLAP WITH INNER SENSOR AREA*/
  59. static string AL_OLCD_TAG = "AL1O"; //TAG FOR OUTER STATUS LCD
  60. static string AL_OLIGHT_TAG = "AL1O"; //TAG FOR OUTER STATUS LIGHT
  61. static string AL_OVENT_TAG = "AL1O"; /*TAG FOR OUTSIDE AIR VENT;
  62. NOT REQUIERED UNLESS BOTH SIDES OF
  63. THE AIR LOCK CAN BE PRESSURISED*/
  64. static string AL_TANK_TAG = "AL1T"; //TAG FOR OXYGEN TANK THAT FEEDS THIS AIRLOCK
  65. static string AL_SOUND_TAG = "AL1S"; //TAG FOR SOUND BLOCK
  66.  
  67. static string AL_STATUS_LCD = "ALSTAT"; //TAG FOR STATUS LCDS
  68. //static string AL_DEBUG = "ALDEBUG";
  69.  
  70.  
  71. //COLORS
  72. static Color STOP_COLOR = new Color(64, 0, 0, 255); //RED
  73. static Color GO_COLOR = new Color(0, 64, 0, 255); //GREEN
  74. static Color CAUTION_COLOR = new Color(64, 64, 0, 255); //YELLOW
  75.  
  76. static bool SMOOTH_COLOR = false;
  77. static Color SMOOTH_STOP_COLOR = new Color(64, 0, 0, 255); //RED
  78. static Color SMOOTH_GO_COLOR = new Color(0, 64, 0, 255); //GREEN
  79.  
  80. //LCD TEXT
  81. static float FONT_SIZE = 1.5F;
  82. static string READY_TEXT = TextTools.Center(" AIRLOCK", FONT_SIZE); //GHETTO CENTER, 18 SPACES
  83. static string STANDBY_TEXT = TextTools.Center(" AIRLOCK", FONT_SIZE);
  84. static string CAUTION_TEXT = TextTools.Center(" AIRLOCK", FONT_SIZE);
  85. static string FULL_TANKS_TEXT = TextTools.Center("[ OXYGEN TANKS FULL ]| OPEN DOOR MANUALY", FONT_SIZE);
  86. static string EMPTY_TANKS_TEXT = TextTools.Center("[ OXYGEN TANKS EMPTY ]| OPEN DOOR MANUALY", FONT_SIZE);
  87. static string DISABLED_TEXT = TextTools.Center(" AIRLOCK DISABLED", FONT_SIZE);
  88. static int LCD_WIDTH = (int) (1/FONT_SIZE * 95); //SINGLE WIDTH LCD
  89.  
  90. static string TITLE_TAG_OPEN = "[title]";
  91. static string TITLE_TAG_CLOSE = "[/title]";
  92.  
  93. static float DEFALT_PRESSURE = 0;
  94. static float SMALL_DIFF = 0.1F;
  95. static float MOD_DIFF = 0.5F;
  96. //static float BIG_DIFF = 0.9F;
  97.  
  98. static bool DEBUG = false; //show debug
  99.  
  100.  
  101. /*--------------Don't change anything beow this line----------------*/
  102.  
  103. DateTime lastChacheTime;
  104. DateTime lastUpdateTime;
  105.  
  106. int highestICount = 0; //instruction count
  107. double highestRunTime = 0;
  108.  
  109. List<AirLock> AirLockList;
  110.  
  111. int startChacheFrom = 0;
  112. int startUpdateFrom = 0;
  113.  
  114. int airLockCount = 0;
  115.  
  116. //bool CMD_VENT = false;
  117. //bool CMD_ENABLED = true;
  118. //bool hasArgument = false;
  119.  
  120. int airLockIndex = -1; //zero indexed, 0 -> airlock 1
  121.  
  122.  
  123. List<IMyTerminalBlock> statusLCDs = new List<IMyTerminalBlock>();
  124. IMyTextPanel tpanel;
  125.  
  126. public void Main(string argument)
  127. {
  128. if (argument != null)
  129. {
  130. //hasArgument = true;
  131. if (argument.ToUpper() == "DISABLE")
  132. {
  133. for (int i = 0; i < AirLockList.Count; i++)
  134. {
  135. AirLockList[i].Enabled = false;
  136. }
  137. }
  138. if (argument.ToUpper() == "ENABLE")
  139. {
  140. for (int i = 0; i < AirLockList.Count; i++)
  141. {
  142. AirLockList[i].Enabled = true;
  143. AirLockList[i].Venting = false;
  144. }
  145. }
  146. if (argument.ToUpper() == "VENT")
  147. {
  148. for (int i = 0; i < AirLockList.Count; i++)
  149. {
  150. AirLockList[i].Venting = true;
  151. }
  152. }
  153. if (argument.ToUpper() == "SCAN")
  154. {
  155. airLockCount = CacheBlockLists();
  156. return;
  157. }
  158. }
  159. else
  160. {
  161. //hasArgument = false;
  162. }
  163.  
  164.  
  165. if ((System.DateTime.Now - lastUpdateTime).TotalMilliseconds < UPDATE_INTERVAL)
  166. {
  167. return;
  168. }
  169. lastUpdateTime = System.DateTime.Now;
  170.  
  171. if ((System.DateTime.Now - lastChacheTime).TotalSeconds > CACHE_INTERVAL) //search for blocks, update options, status
  172. {
  173. GridTerminalSystem.SearchBlocksOfName(AL_STATUS_LCD, statusLCDs);
  174. //ReadUserOptions();
  175. airLockCount = CacheBlockLists();
  176. foreach (AirLock a in AirLockList)
  177. {
  178. a.ReadUserOptions();
  179. }
  180. return;
  181. }
  182.  
  183. foreach (IMyTerminalBlock t in statusLCDs)
  184. {
  185. tpanel = t as IMyTextPanel;
  186. tpanel.WritePublicText("Air Lock Status:" + "\n");
  187. tpanel.ShowPublicTextOnScreen();
  188.  
  189. }
  190.  
  191. for (airLockIndex = startUpdateFrom; airLockIndex < AirLockList.Count-1; airLockIndex++)
  192. {
  193. if (((double)Runtime.CurrentInstructionCount / (double)Runtime.MaxInstructionCount) > INSTRUCTION_LIMIT)
  194. {
  195. startUpdateFrom = airLockIndex;
  196. break;
  197. }
  198.  
  199. AirLockList[airLockIndex].Update();
  200.  
  201. //status LCD
  202.  
  203. foreach (IMyTerminalBlock t in statusLCDs)
  204. {
  205. tpanel = t as IMyTextPanel;
  206. tpanel.WritePublicText("\n" + AirLockList[airLockIndex].ToString(), true);
  207. }
  208.  
  209. }
  210.  
  211.  
  212. if (airLockIndex == AirLockList.Count)
  213. {
  214. startUpdateFrom = 0;
  215. }
  216.  
  217.  
  218.  
  219.  
  220. if (DEBUG)
  221. {
  222. Echo("Updating " + airLockIndex + "/" + AirLockList.Count + " airlocks");
  223. //Echo("Elements:" + alBlocks.Count.ToString());
  224. if (Runtime.CurrentInstructionCount > highestICount)
  225. highestICount = Runtime.CurrentInstructionCount;
  226. Echo("Instructions Used: " + Runtime.CurrentInstructionCount.ToString());
  227. Echo(((double)Runtime.CurrentInstructionCount / (double)Runtime.MaxInstructionCount * 100).ToString() + "%");
  228. Echo("Max: " + highestICount);
  229. Echo(((double)highestICount / (double)Runtime.MaxInstructionCount * 100).ToString() + "%" );
  230. Echo(Runtime.LastRunTimeMs + "ms");
  231. if (Runtime.LastRunTimeMs > highestRunTime)
  232. highestRunTime = Runtime.LastRunTimeMs;
  233. Echo("Max: " + highestRunTime);
  234. Echo("Status LCDS: " + statusLCDs.Count);
  235. }
  236.  
  237. }
  238.  
  239. public int FindBlocks(AirLock al)
  240. {
  241. int blocksFound = 0;
  242. blocksFound += SearchTag<IMyDoor>(AL_IDOOR_TAG.Replace("1", al.id.ToString()), al.innerDoors);
  243. blocksFound += SearchTag<IMySensorBlock>(AL_ISEN_TAG.Replace("1", al.id.ToString()), al.innerSensors);
  244. blocksFound += SearchTag<IMyTextPanel>(AL_ILCD_TAG.Replace("1", al.id.ToString()), al.innerLCDs);
  245. blocksFound += SearchTag<IMyAirVent>(AL_IVENT_TAG.Replace("1", al.id.ToString()), al.innerVents);
  246. blocksFound += SearchTag<IMyLightingBlock>(AL_ILIGHT_TAG.Replace("1", al.id.ToString()), al.innerLights);
  247. blocksFound += SearchTag<IMyAirVent>(AL_VENT_TAG.Replace("1", al.id.ToString()), al.alVents);
  248. blocksFound += SearchTag<IMySensorBlock>(AL_SEN_TAG.Replace("1", al.id.ToString()), al.alSensors);
  249. blocksFound += SearchTag<IMyDoor>(AL_ODOOR_TAG.Replace("1", al.id.ToString()), al.outerDoors);
  250. blocksFound += SearchTag<IMySensorBlock>(AL_OSEN_TAG.Replace("1", al.id.ToString()), al.outerSensors);
  251. blocksFound += SearchTag<IMyTextPanel>(AL_OLCD_TAG.Replace("1", al.id.ToString()), al.outerLCDs);
  252. blocksFound += SearchTag<IMyAirVent>(AL_OVENT_TAG.Replace("1", al.id.ToString()), al.outerVents);
  253. blocksFound += SearchTag<IMyLightingBlock>(AL_OLIGHT_TAG.Replace("1", al.id.ToString()), al.outerLights);
  254. blocksFound += SearchTag<IMyGasTank>(AL_TANK_TAG.Replace("1", al.id.ToString()), al.tanks);
  255. blocksFound += SearchTag<IMySoundBlock>(AL_SOUND_TAG.Replace("1", al.id.ToString()), al.soundblocks);
  256. return blocksFound;
  257. }
  258. public int SearchTag<T>(string tag, List<IMyTerminalBlock> finallist) where T : class
  259. {//returns number of blocks found
  260. finallist.Clear();
  261. //get tagged blocks
  262. List<IMyTerminalBlock> listname = new List<IMyTerminalBlock>();
  263. GridTerminalSystem.SearchBlocksOfName(tag, listname);
  264.  
  265. //get all blocks of type
  266. List<IMyTerminalBlock> listtype = new List<IMyTerminalBlock>();
  267. GridTerminalSystem.GetBlocksOfType<T>(listtype);
  268.  
  269. //check tagged blocks are right type
  270. for (int i = 0; i < listname.Count; i++)
  271. {
  272. if (listname[i] is T)
  273. finallist.Add(listname[i]);
  274. }
  275.  
  276. //get blocks tagged using custom data
  277. List<IMyTerminalBlock> listcustom = new List<IMyTerminalBlock>();
  278. for (int i = 0; i < listtype.Count; i++)
  279. {
  280. if (listtype[i].CustomData.Contains(tag) && !(listtype[i] == Me))
  281. {
  282. listcustom.Add(listtype[i]);
  283. }
  284. }
  285.  
  286. finallist.AddRange(listcustom);
  287.  
  288. //GROUPS
  289. IMyBlockGroup taggedGroup = GridTerminalSystem.GetBlockGroupWithName(tag);
  290. List<IMyTerminalBlock> listGroup = new List<IMyTerminalBlock>();
  291. if (taggedGroup != null)
  292. {
  293. taggedGroup.GetBlocks(listGroup);
  294. }
  295.  
  296. //check group tagged blocks are right type
  297. for (int i = 0; i < listGroup.Count; i++)
  298. {
  299. if (listGroup[i] is T)
  300. finallist.Add(listGroup[i]);
  301. }
  302. return finallist.Count;
  303. }
  304. public float AbsDiff(float a, float b)
  305. {
  306. float result = a - b;
  307. if (result < 0)
  308. return result * -1;
  309. else
  310. return result;
  311. }
  312. public int CacheBlockLists()
  313. {
  314.  
  315. //find new air locks
  316. int i = startChacheFrom; //airlockindex
  317.  
  318. if(AirLockList.Count == 0)
  319. {
  320. AirLockList.Add(new AirLock(1));
  321. }
  322.  
  323. while (((double)Runtime.CurrentInstructionCount / (double)Runtime.MaxInstructionCount) < INSTRUCTION_LIMIT)
  324. {
  325. if (i >= AirLockList.Count)
  326. {
  327. AirLockList.Add(new AirLock(i + 1));
  328. }
  329. if (FindBlocks(AirLockList[i]) > 0)
  330. {
  331. i++;
  332. }
  333. else //no blocks for airlock i, all airlocks found (probably)
  334. {
  335. startChacheFrom = 0;
  336. lastChacheTime = System.DateTime.Now;
  337. return i;
  338. }
  339. }
  340.  
  341. startChacheFrom = i;
  342. return i;
  343. }
  344.  
  345. public void WriteUserOptions()
  346. {
  347. StringBuilder sb = new StringBuilder();
  348. sb.AppendLine("LOCKDOORS = " + LOCKDOORS.ToString());
  349. sb.AppendLine("AUTOOPENDOORS = " + AUTOOPENDOORS.ToString());
  350. sb.AppendLine("AUTOCLOSEDOORS = " + AUTOCLOSEDOORS.ToString());
  351. sb.AppendLine("DOORCLOSEDELAY = " + DOORCLOSEDELAY.ToString());
  352. sb.AppendLine("DISABLED_VENT = " + DISABLED_VENT.ToString());
  353. sb.AppendLine("ENABLE_SOUNDS = " + ENABLE_SOUNDS.ToString());
  354. sb.AppendLine("EQUALISING_SOUND = " + EQUALISING_SOUND.ToString());
  355. sb.AppendLine("READY_SOUND = " + READY_SOUND.ToString());
  356. sb.AppendLine("LOOP_PERIOD_EQ = " + LOOP_PERIOD_EQ.ToString());
  357. sb.AppendLine("LOOP_PERIOD_READY = " + LOOP_PERIOD_READY.ToString());
  358.  
  359. sb.AppendLine("STOP_COLOR = " + STOP_COLOR);
  360. sb.AppendLine("GO_COLOR = " + GO_COLOR);
  361. sb.AppendLine("CAUTION_COLOR = " + CAUTION_COLOR);
  362. sb.AppendLine("SMOOTH_COLOR = " + SMOOTH_COLOR);
  363. sb.AppendLine("SMOOTH_STOP_COLOR = " + SMOOTH_STOP_COLOR);
  364. sb.AppendLine("SMOOTH_GO_COLOR = " + SMOOTH_GO_COLOR);
  365.  
  366. sb.AppendLine("FONT_SIZE = " + FONT_SIZE);
  367. sb.AppendLine("READY_TEXT = " + READY_TEXT);
  368. sb.AppendLine("STANDBY_TEXT = " + STANDBY_TEXT);
  369. sb.AppendLine("CAUTION_TEXT = " + CAUTION_TEXT);
  370. sb.AppendLine("FULL_TANKS_TEXT = " + FULL_TANKS_TEXT);
  371. sb.AppendLine("EMPTY_TANKS_TEXT = " + EMPTY_TANKS_TEXT);
  372. sb.AppendLine("DISABLED_TEXT = " + DISABLED_TEXT);
  373.  
  374. sb.AppendLine("CACHE_INTERVAL = " + CACHE_INTERVAL);
  375. sb.AppendLine("UPDATE_INTERVAL = " + UPDATE_INTERVAL);
  376. sb.AppendLine("INSTRUCTION_LIMIT = " + INSTRUCTION_LIMIT);
  377.  
  378. Me.CustomData = sb.ToString();
  379.  
  380. }
  381. public void ReadUserOptions()
  382. {
  383. //split on " = " (note spaces)
  384. string[] delim1 = {"\n"};
  385. string[] delim2 = { " = " };
  386. string[] lines = Me.CustomData.Split(delim1, StringSplitOptions.RemoveEmptyEntries);
  387.  
  388. string var;
  389. string val;
  390. string[] varval;
  391. foreach(string s in lines)
  392. {
  393. varval = s.Split(delim2, 2, StringSplitOptions.RemoveEmptyEntries);
  394. var = varval[0];
  395. val = varval[1];
  396. Echo("PAIR:" + var + ":" + val);
  397.  
  398. switch(var)
  399. {
  400. case "LOCKDOORS":
  401. SetVar(LOCKDOORS, val);
  402. break;
  403. case "AUTOOPENDOORS":
  404. SetVar(AUTOOPENDOORS, val);
  405. break;
  406. case "AUTOCLOSEDOORS":
  407. SetVar(AUTOCLOSEDOORS, val);
  408. break;
  409. case "DOORCLOSEDELAY":
  410. SetVar(DOORCLOSEDELAY, val);
  411. break;
  412. case "DISABLED_VENT":
  413. SetVar(DISABLED_VENT, val);
  414. break;
  415. case "ENABLE_SOUNDS":
  416. SetVar(ENABLE_SOUNDS, val);
  417. break;
  418. case "EQUALISING_SOUND":
  419. SetVar(EQUALISING_SOUND, val);
  420. break;
  421. case "READY_SOUND":
  422. SetVar(READY_SOUND, val);
  423. break;
  424. case "LOOP_PERIOD_EQ":
  425. SetVar(LOOP_PERIOD_EQ, val);
  426. break;
  427. case "LOOP_PERIOD_READY":
  428. SetVar(LOOP_PERIOD_READY, val);
  429. break;
  430. case "STOP_COLOR":
  431. SetVar(STOP_COLOR, val);
  432. break;
  433. case "GO_COLOR":
  434. SetVar(GO_COLOR, val);
  435. break;
  436. case "CAUTION_COLOR":
  437. SetVar(CAUTION_COLOR, val);
  438. break;
  439. case "SMOOTH_COLOR":
  440. SetVar(SMOOTH_COLOR, val);
  441. break;
  442. case "SMOOTH_STOP_COLOR":
  443. SetVar(SMOOTH_STOP_COLOR, val);
  444. break;
  445. case "SMOOTH_GO_COLOR":
  446. SetVar(SMOOTH_GO_COLOR, val);
  447. break;
  448. case "FONT_SIZE":
  449. SetVar(FONT_SIZE, val);
  450. break;
  451. case "READY_TEXT":
  452. SetVar(READY_TEXT, val);
  453. break;
  454. case "STANDBY_TEXT":
  455. SetVar(STANDBY_TEXT, val);
  456. break;
  457. case "CAUTION_TEXT":
  458. SetVar(CAUTION_TEXT, val);
  459. break;
  460. case "FULL_TANKS_TEXT":
  461. SetVar(FULL_TANKS_TEXT, val);
  462. break;
  463. case "EMPTY_TANKS_TEXT":
  464. SetVar(EMPTY_TANKS_TEXT, val);
  465. break;
  466. case "DISABLED_TEXT":
  467. SetVar(DISABLED_TEXT, val);
  468. break;
  469. case "CACHE_INTERVAL":
  470. SetVar(CACHE_INTERVAL, val);
  471. break;
  472. case "UPDATE_INTERVAL":
  473. SetVar(UPDATE_INTERVAL, val);
  474. break;
  475. case "INSTRUCTION_LIMIT":
  476. SetVar(INSTRUCTION_LIMIT, val);
  477. break;
  478. default:
  479. Echo("Check Options List!");
  480. break;
  481.  
  482. }
  483. }
  484.  
  485. }
  486.  
  487. public bool SetVar(bool variable, string value)
  488. {
  489. //return true iff susessful
  490. if (value.ToUpper().Contains("TRUE"))
  491. {
  492. variable = true;
  493. return true;
  494. }
  495. if (value.ToUpper().Contains("FALSE"))
  496. {
  497. variable = false;
  498. return true;
  499. }
  500. Echo("Not Set");
  501. return false;
  502. }
  503. public bool SetVar(string variable, string value)
  504. {
  505. //return true iff susessful
  506. variable = value;
  507. return true;
  508. }
  509. public bool SetVar(int variable, string value)
  510. {
  511. //return true iff susessful
  512. try
  513. {
  514. variable = Convert.ToInt32(value);
  515. }
  516. catch (FormatException e)
  517. {
  518. Echo("Input string is not a sequence of digits.");
  519. Echo("Not Set");
  520. return false;
  521. }
  522. return true;
  523. }
  524. public bool SetVar(float variable, string value)
  525. {
  526. //return true iff susessful
  527. try
  528. {
  529. variable = Convert.ToSingle(value);
  530. }
  531. catch (FormatException e)
  532. {
  533. Echo("Input string is not a sequence of digits.");
  534. Echo("Not Set");
  535. return false;
  536. }
  537. return true;
  538. }
  539. public bool SetVar(double variable, string value)
  540. {
  541. //return true iff susessful
  542. try
  543. {
  544. variable = Convert.ToDouble(value);
  545. }
  546. catch (FormatException e)
  547. {
  548. Echo("Input string is not a sequence of digits.");
  549. Echo("Not Set");
  550. return false;
  551. }
  552. return true;
  553. }
  554. public bool SetVar(Color variable, string value)
  555. {
  556. //return true iff susessful
  557. //format: {R:64 G:0 B:0 A:255}
  558. char[] b = { '{', '}'};
  559. value = value.Trim(b); //trim brackets
  560. string[] rgba = value.Split(' ');
  561. string[] pair;
  562. foreach (string s in rgba)
  563. {
  564. pair = s.Split(':');
  565. try
  566. {
  567. switch (pair[0])
  568. {
  569. case "R":
  570. variable.R = Convert.ToByte(pair[1]);
  571. break;
  572. case "G":
  573. variable.G = Convert.ToByte(pair[1]);
  574. break;
  575. case "B":
  576. variable.B = Convert.ToByte(pair[1]);
  577. break;
  578. case "A":
  579. variable.A = Convert.ToByte(pair[1]);
  580. break;
  581. default:
  582. Echo("Color format incorrect");
  583. Echo("Not Set");
  584. return false;
  585. }
  586. }
  587. catch (FormatException e)
  588. {
  589. Echo("Input string is not a sequence of digits.");
  590. Echo("Not Set");
  591. return false;
  592. }
  593. }
  594. return true;
  595. }
  596.  
  597.  
  598. public class AirLock
  599. {
  600. //OPTIONS
  601. bool lockDoors { get; set; }
  602. bool autoOpenDoors { get; set; }
  603. bool autoCloseDoors { get; set; }
  604. float doorCloseDelay { get; set; }
  605. string disabled_vent { get; set; }
  606. bool enable_sounds { get; set; }
  607. string equalising_sound { get; set; }
  608. string ready_sound { get; set; }
  609. float loop_period_eq { get; set; }
  610. float loop_period_ready { get; set; }
  611. //COLORS
  612. Color stop_color { get; set; }
  613. Color go_color { get; set; }
  614. Color caution_color { get; set; }
  615. bool smooth_color { get; set; }
  616. Color smooth_stop_color { get; set; }
  617. Color smooth_go_color { get; set; }
  618. //LCD TEXT
  619. private float _font_size;
  620. float font_size
  621. {
  622. get { return _font_size; }
  623. set
  624. {
  625. _font_size = value;
  626. lcd_width = (int)(1 / value * 95); //SINGLE WIDTH LCD
  627. }
  628. }
  629. string ready_text { get; set; }
  630. string standby_text { get; set; }
  631. string caution_text { get; set; }
  632. string full_tanks_text { get; set; }
  633. string empty_tanks_text { get; set; }
  634. string disabled_text { get; set; }
  635. int lcd_width { get; set; }
  636.  
  637.  
  638. //Al specific flags
  639. int lastActiveZone { get; set; }
  640. bool innerDoorWasOpen { get; set; }
  641. bool outerDoorWasOpen { get; set; }
  642. double timeSinceDoorOpened { get; set; }
  643. float timeSinceDoorOpenedInner { get; set; }
  644. float timeSinceDoorOpenedOuter { get; set; }
  645. DateTime doorTimeInner { get; set; }
  646. DateTime doorTimeOuter { get; set; }
  647. bool dontReopenInner { get; set; }
  648. bool dontReopenOuter { get; set; }
  649. bool isEqualised { get; set; }
  650. bool eqSoundPlayed { get; set; }
  651. bool readySoundPlayed { get; set; }
  652.  
  653. private bool isventing;
  654. private bool isenabled;
  655.  
  656. public int id { get; set; }
  657.  
  658.  
  659. public List<IMyTerminalBlock> innerDoors;
  660. public List<IMyTerminalBlock> outerDoors;
  661. public List<IMyTerminalBlock> innerVents;
  662. public List<IMyTerminalBlock> outerVents;
  663. public List<IMyTerminalBlock> innerSensors;
  664. public List<IMyTerminalBlock> outerSensors;
  665. public List<IMyTerminalBlock> innerLCDs;
  666. public List<IMyTerminalBlock> outerLCDs;
  667. public List<IMyTerminalBlock> innerLights;
  668. public List<IMyTerminalBlock> outerLights;
  669. public List<IMyTerminalBlock> alVents;
  670. public List<IMyTerminalBlock> alSensors;
  671. public List<IMyTerminalBlock> tanks;
  672. public List<IMyTerminalBlock> soundblocks;
  673.  
  674. public bool Enabled
  675. {
  676. get { return isenabled; }
  677. set
  678. {
  679. isenabled = value;
  680. if (isenabled == true)
  681. TurnOn(alVents);
  682. if (isenabled == false)
  683. {
  684. TurnOnDoors(innerDoors);
  685. TurnOnDoors(outerDoors);
  686. if (disabled_vent == "OFF")
  687. TurnOff(alVents);
  688. if (disabled_vent == "DEPRESSURISE")
  689. DePressurise(alVents);
  690. if (disabled_vent == "PRESSURISE")
  691. Pressurise(alVents);
  692. }
  693. }
  694. }
  695. public bool Venting
  696. {
  697. get { return isventing; }
  698. set
  699. {
  700. isventing = value;
  701. if (isventing == true)
  702. {
  703. OpenDoors(innerDoors);
  704. OpenDoors(outerDoors);
  705. }
  706. }
  707. }
  708. public string centeredName { get; set; }
  709. private string name;
  710. public string Name
  711. {
  712. get { return name; }
  713. set
  714. {
  715. name = value;
  716. centeredName = TextTools.Center(name, font_size);
  717. ready_text = centeredName;
  718. standby_text = centeredName;
  719. caution_text = centeredName;
  720. }
  721. }
  722.  
  723.  
  724. public AirLock(int number) //constructor, make sure all variables are initilised
  725. {
  726. id = number;
  727. //Name = "AIRLOCK " + number.ToString();
  728.  
  729. //Set Defalts
  730. lockDoors = LOCKDOORS;
  731. autoOpenDoors = AUTOOPENDOORS;
  732. autoCloseDoors = AUTOCLOSEDOORS;
  733. doorCloseDelay = DOORCLOSEDELAY;
  734. disabled_vent = DISABLED_VENT;
  735.  
  736. enable_sounds = ENABLE_SOUNDS;
  737. equalising_sound = EQUALISING_SOUND;
  738. ready_sound = READY_SOUND;
  739. loop_period_eq = LOOP_PERIOD_EQ;
  740. loop_period_ready = LOOP_PERIOD_READY;
  741.  
  742. stop_color = STOP_COLOR;
  743. go_color = GO_COLOR;
  744. caution_color = CAUTION_COLOR;
  745. smooth_color = SMOOTH_COLOR;
  746. smooth_stop_color = SMOOTH_STOP_COLOR;
  747. smooth_go_color = SMOOTH_GO_COLOR;
  748.  
  749. font_size = FONT_SIZE;
  750. ready_text = centeredName;
  751. standby_text = centeredName;
  752. caution_text = centeredName;
  753. full_tanks_text = FULL_TANKS_TEXT;
  754. empty_tanks_text = EMPTY_TANKS_TEXT;
  755. disabled_text = DISABLED_TEXT;
  756. lcd_width = (int)(1 / font_size * 95); //SINGLE WIDTH LCD
  757.  
  758. lastActiveZone = 0;
  759. innerDoorWasOpen = true;
  760. outerDoorWasOpen = true;
  761. timeSinceDoorOpened = 0;
  762. timeSinceDoorOpenedInner = 0;
  763. timeSinceDoorOpenedOuter = 0;
  764. doorTimeInner = System.DateTime.Now;
  765. doorTimeOuter = System.DateTime.Now;
  766. dontReopenInner = false;
  767. dontReopenOuter = false;
  768. isEqualised = true;
  769. eqSoundPlayed = true;
  770. readySoundPlayed = true;
  771. isventing = false;
  772. isenabled = true;
  773.  
  774. Name = "AIRLOCK " + number.ToString();
  775.  
  776. //init block lists
  777. innerDoors = new List<IMyTerminalBlock>();
  778. outerDoors = new List<IMyTerminalBlock>();
  779. innerVents = new List<IMyTerminalBlock>();
  780. outerVents = new List<IMyTerminalBlock>();
  781. innerSensors = new List<IMyTerminalBlock>();
  782. outerSensors = new List<IMyTerminalBlock>();
  783. innerLCDs = new List<IMyTerminalBlock>();
  784. outerLCDs = new List<IMyTerminalBlock>();
  785. innerLights = new List<IMyTerminalBlock>();
  786. outerLights = new List<IMyTerminalBlock>();
  787. alVents = new List<IMyTerminalBlock>();
  788. alSensors = new List<IMyTerminalBlock>();
  789. tanks = new List<IMyTerminalBlock>();
  790. soundblocks = new List<IMyTerminalBlock>();
  791.  
  792.  
  793. }
  794.  
  795. public void Update()
  796. {
  797. SetLCDs();
  798. SetLights();
  799. if (ENABLE_SOUNDS)
  800. SetSoundBlocks();
  801.  
  802. if (Venting || !Enabled) //disabled or venting,
  803. {
  804. if (!Enabled) //don't mess with doors
  805. {
  806. return;
  807. }
  808. OpenDoors(innerDoors); // venting, force open
  809. OpenDoors(outerDoors);
  810. return;
  811. }
  812.  
  813.  
  814.  
  815. if ((SensorActive(outerSensors) && SensorActive(innerSensors))) //overlapping sensor zones,
  816. {
  817. CloseDoors(innerDoors);
  818. CloseDoors(outerDoors);
  819. if (lastActiveZone == 0) //out->in
  820. {
  821. if (Ilevel > 0.5)
  822. {
  823. Pressurise(alVents);
  824.  
  825. }
  826. else
  827. {
  828. DePressurise(alVents);
  829. }
  830.  
  831. }
  832. if (lastActiveZone == 1) //in->out
  833. {
  834. if (Olevel > 0.5)
  835. {
  836. Pressurise(alVents);
  837. }
  838. else
  839. {
  840. DePressurise(alVents);
  841. }
  842. }
  843. return;
  844. }
  845.  
  846. if (SensorActive(innerSensors))
  847. {
  848. lastActiveZone = 1;
  849. CloseDoors(outerDoors);
  850. if (Ilevel > 0.5)
  851. {
  852. Pressurise(alVents);
  853. if (TanksAreEmpty())
  854. {
  855. TurnOn(innerDoors);
  856. return;
  857. }
  858. }
  859. else
  860. {
  861. DePressurise(alVents);
  862. if (TanksAreFull())
  863. {
  864. TurnOn(innerDoors);
  865. return;
  866. }
  867. }
  868. if (AbsDiff(Ilevel, ALlevel) < 0.1 && DoorsClosed(outerDoors))
  869. OpenDoors(innerDoors);
  870. return;
  871. }
  872.  
  873. if (SensorActive(outerSensors))
  874. {
  875. lastActiveZone = 0;
  876. CloseDoors(innerDoors);
  877. if (Olevel > 0.5)
  878. {
  879. Pressurise(alVents);
  880. if (TanksAreEmpty())
  881. {
  882. TurnOn(outerDoors);
  883. return;
  884. }
  885. }
  886. else
  887. {
  888. DePressurise(alVents);
  889. if (TanksAreFull())
  890. {
  891. TurnOn(outerDoors);
  892. return;
  893. }
  894. }
  895. if (AbsDiff(Olevel, ALlevel) < 0.1 && DoorsClosed(innerDoors))
  896. {
  897. OpenDoors(outerDoors);
  898. }
  899. return;
  900. }
  901.  
  902. if (SensorActive(alSensors))
  903. {
  904. if (innerSensors.Count != 0 && outerSensors.Count != 0) //has innner AND outer sensor
  905. {
  906. CloseDoors(innerDoors);
  907. CloseDoors(outerDoors);
  908. if (lastActiveZone == 0) //out->in
  909. {
  910. if (Ilevel > 0.5)
  911. {
  912. Pressurise(alVents);
  913. }
  914. else
  915. {
  916. DePressurise(alVents);
  917. }
  918. }
  919. if (lastActiveZone == 1) //in->out
  920. {
  921. if (Olevel > 0.5)
  922. {
  923. Pressurise(alVents);
  924. }
  925. else
  926. {
  927. DePressurise(alVents);
  928. }
  929. }
  930. return;
  931. }
  932. else //intra sensor only, no door sensors
  933. {
  934. //do nothing
  935. }
  936. }
  937.  
  938.  
  939. //sensorless doors
  940. bool sensorlessOuter = false;
  941. bool sensorlessInner = false;
  942. if (innerSensors.Count == 0) //no inner door sensors
  943. {
  944. sensorlessInner = true;
  945.  
  946. if ((PressureDiff(innerVents, alVents) < SMALL_DIFF) && Samesies(innerVents, alVents) && DoorsClosed(outerDoors))
  947. {
  948. if (!dontReopenInner)
  949. OpenDoors(innerDoors);
  950.  
  951. }
  952.  
  953. else if (PressureDiff(outerVents, innerVents) < SMALL_DIFF && Samesies(outerVents, innerVents)) //pressure same inside and out
  954. {
  955. TurnOnDoors(innerDoors); //unlock doors, don't autoopen in-case al opens into hangar or similar
  956. }
  957. else
  958. {
  959. if (!TanksAreEmpty() && !TanksAreFull())
  960. {
  961. CloseDoors(innerDoors);
  962. dontReopenInner = false;
  963. }
  964. }
  965. }
  966.  
  967. if (outerSensors.Count == 0) //no outer door sensors
  968. {
  969. sensorlessOuter = true;
  970. if ((PressureDiff(outerVents, alVents) < SMALL_DIFF) && Samesies(outerVents, alVents) && DoorsClosed(innerDoors))
  971. {
  972. if (!dontReopenOuter)
  973. OpenDoors(outerDoors);
  974.  
  975. }
  976. else if (PressureDiff(outerVents, innerVents) < SMALL_DIFF && Samesies(outerVents, innerVents)) //pressure same inside and out
  977. {
  978. TurnOnDoors(outerDoors); //unlock doors, don't autoopen in-case al opens into hangar or similar
  979. }
  980. else
  981. {
  982. if (!TanksAreEmpty() && !TanksAreFull())
  983. {
  984. CloseDoors(outerDoors);
  985. dontReopenOuter = false;
  986. }
  987. }
  988. }
  989.  
  990. if (CloseOnDelay(outerDoors, doorTimeOuter))
  991. {
  992. dontReopenOuter = true;
  993. }
  994. if (CloseOnDelay(innerDoors, doorTimeInner))
  995. {
  996. dontReopenInner = true;
  997. }
  998.  
  999.  
  1000.  
  1001. if (AUTOCLOSEDOORS) //not near air-lock,
  1002. {
  1003. if (!sensorlessInner)
  1004. CloseDoors(innerDoors);
  1005. if (!sensorlessOuter)
  1006. CloseDoors(outerDoors);
  1007. else
  1008. {
  1009. if (DoorsClosed(innerDoors))
  1010. {
  1011. ResetDoorTimerInner();
  1012. }
  1013. if (DoorsClosed(outerDoors))
  1014. {
  1015. ResetDoorTimerOuter();
  1016. }
  1017.  
  1018. }
  1019. }
  1020.  
  1021. if (TanksAreEmpty() || TanksAreFull())
  1022. {
  1023. TurnOn(innerDoors);
  1024. TurnOn(outerDoors);
  1025. }
  1026.  
  1027. }
  1028.  
  1029. public float Ilevel
  1030. {
  1031. get { return Pressure(innerVents); }
  1032. }
  1033. public float Olevel
  1034. {
  1035. get { return Pressure(outerVents); }
  1036. }
  1037. public float ALlevel
  1038. {
  1039. get { return Pressure(alVents); }
  1040. }
  1041. public bool IsEqualised
  1042. {
  1043. get
  1044. {
  1045. if (AbsDiff(ALlevel, Ilevel) > SMALL_DIFF && AbsDiff(ALlevel, Olevel) > SMALL_DIFF)
  1046. return false;
  1047. else
  1048. return true;
  1049. }
  1050. }
  1051.  
  1052. public void SetLCDs()
  1053. {
  1054. Color screenColor;
  1055. string screenText;
  1056.  
  1057.  
  1058. //Inner
  1059. if (innerLCDs.Count > 0)
  1060. {
  1061. float pressureDiff = AbsDiff(ALlevel, Ilevel);
  1062. if (pressureDiff < SMALL_DIFF)
  1063. {
  1064. screenColor = GO_COLOR;
  1065. screenText = ready_text;
  1066. }
  1067. else if (pressureDiff > MOD_DIFF)
  1068. {
  1069. screenColor = STOP_COLOR;
  1070. screenText = caution_text;
  1071. }
  1072. else
  1073. {
  1074. screenColor = CAUTION_COLOR;
  1075. screenText = standby_text;
  1076. }
  1077. if (smooth_color)
  1078. {
  1079. screenColor = SmoothColor(pressureDiff);
  1080. }
  1081. WriteToScreens(innerLCDs, screenColor, screenText);
  1082. }
  1083.  
  1084. //Outer
  1085. if (outerLCDs.Count > 0)
  1086. {
  1087. float pressureDiff = AbsDiff(ALlevel, Olevel);
  1088. if (pressureDiff < SMALL_DIFF)
  1089. {
  1090. screenColor = GO_COLOR;
  1091. screenText = ready_text;
  1092. }
  1093. else if (pressureDiff > MOD_DIFF)
  1094. {
  1095. screenColor = STOP_COLOR;
  1096. screenText = caution_text;
  1097. }
  1098. else
  1099. {
  1100. screenColor = CAUTION_COLOR;
  1101. screenText = standby_text;
  1102. }
  1103. if (smooth_color)
  1104. {
  1105. screenColor = SmoothColor(pressureDiff);
  1106. }
  1107. WriteToScreens(outerLCDs, screenColor, screenText);
  1108. }
  1109.  
  1110.  
  1111. }
  1112. private void WriteToScreens(List<IMyTerminalBlock> panels, Color screenColor, string screenText, bool showNormalText = true)
  1113. {
  1114. if (TanksAreEmpty())
  1115. {
  1116. //screenColor = CAUTION_COLOR;
  1117. screenText = empty_tanks_text;
  1118. showNormalText = false;
  1119. }
  1120. if (TanksAreFull())
  1121. {
  1122. //screenColor = CAUTION_COLOR;
  1123. screenText = full_tanks_text;
  1124. showNormalText = false;
  1125. }
  1126.  
  1127. if (!Enabled) //AIR-LOCKS DISABLED
  1128. {
  1129. //screenColor = CAUTION_COLOR;
  1130. screenText = disabled_text;
  1131. showNormalText = false;
  1132. }
  1133.  
  1134. IMyTextPanel tpanel;
  1135. string customScreenText;
  1136. int start, end;
  1137. for (int i = 0; i < panels.Count; i++)
  1138. {
  1139. tpanel = panels[i] as IMyTextPanel;
  1140. tpanel.SetValue("BackgroundColor", screenColor);
  1141. tpanel.SetValue("FontSize", font_size);
  1142. if (showNormalText && tpanel.CustomData.Contains(TITLE_TAG_OPEN)) //shownormaltext = not an error msg
  1143. {
  1144. start = tpanel.CustomData.IndexOf(TITLE_TAG_OPEN) + TITLE_TAG_OPEN.Length;
  1145. if (tpanel.CustomData.Contains(TITLE_TAG_CLOSE))
  1146. {
  1147. end = tpanel.CustomData.IndexOf(TITLE_TAG_CLOSE, start);
  1148. customScreenText = TextTools.Center(tpanel.CustomData.Substring(start, end - start), font_size);
  1149. tpanel.WritePublicText(BuildDisplayText(customScreenText, ALlevel));
  1150. }
  1151. }
  1152. else
  1153. tpanel.WritePublicText(BuildDisplayText(screenText, ALlevel));
  1154.  
  1155. tpanel.ShowPublicTextOnScreen();
  1156. }
  1157. }
  1158. public void SetLights()
  1159. {
  1160. Color lightColor;
  1161. IMyLightingBlock light;
  1162. //Inner
  1163. if (innerLights.Count > 0)
  1164. {
  1165. float pressureDiff = AbsDiff(ALlevel, Ilevel);
  1166.  
  1167. if (pressureDiff < SMALL_DIFF)
  1168. {
  1169. lightColor = go_color;
  1170. }
  1171. else if (pressureDiff > MOD_DIFF)
  1172. {
  1173. lightColor = stop_color;
  1174. }
  1175. else
  1176. {
  1177. lightColor = caution_color;
  1178. }
  1179.  
  1180. if (SMOOTH_COLOR)
  1181. {
  1182. lightColor = SmoothColor(pressureDiff);
  1183. }
  1184.  
  1185. for (int i = 0; i < innerLights.Count; i++)
  1186. {
  1187. light = innerLights[i] as IMyLightingBlock;
  1188. light.SetValue("Color", lightColor);
  1189. }
  1190. }
  1191. //outer
  1192. if (outerLights.Count > 0)
  1193. {
  1194. float pressureDiff = AbsDiff(ALlevel, Olevel);
  1195.  
  1196. if (pressureDiff < SMALL_DIFF)
  1197. {
  1198. lightColor = go_color;
  1199. }
  1200. else if (pressureDiff > MOD_DIFF)
  1201. {
  1202. lightColor = stop_color;
  1203. }
  1204. else
  1205. {
  1206. lightColor = caution_color;
  1207. }
  1208.  
  1209. if (SMOOTH_COLOR)
  1210. {
  1211. lightColor = SmoothColor(pressureDiff);
  1212. }
  1213.  
  1214. for (int i = 0; i < outerLights.Count; i++)
  1215. {
  1216. light = outerLights[i] as IMyLightingBlock;
  1217. light.SetValue("Color", lightColor);
  1218. }
  1219. }
  1220.  
  1221.  
  1222.  
  1223.  
  1224. }
  1225. public void SetSoundBlocks()
  1226. {
  1227. if (soundblocks.Count == 0 || !enable_sounds)
  1228. return;
  1229.  
  1230. if (IsEqualised)
  1231. {
  1232. if (!readySoundPlayed)
  1233. {
  1234. PlaySound(ready_sound, loop_period_ready);
  1235. readySoundPlayed = true;
  1236. }
  1237. eqSoundPlayed = false; //reset eq flag
  1238. }
  1239. else if (!IsEqualised)
  1240. {
  1241. if (!eqSoundPlayed)
  1242. {
  1243. PlaySound(equalising_sound, loop_period_eq);
  1244. eqSoundPlayed = true;
  1245. }
  1246. readySoundPlayed = false; //reset ready flag
  1247. }
  1248. }
  1249. private void PlaySound(string sound, float period)
  1250. {
  1251. IMySoundBlock sb;
  1252. for (int i = 0; i < soundblocks.Count; i++)
  1253. {
  1254. sb = soundblocks[i] as IMySoundBlock;
  1255. sb.SelectedSound = sound;
  1256. sb.LoopPeriod = period;
  1257. sb.Play();
  1258. }
  1259. }
  1260.  
  1261. private void StopSound(string sound, float period)
  1262. {
  1263. IMySoundBlock sb;
  1264. for (int i = 0; i < soundblocks.Count; i++)
  1265. {
  1266. sb = soundblocks[i] as IMySoundBlock;
  1267. sb.Stop();
  1268. }
  1269. }
  1270.  
  1271. private float AbsDiff(float a, float b)
  1272. {
  1273. float result = a - b;
  1274. if (result < 0)
  1275. return result * -1;
  1276. else
  1277. return result;
  1278. }
  1279. private float Pressure(List<IMyTerminalBlock> vents)
  1280. {
  1281. if (vents.Count == 0)
  1282. return DEFALT_PRESSURE;
  1283. else
  1284. {
  1285. IMyAirVent vent = vents[0] as IMyAirVent;
  1286. return vent.GetOxygenLevel();
  1287. }
  1288.  
  1289.  
  1290. }
  1291. public float ALPressure()
  1292. {
  1293. if (alVents.Count == 0)
  1294. return DEFALT_PRESSURE;
  1295. else
  1296. {
  1297. IMyAirVent vent = alVents[0] as IMyAirVent;
  1298. return vent.GetOxygenLevel();
  1299. }
  1300.  
  1301.  
  1302. }
  1303.  
  1304. private bool TanksAreFull()
  1305. {
  1306. if (tanks.Count == 0)
  1307. return false; //no tagged tanks, assume all ok
  1308. IMyGasTank tank;
  1309. for (int i = 0; i < tanks.Count; i++)
  1310. {
  1311. tank = tanks[i] as IMyGasTank;
  1312. if (tank.FilledRatio < 1)
  1313. return false;
  1314. }
  1315. return true;
  1316.  
  1317. }
  1318. private bool TanksAreEmpty()
  1319. {
  1320. if (tanks.Count == 0)
  1321. return false; //no tagged tanks, assume all ok
  1322. IMyGasTank tank;
  1323. for (int i = 0; i < tanks.Count; i++)
  1324. {
  1325. tank = tanks[i] as IMyGasTank;
  1326. if (tank.FilledRatio > 0)
  1327. return false;
  1328. }
  1329. return true;
  1330. }
  1331.  
  1332. private bool SensorActive(List<IMyTerminalBlock> sensors)
  1333. {
  1334. if (sensors.Count == 0)
  1335. return false;
  1336. IMySensorBlock sen;
  1337. for (int i = 0; i < sensors.Count; i++)
  1338. {
  1339. sen = sensors[i] as IMySensorBlock;
  1340. if (sen.IsActive)
  1341. return true;
  1342. }
  1343. return false;
  1344. }
  1345. private void CloseDoors(List<IMyTerminalBlock> doors)
  1346. {
  1347. if (doors.Count == 0)
  1348. return;
  1349. IMyDoor door;
  1350. for (int i = 0; i < doors.Count; i++)
  1351. {
  1352. door = doors[i] as IMyDoor;
  1353. door.ApplyAction("OnOff_On");
  1354. door.ApplyAction("Open_Off");
  1355. if (LOCKDOORS && door.OpenRatio == 0)
  1356. door.ApplyAction("OnOff_Off");
  1357.  
  1358. }
  1359. }
  1360. private void CloseDoorsUnlocked(List<IMyTerminalBlock> doors)
  1361. {
  1362. if (doors.Count == 0)
  1363. return;
  1364. IMyDoor door;
  1365. for (int i = 0; i < doors.Count; i++)
  1366. {
  1367. door = doors[i] as IMyDoor;
  1368. door.ApplyAction("OnOff_On");
  1369. door.ApplyAction("Open_Off");
  1370. }
  1371. }
  1372. public bool CloseOnDelay(List<IMyTerminalBlock> doors, DateTime dTime) //superfluious variable pass
  1373. {
  1374. /*closes doors if they have been open for DOORCLOSEDELAY, doors remain ON, returns true if door was closed*/
  1375. /*takes a list of doors to close and the time they where opened*/
  1376. if (!autoCloseDoors)
  1377. return false;
  1378. timeSinceDoorOpened = (System.DateTime.Now - dTime).TotalMilliseconds;
  1379. if (timeSinceDoorOpened > doorCloseDelay)
  1380. {
  1381. CloseDoors(doors);
  1382. TurnOnDoors(doors); //leave on to allow to be re-opened manualy
  1383. return true;
  1384. }
  1385. else
  1386. return false;
  1387.  
  1388. }
  1389.  
  1390. public void ResetDoorTimer(DateTime time)
  1391. {
  1392. time = System.DateTime.Now;
  1393. }
  1394. public void ResetDoorTimerInner()
  1395. {
  1396. doorTimeInner = System.DateTime.Now;
  1397. }
  1398. public void ResetDoorTimerOuter()
  1399. {
  1400. doorTimeOuter = System.DateTime.Now;
  1401. }
  1402.  
  1403. public bool DoorsClosed(List<IMyTerminalBlock> doors)
  1404. {
  1405. //returns false if any door is open
  1406. if (doors.Count == 0)
  1407. return true;
  1408. IMyDoor d;
  1409. for (int i = 0; i < doors.Count; i++)
  1410. {
  1411. d = doors[i] as IMyDoor;
  1412. if (d.OpenRatio != 0)
  1413. return false;
  1414. }
  1415. return true;
  1416. }
  1417. public void OpenDoors(List<IMyTerminalBlock> doors)
  1418. {
  1419. if (doors.Count == 0)
  1420. return;
  1421. IMyDoor door;
  1422. for (int i = 0; i < doors.Count; i++)
  1423. {
  1424. door = doors[i] as IMyDoor;
  1425. if (door.OpenRatio < 0.9)
  1426. {
  1427. if (door.Enabled)
  1428. {
  1429. if (AUTOOPENDOORS)
  1430. door.ApplyAction("Open_On");
  1431. }
  1432. else
  1433. door.ApplyAction("OnOff_On");
  1434. }
  1435.  
  1436. }
  1437. }
  1438.  
  1439. public void TurnOnDoors(List<IMyTerminalBlock> doors)
  1440. {
  1441. if (doors.Count == 0)
  1442. return;
  1443. IMyDoor door;
  1444. for (int i = 0; i < doors.Count; i++)
  1445. {
  1446. door = doors[i] as IMyDoor;
  1447. door.ApplyAction("OnOff_On");
  1448. }
  1449. }
  1450.  
  1451. public void Pressurise(List<IMyTerminalBlock> vents)
  1452. {//should always be al vents
  1453. if (vents.Count == 0)
  1454. return;
  1455.  
  1456. IMyAirVent vent;
  1457. for (int i = 0; i < vents.Count; i++)
  1458. {
  1459. vent = vents[i] as IMyAirVent;
  1460. vent.ApplyAction("Depressurize_Off");
  1461. }
  1462. }
  1463. public void DePressurise(List<IMyTerminalBlock> vents)
  1464. {//should always be al vents
  1465. if (vents.Count == 0)
  1466. return;
  1467. IMyAirVent vent;
  1468. for (int i = 0; i < vents.Count; i++)
  1469. {
  1470. vent = vents[i] as IMyAirVent;
  1471. vent.ApplyAction("Depressurize_On");
  1472. }
  1473. }
  1474.  
  1475. public bool Samesies(List<IMyTerminalBlock> ventsO, List<IMyTerminalBlock> ventsAL)
  1476. {
  1477. if (ventsAL.Count == 0)
  1478. {
  1479. return true; // no air lock vent, still need to allow doors to open
  1480. }
  1481. if (ventsO.Count == 0)
  1482. {
  1483. return (ventsAL[0] as IMyAirVent).Depressurize; //no vent outer, treat as depressurising
  1484. }
  1485. IMyAirVent ventO = ventsO[0] as IMyAirVent;
  1486. IMyAirVent ventAL = ventsAL[0] as IMyAirVent;
  1487. if (ventO.Depressurize == ventAL.Depressurize)
  1488. return true;
  1489. return false;
  1490.  
  1491. }
  1492.  
  1493. public void TurnOff(List<IMyTerminalBlock> blocks)
  1494. {
  1495. if (blocks.Count == 0)
  1496. return;
  1497. for (int i = 0; i < blocks.Count; i++)
  1498. {
  1499. blocks[i].ApplyAction("OnOff_Off");
  1500. }
  1501. }
  1502.  
  1503. public void TurnOn(List<IMyTerminalBlock> blocks)
  1504. {
  1505. if (blocks.Count == 0)
  1506. return;
  1507. for (int i = 0; i < blocks.Count; i++)
  1508. {
  1509. if (!blocks[i].IsWorking)
  1510. blocks[i].ApplyAction("OnOff_On");
  1511. }
  1512. }
  1513.  
  1514. public float PressureDiff(List<IMyTerminalBlock> ventsA, List<IMyTerminalBlock> ventsB)
  1515. {
  1516. float result = Pressure(ventsA) - Pressure(ventsB);
  1517. if (result < 0)
  1518. return result * -1;
  1519. else
  1520. return result;
  1521. }
  1522.  
  1523.  
  1524. public string ProgressBar(float progress)
  1525. {
  1526. string text = "";
  1527. for (int i = 0; i < progress * lcd_width; i++)
  1528. {
  1529. text += '|';
  1530. }
  1531. return text;
  1532. }
  1533. public string BuildDisplayText(string text, float level)
  1534. {
  1535. return text + '\n' + ProgressBar(level);
  1536. }
  1537. public string BuildDisplayTextWide(string text, float level)
  1538. {
  1539. return text + '\n' + ProgressBar(level * 2);
  1540. }
  1541.  
  1542. public Color SmoothColor(float diff)
  1543. {
  1544. Color c = caution_color;
  1545. c.R = (byte)(smooth_stop_color.R * diff);
  1546. c.G = (byte)(smooth_stop_color.G * diff);
  1547. c.B = (byte)(smooth_stop_color.B * diff);
  1548.  
  1549. c.R += (byte)(smooth_go_color.R - smooth_go_color.R * diff);
  1550. c.G += (byte)(smooth_go_color.G - smooth_go_color.G * diff);
  1551. c.B += (byte)(smooth_go_color.B - smooth_go_color.B * diff);
  1552. return c;
  1553. }
  1554.  
  1555. public override string ToString()
  1556. {
  1557. StringBuilder sb = new StringBuilder();
  1558. sb.Append(Name + " : ");
  1559. sb.Append("Oxygen Level: " + (int)(100 * Pressure(alVents)) + "% ");
  1560. if (!Enabled)
  1561. sb.Append("[DISABLED] ");
  1562. if (isventing)
  1563. sb.Append("[VENTING] ");
  1564. if (TanksAreFull())
  1565. sb.Append("[OXYGEN TANKS FULL] ");
  1566. if (TanksAreEmpty())
  1567. sb.Append("[OXYGEN TANKS EMPTY] ");
  1568. if (!DoorsClosed(innerDoors) || !DoorsClosed(outerDoors))
  1569. sb.Append("[Door Open] ");
  1570. return sb.ToString();
  1571. }
  1572.  
  1573. public void ReadUserOptions()
  1574. {
  1575. string[] lines;
  1576. string[] part;
  1577. char[] delim = { '=' };
  1578. float tempfloat;
  1579. foreach (IMyTerminalBlock b in alVents)
  1580. {
  1581. lines = b.CustomData.Split('\n');
  1582. foreach (string l in lines)
  1583. {
  1584. part = l.Split(delim, 2, StringSplitOptions.RemoveEmptyEntries);
  1585. if (part.Length != 2)
  1586. continue;
  1587. if (part[0].Trim().ToUpper() == "FONT_SIZE")
  1588. {
  1589. if (float.TryParse(part[1].Trim(), out tempfloat))
  1590. {
  1591. font_size = tempfloat;
  1592. }
  1593. }
  1594. if (part[0].Trim().ToUpper() == "NAME")
  1595. {
  1596. Name = part[1].Trim();
  1597. }
  1598. if (part[0].Trim().ToUpper() == "DOORCLOSEDELAY")
  1599. {
  1600. if(float.TryParse(part[1].Trim(), out tempfloat))
  1601. doorCloseDelay = tempfloat;
  1602. }
  1603.  
  1604.  
  1605. }
  1606.  
  1607. }
  1608. }
  1609.  
  1610.  
  1611.  
  1612. }
  1613.  
  1614. public void Save()
  1615. {
  1616. //WriteUserOptions();
  1617. }
  1618.  
  1619.  
  1620.  
  1621.  
  1622. public static class TextTools
  1623. {
  1624. //static float fontSize = 1.0f;
  1625. static public int singlePanelWidth = 660;
  1626. static Dictionary<char, float> charWidth = new Dictionary<char, float>();
  1627. const char PADDING_CHAR = ' ';
  1628. static TextTools()
  1629. {
  1630. AddCharsToDictionary("\n", 0);
  1631. AddCharsToDictionary("'|¦ˉ‘’‚", 6);
  1632. AddCharsToDictionary("ј", 7);
  1633. AddCharsToDictionary(" ", 8);
  1634. AddCharsToDictionary("!I`ijl ¡¨¯´¸ÌÍÎÏìíîïĨĩĪīĮįİıĵĺļľłˆˇ˘˙˚˛˜˝ІЇії‹›∙", 8);
  1635. AddCharsToDictionary("();,.1:;[]ft{}·ţťŧț", 9);
  1636. AddCharsToDictionary("\"; -rª­ºŀŕŗř", 10);
  1637. AddCharsToDictionary("*²³¹", 11);
  1638. AddCharsToDictionary("\\°“”„", 12);
  1639. AddCharsToDictionary("ґ", 13);
  1640. AddCharsToDictionary("/ijтэє", 14);
  1641. AddCharsToDictionary("L_vx«»ĹĻĽĿŁГгзлхчҐ–•", 15);
  1642. AddCharsToDictionary("7?Jcz¢¿çćĉċčĴźżžЃЈЧавийнопсъьѓѕќ", 16);
  1643. AddCharsToDictionary("3FKTabdeghknopqsuy£µÝàáâãäåèéêëðñòóôõöøùúûüýþÿāăąďđēĕėęěĝğġģĥħĶķńņňʼnōŏőśŝşšŢŤŦũūŭůűųŶŷŸșȚЎЗКЛбдекруцяёђћўџ", 17);
  1644. AddCharsToDictionary("+<=>;E^~¬±¶ÈÉÊË×÷ĒĔĖĘĚЄЏЕНЭ−", 18);
  1645. AddCharsToDictionary("#0245689CXZ¤¥ÇßĆĈĊČŹŻŽƒЁЌАБВДИЙПРСТУХЬ€", 19);
  1646. AddCharsToDictionary("$&GHPUVY§ÙÚÛÜÞĀĜĞĠĢĤĦŨŪŬŮŰŲОФЦЪЯжы†‡", 20);
  1647. AddCharsToDictionary("ABDNOQRSÀÁÂÃÄÅÐÑÒÓÔÕÖØĂĄĎĐŃŅŇŌŎŐŔŖŘŚŜŞŠȘЅЊЖф□", 21);
  1648. AddCharsToDictionary("љ", 22);
  1649. AddCharsToDictionary("ю", 23);
  1650. AddCharsToDictionary("%IJЫ", 24);
  1651. AddCharsToDictionary("@©®мшњ", 25);
  1652. AddCharsToDictionary("MМШ", 26);
  1653. AddCharsToDictionary("mw¼ŵЮщ", 27);
  1654. AddCharsToDictionary("¾æœЉ", 28);
  1655. AddCharsToDictionary("½Щ", 29);
  1656. AddCharsToDictionary("™", 30);
  1657. AddCharsToDictionary("WÆŒŴ—…‰", 31);
  1658. AddCharsToDictionary("", 32);
  1659. AddCharsToDictionary("", 34);
  1660. AddCharsToDictionary("", 40);
  1661. AddCharsToDictionary("", 41);
  1662.  
  1663.  
  1664. }
  1665.  
  1666. static private void AddCharsToDictionary(string chars, float charSize)
  1667. {
  1668.  
  1669. for (int i = 0; i < chars.Length; i++)
  1670. {
  1671. if (!charWidth.ContainsKey(chars[i]))
  1672. charWidth.Add(chars[i], charSize);
  1673. }
  1674. }
  1675.  
  1676. static public float TotalWidth(string text)
  1677. {
  1678. float width = 0;
  1679. float w;
  1680. foreach (char c in text)
  1681. {
  1682. if (charWidth.TryGetValue(c, out w))
  1683. width += charWidth[c] + 1; //add 1 for space betwixt chars
  1684. else
  1685. width += 18; //some middleing value 18
  1686. }
  1687. if (width > 1)
  1688. return width - 1; //remove 1 for trailing space
  1689. else
  1690. return 0;
  1691. }
  1692.  
  1693. static public string Center(string text, float fontSize = 1.0f, float screenWidth = 1)
  1694. {
  1695. text = text.Trim();
  1696. screenWidth = (screenWidth * singlePanelWidth) / fontSize; //screen width in px
  1697. float margin = 2 * fontSize;
  1698. float textWidth = TotalWidth(text);
  1699. float paddingwidth = (screenWidth - textWidth) / 2 - margin;
  1700. float paddingcharwidth = charWidth[PADDING_CHAR] + 1;
  1701. int paddingchars = (int)Math.Round(paddingwidth / paddingcharwidth, MidpointRounding.AwayFromZero); // +1
  1702. if (paddingchars < 1)
  1703. return text;
  1704. string s = new string(PADDING_CHAR, paddingchars);
  1705. return s + text;
  1706. }
  1707.  
  1708.  
  1709.  
  1710. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement