Advertisement
Guest User

LCD

a guest
Dec 2nd, 2016
107
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 94.50 KB | None | 0 0
  1. /* v:1.132 [01.144 Stable compatibility, Right command, DetailsX & Dampeners & Occupied commands, Accel, More Power variants, PowerTime, Same grid filter]    
  2. * In-game script by MMaster    
  3. *
  4. * Last Update: Fix for modded items with space in SubtypeId not showing up
  5. * 01.144 game update compatibility  
  6. * Right command  
  7. *    
  8. * Previous updates: Look at Change notes tab on Steam workshop page.    
  9. * Dampeners & Occupied commands, DetailsX which skips "Type:" line  
  10. * Performance optimizations when Trigger Now is used  
  11. * Fixed \ adding space to command  
  12. * Comments in Private text using //  
  13. *    
  14. * Customize these: (do not report problems with modified values!) */
  15.  
  16. // Use this tag to identify LCDs managed by this script    
  17. // Name filtering rules can be used here so you can use even G:Group or T:[My LCD]    
  18. public static string LCD_TAG = "T:[LCD]";
  19.  
  20. // How many panels to update per one step    
  21. public static int PANELS_PER_STEP = 1;
  22. // How many lines to scroll per step    
  23. public static int SCROLL_LINES_PER_STEP = 5;
  24.  
  25. // Enable initial boot sequence (after compile / world load)    
  26. public static bool ENABLE_BOOT = true;
  27.  
  28. // Force redraw of panels? (default = true)    
  29. // true - forces redraw of panels (should no longer be needed - its needed again!)  
  30. public static bool FORCE_REDRAW = true;
  31.  
  32. // (for developer) Enable debug to LCD marked with [DEBUG]    
  33. public static bool EnableDebug = false;
  34.  
  35. /*    
  36. READ THIS FULL GUIDE    
  37. http://steamcommunity.com/sharedfiles/filedetails/?id=407158161    
  38.    
  39. Basic video guide    
  40. Please watch the video guide even if you don't understand my English. You can see how things are done there.    
  41.    
  42. http://www.youtube.com/watch?v=oopzyQ0t6Dk    
  43.    
  44. EXAMPLE WORLD    
  45. http://steamcommunity.com/sharedfiles/filedetails/?id=412154340    
  46.    
  47. Read Change Notes (above screenshots) for latest updates and new features.    
  48. I notify about updates on twitter so follow if interested.    
  49.    
  50. Please carefully read the FULL GUIDE before asking questions I had to remove guide from here to add more features :(    
  51. Please DO NOT publish this script or its derivations without my permission! Feel free to use it in blueprints!    
  52.    
  53. Special Thanks    
  54. bssespaceengineers.com - awesome server    
  55. Rhedd - for his contribution to modded items entries    
  56. Textor and CyberVic for their great script related contributions on Keen forums.    
  57.    
  58. Watch Twitter: https://twitter.com/MattsPlayCorner    
  59. and Facebook: https://www.facebook.com/MattsPlayCorner1080p    
  60. for more crazy stuff from me in the future :)    
  61. */
  62. void InitBoot()
  63. {
  64. if (LCDsProgram.bootFrames == null)
  65. LCDsProgram.bootFrames = new List<string>()    
  66. {    
  67.    
  68. /* BOOT FRAMES    
  69. * Each @"<text>" marks single frame, add as many as you want each will be displayed for one second    
  70. * @"" is multiline string so you can write multiple lines    
  71. */    
  72. @"    
  73. Initializing systems"    
  74. ,    
  75. @"    
  76. Verifying connections"    
  77. ,    
  78. @"    
  79. Loading commands"    
  80. /* END OF BOOT FRAMES */    
  81.    
  82. // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!    
  83. // DO NOT MODIFY ANYTHING BELOW THIS    
  84. // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!    
  85. };
  86. }
  87.  
  88. public static string SECONDARY_TAG = "T:!LCD!";
  89. public static int step;
  90. void Main(string argument)
  91. {
  92. MM.EnableDebug = EnableDebug;
  93. MM.Me = Me;
  94. MM.Echo = Echo;
  95. MM.ElapsedTime += Runtime.TimeSinceLastRun.TotalSeconds;
  96. InitBoot();
  97. if (!MM.Init(GridTerminalSystem)) return;
  98. MMLCDMgr.forceRedraw = FORCE_REDRAW;
  99. MMLCDMgr.SCROLL_LINES = SCROLL_LINES_PER_STEP;
  100. LCDsProgram.SECONDARY_TAG = SECONDARY_TAG;
  101. LCDsProgram.PANELS_PER_STEP = PANELS_PER_STEP;
  102. if (!ENABLE_BOOT)
  103. LCDsProgram.bootStep = int.MaxValue;
  104. LCDsProgram.bootScreens = ENABLE_BOOT;
  105.  
  106. LCDsProgram lcdProg = new LCDsProgram(LCD_TAG);
  107. lcdProg.Run(argument.ToLower(), step++);
  108. MM.ElapsedTime = 0;
  109. }
  110. }
  111.  
  112. public static class MMItems
  113. {
  114. public static Dictionary<string, MMItem> items = new Dictionary<string, MMItem>();
  115. public static Dictionary<string, MMItem> itemsBySubtype = new Dictionary<string, MMItem>();
  116. public static List<string> keys = new List<string>();
  117. public static Dictionary<string, MMItem> itemsByShort = new Dictionary<string, MMItem>();
  118.  
  119. public static void Init()
  120. {
  121. if (items.Count > 0) return;
  122.  
  123. // **************************************************    
  124. // OK MAYBE YOU CAN ADD MODDED ITEMS AND MODIFY QUOTAS    
  125. //    IF THAT WARNING DIDN'T SCARE YOU    
  126. // **************************************************    
  127. // ITEMS AND QUOTAS LIST    
  128. // (subType, mainType, quota, display name, short name)    
  129. // ADD MODDED ITEMS TO THIS LIST    
  130. // !! MAIN TYPES MUST GO TOGETHER FOR INV CATEGORIES !!    
  131. // VANILLA ITEMS  
  132. Add("Stone", "Ore");
  133. Add("Iron", "Ore");
  134. Add("Nickel", "Ore");
  135. Add("Cobalt", "Ore");
  136. Add("Magnesium", "Ore");
  137. Add("Silicon", "Ore");
  138. Add("Silver", "Ore");
  139. Add("Gold", "Ore");
  140. Add("Platinum", "Ore");
  141. Add("Uranium", "Ore");
  142. Add("Ice", "Ore");
  143. Add("Stone", "Ingot", 40000, "Gravel", "gravel");
  144. Add("Iron", "Ingot", 300000);
  145. Add("Nickel", "Ingot", 900000);
  146. Add("Cobalt", "Ingot", 120000);
  147. Add("Magnesium", "Ingot", 80000);
  148. Add("Silicon", "Ingot", 80000);
  149. Add("Silver", "Ingot", 800000);
  150. Add("Gold", "Ingot", 80000);
  151. Add("Platinum", "Ingot", 45000);
  152. Add("Uranium", "Ingot", 12000);
  153. Add("Scrap", "Ingot");
  154. Add("AutomaticRifleItem", "Tool", 0, "Automatic Rifle");
  155. Add("PreciseAutomaticRifleItem", "Tool", 0, "* Precise Rifle");
  156. Add("RapidFireAutomaticRifleItem", "Tool", 0, "** Rapid-Fire Rifle");
  157. Add("UltimateAutomaticRifleItem", "Tool", 0, "*** Elite Rifle");
  158. Add("WelderItem", "Tool", 0, "Welder");
  159. Add("Welder2Item", "Tool", 0, "* Enh. Welder");
  160. Add("Welder3Item", "Tool", 0, "** Prof. Welder");
  161. Add("Welder4Item", "Tool", 0, "*** Elite Welder");
  162. Add("AngleGrinderItem", "Tool", 0, "Angle Grinder");
  163. Add("AngleGrinder2Item", "Tool", 0, "* Enh. Grinder");
  164. Add("AngleGrinder3Item", "Tool", 0, "** Prof. Grinder");
  165. Add("AngleGrinder4Item", "Tool", 0, "*** Elite Grinder");
  166. Add("HandDrillItem", "Tool", 0, "Hand Drill");
  167. Add("HandDrill2Item", "Tool", 0, "* Enh. Drill");
  168. Add("HandDrill3Item", "Tool", 0, "** Prof. Drill");
  169. Add("HandDrill4Item", "Tool", 0, "*** Elite Drill");
  170. Add("Construction", "Component", 50000);
  171. Add("MetalGrid", "Component", 15500, "Metal Grid");
  172. Add("InteriorPlate", "Component", 55000, "Interior Plate");
  173. Add("SteelPlate", "Component", 300000, "Steel Plate");
  174. Add("Girder", "Component", 3500);
  175. Add("SmallTube", "Component", 26000, "Small Tube");
  176. Add("LargeTube", "Component", 6000, "Large Tube");
  177. Add("Motor", "Component", 16000);
  178. Add("Display", "Component", 500);
  179. Add("BulletproofGlass", "Component", 12000, "Bulletp. Glass", "bpglass");
  180. Add("Computer", "Component", 6500);
  181. Add("Reactor", "Component", 10000);
  182. Add("Thrust", "Component", 16000, "Thruster", "thruster");
  183. Add("GravityGenerator", "Component", 250, "GravGen", "gravgen");
  184. Add("Medical", "Component", 120);
  185. Add("RadioCommunication", "Component", 250, "Radio-comm", "radio");
  186. Add("Detector", "Component", 400);
  187. Add("Explosives", "Component", 500);
  188. Add("SolarCell", "Component", 2800, "Solar Cell");
  189. Add("PowerCell", "Component", 2800, "Power Cell");
  190. Add("Superconductor", "Component", 3000);
  191. Add("NATO_5p56x45mm", "Ammo", 8000, "5.56x45mm", "5.56x45mm");
  192. Add("NATO_25x184mm", "Ammo", 2500, "25x184mm", "25x184mm");
  193. Add("Missile200mm", "Ammo", 1600, "200mm Missile", "200mmmissile");
  194. Add("OxygenBottle", "OxygenContainerObject", 5, "Oxygen Bottle");
  195. Add("HydrogenBottle", "GasContainerObject", 5, "Hydrogen Bottle");
  196.  
  197.  
  198. // MODDED ITEMS    
  199. // (subType, mainType, quota, display name, short name, used)    
  200. // * if used is true, item will be shown in inventory even for 0 items    
  201. // * if used is false, item will be used only for display name and short name    
  202. // AzimuthSupercharger    
  203. Add("AzimuthSupercharger", "Component", 1600, "Supercharger", "supercharger", false);
  204. // OKI Ammo    
  205. Add("OKI23mmAmmo", "Ammo", 500, "23x180mm", "23x180mm", false);
  206. Add("OKI50mmAmmo", "Ammo", 500, "50x450mm", "50x450mm", false);
  207. Add("OKI122mmAmmo", "Ammo", 200, "122x640mm", "122x640mm", false);
  208. Add("OKI230mmAmmo", "Ammo", 100, "230x920mm", "230x920mm", false);
  209. }
  210.  
  211. /* REALLY REALLY REALLY    
  212. * DO NOT MODIFY ANYTHING BELOW THIS    
  213. */
  214.  
  215. // displayName - how the item will be displayed    
  216. // shortName - how the item can be called in arguments (eg: +supercharger)    
  217. public static void Add(string subType, string mainType, int quota = 0, string displayName = "", string shortName = "", bool used = true)
  218. {
  219. if (mainType == "Ammo")
  220. mainType = "AmmoMagazine";
  221. else if (mainType == "Tool")
  222. mainType = "PhysicalGunObject";
  223. string fullType = subType + ' ' + mainType;
  224. MMItem item = new MMItem(subType, mainType, quota, displayName, shortName, used);
  225. items.Add(fullType, item);
  226. if (!itemsBySubtype.ContainsKey(subType))
  227. itemsBySubtype.Add(subType, item);
  228. if (shortName != "")
  229. itemsByShort.Add(shortName.ToLower(), item);
  230. keys.Add(fullType);
  231. }
  232.  
  233. public static MMItem GetItemOfType(string subType = "", string mainType = "")
  234. {
  235. if (items.ContainsKey(subType + " " + mainType))
  236. return items[subType + " " + mainType];
  237.  
  238. if (mainType == "") {
  239. MMItem item = null;
  240. itemsBySubtype.TryGetValue(subType, out item);
  241. return item;
  242. }
  243.  
  244. if (subType == "")
  245. for (int i = 0; i < items.Count; i++) {
  246. MMItem item = items[keys[i]];
  247. if (mainType == item.mainType)
  248. return item;
  249. }
  250. return null;
  251. }
  252. }
  253.  
  254. public class LCDsProgram
  255. {
  256. // for german clients    
  257. public static string SECONDARY_TAG = "";
  258. // approximate width of LCD panel line    
  259. public const float LCD_LINE_WIDTH = 730;
  260. // x position of inventory numbers    
  261. public const float LCD_LINE_NUMERS_POS = LCD_LINE_WIDTH - 30;
  262.  
  263. public const float LCD_LINE_INV_NUMBERS_POS = LCD_LINE_WIDTH - 130;
  264. public const float LCD_LINE_INGOT_NUMBERS_POS = 375;
  265. public const float LCD_LINE_DMG_NUMBERS_POS = LCD_LINE_WIDTH - 230;
  266. public const float LCD_LINE_WORK_STATE_POS = LCD_LINE_WIDTH - 30;
  267. public const float LCD_LINE_BLOCK_COUNT_POS = LCD_LINE_WIDTH - 30;
  268.  
  269. public const float PERCENT_TEXT_SIZE = 110f;
  270.  
  271. // number of component progress bar characters    
  272. public const int INV_PROGRESS_CHARS = 38;
  273. // full line of progress bar    
  274. public const int FULL_PROGRESS_CHARS = 116;
  275.  
  276. public static int PANELS_PER_STEP = 1;
  277.  
  278. public MMPanelDict panels = new MMPanelDict();
  279. public double velocity = 0;
  280. public static double lastVel = 0;
  281. public double accel = 0;
  282.  
  283. public static Dictionary<string, int> ptNLtoIdx = new Dictionary<string, int>();
  284. public static List<double> ptElapsedL = new List<double>();
  285. public static VRageMath.Vector3D lastPos;
  286. public static int bootStep = 0;
  287. public static bool bootScreens = true;
  288. public static List<string> bootFrames = null;
  289. public LCDsProgram(string nameLike)
  290. {
  291. MMBlkCol lcds = new MMBlkCol();
  292. lcds.AddBofT("textpanel", nameLike);
  293. if (nameLike == "T:[LCD]" && SECONDARY_TAG != "")
  294. lcds.AddBofT("textpanel", SECONDARY_TAG);
  295.  
  296. int i = 0;
  297. while (i < lcds.Count()) {
  298. IMyTextPanel panel = (lcds.Blocks[i] as IMyTextPanel);
  299. if (!panel.IsWorking) {
  300. lcds.Blocks.RemoveAt(i);
  301. continue;
  302. }
  303. string text = panel.CustomName + " " + panel.NumberInGrid + " " + panel.GetPosition().ToString("F0");
  304. MMPanel p = null;
  305.  
  306. int joinpos = text.IndexOf("!LINK:");
  307.  
  308. if (joinpos < 0 || text.Length == joinpos + 6) {
  309. p = new MMPanel();
  310. p.panels.AddItem(text, panel);
  311. panels.AddItem(text, p);
  312. i++;
  313. continue;
  314. }
  315.  
  316. text = text.Substring(joinpos + 6);
  317.  
  318. string[] subs = text.Split(' ');
  319. string group = subs[0];
  320. p = panels.GetItem(group);
  321. if (p == null) {
  322. p = new MMPanel();
  323. panels.AddItem(group, p);
  324. }
  325. p.panels.AddItem(text, panel);
  326. i++;
  327. }
  328. }
  329.  
  330. public void Run(string argument, int step)
  331. {
  332. if (panels.CountAll() == 0)
  333. return;
  334.  
  335. velocity = (MM.Me.GetPosition() - lastPos).Length() / MM.ElapsedTime;
  336. accel = (velocity - lastVel) / MM.ElapsedTime;
  337.  
  338. for (int ei = 0; ei < ptElapsedL.Count; ei++)
  339. ptElapsedL[ei] += MM.ElapsedTime;
  340.  
  341. if (argument == "clear") {
  342. bootStep = (bootScreens ? 0 : int.MaxValue);
  343. for (int i = 0; i < panels.CountAll(); i++) {
  344. MMPanel p = panels.GetItemAt(i);
  345. p.SortPanels();
  346. MMLCDMgr.SetupLCDText(p);
  347. MMLCDMgr.ClearText();
  348. MMLCDMgr.UpdatePanel(p);
  349. }
  350. }
  351. else
  352. if (argument == "boot" || bootStep <= bootFrames.Count) {
  353. if (bootStep > bootFrames.Count)
  354. bootStep = 0;
  355.  
  356. for (int i = 0; i < panels.CountAll(); i++) {
  357. MMPanel p = panels.GetItemAt(i);
  358. p.SortPanels();
  359. MMLCDMgr.SetupLCDText(p);
  360. MMLCDMgr.ClearText();
  361. // don't display on LCDs with really large font    
  362. if (p.first.GetValueFloat("FontSize") > 3f)
  363. continue;
  364. MMLCDMgr.AddCenterLn(M.T["B1"], LCD_LINE_WIDTH / 2);
  365. double perc = (double)bootStep / bootFrames.Count * 100;
  366. MMLCDMgr.AddBarLn(perc, FULL_PROGRESS_CHARS);
  367. if (bootStep == bootFrames.Count) {
  368. MMLCDMgr.AddLn("");
  369. MMLCDMgr.AddCenterLn("Configurable Automatic LCDs", LCD_LINE_WIDTH / 2);
  370. MMLCDMgr.AddCenterLn("by MMaster", LCD_LINE_WIDTH / 2);
  371. }
  372. else
  373. MMLCDMgr.AddMultiLn(bootFrames[bootStep]);
  374. MMLCDMgr.UpdatePanel(p);
  375. }
  376. bootStep++;
  377. }
  378. else {
  379. for (int i = 0; i < PANELS_PER_STEP; i++) {
  380. RunSingle(panels.GetItemAt((step * PANELS_PER_STEP + i) % panels.CountAll()));
  381. }
  382. }
  383.  
  384. lastPos = MM.Me.GetPosition();
  385. lastVel = velocity;
  386. }
  387.  
  388. public void RunSingle(MMPanel panel)
  389. {
  390.  
  391. bool useText = false;
  392. panel.SortPanels();
  393. MMLCDMgr.SetupLCDText(panel);
  394.  
  395. string pubText = panel.first.CustomName;
  396. pubText = (pubText.Contains("#") ? pubText.Substring(pubText.LastIndexOf('#') + 1) : "");
  397. MMLCDMgr.ClearText();
  398.  
  399. if (pubText != "")
  400. MMLCDMgr.AddLn(pubText);
  401.  
  402. string title = panel.first.GetPrivateTitle();
  403. if (title == "Title" || title == "")
  404. title = panel.first.GetPublicTitle();
  405.  
  406. if (title.Trim() == "UseTextCommands") {
  407. useText = true;
  408. title = panel.first.GetPrivateText();
  409. title = title.Replace("\\\n", "");
  410. }
  411.  
  412. if (title.StartsWith("Public") || title == "") {
  413. if (useText)
  414. MMLCDMgr.AddLn(M.T["H1"]);
  415. else
  416. MMLCDMgr.AddLn(M.T["H2"]);
  417. MMLCDMgr.UpdatePanel(panel);
  418. return;
  419. }
  420.  
  421. char[] delim = { ';', '\n' };
  422. string[] cmds = title.Split(delim);
  423. for (int i = 0; i < cmds.Length; i++) {
  424. MM.Debug("Running command " + cmds[i]);
  425. if (cmds[i].Trim().StartsWith("//"))
  426. continue;
  427.  
  428. MMCmd cmd = new MMCmd(cmds[i]);
  429.  
  430. if (cmd.cmdstr.StartsWith("inventory") ||
  431. cmd.cmdstr == "missing" ||
  432. cmd.cmdstr.StartsWith("invlist"))
  433. RunInvListing(cmd);
  434. else
  435. if (cmd.cmdstr.StartsWith("cargo"))
  436. RunCargoStatus(cmd);
  437. else
  438. if (cmd.cmdstr.StartsWith("mass"))
  439. RunMass(cmd);
  440. else
  441. if (cmd.cmdstr == "oxygen")
  442. RunOxygenStatus(cmd);
  443. else
  444. if (cmd.cmdstr == "tanks")
  445. RunTankStatus(cmd);
  446. else
  447. if (cmd.cmdstr.StartsWith("powertime"))
  448. RunPowerTime(cmd);
  449. else
  450. if (cmd.cmdstr.StartsWith("power"))
  451. RunPowerStatus(cmd);
  452. else
  453. if (cmd.cmdstr == "speed")
  454. RunVelocity(cmd);
  455. else
  456. if (cmd.cmdstr.StartsWith("accel"))
  457. RunAccel(cmd);
  458. else
  459. if (cmd.cmdstr.StartsWith("charge"))
  460. RunCharge(cmd);
  461. else
  462. if (cmd.cmdstr.StartsWith("time") ||
  463. cmd.cmdstr.StartsWith("date"))
  464. RunCurrentTime(cmd);
  465. else
  466. if (cmd.cmdstr.StartsWith("countdown"))
  467. RunCountdown(cmd);
  468. else
  469. if (cmd.cmdstr == "echo" ||
  470. cmd.cmdstr == "center" ||
  471. cmd.cmdstr == "right")
  472. RunEcho(cmd);
  473. else
  474. if (cmd.cmdstr.StartsWith("text"))
  475. RunText(cmd);
  476. else
  477. if (cmd.cmdstr.EndsWith("count"))
  478. RunBlockCount(cmd);
  479. else
  480. if (cmd.cmdstr.StartsWith("dampeners") || cmd.cmdstr.StartsWith("occupied"))
  481. RunShipCtrlStatus(cmd);
  482. else
  483. if (cmd.cmdstr.StartsWith("working"))
  484. RunWorkingList(cmd);
  485. else
  486. if (cmd.cmdstr.StartsWith("damage"))
  487. RunDamage(cmd);
  488. else
  489. if (cmd.cmdstr.StartsWith("amount"))
  490. RunItemAmount(cmd);
  491. else
  492. if (cmd.cmdstr.StartsWith("pos"))
  493. RunPosition(cmd);
  494. else
  495. if (cmd.cmdstr.StartsWith("details"))
  496. RunDetails(cmd);
  497. else
  498. MMLCDMgr.AddLn(M.T["UC"] + ": " + cmd.cmdstr);
  499.  
  500. MM.Debug("Done.");
  501. }
  502.  
  503. MMLCDMgr.UpdatePanel(panel);
  504.  
  505. }
  506.  
  507. public void RunCharge(MMCmd cmd)
  508. {
  509. bool simple = cmd.cmdstr.Contains("x");
  510. MMBlkCol blocks = new MMBlkCol();
  511. blocks.AddBofT("jumpdrive", cmd.nameLike);
  512.  
  513. if (blocks.Count() <= 0) {
  514. MMLCDMgr.AddLn("Charge: " + M.T["D2"]);
  515. return;
  516. }
  517.  
  518. for (int i = 0; i < blocks.Count(); i++) {
  519. IMyJumpDrive jd = blocks.Blocks[i] as IMyJumpDrive;
  520.  
  521. double cur, max, perc;
  522. perc = MMStatus.GetJDChargeVals(jd, out cur, out max);
  523.  
  524. MMLCDMgr.Add(jd.CustomName);
  525. if (!simple) {
  526. MMLCDMgr.AddRightLn(MM.FormatLargeNumber(cur) + "Wh / " + MM.FormatLargeNumber(max) + "Wh", LCD_LINE_WIDTH);
  527. MMLCDMgr.AddBar(perc, FULL_PROGRESS_CHARS, PERCENT_TEXT_SIZE);
  528. }
  529. MMLCDMgr.AddRightLn(' ' + perc.ToString("0.0") + "%", LCD_LINE_WIDTH);
  530. }
  531. }
  532.  
  533. public void RunVelocity(MMCmd cmd)
  534. {
  535. MMLCDMgr.Add(M.T["S1"] + " ");
  536. MMLCDMgr.AddRightLn(velocity.ToString("F1") + " m/s ", LCD_LINE_WIDTH);
  537. }
  538.  
  539. public void RunAccel(MMCmd cmd)
  540. {
  541. MMLCDMgr.Add(M.T["AC1"] + " ");
  542. MMLCDMgr.AddRightLn(accel.ToString("F1") + " m/s²", LCD_LINE_WIDTH);
  543. }
  544.  
  545. public void RunText(MMCmd cmd)
  546. {
  547. bool fromLCD = (cmd.cmdstr == "textlcd");
  548.  
  549. IMyTextPanel p = MMLCDMgr.curP.first;
  550. if (p == null)
  551. return;
  552.  
  553. string text = p.GetPrivateText();
  554.  
  555. if (fromLCD) {
  556. if (cmd.nameLike != "" && cmd.nameLike != "*") {
  557. IMyTextPanel tp = MM._GridTerminalSystem.GetBlockWithName(cmd.nameLike) as IMyTextPanel;
  558. if (tp == null) {
  559. MMLCDMgr.AddLn("TextLCD: " + M.T["T1"] + cmd.nameLike);
  560. return;
  561. }
  562.  
  563. text = tp.GetPublicText();
  564. }
  565. else {
  566. MMLCDMgr.AddLn("TextLCD:" + M.T["T2"]);
  567. return;
  568. }
  569. }
  570.  
  571. string[] lines = text.Split('\n');
  572. if (lines.Length == 0) {
  573. if (!fromLCD)
  574. MMLCDMgr.AddLn("Text: " + M.T["T3"]);
  575. return;
  576. }
  577.  
  578. for (int i = 0; i < lines.Length; i++)
  579. MMLCDMgr.AddLn(lines[i]);
  580. }
  581.  
  582. private void PrintDetails(IMyTerminalBlock block, int first = 0)
  583. {
  584. string[] lines = block.DetailedInfo.Split('\n');
  585. for (int j = first; j < lines.Length; j++)
  586. if (lines[j] != "")
  587. MMLCDMgr.AddLn("  " + lines[j]);
  588. }
  589.  
  590. public void RunDetails(MMCmd cmd)
  591. {
  592. if (cmd.nameLike == "" || cmd.nameLike == "*") {
  593. MMLCDMgr.AddLn("Details: " + M.T["D1"]);
  594. return;
  595. }
  596.  
  597. MMBlkCol blocks = new MMBlkCol();
  598. blocks.AddBOfName(cmd.nameLike);
  599.  
  600. if (blocks.Count() <= 0) {
  601. MMLCDMgr.AddLn("Details: " + M.T["D2"]);
  602. return;
  603. }
  604.  
  605. int si = (cmd.cmdstr.EndsWith("x") ? 1 : 0);
  606. IMyTerminalBlock block = blocks.Blocks[0];
  607. MMLCDMgr.AddLn(block.CustomName);
  608. PrintDetails(block, si);
  609.  
  610. for (int i = 1; i < blocks.Count(); i++) {
  611. block = blocks.Blocks[i];
  612. MMLCDMgr.AddLn("");
  613. MMLCDMgr.AddLn(block.CustomName);
  614. PrintDetails(block, si);
  615. }
  616. }
  617.  
  618. public void RunPosition(MMCmd cmd)
  619. {
  620. bool posxyz = (cmd.cmdstr == "posxyz");
  621. bool gps = (cmd.cmdstr == "posgps");
  622.  
  623. IMyTerminalBlock block = MMLCDMgr.curP.first;
  624. if (cmd.nameLike != "" && cmd.nameLike != "*") {
  625. block = MM._GridTerminalSystem.GetBlockWithName(cmd.nameLike);
  626. if (block == null) {
  627. MMLCDMgr.AddLn(M.T["P1"] + ": " + cmd.nameLike);
  628. return;
  629. }
  630. }
  631.  
  632. if (gps) {
  633. VRageMath.Vector3D pos = block.GetPosition();
  634.  
  635. MMLCDMgr.AddLn("GPS:" + M.T["P2"] + ":" +
  636. pos.GetDim(0).ToString("F2") + ":" +
  637. pos.GetDim(1).ToString("F2") + ":" +
  638. pos.GetDim(2).ToString("F2") + ":");
  639. return;
  640. }
  641.  
  642. MMLCDMgr.Add(M.T["P2"] + ": ");
  643. if (!posxyz) {
  644. MMLCDMgr.AddRightLn(block.GetPosition().ToString("F0"), LCD_LINE_WORK_STATE_POS);
  645. return;
  646. }
  647.  
  648. MMLCDMgr.AddLn("");
  649. MMLCDMgr.Add(" X: ");
  650. MMLCDMgr.AddRightLn(block.GetPosition().GetDim(0).ToString("F0"), LCD_LINE_WORK_STATE_POS);
  651. MMLCDMgr.Add(" Y: ");
  652. MMLCDMgr.AddRightLn(block.GetPosition().GetDim(1).ToString("F0"), LCD_LINE_WORK_STATE_POS);
  653. MMLCDMgr.Add(" Z: ");
  654. MMLCDMgr.AddRightLn(block.GetPosition().GetDim(2).ToString("F0"), LCD_LINE_WORK_STATE_POS);
  655. }
  656.  
  657. private void ShowBlkCntOfType(MMBlkCol blocks, string type, bool enabledCnt, bool producingCnt)
  658. {
  659. string name;
  660.  
  661. if (blocks.Count() == 0) {
  662. name = type.ToLower();
  663. name = char.ToUpper(name[0]) + name.Substring(1).ToLower();
  664. MMLCDMgr.Add(name + " " + M.T["C1"] + " ");
  665. string countstr = (enabledCnt || producingCnt ? "0 / 0" : "0");
  666. MMLCDMgr.AddRightLn(countstr, LCD_LINE_BLOCK_COUNT_POS);
  667. }
  668. else {
  669. Dictionary<string, int> typeCount = new Dictionary<string, int>();
  670. Dictionary<string, int> typeWorkingCount = new Dictionary<string, int>();
  671. List<string> blockTypes = new List<string>();
  672.  
  673. for (int j = 0; j < blocks.Count(); j++) {
  674. IMyProductionBlock prod = blocks.Blocks[j] as IMyProductionBlock;
  675. name = blocks.Blocks[j].DefinitionDisplayNameText;
  676. if (blockTypes.Contains(name)) {
  677. typeCount[name]++;
  678. if ((enabledCnt && blocks.Blocks[j].IsWorking) ||
  679. (producingCnt && prod != null && prod.IsProducing))
  680. typeWorkingCount[name]++;
  681. }
  682. else {
  683. typeCount.Add(name, 1);
  684. blockTypes.Add(name);
  685. if (enabledCnt || producingCnt)
  686. if ((enabledCnt && blocks.Blocks[j].IsWorking) ||
  687. (producingCnt && prod != null && prod.IsProducing))
  688. typeWorkingCount.Add(name, 1);
  689. else
  690. typeWorkingCount.Add(name, 0);
  691. }
  692. }
  693. for (int j = 0; j < typeCount.Count; j++) {
  694. MMLCDMgr.Add(blockTypes[j] + " " + M.T["C1"] + " ");
  695. string countstr = (enabledCnt || producingCnt ?
  696. typeWorkingCount[blockTypes[j]] + " / " : "") +
  697. typeCount[blockTypes[j]];
  698.  
  699. MMLCDMgr.AddRightLn(countstr, LCD_LINE_BLOCK_COUNT_POS);
  700. }
  701. }
  702. }
  703.  
  704. public void RunBlockCount(MMCmd cmd)
  705. {
  706. bool enabledCnt = (cmd.cmdstr == "enabledcount");
  707. bool producingCnt = (cmd.cmdstr == "prodcount");
  708.  
  709. if (cmd.args.Count == 0) {
  710. MMBlkCol blocks = new MMBlkCol();
  711. blocks.AddBOfName(cmd.nameLike);
  712. ShowBlkCntOfType(blocks, "blocks", enabledCnt, producingCnt);
  713. return;
  714. }
  715.  
  716. for (int i = 0; i < cmd.args.Count; i++) {
  717. MMArg arg = cmd.args[i];
  718. arg.Parse();
  719.  
  720. for (int subi = 0; subi < arg.sub.Count; subi++) {
  721. MMBlkCol blocks = new MMBlkCol();
  722. blocks.AddBofT(arg.sub[subi], cmd.nameLike);
  723. ShowBlkCntOfType(blocks, arg.sub[subi], enabledCnt, producingCnt);
  724. }
  725. }
  726. }
  727.  
  728. public string GetWorkingString(IMyTerminalBlock block)
  729. {
  730. if (!block.IsWorking)
  731. return M.T["W1"];
  732.  
  733. IMyProductionBlock prod = block as IMyProductionBlock;
  734. if (prod != null)
  735. if (prod.IsProducing)
  736. return M.T["W2"];
  737. else
  738. return M.T["W3"];
  739.  
  740. IMyAirVent vent = block as IMyAirVent;
  741. if (vent != null) {
  742. if (vent.CanPressurize)
  743. return (vent.GetOxygenLevel() * 100).ToString("F1") + "%";
  744. else
  745. return M.T["W4"];
  746. }
  747.  
  748. IMyOxygenTank tank = block as IMyOxygenTank;
  749. if (tank != null)
  750. return (tank.GetOxygenLevel() * 100).ToString("F1") + "%";
  751.  
  752. IMyBatteryBlock battery = block as IMyBatteryBlock;
  753. if (battery != null)
  754. return MMStatus.GetBatWorkingStr(battery);
  755.  
  756. IMyJumpDrive jd = block as IMyJumpDrive;
  757. if (jd != null)
  758. return MMStatus.GetJDCharge(jd).ToString("0.0") + "%";
  759.  
  760. IMyLandingGear gear = block as IMyLandingGear;
  761. if (gear != null)
  762. return MMStatus.GetLGStatus(gear);
  763.  
  764. IMyDoor door = block as IMyDoor;
  765. if (door != null) {
  766. if (door.Open)
  767. return M.T["W5"];
  768. return M.T["W6"];
  769. }
  770.  
  771. IMyShipConnector conn = block as IMyShipConnector;
  772. if (conn != null)
  773. if (conn.IsLocked) {
  774. if (conn.IsConnected)
  775. return M.T["W7"];
  776. else
  777. return M.T["W10"];
  778. }
  779. else
  780. return M.T["W8"];
  781.  
  782. IMyLaserAntenna lasant = block as IMyLaserAntenna;
  783. if (lasant != null)
  784. return MMStatus.GetLAStatus(lasant);
  785.  
  786. IMyRadioAntenna ant = block as IMyRadioAntenna;
  787. if (ant != null)
  788. return MM.FormatLargeNumber(ant.Radius) + "m";
  789.  
  790. IMyBeacon beacon = block as IMyBeacon;
  791. if (beacon != null)
  792. return MM.FormatLargeNumber(beacon.Radius) + "m";
  793.  
  794. return M.T["W9"];
  795. }
  796.  
  797. private void ShowWorkingOfType(MMBlkCol blocks, bool enabledList, string state)
  798. {
  799. for (int j = 0; j < blocks.Count(); j++) {
  800. IMyTerminalBlock block = blocks.Blocks[j];
  801. string onoff = (enabledList ? (block.IsWorking ? M.T["W9"] : M.T["W1"]) : GetWorkingString(block));
  802. if (state != "" && onoff.ToLower() != state)
  803. continue;
  804. if (enabledList)
  805. onoff = GetWorkingString(block);
  806.  
  807. string blockName = block.CustomName;
  808. blockName = MMStrFn.GetTrimmed(blockName, LCD_LINE_WORK_STATE_POS - 100);
  809. MMLCDMgr.Add(blockName);
  810. MMLCDMgr.AddRightLn(onoff, LCD_LINE_WORK_STATE_POS);
  811. }
  812. }
  813. public void RunShipCtrlStatus(MMCmd cmd)
  814. {
  815. MMBlkCol blocks = new MMBlkCol();
  816. blocks.AddBofT("shipctrl", cmd.nameLike);
  817.  
  818. if (blocks.Count() <= 0) {
  819. if (cmd.nameLike != "" && cmd.nameLike != "*")
  820. MMLCDMgr.AddLn(cmd.cmdstr + ": " + M.T["SC1"] + " (" + cmd.nameLike + ")");
  821. else
  822. MMLCDMgr.AddLn(cmd.cmdstr + ": " + M.T["SC1"]);
  823. return;
  824. }
  825.  
  826. if (cmd.cmdstr.StartsWith("damp")) {
  827. bool s = (blocks.Blocks[0] as IMyShipController).DampenersOverride;
  828. MMLCDMgr.Add(M.T["SCD"]);
  829. MMLCDMgr.AddRightLn(s ? "ON" : "OFF", LCD_LINE_WORK_STATE_POS);
  830. }
  831. else {
  832. bool s = (blocks.Blocks[0] as IMyShipController).IsUnderControl;
  833. MMLCDMgr.Add(M.T["SCO"]);
  834. MMLCDMgr.AddRightLn(s ? "YES" : "NO", LCD_LINE_WORK_STATE_POS);
  835. }
  836. }
  837. public void RunWorkingList(MMCmd cmd)
  838. {
  839. bool enabledList = (cmd.cmdstr == "workingx");
  840.  
  841. if (cmd.args.Count == 0) {
  842. MMBlkCol blocks = new MMBlkCol();
  843. blocks.AddBOfName(cmd.nameLike);
  844. ShowWorkingOfType(blocks, enabledList, "");
  845. return;
  846. }
  847.  
  848. for (int i = 0; i < cmd.args.Count; i++) {
  849. MMArg arg = cmd.args[i];
  850. arg.Parse();
  851.  
  852. for (int subi = 0; subi < arg.sub.Count; subi++) {
  853. MMBlkCol blocks = new MMBlkCol();
  854. if (arg.sub[subi] == "")
  855. continue;
  856. string[] subparts = arg.sub[subi].ToLower().Split(':');
  857. string subargtype = subparts[0];
  858. string subargstate = (subparts.Length > 1 ? subparts[1] : "");
  859. if (subargtype != "")
  860. blocks.AddBofT(subargtype, cmd.nameLike);
  861. else
  862. blocks.AddBOfName(cmd.nameLike);
  863.  
  864. ShowWorkingOfType(blocks, enabledList, subargstate);
  865. }
  866. }
  867. }
  868.  
  869. public void RunItemAmount(MMCmd cmd)
  870. {
  871. bool progressbars = true;
  872. if (cmd.cmdstr[cmd.cmdstr.Length - 1] == 'x') {
  873. cmd.cmdstr = cmd.cmdstr.Substring(0, cmd.cmdstr.Length - 1);
  874. progressbars = false;
  875. }
  876.  
  877. if (cmd.args.Count == 0)
  878. cmd.args.Add(new MMArg(
  879. "reactor,gatlingturret,missileturret,interiorturret,gatlinggun,launcherreload,launcher,oxygenerator"));
  880.  
  881. for (int i = 0; i < cmd.args.Count; i++) {
  882. MMArg arg = cmd.args[i];
  883. arg.Parse();
  884.  
  885. for (int subi = 0; subi < arg.sub.Count; subi++) {
  886. MMBlkCol blocks = new MMBlkCol();
  887. if (arg.sub[subi] == "")
  888. continue;
  889. string subargtype = arg.sub[subi];
  890. blocks.AddBofT(subargtype, cmd.nameLike);
  891.  
  892. for (int j = 0; j < blocks.Count(); j++) {
  893. IMyTerminalBlock block = blocks.Blocks[j];
  894. IMyInventory inv = block.GetInventory(0);
  895. if (inv == null)
  896. continue;
  897.  
  898. double amt = 0;
  899. double maxAmt = 0;
  900. double otherAmt = 0;
  901. List<IMyInventoryItem> items = inv.GetItems();
  902. string itemType = (items.Count > 0 ? items[0].Content.ToString() : "");
  903. for (int idx = 0; idx < items.Count; idx++) {
  904. IMyInventoryItem item = items[idx];
  905.  
  906. if (item.Content.ToString() != itemType)
  907. otherAmt += (double)item.Amount;
  908. else
  909. amt += (double)item.Amount;
  910. }
  911. string amountStr = M.T["A1"];
  912. string blockName = block.CustomName;
  913.  
  914. if (amt > 0 && (double)inv.CurrentVolume > 0) {
  915. double otherVol = otherAmt * (double)inv.CurrentVolume / (amt + otherAmt);
  916. maxAmt = Math.Floor(amt * ((double)inv.MaxVolume - otherVol) / (double)inv.CurrentVolume - otherVol);
  917.  
  918. amountStr = MM.FormatLargeNumber(amt) + " / " + (otherAmt > 0 ? "~" : "") + MM.FormatLargeNumber(maxAmt);
  919. }
  920.  
  921. blockName = MMStrFn.GetTrimmed(blockName, LCD_LINE_WORK_STATE_POS - 60);
  922. MMLCDMgr.Add(blockName);
  923. MMLCDMgr.AddRightLn(amountStr, LCD_LINE_WORK_STATE_POS);
  924.  
  925. if (progressbars && maxAmt > 0) {
  926. double perc = 100 * amt / maxAmt;
  927. MMLCDMgr.AddBarLn(perc, FULL_PROGRESS_CHARS);
  928. }
  929. }
  930. }
  931. }
  932. }
  933.  
  934. public void RunEcho(MMCmd cmd)
  935. {
  936. string type = (cmd.cmdstr == "center" ? "c" : (cmd.cmdstr == "right" ? "r" : "n"));
  937. int idx = cmd.cmdLine.IndexOf(' ');
  938. string msg = "";
  939. if (idx >= 0)
  940. msg = cmd.cmdLine.Substring(idx + 1);
  941.  
  942. switch (type) {
  943. case "c":
  944. MMLCDMgr.AddCenterLn(msg, LCD_LINE_WIDTH / 2);
  945. break;
  946. case "r":
  947. MMLCDMgr.AddRightLn(msg, LCD_LINE_WIDTH);
  948. break;
  949. default:
  950. MMLCDMgr.AddLn(msg);
  951. break;
  952. }
  953. }
  954.  
  955. public void RunDamage(MMCmd cmd)
  956. {
  957. bool simple = cmd.cmdstr.StartsWith("damagex");
  958. bool onlyDmg = cmd.cmdstr.EndsWith("noc"); // no construct    
  959.  
  960. MMBlkCol blocks = new MMBlkCol();
  961. blocks.AddBOfName(cmd.nameLike);
  962. bool found = false;
  963.  
  964. for (int i = 0; i < blocks.Count(); i++) {
  965. IMyTerminalBlock block = blocks.Blocks[i];
  966. IMySlimBlock slim = block.CubeGrid.GetCubeBlock(block.Position);
  967. float hull = (onlyDmg ? slim.MaxIntegrity : slim.BuildIntegrity) - slim.CurrentDamage;
  968. float perc = 100 * (hull / slim.MaxIntegrity);
  969.  
  970. if (perc >= 100)
  971. continue;
  972.  
  973. found = true;
  974.  
  975. MMLCDMgr.Add(MMStrFn.GetTrimmed(slim.FatBlock.DisplayNameText,
  976. LCD_LINE_DMG_NUMBERS_POS - 70) + " ");
  977. if (!simple) {
  978. MMLCDMgr.AddRight(MM.FormatLargeNumber(hull) + " / ",
  979. LCD_LINE_DMG_NUMBERS_POS);
  980. MMLCDMgr.Add(MM.FormatLargeNumber(slim.MaxIntegrity));
  981. }
  982. MMLCDMgr.AddRightLn(' ' + perc.ToString("0.0") + "%", LCD_LINE_WIDTH);
  983. MMLCDMgr.AddBarLn(perc, FULL_PROGRESS_CHARS);
  984. }
  985.  
  986. if (!found)
  987. MMLCDMgr.AddLn(M.T["D3"]);
  988. }
  989.  
  990. public void RunTankStatus(MMCmd cmd)
  991. {
  992. List<MMArg> args = cmd.args;
  993. string tankType;
  994.  
  995. if (args.Count == 0) {
  996. MMLCDMgr.AddLn(M.T["T4"]);
  997. return;
  998. }
  999.  
  1000. tankType = args[0].arg.Trim().ToLower();
  1001.  
  1002. double percent;
  1003. MMBlkCol blocks = new MMBlkCol();
  1004.  
  1005. blocks.AddBofT("oxytank", cmd.nameLike);
  1006.  
  1007. double tankSum = 0;
  1008. int cnt = blocks.Count();
  1009. for (int i = 0; i < blocks.Count(); i++) {
  1010. IMyOxygenTank tank = blocks.Blocks[i] as IMyOxygenTank;
  1011. if ((tankType == "oxygen" && tank.BlockDefinition.SubtypeId == "") ||
  1012. tank.BlockDefinition.SubtypeId.ToLower().Contains(tankType)) // only selected tank type    
  1013. tankSum += tank.GetOxygenLevel() * 100;
  1014. else
  1015. cnt--;
  1016. }
  1017.  
  1018. if (cnt == 0) {
  1019. MMLCDMgr.AddLn(String.Format(M.T["T5"], tankType));
  1020. return;
  1021. }
  1022.  
  1023. percent = tankSum / cnt;
  1024.  
  1025. tankType = char.ToUpper(tankType[0]) + tankType.Substring(1);
  1026.  
  1027. MMLCDMgr.Add(tankType + " " + M.T["T6"]);
  1028. MMLCDMgr.AddRightLn(percent.ToString("F2") + "%", LCD_LINE_WORK_STATE_POS);
  1029. MMLCDMgr.AddBarLn(percent, FULL_PROGRESS_CHARS);
  1030. }
  1031.  
  1032. public void RunOxygenStatus(MMCmd cmd)
  1033. {
  1034. double percent;
  1035. MMBlkCol blocks = new MMBlkCol();
  1036.  
  1037. blocks.AddBofT("airvent", cmd.nameLike);
  1038. bool found = (blocks.Count() > 0);
  1039.  
  1040. for (int i = 0; i < blocks.Count(); i++) {
  1041. IMyAirVent vent = blocks.Blocks[i] as IMyAirVent;
  1042. percent = Math.Max(vent.GetOxygenLevel() * 100, 0f);
  1043.  
  1044. MMLCDMgr.Add(vent.CustomName);
  1045.  
  1046. if (vent.CanPressurize)
  1047. MMLCDMgr.AddRightLn(percent.ToString("F1") + "%", LCD_LINE_WORK_STATE_POS);
  1048. else
  1049. MMLCDMgr.AddRightLn(M.T["O1"], LCD_LINE_WORK_STATE_POS);
  1050. MMLCDMgr.AddBarLn(percent, FULL_PROGRESS_CHARS);
  1051. }
  1052.  
  1053. blocks.Clear();
  1054. blocks.AddBofT("oxyfarm", cmd.nameLike);
  1055. int cnt = blocks.Count();
  1056. if (cnt > 0) {
  1057. double farmSum = 0;
  1058. for (int i = 0; i < cnt; i++) {
  1059. IMyOxygenFarm farm = blocks.Blocks[i] as IMyOxygenFarm;
  1060. farmSum += farm.GetOutput() * 100;
  1061. }
  1062.  
  1063. percent = farmSum / cnt;
  1064.  
  1065. if (found)
  1066. MMLCDMgr.AddLn("");
  1067.  
  1068. found |= (cnt > 0);
  1069.  
  1070. MMLCDMgr.Add(M.T["O2"]);
  1071. MMLCDMgr.AddRightLn(percent.ToString("F2") + "%", LCD_LINE_WORK_STATE_POS);
  1072. MMLCDMgr.AddBarLn(percent, FULL_PROGRESS_CHARS);
  1073. }
  1074.  
  1075. blocks.Clear();
  1076. blocks.AddBofT("oxytank", cmd.nameLike);
  1077. cnt = blocks.Count();
  1078.  
  1079. if (cnt == 0) {
  1080. if (!found)
  1081. MMLCDMgr.AddLn(M.T["O3"]);
  1082. return;
  1083. }
  1084.  
  1085. double tankSum = 0;
  1086. int tankCnt = cnt;
  1087. for (int i = 0; i < cnt; i++) {
  1088. IMyOxygenTank tank = blocks.Blocks[i] as IMyOxygenTank;
  1089. if (tank.BlockDefinition.SubtypeId == "" ||
  1090. tank.BlockDefinition.SubtypeId.Contains("Oxygen")) // only oxygen tanks    
  1091. tankSum += tank.GetOxygenLevel() * 100;
  1092. else
  1093. tankCnt--;
  1094. }
  1095.  
  1096. if (tankCnt == 0) {
  1097. if (!found)
  1098. MMLCDMgr.AddLn(M.T["O3"]);
  1099. return;
  1100. }
  1101.  
  1102. percent = tankSum / tankCnt;
  1103.  
  1104. if (found)
  1105. MMLCDMgr.AddLn("");
  1106. MMLCDMgr.Add(M.T["O4"]);
  1107. MMLCDMgr.AddRightLn(percent.ToString("F2") + "%", LCD_LINE_WORK_STATE_POS);
  1108. MMLCDMgr.AddBarLn(percent, FULL_PROGRESS_CHARS);
  1109. }
  1110.  
  1111. public void RunMass(MMCmd cmd)
  1112. {
  1113. MMBlkCol blocks = new MMBlkCol();
  1114. bool simple = (cmd.cmdstr[cmd.cmdstr.Length - 1] == 'x');
  1115. bool progress = (cmd.cmdstr[cmd.cmdstr.Length - 1] == 'p');
  1116.  
  1117. blocks.AddBOfName(cmd.nameLike);
  1118.  
  1119. double used = blocks.GetMassSummary();
  1120. double total = 0;
  1121.  
  1122. int argCnt = cmd.args.Count;
  1123. if (argCnt > 0) {
  1124. cmd.args[0].Parse();
  1125. if (cmd.args[0].sub.Count > 0)
  1126. double.TryParse(cmd.args[0].sub[0].Trim(), out total);
  1127. if (argCnt > 1) {
  1128. cmd.args[1].Parse();
  1129. if (cmd.args[1].sub.Count > 0) {
  1130. string unit = cmd.args[1].sub[0].Trim().ToLower();
  1131. if (unit != "")
  1132. total *= Math.Pow(1000.0, "kmgtpezy".IndexOf(unit[0]));
  1133. }
  1134. }
  1135. total *= 1000.0;
  1136. }
  1137.  
  1138. MMLCDMgr.Add(M.T["M1"] + " ");
  1139. if (total <= 0) {
  1140. MMLCDMgr.AddRightLn(MM.FormatLargeNumber(used), LCD_LINE_WIDTH);
  1141. return;
  1142. }
  1143.  
  1144. double perc = used / total * 100;
  1145.  
  1146. if (!simple && !progress) {
  1147. MMLCDMgr.AddRightLn(MM.FormatLargeNumber(used) + "g / " + MM.FormatLargeNumber(total) + "g", LCD_LINE_WIDTH);
  1148. MMLCDMgr.AddBar(perc, FULL_PROGRESS_CHARS, PERCENT_TEXT_SIZE);
  1149. MMLCDMgr.AddLn(' ' + perc.ToString("0.0") + "%");
  1150. }
  1151. else if (progress) {
  1152. MMLCDMgr.AddRightLn(perc.ToString("0.0") + "%", LCD_LINE_WIDTH);
  1153. MMLCDMgr.AddBarLn(perc, FULL_PROGRESS_CHARS);
  1154. }
  1155. else
  1156. MMLCDMgr.AddRightLn(perc.ToString("0.0") + "%", LCD_LINE_WIDTH);
  1157. }
  1158.  
  1159.  
  1160. class PTD
  1161. {
  1162. public TimeSpan t = new TimeSpan(-1);
  1163. public double ct = -1;
  1164. public double lastFuel = 0;
  1165. }
  1166. static Dictionary<string, PTD> savedPT = new Dictionary<string, PTD>();
  1167.  
  1168. private double GetPTElapsed(string nameLike)
  1169. {
  1170. if (ptNLtoIdx.ContainsKey(nameLike))
  1171. return ptElapsedL[ptNLtoIdx[nameLike]];
  1172. ptElapsedL.Add(0);
  1173. ptNLtoIdx.Add(nameLike, ptElapsedL.Count - 1);
  1174. return 0;
  1175. }
  1176. private PTD GetSavedPT(string nameLike)
  1177. {
  1178. if (!savedPT.ContainsKey(nameLike))
  1179. savedPT[nameLike] = new PTD();
  1180. return savedPT[nameLike];
  1181. }
  1182. private TimeSpan GetPowerTime(string nameLike, out double chargeTime)
  1183. {
  1184. double ptElapsed = GetPTElapsed(nameLike);
  1185. PTD pt = GetSavedPT(nameLike);
  1186.  
  1187. // at least few seconds to get somehow reliable values    
  1188. if (ptElapsed <= 3) {
  1189. chargeTime = pt.ct;
  1190. return pt.t;
  1191. }
  1192. pt.ct = 0;
  1193.  
  1194. MMBlkCol rbs = new MMBlkCol();
  1195. rbs.AddBofT("reactor", nameLike);
  1196.  
  1197. double fuel = 0;
  1198. double rcur = 0, rmax = 0;
  1199. for (int bi = 0; bi < rbs.Blocks.Count; bi++) {
  1200. IMyReactor block = rbs.Blocks[bi] as IMyReactor;
  1201. if (block == null || !block.IsWorking)
  1202. continue;
  1203. List<double> vals = MMStatus.GetDetailVals(block);
  1204. if (vals.Count < 2)
  1205. continue;
  1206. rmax += vals[0] / 1000000;
  1207. rcur += vals[1] / 1000000;
  1208. IMyInventory inv = block.GetInventory(0);
  1209. fuel += (double)inv.CurrentMass;
  1210. }
  1211.  
  1212. MMBlkCol bbs = new MMBlkCol();
  1213. bbs.AddBofT("battery", nameLike);
  1214. double stored = 0;
  1215. double bcur = 0, bmax = 0;
  1216. for (int bi = 0; bi < bbs.Blocks.Count; bi++) {
  1217. IMyBatteryBlock block = bbs.Blocks[bi] as IMyBatteryBlock;
  1218. if (block == null || !block.IsWorking)
  1219. continue;
  1220. List<double> vals = MMStatus.GetDetailVals(block);
  1221. if (vals.Count < 6)
  1222. continue;
  1223. double output = (vals[4] - vals[3]) / 1000000;
  1224. double cTime = (output < 0 ? (block.MaxStoredPower - block.CurrentStoredPower) / (-output / 3600) : 0);
  1225. if (cTime > pt.ct) pt.ct = cTime;
  1226. if (block.GetValueBool("Recharge"))
  1227. continue;
  1228. bcur += output;
  1229. bmax += vals[0] / 1000000;
  1230. stored += block.CurrentStoredPower;
  1231. }
  1232.  
  1233. double usedPower = rcur + bcur;
  1234. if (usedPower <= 0)
  1235. pt.t = TimeSpan.FromSeconds(-1);
  1236. else {
  1237. double tPT = pt.t.TotalSeconds;
  1238. double sPT;
  1239. double deltaF = (pt.lastFuel - fuel) / ptElapsed;
  1240. if (rcur <= 0) /* 1000MW per ingot .. better than nothing */
  1241. deltaF = Math.Min(usedPower, rmax) / 3600000;
  1242.  
  1243. double deltaS = 0;
  1244. if (bmax > 0)
  1245. deltaS = Math.Min(usedPower, bmax) / 3600;
  1246.  
  1247. if (deltaF <= 0 && deltaS <= 0)
  1248. sPT = -1;
  1249. else
  1250. if (deltaF <= 0)
  1251. sPT = stored / deltaS;
  1252. else
  1253. if (deltaS <= 0)
  1254. sPT = fuel / deltaF;
  1255. else {
  1256. double adS = deltaS;
  1257. double adF = (rcur <= 0 ? usedPower / 3600 : deltaF * usedPower / rcur);
  1258. sPT = stored / adS + fuel / adF;
  1259. }
  1260. if (tPT <= 0 || sPT < 0)
  1261. tPT = sPT;
  1262. else
  1263. tPT = (tPT + sPT) / 2;
  1264. pt.t = TimeSpan.FromSeconds(tPT);
  1265. }
  1266. ptElapsedL[ptNLtoIdx[nameLike]] = 0;
  1267. pt.lastFuel = fuel;
  1268. chargeTime = pt.ct;
  1269. return pt.t;
  1270. }
  1271. private string GetRemTStr(TimeSpan remT)
  1272. {
  1273. string text = "";
  1274.  
  1275. if (remT.Ticks <= 0)
  1276. return "-";
  1277. if ((int)remT.TotalDays > 0)
  1278. text += (long)remT.TotalDays + " " + M.T["C5"] + " ";
  1279. if (remT.Hours > 0 || text != "")
  1280. text += remT.Hours + "h ";
  1281. if (remT.Minutes > 0 || text != "")
  1282. text += remT.Minutes + "m ";
  1283. return text + remT.Seconds + "s";
  1284. }
  1285. public void RunPowerTime(MMCmd cmd)
  1286. {
  1287. bool simple = (cmd.cmdstr[cmd.cmdstr.Length - 1] == 'x');
  1288. bool progress = (cmd.cmdstr[cmd.cmdstr.Length - 1] == 'p');
  1289.  
  1290. int h = 0, m = 0, s = 0;
  1291. int c = 0;
  1292. if (cmd.args.Count > 0) {
  1293. for (int ai = 0; ai < cmd.args.Count; ai++) {
  1294. cmd.args[ai].Parse();
  1295. if (cmd.args[ai].sub.Count <= 0)
  1296. continue;
  1297. string arg = cmd.args[ai].sub[0];
  1298. int.TryParse(arg, out c);
  1299. if (ai == 0)
  1300. h = c;
  1301. else if (ai == 1)
  1302. m = c;
  1303. else if (ai == 2)
  1304. s = c;
  1305. }
  1306. }
  1307.  
  1308. double ct = 0, t = 0;
  1309. TimeSpan remT = GetPowerTime(cmd.nameLike, out ct);
  1310. TimeSpan totalT = new TimeSpan(h, m, s);
  1311.  
  1312. string text;
  1313. if (remT.TotalSeconds > 0 || ct <= 0) {
  1314. MMLCDMgr.Add(M.T["PT1"] + " ");
  1315. text = GetRemTStr(remT);
  1316. t = remT.TotalSeconds;
  1317. }
  1318. else {
  1319. MMLCDMgr.Add(M.T["PT2"] + " ");
  1320. text = GetRemTStr(TimeSpan.FromSeconds(ct));
  1321. if (totalT.TotalSeconds >= ct)
  1322. t = totalT.TotalSeconds - ct;
  1323. else
  1324. t = 0;
  1325. }
  1326.  
  1327. if (totalT.Ticks <= 0) {
  1328. MMLCDMgr.AddRightLn(text, LCD_LINE_WIDTH);
  1329. return;
  1330. }
  1331.  
  1332. double perc = t / totalT.TotalSeconds * 100;
  1333. if (perc > 100) perc = 100;
  1334.  
  1335. if (!simple && !progress) {
  1336. MMLCDMgr.AddRightLn(text, LCD_LINE_WIDTH);
  1337. MMLCDMgr.AddBar(perc, FULL_PROGRESS_CHARS, PERCENT_TEXT_SIZE);
  1338. MMLCDMgr.AddLn(' ' + perc.ToString("0.0") + "%");
  1339. }
  1340. else if (progress) {
  1341. MMLCDMgr.AddRightLn(perc.ToString("0.0") + "%", LCD_LINE_WIDTH);
  1342. MMLCDMgr.AddBarLn(perc, FULL_PROGRESS_CHARS);
  1343. }
  1344. else
  1345. MMLCDMgr.AddRightLn(perc.ToString("0.0") + "%", LCD_LINE_WIDTH);
  1346. }
  1347.  
  1348. public void RunCargoStatus(MMCmd cmd)
  1349. {
  1350. MMBlkCol blocks = new MMBlkCol();
  1351. bool alltypes = cmd.cmdstr.Contains("all");
  1352. bool simple = (cmd.cmdstr[cmd.cmdstr.Length - 1] == 'x');
  1353. bool progress = (cmd.cmdstr[cmd.cmdstr.Length - 1] == 'p');
  1354.  
  1355. if (alltypes)
  1356. blocks.AddBOfName(cmd.nameLike);
  1357. else
  1358. blocks.AddBofT("cargocontainer", cmd.nameLike);
  1359.  
  1360. double usedCargo = 0;
  1361. double totalCargo = 0;
  1362. double percentCargo = blocks.GetCargoSummary(
  1363. ref usedCargo, ref totalCargo);
  1364.  
  1365. MMLCDMgr.Add(M.T["C2"] + " ");
  1366. if (!simple && !progress) {
  1367. MMLCDMgr.AddRightLn(MM.FormatLargeNumber(usedCargo) + "L / " + MM.FormatLargeNumber(totalCargo) + "L", LCD_LINE_WIDTH);
  1368. MMLCDMgr.AddBar(percentCargo, FULL_PROGRESS_CHARS, PERCENT_TEXT_SIZE);
  1369. MMLCDMgr.AddLn(' ' + percentCargo.ToString("0.0") + "%");
  1370. }
  1371. else if (progress) {
  1372. MMLCDMgr.AddRightLn(percentCargo.ToString("0.0") + "%", LCD_LINE_WIDTH);
  1373. MMLCDMgr.AddBarLn(percentCargo, FULL_PROGRESS_CHARS);
  1374. }
  1375. else
  1376. MMLCDMgr.AddRightLn(percentCargo.ToString("0.0") + "%", LCD_LINE_WIDTH);
  1377. }
  1378.  
  1379. // type: simple, progress, normal    
  1380. public void ShowPowerOutput(MMBlkCol generators, string title, string type = "n")
  1381. {
  1382. double usedPower = 0, totalPower = 0;
  1383. double percentPower = generators.GetPowerOutput(ref usedPower, ref totalPower);
  1384.  
  1385. MMLCDMgr.Add(title + ": ");
  1386. switch (type) {
  1387. case "s":
  1388. MMLCDMgr.AddRightLn(' ' + percentPower.ToString("0.0") + "%", LCD_LINE_WIDTH);
  1389. break;
  1390. case "v":
  1391. MMLCDMgr.AddRightLn(MM.FormatLargeNumber(usedPower) + "W / " + MM.FormatLargeNumber(totalPower) + "W", LCD_LINE_WIDTH);
  1392. break;
  1393. case "p":
  1394. MMLCDMgr.AddRightLn(' ' + percentPower.ToString("0.0") + "%", LCD_LINE_WIDTH);
  1395. MMLCDMgr.AddBarLn(percentPower, FULL_PROGRESS_CHARS);
  1396. break;
  1397. default:
  1398. MMLCDMgr.AddRightLn(MM.FormatLargeNumber(usedPower) + "W / " + MM.FormatLargeNumber(totalPower) + "W", LCD_LINE_WIDTH);
  1399. MMLCDMgr.AddBar(percentPower, FULL_PROGRESS_CHARS, PERCENT_TEXT_SIZE);
  1400. MMLCDMgr.AddRightLn(' ' + percentPower.ToString("0.0") + "%", LCD_LINE_WIDTH);
  1401. break;
  1402. }
  1403. }
  1404.  
  1405. public void ShowSolarOutput(MMBlkCol generators, string title, string type = "n")
  1406. {
  1407. double usedPower = 0, totalPower = 0;
  1408. generators.GetPowerOutput(ref usedPower, ref totalPower);
  1409. double percentPower = (totalPower > 0 ? (usedPower / totalPower) * 100 : 100);
  1410.  
  1411. MMLCDMgr.Add(title + ": ");
  1412. switch (type) {
  1413. case "s":
  1414. MMLCDMgr.AddRightLn(' ' + percentPower.ToString("0.0") + "%", LCD_LINE_WIDTH);
  1415. break;
  1416. case "v":
  1417. MMLCDMgr.AddRightLn(MM.FormatLargeNumber(usedPower) + "W / " + MM.FormatLargeNumber(totalPower) + "W", LCD_LINE_WIDTH);
  1418. break;
  1419. case "p":
  1420. MMLCDMgr.AddRightLn(' ' + percentPower.ToString("0.0") + "%", LCD_LINE_WIDTH);
  1421. MMLCDMgr.AddBarLn(percentPower, FULL_PROGRESS_CHARS);
  1422. break;
  1423. default:
  1424. MMLCDMgr.AddRightLn(MM.FormatLargeNumber(usedPower) + "W / " + MM.FormatLargeNumber(totalPower) + "W", LCD_LINE_WIDTH);
  1425. MMLCDMgr.AddBar(percentPower, FULL_PROGRESS_CHARS, PERCENT_TEXT_SIZE);
  1426. MMLCDMgr.AddRightLn(' ' + percentPower.ToString("0.0") + "%", LCD_LINE_WIDTH);
  1427. break;
  1428. }
  1429. }
  1430.  
  1431. public void ShowBatteriesInfo(MMBlkCol batteries, string title, string what = "a", string type = "n")
  1432. {
  1433. double output = 0, maxOutput = 0, input = 0, maxInput = 0;
  1434. double stored = 0, maxStored = 0;
  1435. double percentStored =
  1436. batteries.GetBatStats(
  1437. ref output, ref maxOutput,
  1438. ref input, ref maxInput,
  1439. ref stored, ref maxStored);
  1440. double percentOutput = (maxOutput > 0 ? (output / maxOutput) * 100 : 100);
  1441. double percentInput = (maxInput > 0 ? (input / maxInput) * 100 : 100);
  1442. bool showall = what == "a";
  1443.  
  1444. if (showall) {
  1445. if (type != "p") {
  1446. MMLCDMgr.Add(title + ": ");
  1447. MMLCDMgr.AddRightLn("(IN " + MM.FormatLargeNumber(input) + "W / OUT " + MM.FormatLargeNumber(output) + "W)", LCD_LINE_WIDTH);
  1448. }
  1449. else
  1450. MMLCDMgr.AddLn(title + ": ");
  1451.  
  1452. MMLCDMgr.Add("  " + M.T["P3"] + ": ");
  1453. }
  1454. else
  1455. MMLCDMgr.Add(title + ": ");
  1456.  
  1457. if (showall || what == "s")
  1458. switch (type) {
  1459. case "s":
  1460. MMLCDMgr.AddRightLn(' ' + percentStored.ToString("0.0") + "%", LCD_LINE_WIDTH);
  1461. break;
  1462. case "v":
  1463. MMLCDMgr.AddRightLn(MM.FormatLargeNumber(stored) + "Wh / " + MM.FormatLargeNumber(maxStored) + "Wh", LCD_LINE_WIDTH);
  1464. break;
  1465. case "p":
  1466. MMLCDMgr.AddRightLn(' ' + percentStored.ToString("0.0") + "%", LCD_LINE_WIDTH);
  1467. MMLCDMgr.AddBarLn(percentStored, FULL_PROGRESS_CHARS);
  1468. break;
  1469. default:
  1470. MMLCDMgr.AddRightLn(MM.FormatLargeNumber(stored) + "Wh / " + MM.FormatLargeNumber(maxStored) + "Wh", LCD_LINE_WIDTH);
  1471. MMLCDMgr.AddBar(percentStored, FULL_PROGRESS_CHARS, PERCENT_TEXT_SIZE);
  1472. MMLCDMgr.AddRightLn(' ' + percentStored.ToString("0.0") + "%", LCD_LINE_WIDTH);
  1473. break;
  1474. }
  1475.  
  1476. if (what == "s")
  1477. return;
  1478.  
  1479. if (showall)
  1480. MMLCDMgr.Add("  " + M.T["P4"] + ": ");
  1481.  
  1482. if (showall || what == "o")
  1483. switch (type) {
  1484. case "s":
  1485. MMLCDMgr.AddRightLn(' ' + percentOutput.ToString("0.0") + "%", LCD_LINE_WIDTH);
  1486. break;
  1487. case "v":
  1488. MMLCDMgr.AddRightLn(MM.FormatLargeNumber(output) + "W / " + MM.FormatLargeNumber(maxOutput) + "W", LCD_LINE_WIDTH);
  1489. break;
  1490. case "p":
  1491. MMLCDMgr.AddRightLn(' ' + percentOutput.ToString("0.0") + "%", LCD_LINE_WIDTH);
  1492. MMLCDMgr.AddBarLn(percentOutput, FULL_PROGRESS_CHARS);
  1493. break;
  1494. default:
  1495. MMLCDMgr.AddRightLn(MM.FormatLargeNumber(output) + "W / " + MM.FormatLargeNumber(maxOutput) + "W", LCD_LINE_WIDTH);
  1496. MMLCDMgr.AddBar(percentOutput, FULL_PROGRESS_CHARS, PERCENT_TEXT_SIZE);
  1497. MMLCDMgr.AddRightLn(' ' + percentOutput.ToString("0.0") + "%", LCD_LINE_WIDTH);
  1498. break;
  1499. }
  1500.  
  1501. if (what == "o")
  1502. return;
  1503.  
  1504. if (showall)
  1505. MMLCDMgr.Add("  " + M.T["P5"] + ": ");
  1506.  
  1507. if (showall || what == "i")
  1508. switch (type) {
  1509. case "s":
  1510. MMLCDMgr.AddRightLn(' ' + percentInput.ToString("0.0") + "%", LCD_LINE_WIDTH);
  1511. break;
  1512. case "v":
  1513. MMLCDMgr.AddRightLn(MM.FormatLargeNumber(input) + "W / " + MM.FormatLargeNumber(maxInput) + "W", LCD_LINE_WIDTH);
  1514. break;
  1515. case "p":
  1516. MMLCDMgr.AddRightLn(' ' + percentInput.ToString("0.0") + "%", LCD_LINE_WIDTH);
  1517. MMLCDMgr.AddBarLn(percentInput, FULL_PROGRESS_CHARS);
  1518. break;
  1519. default:
  1520. MMLCDMgr.AddRightLn(MM.FormatLargeNumber(input) + "W / " + MM.FormatLargeNumber(maxInput) + "W", LCD_LINE_WIDTH);
  1521. MMLCDMgr.AddBar(percentInput, FULL_PROGRESS_CHARS, PERCENT_TEXT_SIZE);
  1522. MMLCDMgr.AddRightLn(' ' + percentInput.ToString("0.0") + "%", LCD_LINE_WIDTH);
  1523. break;
  1524. }
  1525. }
  1526.  
  1527. public void RunPowerStatus(MMCmd cmd)
  1528. {
  1529. MMBlkCol reactors = new MMBlkCol();
  1530. MMBlkCol solars = new MMBlkCol();
  1531. MMBlkCol batteries = new MMBlkCol();
  1532. int got;
  1533. string displayType = (cmd.cmdstr.EndsWith("x") ? "s" : (cmd.cmdstr.EndsWith("p") ? "p" : (cmd.cmdstr.EndsWith("v") ? "v" : "n")));
  1534. bool issummary = (cmd.cmdstr.StartsWith("powersummary"));
  1535. string what = "a";
  1536. string titleOvrd = "";
  1537.  
  1538. if (cmd.cmdstr.Contains("stored"))
  1539. what = "s";
  1540. else if (cmd.cmdstr.Contains("in"))
  1541. what = "i";
  1542. else if (cmd.cmdstr.Contains("out"))
  1543. what = "o";
  1544.  
  1545. if (what == "a") {
  1546. reactors.AddBofT("reactor", cmd.nameLike);
  1547. solars.AddBofT("solarpanel", cmd.nameLike);
  1548. }
  1549. batteries.AddBofT("battery", cmd.nameLike);
  1550.  
  1551. got = 0;
  1552. int reactCnt = reactors.Count();
  1553. int solarCnt = solars.Count();
  1554. int batteCnt = batteries.Count();
  1555.  
  1556. if (reactCnt > 0) got++;
  1557. if (solarCnt > 0) got++;
  1558. if (batteCnt > 0) got++;
  1559.  
  1560. if (got < 1) {
  1561. MMLCDMgr.AddLn(M.T["P6"]);
  1562. return;
  1563. }
  1564.  
  1565. if (cmd.args.Count > 0) {
  1566. cmd.args[0].Parse();
  1567. if (cmd.args[0].sub.Count > 0 && cmd.args[0].sub[0].Length > 0)
  1568. titleOvrd = cmd.args[0].sub[0];
  1569. }
  1570.  
  1571. if (what != "a") {
  1572. ShowBatteriesInfo(batteries, (titleOvrd == "" ? M.T["P7"] : titleOvrd), what, displayType);
  1573. return;
  1574. }
  1575.  
  1576. string title = M.T["P8"];
  1577.  
  1578. if (!issummary) {
  1579. if (reactCnt > 0)
  1580. ShowPowerOutput(reactors, (titleOvrd == "" ? M.T["P9"] : titleOvrd), displayType);
  1581. if (solarCnt > 0)
  1582. ShowSolarOutput(solars, (titleOvrd == "" ? M.T["P10"] : titleOvrd), displayType);
  1583. if (batteCnt > 0)
  1584. ShowBatteriesInfo(batteries, (titleOvrd == "" ? M.T["P7"] : titleOvrd), what, displayType);
  1585. }
  1586. else {
  1587. title = M.T["P11"];
  1588. got = 10; // hack ;)    
  1589. }
  1590.  
  1591. if (got == 1)
  1592. return;
  1593.  
  1594. MMBlkCol blocks = new MMBlkCol();
  1595. blocks.AddFromBC(reactors);
  1596. blocks.AddFromBC(solars);
  1597. blocks.AddFromBC(batteries);
  1598. ShowPowerOutput(blocks, title, displayType);
  1599. }
  1600.  
  1601. public void RunCountdown(MMCmd cmd)
  1602. {
  1603. bool center = cmd.cmdstr.EndsWith("c");
  1604. bool right = cmd.cmdstr.EndsWith("r");
  1605.  
  1606. string input = "";
  1607. int firstSpace = cmd.cmdLine.IndexOf(' ');
  1608. if (firstSpace >= 0)
  1609. input = cmd.cmdLine.Substring(firstSpace + 1).Trim();
  1610.  
  1611. DateTime now = DateTime.Now;
  1612. DateTime inputt;
  1613. // 19:02 3.9.2015    
  1614. if (!DateTime.TryParseExact(input, "H:mm d.M.yyyy", System.Globalization.CultureInfo.InvariantCulture,
  1615. System.Globalization.DateTimeStyles.None, out inputt)) {
  1616. MMLCDMgr.AddLn(M.T["C3"]);
  1617. MMLCDMgr.AddLn("  Countdown 19:02 28.2.2015");
  1618. return;
  1619. }
  1620.  
  1621. TimeSpan dt = inputt - now;
  1622. string text = "";
  1623.  
  1624. if (dt.Ticks <= 0)
  1625. text = M.T["C4"];
  1626. else {
  1627. if ((int)dt.TotalDays > 0)
  1628. text += (int)dt.TotalDays + " " + M.T["C5"] + " ";
  1629. if (dt.Hours > 0 || text != "")
  1630. text += dt.Hours + "h ";
  1631. if (dt.Minutes > 0 || text != "")
  1632. text += dt.Minutes + "m ";
  1633. text += dt.Seconds + "s";
  1634. }
  1635. if (center)
  1636. MMLCDMgr.AddCenterLn(text, LCD_LINE_WIDTH / 2);
  1637. else if (right)
  1638. MMLCDMgr.AddRightLn(text, LCD_LINE_WIDTH);
  1639. else
  1640. MMLCDMgr.AddLn(text);
  1641. }
  1642.  
  1643. public void RunCurrentTime(MMCmd cmd)
  1644. {
  1645. bool datetime = (cmd.cmdstr.StartsWith("datetime"));
  1646. bool date = (cmd.cmdstr.StartsWith("date"));
  1647. bool center = cmd.cmdstr.Contains("c");
  1648. int offsetIdx = cmd.cmdstr.IndexOf('+');
  1649. if (offsetIdx < 0)
  1650. offsetIdx = cmd.cmdstr.IndexOf('-');
  1651. float offset = 0;
  1652.  
  1653. if (offsetIdx >= 0)
  1654. float.TryParse(cmd.cmdstr.Substring(offsetIdx), out offset);
  1655.  
  1656. DateTime dt = DateTime.Now.AddHours(offset);
  1657.  
  1658. string text = "";
  1659. int firstSpace = cmd.cmdLine.IndexOf(' ');
  1660. if (firstSpace >= 0)
  1661. text = cmd.cmdLine.Substring(firstSpace + 1);
  1662. if (!datetime) {
  1663. if (!date)
  1664. text += dt.ToShortTimeString();
  1665. else
  1666. text += dt.ToShortDateString();
  1667. }
  1668. else {
  1669. if (text == "")
  1670. text = String.Format("{0:d} {0:t}", dt);
  1671. else {
  1672. // try to prevent exceptions    
  1673. text = text.Replace("/", "\\/");
  1674. text = text.Replace(":", "\\:");
  1675. text = text.Replace("\"", "\\\"");
  1676. text = text.Replace("'", "\\'");
  1677. text = dt.ToString(text + ' ');
  1678. text = text.Substring(0, text.Length - 1);
  1679. }
  1680. }
  1681.  
  1682. if (center)
  1683. MMLCDMgr.AddCenterLn(text, LCD_LINE_WIDTH / 2);
  1684. else
  1685. MMLCDMgr.AddLn(text);
  1686. }
  1687.  
  1688. private void ShowInvLine(string msg, double num, int quota)
  1689. {
  1690. if (quota > 0) {
  1691. MMLCDMgr.AddBar(Math.Min(100, 100 * num / quota), INV_PROGRESS_CHARS);
  1692. MMLCDMgr.Add(' ' + msg + ' ');
  1693. MMLCDMgr.AddRight(MM.FormatLargeNumber(num), LCD_LINE_INV_NUMBERS_POS);
  1694. MMLCDMgr.AddLn(" / " + MM.FormatLargeNumber(quota));
  1695. }
  1696. else {
  1697. MMLCDMgr.Add(msg + ':');
  1698. MMLCDMgr.AddRightLn(MM.FormatLargeNumber(num), LCD_LINE_NUMERS_POS);
  1699. }
  1700. }
  1701.  
  1702. private void ShowInvIngotLine(string msg, double num, double numOres, int quota)
  1703. {
  1704. if (quota > 0) {
  1705. MMLCDMgr.Add(msg + ' ');
  1706. MMLCDMgr.AddRight(MM.FormatLargeNumber(num), LCD_LINE_INGOT_NUMBERS_POS);
  1707. MMLCDMgr.Add(" / " + MM.FormatLargeNumber(quota));
  1708. MMLCDMgr.AddRightLn("+" + MM.FormatLargeNumber(numOres) + " " + M.T["I1"], LCD_LINE_WIDTH);
  1709. MMLCDMgr.AddBarLn(Math.Min(100, 100 * num / quota), FULL_PROGRESS_CHARS);
  1710. }
  1711. else {
  1712. MMLCDMgr.Add(msg + ':');
  1713. MMLCDMgr.AddRight(MM.FormatLargeNumber(num), LCD_LINE_INGOT_NUMBERS_POS);
  1714. MMLCDMgr.AddRightLn("+" + MM.FormatLargeNumber(numOres) + " " + M.T["I1"], LCD_LINE_WIDTH);
  1715. }
  1716. }
  1717.  
  1718. public void PrintItems(MMItemAmounts amounts, bool missing, bool simple, string mainType, string displayType)
  1719. {
  1720. List<MMAmountSpec> items = amounts.GetAmountsOfMain(mainType);
  1721. if (items.Count > 0) {
  1722. if (!simple) {
  1723. if (MMLCDMgr.curLcd.curLine > 0 && MMLCDMgr.curLcd.lines[0] != "")
  1724. MMLCDMgr.AddLn("");  // add empty line    
  1725. MMLCDMgr.AddCenterLn("<< " + displayType + " " + M.T["I2"] + " >>", LCD_LINE_WIDTH / 2);
  1726. }
  1727.  
  1728. for (int i = 0; i < items.Count; i++) {
  1729. double num = items[i].current;
  1730.  
  1731. if (missing && num >= items[i].min)
  1732. continue;
  1733.  
  1734. int quota = items[i].max;
  1735. if (missing)
  1736. quota = items[i].min;
  1737.  
  1738. string msg = MM.ToDisplay(items[i].subType, items[i].mainType);
  1739.  
  1740. ShowInvLine(msg, num, quota);
  1741. }
  1742. }
  1743. }
  1744.  
  1745. public void RunInvListing(MMCmd cmd)
  1746. {
  1747. MMBlkCol blocks = new MMBlkCol();
  1748. bool noexpand = false;
  1749. bool simple = false;
  1750. if (cmd.cmdstr[cmd.cmdstr.Length - 1] == 's') {
  1751. cmd.cmdstr = cmd.cmdstr.Substring(0, cmd.cmdstr.Length - 1);
  1752. simple = true;
  1753. }
  1754. if (cmd.cmdstr[cmd.cmdstr.Length - 1] == 'x') {
  1755. cmd.cmdstr = cmd.cmdstr.Substring(0, cmd.cmdstr.Length - 1);
  1756. noexpand = true;
  1757. }
  1758.  
  1759. bool missing = (cmd.cmdstr == "missing");
  1760. bool nocats = (cmd.cmdstr == "invlist");
  1761.  
  1762. blocks.AddBOfName(cmd.nameLike);
  1763.  
  1764. MMItemAmounts amounts = new MMItemAmounts();
  1765. List<MMArg> args = cmd.args;
  1766. if (args.Count == 0)
  1767. args.Add(new MMArg("all"));
  1768.  
  1769. for (int i = 0; i < args.Count; i++) {
  1770. MMArg arg = args[i];
  1771. arg.Parse();
  1772. string mainType = arg.main.ToLower();
  1773.  
  1774. for (int subi = 0; subi < arg.sub.Count; subi++) {
  1775. string[] subs = arg.sub[subi].ToLower().Split(':');
  1776. double number;
  1777.  
  1778. if (subs[0] == "all")
  1779. subs[0] = "";
  1780.  
  1781. int min = 1;
  1782. int max = -1;
  1783. if (subs.Length > 1) {
  1784. if (Double.TryParse(subs[1], out number)) {
  1785. if (missing)
  1786. min = (int)Math.Ceiling(number);
  1787. else
  1788. max = (int)Math.Ceiling(number);
  1789. }
  1790. }
  1791.  
  1792. string subfulltype = subs[0];
  1793. if (mainType != "")
  1794. subfulltype += ' ' + mainType;
  1795. amounts.AddSpec(subfulltype, (arg.op == "-"), min, max);
  1796. }
  1797. }
  1798.  
  1799. if (!noexpand) {
  1800. amounts.ExpandSpecs();
  1801. }
  1802. amounts.ProcessItemsFromBC(blocks);
  1803.  
  1804. PrintItems(amounts, missing, nocats, "Ore", M.T["I3"]);
  1805.  
  1806. if (simple)
  1807. PrintItems(amounts, missing, nocats, "Ingot", M.T["I4"]);
  1808. else {
  1809. List<MMAmountSpec> ingots = amounts.GetAmountsOfMain("Ingot");
  1810. if (ingots.Count > 0) {
  1811. if (!nocats) {
  1812. if (MMLCDMgr.curLcd.curLine > 0 && MMLCDMgr.curLcd.lines[0] != "")
  1813. MMLCDMgr.AddLn("");  // add empty line    
  1814. MMLCDMgr.AddCenterLn("<< " + M.T["I4"] + " " + M.T["I2"] + " >>", LCD_LINE_WIDTH / 2);
  1815. }
  1816.  
  1817. for (int i = 0; i < ingots.Count; i++) {
  1818. double num = ingots[i].current;
  1819.  
  1820. if (missing && num >= ingots[i].min)
  1821. continue;
  1822.  
  1823. int quota = ingots[i].max;
  1824. if (missing)
  1825. quota = ingots[i].min;
  1826.  
  1827. string msg = MM.ToDisplay(ingots[i].subType, ingots[i].mainType);
  1828. if (ingots[i].subType != "Scrap") {
  1829. double numOres = amounts.GetAmountSpec(ingots[i].subType + " Ore", ingots[i].subType, "Ore").current;
  1830. ShowInvIngotLine(msg, num, numOres, quota);
  1831. }
  1832. else
  1833. ShowInvLine(msg, num, quota);
  1834. }
  1835. }
  1836. }
  1837.  
  1838. PrintItems(amounts, missing, nocats, "Component", M.T["I5"]);
  1839. PrintItems(amounts, missing, nocats, "OxygenContainerObject", M.T["I6"]);
  1840. PrintItems(amounts, missing, true, "GasContainerObject", "");
  1841. PrintItems(amounts, missing, nocats, "AmmoMagazine", M.T["I7"]);
  1842. PrintItems(amounts, missing, nocats, "PhysicalGunObject", M.T["I8"]);
  1843. }
  1844. }
  1845.  
  1846. public class MMCmd
  1847. {
  1848. public string cmdstr = "";
  1849. public string nameLike = "";
  1850. public string cmdLine;
  1851. public string cmdLineAfterName = "";
  1852.  
  1853. public List<MMArg> args = new List<MMArg>();
  1854.  
  1855. public MMCmd(string _cmdLine)
  1856. {
  1857. cmdLine = _cmdLine.TrimStart(' ');
  1858. if (cmdLine == "")
  1859. return;
  1860.  
  1861. string[] targs = cmdLine.Split(' ');
  1862. string fullArg = "";
  1863. bool multiWord = false;
  1864.  
  1865. cmdstr = targs[0].ToLower();
  1866.  
  1867. for (int i = 1; i < targs.Length; i++) {
  1868. string arg = targs[i];
  1869. if (arg == "")
  1870. continue;
  1871.  
  1872. if (arg[0] == '{' && arg[arg.Length - 1] == '}') {
  1873. arg = arg.Substring(1, arg.Length - 2);
  1874. if (arg == "")
  1875. continue;
  1876. if (nameLike == "")
  1877. nameLike = arg;
  1878. else
  1879. args.Add(new MMArg(arg));
  1880. continue;
  1881. }
  1882. if (arg[0] == '{') {
  1883. multiWord = true;
  1884. fullArg = arg.Substring(1);
  1885. continue;
  1886. }
  1887. if (arg[arg.Length - 1] == '}') {
  1888. multiWord = false;
  1889. fullArg += ' ' + arg.Substring(0, arg.Length - 1);
  1890. if (nameLike == "")
  1891. nameLike = fullArg;
  1892. else
  1893. args.Add(new MMArg(fullArg));
  1894. continue;
  1895. }
  1896.  
  1897. if (multiWord) {
  1898. if (fullArg.Length != 0)
  1899. fullArg += ' ';
  1900. fullArg += arg;
  1901. continue;
  1902. }
  1903.  
  1904. if (nameLike == "")
  1905. nameLike = arg;
  1906. else
  1907. args.Add(new MMArg(arg));
  1908. }
  1909. }
  1910. }
  1911.  
  1912. public class MMArg
  1913. {
  1914. public string op = "";
  1915. public string main = "";
  1916. public string arg = "";
  1917. public List<string> sub = new List<string>();
  1918.  
  1919. public MMArg(string _arg)
  1920. {
  1921. arg = _arg;
  1922. }
  1923.  
  1924. public void Parse()
  1925. {
  1926. string cur = arg.Trim();
  1927. if (cur[0] == '+' || cur[0] == '-') {
  1928. op += cur[0];
  1929. cur = arg.Substring(1);
  1930. }
  1931.  
  1932. string[] parts = cur.Split('/');
  1933. string subargs = parts[0];
  1934.  
  1935. if (parts.Length > 1) {
  1936. main = parts[0];
  1937. subargs = parts[1];
  1938. }
  1939. else
  1940. main = "";
  1941.  
  1942. if (subargs.Length > 0) {
  1943. string[] subs = subargs.Split(',');
  1944. for (int i = 0; i < subs.Length; i++)
  1945. if (subs[i] != "")
  1946. sub.Add(subs[i]);
  1947. }
  1948. }
  1949. }
  1950.  
  1951. public class MMBlkCol
  1952. {
  1953. public List<IMyTerminalBlock> Blocks = new List<IMyTerminalBlock>();
  1954.  
  1955. public double GetCargoSummary(ref double usedAmount, ref double totalAmount)
  1956. {
  1957. for (int i = 0; i < Blocks.Count; i++) {
  1958. IMyInventory inv = Blocks[i].GetInventory(0);
  1959. if (inv == null)
  1960. continue;
  1961.  
  1962. usedAmount += (double)inv.CurrentVolume;
  1963. totalAmount += (double)inv.MaxVolume;
  1964. }
  1965. usedAmount *= 1000;
  1966. totalAmount *= 1000;
  1967. return MM.GetPercent(usedAmount, totalAmount);
  1968. }
  1969.  
  1970. public double GetMassSummary()
  1971. {
  1972. double used = 0;
  1973. for (int i = 0; i < Blocks.Count; i++) {
  1974. for (int invId = 0; invId < 2; invId++) {
  1975. IMyInventory inv = Blocks[i].GetInventory(invId);
  1976. if (inv == null)
  1977. continue;
  1978.  
  1979. used += (double)inv.CurrentMass;
  1980. }
  1981. }
  1982. return used * 1000;
  1983. }
  1984.  
  1985. public double GetPowerOutput(ref double current, ref double max)
  1986. {
  1987. for (int i = 0; i < Blocks.Count; i++) {
  1988. IMyBatteryBlock bat = (Blocks[i] as IMyBatteryBlock);
  1989. List<double> vals = MMStatus.GetDetailVals(Blocks[i]);
  1990. if ((bat != null && vals.Count < 6) ||
  1991. (bat == null && vals.Count < 2))
  1992. continue;
  1993.  
  1994. max += vals[0];
  1995.  
  1996. if (bat != null)
  1997. current += vals[4];
  1998. else
  1999. current += vals[1];
  2000. }
  2001. return MM.GetPercent(current, max);
  2002. }
  2003.  
  2004.  
  2005. // returns percent stored    
  2006. public double GetBatStats(ref double output, ref double max_output,
  2007. ref double input, ref double max_input,
  2008. ref double stored, ref double max_stored)
  2009. {
  2010. for (int i = 0; i < Blocks.Count; i++) {
  2011. List<double> vals = MMStatus.GetDetailVals(Blocks[i]);
  2012. if (vals.Count < 6)
  2013. continue;
  2014.  
  2015. max_output += vals[0];
  2016. max_input += vals[1];
  2017. max_stored += vals[2];
  2018. input += vals[3];
  2019. output += vals[4];
  2020. stored += vals[5];
  2021. }
  2022. return MM.GetPercent(stored, max_stored);
  2023. }
  2024.  
  2025. private void RemoveDiffGrid()
  2026. {
  2027. int i = 0;
  2028. while (i < Blocks.Count) {
  2029. if (Blocks[i].CubeGrid != MM.Me.CubeGrid) {
  2030. Blocks.RemoveAt(i);
  2031. continue;
  2032. }
  2033. i++;
  2034. }
  2035. }
  2036.  
  2037. public void AddBOfName(string nameLike)
  2038. {
  2039. int sep = nameLike.IndexOf(':');
  2040. string modstr = (sep >= 1 && sep <= 2 ? nameLike.Substring(0, sep) : "");
  2041. bool thisgrid = modstr.Contains("T");
  2042. if (modstr != "")
  2043. nameLike = nameLike.Substring(sep + 1);
  2044.  
  2045. if (nameLike == "" || nameLike == "*") {
  2046. List<IMyTerminalBlock> lBlocks = new List<IMyTerminalBlock>();
  2047. MM._GridTerminalSystem.GetBlocks(lBlocks);
  2048. Blocks.AddList(lBlocks);
  2049. if (thisgrid)
  2050. RemoveDiffGrid();
  2051. return;
  2052. }
  2053.  
  2054. string group = (modstr.Contains("G") ? nameLike.Trim().ToLower() : "");
  2055. if (group != "") {
  2056. List<IMyBlockGroup> BlockGroups = new List<IMyBlockGroup>();
  2057. MM._GridTerminalSystem.GetBlockGroups(BlockGroups);
  2058. for (int i = 0; i < BlockGroups.Count; i++) {
  2059. IMyBlockGroup g = BlockGroups[i];
  2060. if (g.Name.ToLower() == group) {
  2061. g.GetBlocks(Blocks);
  2062. if (thisgrid)
  2063. RemoveDiffGrid();
  2064. return;
  2065. }
  2066. }
  2067. return;
  2068. }
  2069. MM._GridTerminalSystem.SearchBlocksOfName(nameLike, Blocks);
  2070. if (thisgrid)
  2071. RemoveDiffGrid();
  2072. }
  2073.  
  2074. public void AddBofT(string type, string nameLike = "")
  2075. {
  2076. int sep = nameLike.IndexOf(':');
  2077. string modstr = (sep >= 1 && sep <= 2 ? nameLike.Substring(0, sep) : "");
  2078. bool thisgrid = modstr.Contains("T");
  2079. if (modstr != "")
  2080. nameLike = nameLike.Substring(sep + 1);
  2081.  
  2082. List<IMyTerminalBlock> blocksOfType = new List<IMyTerminalBlock>();
  2083. if (nameLike == "" || nameLike == "*") {
  2084. MMBlkMgr.GetBlocksOfType(ref blocksOfType, type);
  2085. Blocks.AddList(blocksOfType);
  2086. if (thisgrid)
  2087. RemoveDiffGrid();
  2088. return;
  2089. }
  2090. string group = (modstr.Contains("G") ? nameLike.Trim().ToLower() : "");
  2091. List<IMyTerminalBlock> blocks = new List<IMyTerminalBlock>();
  2092. if (group != "") {
  2093. List<IMyBlockGroup> BlockGroups = new List<IMyBlockGroup>();
  2094. MM._GridTerminalSystem.GetBlockGroups(BlockGroups);
  2095. for (int i = 0; i < BlockGroups.Count; i++) {
  2096. IMyBlockGroup g = BlockGroups[i];
  2097. if (g.Name.ToLower() == group) {
  2098. blocks.Clear();
  2099. g.GetBlocks(blocks);
  2100. for (int j = 0; j < blocks.Count; j++) {
  2101. if (thisgrid && blocks[j].CubeGrid != MM.Me.CubeGrid)
  2102. continue;
  2103. if (MMBlkMgr.IsBlockOfType(blocks[j], type))
  2104. Blocks.Add(blocks[j]);
  2105. }
  2106. return;
  2107. }
  2108. }
  2109. return;
  2110. }
  2111. MMBlkMgr.GetBlocksOfType(ref blocksOfType, type);
  2112. for (int i = 0; i < blocksOfType.Count; i++) {
  2113. if (thisgrid && blocksOfType[i].CubeGrid != MM.Me.CubeGrid)
  2114. continue;
  2115. if (blocksOfType[i].CustomName.Contains(nameLike))
  2116. Blocks.Add(blocksOfType[i]);
  2117. }
  2118. }
  2119.  
  2120. // add all Blocks from collection col to this collection      
  2121. public void AddFromBC(MMBlkCol col)
  2122. {
  2123. Blocks.AddList(col.Blocks);
  2124. }
  2125.  
  2126. // clear all reactors from this collection      
  2127. public void Clear()
  2128. {
  2129. Blocks.Clear();
  2130. }
  2131.  
  2132. // number of reactors in collection      
  2133. public int Count()
  2134. {
  2135. return Blocks.Count;
  2136. }
  2137. }
  2138.  
  2139. public class MMAmountSpec
  2140. {
  2141. public int min;
  2142. public int max;
  2143. public string subType = "";
  2144. public string mainType = "";
  2145. public bool ignore;
  2146. public double current;
  2147.  
  2148. public MMAmountSpec(bool _ignore = false, int _min = 1, int _max = -1)
  2149. {
  2150. min = _min;
  2151. ignore = _ignore;
  2152. max = _max;
  2153. }
  2154. }
  2155.  
  2156. // Item amounts class    
  2157. public class MMItemAmounts
  2158. {
  2159. private static Dictionary<string, string> mainTypeMap = new Dictionary<string, string>() {  
  2160. { "ingot", "ingot" },  
  2161. { "ore", "ore" },  
  2162. { "component", "component" },  
  2163. { "tool", "physicalgunobject" },  
  2164. { "ammo", "ammomagazine"},  
  2165. { "oxygen", "oxygencontainerobject" },  
  2166. { "gas", "gascontainerobject" }  
  2167. };
  2168.  
  2169. public MMAmountSpecDict specBySubLower;
  2170. public MMAmountSpecDict specByMainLower;
  2171. public MMAmountSpecDict specByFullLower;
  2172. public bool specAll;
  2173.  
  2174. public MMAmountSpecDict amountByFullType;
  2175.  
  2176. public MMItemAmounts(int size = 20)
  2177. {
  2178. specBySubLower = new MMAmountSpecDict();
  2179. specByMainLower = new MMAmountSpecDict();
  2180. specByFullLower = new MMAmountSpecDict();
  2181. specAll = false;
  2182. amountByFullType = new MMAmountSpecDict();
  2183. }
  2184.  
  2185. public void AddSpec(string subfulltype, bool ignore = false, int min = 1, int max = -1)
  2186. {
  2187. if (subfulltype == "") {
  2188. specAll = true;
  2189. return;
  2190. }
  2191.  
  2192. string[] parts = subfulltype.Split(' ');
  2193.  
  2194. string mainType = "";
  2195. MMAmountSpec spec = new MMAmountSpec(ignore, min, max);
  2196.  
  2197. if (parts.Length == 2) {
  2198. if (!mainTypeMap.TryGetValue(parts[1], out mainType))
  2199. mainType = parts[1];
  2200. }
  2201.  
  2202. string subType = parts[0];
  2203.  
  2204. if (mainTypeMap.TryGetValue(subType, out spec.mainType)) {
  2205. specByMainLower.AddItem(spec.mainType, spec);
  2206. return;
  2207. }
  2208.  
  2209. MM.ToInternal(ref subType, ref mainType);
  2210. if (mainType == "") {
  2211. spec.subType = subType.ToLower();
  2212. specBySubLower.AddItem(spec.subType, spec);
  2213. return;
  2214. }
  2215.  
  2216. spec.subType = subType;
  2217. spec.mainType = mainType;
  2218. specByFullLower.AddItem(subType.ToLower() + ' ' + mainType.ToLower(), spec);
  2219. }
  2220.  
  2221. public MMAmountSpec GetSpec(string fullType, string subType, string mainType)
  2222. {
  2223. MMAmountSpec spec;
  2224.  
  2225. fullType = fullType.ToLower();
  2226. spec = specByFullLower.GetItem(fullType);
  2227. if (spec != null)
  2228. return spec;
  2229.  
  2230. subType = subType.ToLower();
  2231. spec = specBySubLower.GetItem(subType);
  2232. if (spec != null)
  2233. return spec;
  2234.  
  2235. mainType = mainType.ToLower();
  2236. spec = specByMainLower.GetItem(mainType);
  2237. if (spec != null)
  2238. return spec;
  2239.  
  2240. return null;
  2241. }
  2242.  
  2243. public bool IsIgnored(string fullType, string subType, string mainType)
  2244. {
  2245. MMAmountSpec spec;
  2246. bool found = false;
  2247.  
  2248. spec = specByMainLower.GetItem(mainType.ToLower());
  2249. if (spec != null) {
  2250. if (spec.ignore)
  2251. return true;
  2252. found = true;
  2253. }
  2254. spec = specBySubLower.GetItem(subType.ToLower());
  2255. if (spec != null) {
  2256. if (spec.ignore)
  2257. return true;
  2258. found = true;
  2259. }
  2260. spec = specByFullLower.GetItem(fullType.ToLower());
  2261. if (spec != null) {
  2262. if (spec.ignore)
  2263. return true;
  2264. found = true;
  2265. }
  2266.  
  2267. return !(specAll || found);
  2268. }
  2269.  
  2270. public MMAmountSpec CreateAmountSpec(string fullType, string subType, string mainType)
  2271. {
  2272. MMAmountSpec amount = new MMAmountSpec();
  2273.  
  2274. fullType = fullType.ToLower();
  2275. MMAmountSpec spec = GetSpec(fullType, subType.ToLower(), mainType.ToLower());
  2276. if (spec != null) {
  2277. amount.min = spec.min;
  2278. amount.max = spec.max;
  2279. }
  2280. amount.subType = subType;
  2281. amount.mainType = mainType;
  2282.  
  2283. amountByFullType.AddItem(fullType, amount);
  2284.  
  2285. return amount;
  2286. }
  2287.  
  2288. public MMAmountSpec GetAmountSpec(string fullType, string subType, string mainType)
  2289. {
  2290. MMAmountSpec amount = amountByFullType.GetItem(fullType.ToLower());
  2291. if (amount == null)
  2292. amount = CreateAmountSpec(fullType, subType, mainType);
  2293. return amount;
  2294. }
  2295.  
  2296. public List<MMAmountSpec> GetAmountsOfMain(string mainType)
  2297. {
  2298. List<MMAmountSpec> result = new List<MMAmountSpec>();
  2299.  
  2300. for (int i = 0; i < amountByFullType.CountAll(); i++) {
  2301. MMAmountSpec spec = amountByFullType.GetItemAt(i);
  2302. if (IsIgnored((spec.subType + ' ' + spec.mainType).ToLower(),
  2303. spec.subType, spec.mainType))
  2304. continue;
  2305. if (spec.mainType == mainType)
  2306. result.Add(spec);
  2307. }
  2308.  
  2309. return result;
  2310. }
  2311.  
  2312. public void ExpandSpecs()
  2313. {
  2314. for (int i = 0; i < MMItems.keys.Count; i++) {
  2315. MMItem item = MMItems.items[MMItems.keys[i]];
  2316. if (!item.used)
  2317. continue;
  2318. string fullType = item.subType + ' ' + item.mainType;
  2319.  
  2320. if (IsIgnored(fullType, item.subType, item.mainType))
  2321. continue;
  2322.  
  2323. MMAmountSpec amount = GetAmountSpec(fullType, item.subType, item.mainType);
  2324. if (amount.max == -1)
  2325. amount.max = item.defQt;
  2326. }
  2327. }
  2328.  
  2329. public void ProcessItemsFromBC(MMBlkCol col)
  2330. {
  2331. for (int i = 0; i < col.Count(); i++) {
  2332. for (int invId = 0; invId < col.Blocks[i].GetInventoryCount(); invId++) {
  2333. IMyInventory inv = col.Blocks[i].GetInventory(invId);
  2334.  
  2335. List<IMyInventoryItem> items = inv.GetItems();
  2336. for (int j = 0; j < items.Count; j++) {
  2337. IMyInventoryItem item = items[j];
  2338. string fullType = MM.GetItemFullType(item);
  2339. string fullTypeL = fullType.ToLower();
  2340. string subType, mainType;
  2341. MM.ParseFullType(fullTypeL, out subType, out mainType);
  2342.  
  2343. if (mainType == "ore") {
  2344. if (IsIgnored(subType.ToLower() + " ingot", subType, "Ingot") &&
  2345. IsIgnored(fullType, subType, mainType))
  2346. continue;
  2347. }
  2348. else {
  2349. if (IsIgnored(fullType, subType, mainType))
  2350. continue;
  2351. }
  2352.  
  2353. MM.ParseFullType(fullType, out subType, out mainType);
  2354. MMAmountSpec amount = GetAmountSpec(fullTypeL, subType, mainType);
  2355. amount.current += (double)item.Amount;
  2356. }
  2357. }
  2358. }
  2359. }
  2360. }
  2361.  
  2362. // MMAPI Helper functions    
  2363. public static class MMBlkMgr
  2364. {
  2365. public static IMyGridTerminalSystem _GridTerminalSystem;
  2366.  
  2367. private static Dictionary<string, Action<List<IMyTerminalBlock>, Func<IMyTerminalBlock, bool>>> BofT = null;
  2368.  
  2369. public static void InitBlocksOfExactType()
  2370. {
  2371. if (BofT != null && _GridTerminalSystem.GetBlocksOfType<IMyCargoContainer> == BofT["CargoContainer"])
  2372. return;
  2373.  
  2374. BofT = new Dictionary<string, Action<List<IMyTerminalBlock>, Func<IMyTerminalBlock, bool>>>() {  
  2375. { "CargoContainer", _GridTerminalSystem.GetBlocksOfType<IMyCargoContainer> },  
  2376. { "TextPanel", _GridTerminalSystem.GetBlocksOfType<IMyTextPanel> },  
  2377. { "Assembler", _GridTerminalSystem.GetBlocksOfType<IMyAssembler> },  
  2378. { "Refinery", _GridTerminalSystem.GetBlocksOfType<IMyRefinery> },  
  2379. { "Reactor", _GridTerminalSystem.GetBlocksOfType<IMyReactor> },  
  2380. { "SolarPanel", _GridTerminalSystem.GetBlocksOfType<IMySolarPanel> },  
  2381. { "BatteryBlock", _GridTerminalSystem.GetBlocksOfType<IMyBatteryBlock> },  
  2382. { "Beacon", _GridTerminalSystem.GetBlocksOfType<IMyBeacon> },  
  2383. { "RadioAntenna", _GridTerminalSystem.GetBlocksOfType<IMyRadioAntenna> },  
  2384. { "AirVent", _GridTerminalSystem.GetBlocksOfType<IMyAirVent> },  
  2385. { "ConveyorSorter", _GridTerminalSystem.GetBlocksOfType<IMyConveyorSorter> },  
  2386. { "OxygenTank", _GridTerminalSystem.GetBlocksOfType<IMyOxygenTank> },  
  2387. { "OxygenGenerator", _GridTerminalSystem.GetBlocksOfType<IMyOxygenGenerator> },  
  2388. { "OxygenFarm", _GridTerminalSystem.GetBlocksOfType<IMyOxygenFarm> },  
  2389. { "LaserAntenna", _GridTerminalSystem.GetBlocksOfType<IMyLaserAntenna> },  
  2390. { "Thrust", _GridTerminalSystem.GetBlocksOfType<IMyThrust> },  
  2391. { "Gyro", _GridTerminalSystem.GetBlocksOfType<IMyGyro> },  
  2392. { "SensorBlock", _GridTerminalSystem.GetBlocksOfType<IMySensorBlock> },  
  2393. { "ShipConnector", _GridTerminalSystem.GetBlocksOfType<IMyShipConnector> },  
  2394. { "ReflectorLight", _GridTerminalSystem.GetBlocksOfType<IMyReflectorLight> },  
  2395. { "InteriorLight", _GridTerminalSystem.GetBlocksOfType<IMyInteriorLight> },  
  2396. { "LandingGear", _GridTerminalSystem.GetBlocksOfType<IMyLandingGear> },  
  2397. { "ProgrammableBlock", _GridTerminalSystem.GetBlocksOfType<IMyProgrammableBlock> },  
  2398. { "TimerBlock", _GridTerminalSystem.GetBlocksOfType<IMyTimerBlock> },  
  2399. { "MotorStator", _GridTerminalSystem.GetBlocksOfType<IMyMotorStator> },  
  2400. { "PistonBase", _GridTerminalSystem.GetBlocksOfType<IMyPistonBase> },  
  2401. { "Projector", _GridTerminalSystem.GetBlocksOfType<IMyProjector> },  
  2402. { "ShipMergeBlock", _GridTerminalSystem.GetBlocksOfType<IMyShipMergeBlock> },  
  2403. { "SoundBlock", _GridTerminalSystem.GetBlocksOfType<IMySoundBlock> },  
  2404. { "Collector", _GridTerminalSystem.GetBlocksOfType<IMyCollector> },  
  2405. { "JumpDrive", _GridTerminalSystem.GetBlocksOfType<IMyJumpDrive> },  
  2406. { "Door", _GridTerminalSystem.GetBlocksOfType<IMyDoor> },  
  2407. { "GravityGeneratorSphere", _GridTerminalSystem.GetBlocksOfType<IMyGravityGeneratorSphere> },  
  2408. { "GravityGenerator", _GridTerminalSystem.GetBlocksOfType<IMyGravityGenerator> },  
  2409. { "ShipDrill", _GridTerminalSystem.GetBlocksOfType<IMyShipDrill> },  
  2410. { "ShipGrinder", _GridTerminalSystem.GetBlocksOfType<IMyShipGrinder> },  
  2411. { "ShipWelder", _GridTerminalSystem.GetBlocksOfType<IMyShipWelder> },  
  2412. { "LargeGatlingTurret", _GridTerminalSystem.GetBlocksOfType<IMyLargeGatlingTurret> },  
  2413. { "LargeInteriorTurret", _GridTerminalSystem.GetBlocksOfType<IMyLargeInteriorTurret> },  
  2414. { "LargeMissileTurret", _GridTerminalSystem.GetBlocksOfType<IMyLargeMissileTurret> },  
  2415. { "SmallGatlingGun", _GridTerminalSystem.GetBlocksOfType<IMySmallGatlingGun> },  
  2416. { "SmallMissileLauncherReload", _GridTerminalSystem.GetBlocksOfType<IMySmallMissileLauncherReload> },  
  2417. { "SmallMissileLauncher", _GridTerminalSystem.GetBlocksOfType<IMySmallMissileLauncher> },  
  2418. { "VirtualMass", _GridTerminalSystem.GetBlocksOfType<IMyVirtualMass> },  
  2419. { "Warhead", _GridTerminalSystem.GetBlocksOfType<IMyWarhead> },  
  2420. { "FunctionalBlock", _GridTerminalSystem.GetBlocksOfType<IMyFunctionalBlock> },  
  2421. { "LightingBlock", _GridTerminalSystem.GetBlocksOfType<IMyLightingBlock> },  
  2422. { "ControlPanel", _GridTerminalSystem.GetBlocksOfType<IMyControlPanel> },  
  2423. { "Cockpit", _GridTerminalSystem.GetBlocksOfType<IMyCockpit> },  
  2424. { "MedicalRoom", _GridTerminalSystem.GetBlocksOfType<IMyMedicalRoom> },  
  2425. { "RemoteControl", _GridTerminalSystem.GetBlocksOfType<IMyRemoteControl> },  
  2426. { "ButtonPanel", _GridTerminalSystem.GetBlocksOfType<IMyButtonPanel> },  
  2427. { "CameraBlock", _GridTerminalSystem.GetBlocksOfType<IMyCameraBlock> },  
  2428. { "OreDetector", _GridTerminalSystem.GetBlocksOfType<IMyOreDetector> },  
  2429. { "ShipController", _GridTerminalSystem.GetBlocksOfType<IMyShipController> }  
  2430. };
  2431. }
  2432.  
  2433. private static bool IsCryoChamber(IMyTerminalBlock block)
  2434. {
  2435. return block.BlockDefinition.ToString().Contains("Cryo");
  2436. }
  2437.  
  2438. public static void GetBlocksOfExactType(ref List<IMyTerminalBlock> blocks, string exact)
  2439. {
  2440. Action<List<IMyTerminalBlock>, Func<IMyTerminalBlock, bool>> fn = null;
  2441. if (BofT.TryGetValue(exact, out fn))
  2442. fn(blocks, null);
  2443. else {
  2444. if (exact == "CryoChamber") {
  2445. _GridTerminalSystem.GetBlocksOfType<IMyCockpit>(blocks, IsCryoChamber);
  2446. return;
  2447. }
  2448. }
  2449. }
  2450.  
  2451. public static void GetBlocksOfType(ref List<IMyTerminalBlock> blocks, string typestr)
  2452. {
  2453. GetBlocksOfExactType(ref blocks, ToExactBlockType(typestr.Trim()));
  2454. }
  2455.  
  2456. public static bool IsBlockOfType(IMyTerminalBlock block, string typestr)
  2457. {
  2458. string et = ToExactBlockType(typestr);
  2459. switch (et) {
  2460. case "FunctionalBlock":
  2461. return true;
  2462. case "ShipController":
  2463. return (block as IMyShipController != null);
  2464. default:
  2465. return block.BlockDefinition.ToString().Contains(ToExactBlockType(typestr));
  2466. }
  2467. }
  2468.  
  2469. public static string ToExactBlockType(string typeInStr)
  2470. {
  2471. typeInStr = typeInStr.ToLower();
  2472.  
  2473. if (typeInStr.StartsWith("carg")
  2474. || typeInStr.StartsWith("conta")) return "CargoContainer";
  2475. if (typeInStr.StartsWith("text")
  2476. || typeInStr.StartsWith("lcd")) return "TextPanel";
  2477. if (typeInStr.StartsWith("ass")) return "Assembler";
  2478. if (typeInStr.StartsWith("refi")) return "Refinery";
  2479. if (typeInStr.StartsWith("reac")) return "Reactor";
  2480. if (typeInStr.StartsWith("solar")) return "SolarPanel";
  2481. if (typeInStr.StartsWith("bat")) return "BatteryBlock";
  2482. if (typeInStr.StartsWith("bea")) return "Beacon";
  2483. if (typeInStr.Contains("vent")) return "AirVent";
  2484. if (typeInStr.Contains("sorter")) return "ConveyorSorter";
  2485. if (typeInStr.Contains("tank")) return "OxygenTank";
  2486. if (typeInStr.Contains("farm")
  2487. && typeInStr.Contains("oxy")) return "OxygenFarm";
  2488. if (typeInStr.Contains("gene")
  2489. && typeInStr.Contains("oxy")) return "OxygenGenerator";
  2490. if (typeInStr.Contains("cryo")) return "CryoChamber";
  2491. if (typeInStr == "laserantenna") return "LaserAntenna";
  2492. if (typeInStr.Contains("antenna")) return "RadioAntenna";
  2493. if (typeInStr.StartsWith("thrust")) return "Thrust";
  2494. if (typeInStr.StartsWith("gyro")) return "Gyro";
  2495. if (typeInStr.StartsWith("sensor")) return "SensorBlock";
  2496. if (typeInStr.Contains("connector")) return "ShipConnector";
  2497. if (typeInStr.StartsWith("reflector")) return "ReflectorLight";
  2498. if ((typeInStr.StartsWith("inter")
  2499. && typeInStr.EndsWith("light"))) return "InteriorLight";
  2500. if (typeInStr.StartsWith("land")) return "LandingGear";
  2501. if (typeInStr.StartsWith("program")) return "ProgrammableBlock";
  2502. if (typeInStr.StartsWith("timer")) return "TimerBlock";
  2503. if (typeInStr.StartsWith("motor")) return "MotorStator";
  2504. if (typeInStr.StartsWith("piston")) return "PistonBase";
  2505. if (typeInStr.StartsWith("proj")) return "Projector";
  2506. if (typeInStr.Contains("merge")) return "ShipMergeBlock";
  2507. if (typeInStr.StartsWith("sound")) return "SoundBlock";
  2508. if (typeInStr.StartsWith("col")) return "Collector";
  2509. if (typeInStr.Contains("jump")) return "JumpDrive";
  2510. if (typeInStr == "door") return "Door";
  2511. if ((typeInStr.Contains("grav")
  2512. && typeInStr.Contains("sphe"))) return "GravityGeneratorSphere";
  2513. if (typeInStr.Contains("grav")) return "GravityGenerator";
  2514. if (typeInStr.EndsWith("drill")) return "ShipDrill";
  2515. if (typeInStr.Contains("grind")) return "ShipGrinder";
  2516. if (typeInStr.EndsWith("welder")) return "ShipWelder";
  2517. if ((typeInStr.Contains("turret")
  2518. && typeInStr.Contains("gatl"))) return "LargeGatlingTurret";
  2519. if ((typeInStr.Contains("turret")
  2520. && typeInStr.Contains("inter"))) return "LargeInteriorTurret";
  2521. if ((typeInStr.Contains("turret")
  2522. && typeInStr.Contains("miss"))) return "LargeMissileTurret";
  2523. if (typeInStr.Contains("gatl")) return "SmallGatlingGun";
  2524. if ((typeInStr.Contains("launcher")
  2525. && typeInStr.Contains("reload"))) return "SmallMissileLauncherReload";
  2526. if ((typeInStr.Contains("launcher"))) return "SmallMissileLauncher";
  2527. if (typeInStr.Contains("mass")) return "VirtualMass";
  2528. if (typeInStr == "warhead") return "Warhead";
  2529. if (typeInStr.StartsWith("func")) return "FunctionalBlock";
  2530. if (typeInStr == "shipctrl") return "ShipController";
  2531. if (typeInStr.StartsWith("light")) return "LightingBlock";
  2532. if (typeInStr.StartsWith("contr")) return "ControlPanel";
  2533. if (typeInStr.StartsWith("coc")) return "Cockpit";
  2534. if (typeInStr.StartsWith("medi")) return "MedicalRoom";
  2535. if (typeInStr.StartsWith("remote")) return "RemoteControl";
  2536. if (typeInStr.StartsWith("but")) return "ButtonPanel";
  2537. if (typeInStr.StartsWith("cam")) return "CameraBlock";
  2538. if (typeInStr.Contains("detect")) return "OreDetector";
  2539. return "Unknown";
  2540. }
  2541. }
  2542.  
  2543. public static class MMStatus
  2544. {
  2545. public static List<double> GetDetailVals(IMyTerminalBlock block, int lines = -1)
  2546. {
  2547. List<double> result = new List<double>();
  2548.  
  2549. string[] attrLines = block.DetailedInfo.Split('\n');
  2550. int max = Math.Min(attrLines.Length, (lines > 0 ? lines : attrLines.Length));
  2551.  
  2552. for (int i = 0; i < max; i++) {
  2553. string[] parts = attrLines[i].Split(':');
  2554. // broken line? (try German)    
  2555. if (parts.Length < 2) {
  2556. parts = attrLines[i].Split('r');
  2557. // still broken line? (try Portuguese)    
  2558. if (parts.Length < 2)
  2559. parts = attrLines[i].Split('x');
  2560. }
  2561.  
  2562. string valStr = (parts.Length < 2 ? parts[0] : parts[1]);
  2563. string[] valParts = valStr.Trim().Split(' ');
  2564. string strVal = valParts[0].Trim();
  2565. char strUnit = (valParts.Length > 1 && valParts[1].Length > 1 ? valParts[1][0] : '.');
  2566.  
  2567. double val;
  2568. if (Double.TryParse(strVal, out val)) {
  2569. double finalVal = val * Math.Pow(1000.0, ".kMGTPEZY".IndexOf(strUnit));
  2570. result.Add(finalVal);
  2571. }
  2572. }
  2573. return result;
  2574. }
  2575.  
  2576. public static string GetBatWorkingStr(IMyBatteryBlock battery)
  2577. {
  2578. string prefix = "";
  2579. if (battery.GetValueBool("Recharge"))
  2580. prefix = "(+) ";
  2581. else
  2582. if (battery.GetValueBool("Discharge"))
  2583. prefix = "(-) ";
  2584. else
  2585. prefix = "(±) ";
  2586. return prefix + ((battery.CurrentStoredPower / battery.MaxStoredPower) * 100.0f).ToString("0.0") + "%";
  2587. }
  2588.  
  2589. // Get laser antenna status    
  2590. public static string GetLAStatus(IMyLaserAntenna gear)
  2591. {
  2592. string[] infoLines = gear.DetailedInfo.Split('\n');
  2593. return infoLines[infoLines.Length - 1].Split(' ')[0].ToUpper();
  2594. }
  2595.  
  2596. public static double GetJDChargeVals(IMyJumpDrive jd, out double cur, out double max)
  2597. {
  2598. List<double> vals = GetDetailVals(jd, 5);
  2599. if (vals.Count < 4) {
  2600. max = 0;
  2601. cur = 0;
  2602. return 0;
  2603. }
  2604.  
  2605. max = vals[1];
  2606. cur = vals[3];
  2607.  
  2608. return MM.GetPercent(cur, max);
  2609. }
  2610.  
  2611. public static double GetJDCharge(IMyJumpDrive jd)
  2612. {
  2613. List<double> vals = GetDetailVals(jd, 5);
  2614. double max = 0, cur = 0;
  2615. if (vals.Count < 4)
  2616. return 0;
  2617.  
  2618. max = vals[1];
  2619. cur = vals[3];
  2620.  
  2621. return MM.GetPercent(cur, max);
  2622. }
  2623.  
  2624. // Get landing gear status    
  2625. public static string GetLGStatus(IMyLandingGear gear)
  2626. {
  2627. string unlockchars = "udoesnp";
  2628.  
  2629. string[] infoLines = gear.DetailedInfo.Split('\n');
  2630. string attrLine = infoLines[infoLines.Length - 1];
  2631.  
  2632. string[] attr = attrLine.Split(':');
  2633.  
  2634. string state;
  2635. if (attr.Length < 2) {
  2636. state = attr[0].Trim().ToLower();
  2637. // Nederlands language (broken)    
  2638. if (state.StartsWith("slot status"))
  2639. state = state.Substring(11);
  2640. }
  2641. else
  2642. state = attr[1].Trim().ToLower();
  2643.  
  2644. if (state == "")
  2645. return M.T["W8"];
  2646.  
  2647. // hope it will be more words in other langs too    
  2648. if (state.Split(' ').Length > 1)
  2649. return M.T["W10"];
  2650.  
  2651. if ((unlockchars.IndexOf(state[0]) < 0) && !state.StartsWith("au"))
  2652. return M.T["W7"];
  2653.  
  2654. return M.T["W8"];
  2655. }
  2656. }
  2657.  
  2658. public static class MM
  2659. {
  2660. public static bool EnableDebug;
  2661. public static IMyGridTerminalSystem _GridTerminalSystem;
  2662. public static MMBlkCol _DebugTextPanels;
  2663. public static IMyProgrammableBlock Me;
  2664. public static Action<string> Echo;
  2665. public static double ElapsedTime = 0;
  2666.  
  2667. public static bool Init(IMyGridTerminalSystem gridSystem)
  2668. {
  2669. _GridTerminalSystem = gridSystem;
  2670. MMBlkMgr._GridTerminalSystem = gridSystem;
  2671. if (MM.ElapsedTime < 0.2f) return false;
  2672. _DebugTextPanels = new MMBlkCol();
  2673. MMBlkMgr.InitBlocksOfExactType();
  2674. MMStrFn.InitCharSizes();
  2675. if (MM.EnableDebug) {
  2676. _DebugTextPanels.AddBofT("textpanel", "[DEBUG]");
  2677. Debug("DEBUG Panel started.", false, "DEBUG PANEL");
  2678. }
  2679.  
  2680. MMItems.Init();
  2681. return true;
  2682. }
  2683.  
  2684. public static double GetPercent(double current, double max)
  2685. {
  2686. return (max > 0 ? (current / max) * 100 : 100);
  2687. }
  2688.  
  2689. // return full type of item      
  2690. public static string GetItemFullType(IMyInventoryItem item)
  2691. {
  2692. string typeid = item.Content.TypeId.ToString();
  2693. typeid = typeid.Substring(typeid.LastIndexOf('_') + 1);
  2694. return item.Content.SubtypeName + " " + typeid;
  2695. }
  2696.  
  2697. // parse full type into subType and mainType      
  2698. public static void ParseFullType(string fullType, out string subType, out string mainType)
  2699. {
  2700. int idx = fullType.LastIndexOf(' ');
  2701.  
  2702. if (idx >= 0) {
  2703. subType = fullType.Substring(0, idx);
  2704. mainType = fullType.Substring(idx + 1);
  2705. return;
  2706. }
  2707. subType = fullType;
  2708. mainType = "";
  2709. }
  2710.  
  2711. public static string ToDisplay(string fullType)
  2712. {
  2713. string subType, mainType;
  2714. ParseFullType(fullType, out subType, out mainType);
  2715.  
  2716. return ToDisplay(subType, mainType);
  2717. }
  2718.  
  2719. public static string ToDisplay(string subType, string mainType)
  2720. {
  2721. MMItem item = MMItems.GetItemOfType(subType, mainType);
  2722. if (item != null) {
  2723. if (item.dName != "")
  2724. return item.dName;
  2725.  
  2726. return item.subType;
  2727. }
  2728.  
  2729. return System.Text.RegularExpressions.Regex.Replace(
  2730. subType, "([a-z])([A-Z])", "$1 $2");
  2731. }
  2732.  
  2733. public static void ToInternal(ref string subType, ref string mainType)
  2734. {
  2735. string shortName = subType.ToLower();
  2736. MMItem item;
  2737.  
  2738. if (MMItems.itemsByShort.TryGetValue(shortName, out item)) {
  2739. subType = item.subType;
  2740. mainType = item.mainType;
  2741. return;
  2742. }
  2743.  
  2744. item = MMItems.GetItemOfType(subType, mainType);
  2745. if (item != null) {
  2746. subType = item.subType;
  2747. if (mainType == "Ore" || mainType == "Ingot")
  2748. return;
  2749. mainType = item.mainType;
  2750. }
  2751. }
  2752.  
  2753. public static string FormatLargeNumber(double number, bool compress = true)
  2754. {
  2755. if (!compress)
  2756. return number.ToString(
  2757. "#,###,###,###,###,###,###,###,###,###");
  2758.  
  2759. string ordinals = " kMGTPEZY";
  2760. double compressed = number;
  2761.  
  2762. var ordinal = 0;
  2763.  
  2764. while (compressed >= 1000) {
  2765. compressed /= 1000;
  2766. ordinal++;
  2767. }
  2768.  
  2769. string res = Math.Round(compressed, 1, MidpointRounding.AwayFromZero).ToString();
  2770.  
  2771. if (ordinal > 0)
  2772. res += " " + ordinals[ordinal];
  2773.  
  2774. return res;
  2775. }
  2776.  
  2777. public static void WriteLine(IMyTextPanel textpanel, string message, bool append = true, string title = "")
  2778. {
  2779. textpanel.WritePublicText(message + "\n", append);
  2780. if (title != "")
  2781. textpanel.WritePublicTitle(title);
  2782. textpanel.ShowTextureOnScreen();
  2783. textpanel.ShowPublicTextOnScreen();
  2784. }
  2785.  
  2786. public static void Debug(string message, bool append = true, string title = "")
  2787. {
  2788. if (EnableDebug && _DebugTextPanels != null && _DebugTextPanels.Count() != 0)
  2789. DebugTextPanel(message, append, title);
  2790. }
  2791.  
  2792. public static void DebugTextPanel(string message, bool append = true, string title = "")
  2793. {
  2794. for (int i = 0; i < _DebugTextPanels.Count(); i++) {
  2795. IMyTextPanel debugpanel = _DebugTextPanels.Blocks[i] as IMyTextPanel;
  2796. debugpanel.SetCustomName("[DEBUG] Prog: " + message);
  2797. WriteLine(debugpanel, message, append, title);
  2798. }
  2799. }
  2800. }
  2801.  
  2802. public class MMPanel
  2803. {
  2804. // approximate width of LCD panel line    
  2805. public const float LCD_LINE_WIDTH = 730;
  2806.  
  2807. public MMTextPanelDict panels = new MMTextPanelDict();
  2808. public MMLCDMgr.MMLCDText text;
  2809. public IMyTextPanel first;
  2810.  
  2811. public void SetFontSize(float size)
  2812. {
  2813. for (int i = 0; i < panels.CountAll(); i++)
  2814. panels.GetItemAt(i).SetValueFloat("FontSize", size);
  2815. }
  2816.  
  2817. public void SortPanels()
  2818. {
  2819. panels.SortAll();
  2820. first = panels.GetItemAt(0);
  2821. }
  2822.  
  2823. public bool IsWide()
  2824. {
  2825. return (first.BlockDefinition.SubtypeId.Contains("Wide")
  2826. || first.DefinitionDisplayNameText == "Computer Monitor");
  2827. }
  2828.  
  2829. public void Update()
  2830. {
  2831. if (text == null || first == null)
  2832. return;
  2833.  
  2834. float size = first.GetValueFloat("FontSize");
  2835.  
  2836. for (int i = 0; i < panels.CountAll(); i++) {
  2837. IMyTextPanel panel = panels.GetItemAt(i);
  2838. if (i > 0)
  2839. panel.SetValueFloat("FontSize", size);
  2840. panel.WritePublicText(text.GetDisplayString(i));
  2841. if (MMLCDMgr.forceRedraw) {
  2842. panel.ShowTextureOnScreen();
  2843. }
  2844. panel.ShowPublicTextOnScreen();
  2845. }
  2846. }
  2847. }
  2848.  
  2849. public static class MMLCDMgr
  2850. {
  2851. private static Dictionary<IMyTextPanel, MMLCDText> texts = new Dictionary<IMyTextPanel, MMLCDText>();
  2852. public static bool forceRedraw = true;
  2853. public static int SCROLL_LINES = 5;
  2854. public static MMLCDText curLcd = null;
  2855. public static MMPanel curP = null;
  2856.  
  2857. public static void SetupLCDText(MMPanel p)
  2858. {
  2859. MMLCDText lcdText = GetLCDText(p);
  2860. lcdText.SetFontSize(p.first.GetValueFloat("FontSize"));
  2861. lcdText.SetNrScreens(p.panels.CountAll());
  2862. lcdText.widthMod = (p.IsWide() ? 2.0f : 1.0f) * (0.8f / lcdText.fontSize);
  2863. curLcd = lcdText;
  2864. curP = p;
  2865. }
  2866.  
  2867. public static MMLCDText GetLCDText(MMPanel p)
  2868. {
  2869. MMLCDText lcdText;
  2870. IMyTextPanel panel = p.first;
  2871.  
  2872. if (!texts.TryGetValue(panel, out lcdText)) {
  2873. lcdText = new MMLCDText();
  2874. p.text = lcdText;
  2875. texts.Add(panel, lcdText);
  2876. }
  2877. else
  2878. p.text = lcdText;
  2879. return lcdText;
  2880. }
  2881.  
  2882. public static void AddLn(string line)
  2883. {
  2884. curLcd.AddLine(line);
  2885. }
  2886.  
  2887. public static void AddMultiLn(string multiline)
  2888. {
  2889. curLcd.AddMultiLine(multiline);
  2890. }
  2891.  
  2892. public static void Add(string text)
  2893. {
  2894. curLcd.AddFast(text);
  2895. curLcd.curWidth += MMStrFn.GetSize(text);
  2896. }
  2897.  
  2898. public static void AddRightLn(string text, float endScreenX)
  2899. {
  2900. AddRight(text, endScreenX);
  2901. AddLn("");
  2902. }
  2903.  
  2904. public static void AddRight(string text, float endScreenX)
  2905. {
  2906. float textWidth = MMStrFn.GetSize(text);
  2907. endScreenX = endScreenX * curLcd.widthMod - curLcd.curWidth;
  2908.  
  2909. if (endScreenX < textWidth) {
  2910. curLcd.AddFast(text);
  2911. curLcd.curWidth += textWidth;
  2912. return;
  2913. }
  2914.  
  2915. endScreenX -= textWidth;
  2916. int fillchars = (int)Math.Round(endScreenX / MMStrFn.WHITESPACE_WIDTH, MidpointRounding.AwayFromZero);
  2917. float fillWidth = fillchars * MMStrFn.WHITESPACE_WIDTH;
  2918.  
  2919. curLcd.AddFast(new String(' ', fillchars) + text);
  2920. curLcd.curWidth += fillWidth + textWidth;
  2921. }
  2922.  
  2923. public static void AddCenterLn(string text, float screenX)
  2924. {
  2925. AddCenter(text, screenX);
  2926. AddLn("");
  2927. }
  2928.  
  2929. public static void AddCenter(string text, float screenX)
  2930. {
  2931. float textWidth = MMStrFn.GetSize(text);
  2932. screenX = screenX * curLcd.widthMod - curLcd.curWidth;
  2933.  
  2934. if (screenX < textWidth / 2) {
  2935. curLcd.AddFast(text);
  2936. curLcd.curWidth += textWidth;
  2937. return;
  2938. }
  2939.  
  2940. screenX -= textWidth / 2;
  2941. int fillchars = (int)Math.Round(screenX / MMStrFn.WHITESPACE_WIDTH, MidpointRounding.AwayFromZero);
  2942. float fillWidth = fillchars * MMStrFn.WHITESPACE_WIDTH;
  2943.  
  2944. curLcd.AddFast(new String(' ', fillchars) + text);
  2945. curLcd.curWidth += fillWidth + textWidth;
  2946. }
  2947.  
  2948. public static void AddBarLn(double percent, int width = 22, float leaveSpaceX = 0f)
  2949. {
  2950. if (Double.IsNaN(percent)) percent = 0;
  2951. int totalBars = (int)(width * curLcd.widthMod) - 2 - (int)(leaveSpaceX / MMStrFn.PROGRESSCHAR_WIDTH);
  2952. int fill = Math.Min((int)(percent * totalBars) / 100, totalBars);
  2953. curLcd.AddLine("[" + new String('|', fill) + new String('\'', totalBars - fill) + "]");
  2954. }
  2955.  
  2956. public static void AddBar(double percent, int width = 22, float leaveSpaceX = 0f)
  2957. {
  2958. if (Double.IsNaN(percent)) percent = 0;
  2959. int totalBars = (int)(width * curLcd.widthMod) - 2 - (int)(leaveSpaceX / MMStrFn.PROGRESSCHAR_WIDTH);
  2960. int fill = Math.Min((int)(percent * totalBars) / 100, totalBars);
  2961. curLcd.AddFast("[" + new String('|', fill) + new String('\'', totalBars - fill) + "]");
  2962. curLcd.curWidth += MMStrFn.PROGRESSCHAR_WIDTH * totalBars + 18f;
  2963. }
  2964.  
  2965. public static void ClearText()
  2966. {
  2967. curLcd.ClearText();
  2968. }
  2969.  
  2970. public static void UpdatePanel(MMPanel panel)
  2971. {
  2972. panel.Update();
  2973. curLcd.Scroll();
  2974. }
  2975.  
  2976. public class MMLCDText
  2977. {
  2978. public float fontSize = 0.8f;
  2979. public float widthMod = 1.0f;
  2980. public int scrollPos;
  2981. public int scrollDir = 1;
  2982. public int DisplayLines = 22; // 22 for font size 0.8    
  2983. public int screens = 1;
  2984.  
  2985. public List<string> lines = new List<string>();
  2986. public int curLine;
  2987. public float curWidth;
  2988.  
  2989. public MMLCDText(float fontSize = 0.8f)
  2990. {
  2991. SetFontSize(fontSize);
  2992. lines.Add("");
  2993. }
  2994.  
  2995. public void SetFontSize(float size)
  2996. {
  2997. fontSize = size;
  2998. DisplayLines = (int)Math.Round(22 * (0.8 / fontSize) * screens);
  2999. }
  3000.  
  3001. public void SetNrScreens(int cnt)
  3002. {
  3003. screens = cnt;
  3004. DisplayLines = (int)Math.Round(22 * (0.8 / fontSize) * screens);
  3005. }
  3006.  
  3007. public void AddFast(string text)
  3008. {
  3009. lines[curLine] += text;
  3010. }
  3011.  
  3012. public void AddMultiLine(string multiline)
  3013. {
  3014. string[] lines = multiline.Split('\n');
  3015.  
  3016. for (int i = 0; i < lines.Length; i++)
  3017. AddLine(lines[i]);
  3018. }
  3019.  
  3020. public void AddLine(string line)
  3021. {
  3022. lines[curLine] += line;
  3023. lines.Add("");
  3024. curLine++;
  3025. curWidth = 0;
  3026. }
  3027.  
  3028. public void ClearText()
  3029. {
  3030. lines.Clear();
  3031. lines.Add("");
  3032. curWidth = 0;
  3033. curLine = 0;
  3034. }
  3035.  
  3036. public string GetFullString()
  3037. {
  3038. return String.Join("\n", lines);
  3039. }
  3040.  
  3041. // Display only X lines from scrollPos    
  3042. public string GetDisplayString(int screenidx = 0)
  3043. {
  3044. if (lines.Count < DisplayLines / screens) {
  3045. if (screenidx != 0) return "";
  3046. scrollPos = 0;
  3047. scrollDir = 1;
  3048. return GetFullString();
  3049. }
  3050.  
  3051. int pos = scrollPos + screenidx * (DisplayLines / screens);
  3052. if (pos > lines.Count)
  3053. pos = lines.Count;
  3054.  
  3055. List<string> display =
  3056. lines.GetRange(pos,
  3057. Math.Min(lines.Count - pos, DisplayLines / screens));
  3058.  
  3059. return String.Join("\n", display);
  3060. }
  3061.  
  3062. public void Scroll()
  3063. {
  3064. int linesCnt = lines.Count - 1;
  3065. if (linesCnt <= DisplayLines) {
  3066. scrollPos = 0;
  3067. scrollDir = 1;
  3068. return;
  3069. }
  3070.  
  3071. if (scrollDir > 0) {
  3072. if (scrollPos + SCROLL_LINES + DisplayLines > linesCnt) {
  3073. scrollDir = -1;
  3074. scrollPos = Math.Max(linesCnt - DisplayLines, 0);
  3075. return;
  3076. }
  3077.  
  3078. scrollPos += SCROLL_LINES;
  3079. }
  3080. else {
  3081. if (scrollPos - SCROLL_LINES < 0) {
  3082. scrollPos = 0;
  3083. scrollDir = 1;
  3084. return;
  3085. }
  3086.  
  3087. scrollPos -= SCROLL_LINES;
  3088. }
  3089. }
  3090. }
  3091. }
  3092.  
  3093. public static class MMStrFn
  3094. {
  3095. private static Dictionary<char, float> charSize = new Dictionary<char, float>();
  3096.  
  3097. public const float WHITESPACE_WIDTH = 8f;
  3098. public const float PROGRESSCHAR_WIDTH = 6.4f;
  3099.  
  3100. public static void InitCharSizes()
  3101. {
  3102. if (charSize.Count > 0)
  3103. return;
  3104.  
  3105. AddCharsSize("3FKTabdeghknopqsuy£µÝàáâãäåèéêëðñòóôõöøùúûüýþÿāăąďđēĕėęěĝğġģĥħĶķńņňʼnōŏőśŝşšŢŤŦũūŭůűųŶŷŸșȚЎЗКЛбдекруцяёђћўџ", 17f);
  3106. AddCharsSize("#0245689CXZ¤¥ÇßĆĈĊČŹŻŽƒЁЌАБВДИЙПРСТУХЬ€", 19f);
  3107. AddCharsSize("$&GHPUVY§ÙÚÛÜÞĀĜĞĠĢĤĦŨŪŬŮŰŲОФЦЪЯжы†‡", 20f);
  3108. AddCharsSize("ABDNOQRSÀÁÂÃÄÅÐÑÒÓÔÕÖØĂĄĎĐŃŅŇŌŎŐŔŖŘŚŜŞŠȘЅЊЖф□", 21f);
  3109. AddCharsSize("(),.1:;[]ft{}·ţťŧț", 9f);
  3110. AddCharsSize("+<=>E^~¬±¶ÈÉÊË×÷ĒĔĖĘĚЄЏЕНЭ−", 18f);
  3111. AddCharsSize(" !I`ijl ¡¨¯´¸ÌÍÎÏìíîïĨĩĪīĮįİıĵĺļľłˆˇ˘˙˚˛˜˝ІЇії‹›∙", 8f);
  3112. AddCharsSize("7?Jcz¢¿çćĉċčĴźżžЃЈЧавийнопсъьѓѕќ", 16f);
  3113. AddCharsSize("L_vx«»ĹĻĽĿŁГгзлхчҐ–•", 15f);
  3114. AddCharsSize("\"-rª­ºŀŕŗř", 10f);
  3115. AddCharsSize("mw¼ŵЮщ", 27f);
  3116. AddCharsSize("MМШ", 26f);
  3117. AddCharsSize("WÆŒŴ—…‰", 31f);
  3118. AddCharsSize("'|¦ˉ‘’‚", 6f);
  3119. AddCharsSize("*²³¹", 11f);
  3120. AddCharsSize("\\°“”„", 12f);
  3121. AddCharsSize("/ijтэє", 14f);
  3122. AddCharsSize("%IJЫ", 24f);
  3123. AddCharsSize("@©®мшњ", 25f);
  3124. AddCharsSize("\n", 0f);
  3125. AddCharsSize("¾æœЉ", 28f);
  3126. AddCharsSize("½Щ", 29f);
  3127. AddCharsSize("ј", 7f);
  3128. AddCharsSize("љ", 22f);
  3129. AddCharsSize("ґ", 13f);
  3130. AddCharsSize("ю", 23f);
  3131. AddCharsSize("™", 30f);
  3132. AddCharsSize("", 34f);
  3133. AddCharsSize("", 32f);
  3134. AddCharsSize("", 41f);
  3135. }
  3136.  
  3137. private static void AddCharsSize(string chars, float size)
  3138. {
  3139. for (int i = 0; i < chars.Length; i++)
  3140. charSize.Add(chars[i], size);
  3141. }
  3142.  
  3143. public static float GetCharSize(char c)
  3144. {
  3145. float width = 40;
  3146. charSize.TryGetValue(c, out width);
  3147.  
  3148. return width;
  3149. }
  3150.  
  3151. public static float GetSize(string str)
  3152. {
  3153. float sum = 0;
  3154. for (int i = 0; i < str.Length; i++)
  3155. sum += GetCharSize(str[i]);
  3156.  
  3157. return sum;
  3158. }
  3159.  
  3160. public static string GetTrimmed(string text, float pixelWidth)
  3161. {
  3162. int trimlen = Math.Min((int)pixelWidth / 14, text.Length - 2);
  3163. float stringSize = GetSize(text);
  3164. if (stringSize <= pixelWidth)
  3165. return text;
  3166.  
  3167. while (stringSize > pixelWidth - 20) {
  3168. text = text.Substring(0, trimlen);
  3169. stringSize = GetSize(text);
  3170. trimlen -= 2;
  3171. }
  3172. return text + "..";
  3173. }
  3174. }
  3175.  
  3176.  
  3177. public class MMItem
  3178. {
  3179. public string subType;
  3180. public string mainType;
  3181.  
  3182. public int defQt;
  3183. public string dName;
  3184. public string sName;
  3185.  
  3186. public bool used;
  3187.  
  3188. public MMItem(string _subType, string _mainType, int _defaultQuota = 0, string _displayName = "", string _shortName = "", bool _used = true)
  3189. {
  3190. subType = _subType;
  3191. mainType = _mainType;
  3192. defQt = _defaultQuota;
  3193. dName = _displayName;
  3194. sName = _shortName;
  3195. used = _used;
  3196. }
  3197. }
  3198. public class MMPanelDict
  3199. {
  3200. public Dictionary<string, MMPanel> dict = new Dictionary<string, MMPanel>();
  3201. public List<string> keys = new List<string>();
  3202.  
  3203. public void AddItem(string key, MMPanel item) { if (!dict.ContainsKey(key)) { keys.Add(key); dict.Add(key, item); } }
  3204. public int CountAll() { return dict.Count; }
  3205. public MMPanel GetItem(string key) { if (dict.ContainsKey(key)) return dict[key]; return null; }
  3206. public MMPanel GetItemAt(int index) { return dict[keys[index]]; }
  3207. public void ClearAll() { keys.Clear(); dict.Clear(); }
  3208. public void SortAll() { keys.Sort(); }
  3209. }
  3210. public class MMTextPanelDict
  3211. {
  3212. public Dictionary<string, IMyTextPanel> dict = new Dictionary<string, IMyTextPanel>();
  3213. public List<string> keys = new List<string>();
  3214.  
  3215. public void AddItem(string key, IMyTextPanel item) { if (!dict.ContainsKey(key)) { keys.Add(key); dict.Add(key, item); } }
  3216. public int CountAll() { return dict.Count; }
  3217. public IMyTextPanel GetItem(string key) { if (dict.ContainsKey(key)) return dict[key]; return null; }
  3218. public IMyTextPanel GetItemAt(int index) { return dict[keys[index]]; }
  3219. public void ClearAll() { keys.Clear(); dict.Clear(); }
  3220. public void SortAll() { keys.Sort(); }
  3221. }
  3222. public class MMAmountSpecDict
  3223. {
  3224. public Dictionary<string, MMAmountSpec> dict = new Dictionary<string, MMAmountSpec>();
  3225. public List<string> keys = new List<string>();
  3226.  
  3227. public void AddItem(string key, MMAmountSpec item) { if (!dict.ContainsKey(key)) { keys.Add(key); dict.Add(key, item); } }
  3228. public int CountAll() { return dict.Count; }
  3229. public MMAmountSpec GetItem(string key) { if (dict.ContainsKey(key)) return dict[key]; return null; }
  3230. public MMAmountSpec GetItemAt(int index) { return dict[keys[index]]; }
  3231. public void ClearAll() { keys.Clear(); dict.Clear(); }
  3232. public void SortAll() { keys.Sort(); }
  3233. }
  3234.  
  3235. public static class M
  3236. {
  3237. public static readonly Dictionary<string, string> T = new Dictionary<string, string>    
  3238. {    
  3239. // TRANSLATION STRINGS    
  3240. // msg id, text    
  3241. { "AC1", "Acceleration:" },  
  3242. { "A1", "EMPTY" }, // amount    
  3243. { "B1", "Booting up..." },    
  3244. { "C1", "count:" },  
  3245. { "C2", "Cargo Used:" },  
  3246. { "C3", "Invalid countdown format, use:" },    
  3247. { "C4", "EXPIRED" },    
  3248. { "C5", "days" },    
  3249. { "D1", "You need to enter name." },    
  3250. { "D2", "No blocks found." },    
  3251. { "D3", "No damaged blocks found." },    
  3252. { "H1", "Write commands to Private Text." },    
  3253. { "H2", "Write commands to Public or Private Title." },    
  3254. // inventory    
  3255. { "I1", "ore" },    
  3256. { "I2", "summary" },    
  3257. { "I3", "Ores" },    
  3258. { "I4", "Ingots" },    
  3259. { "I5", "Components" },    
  3260. { "I6", "Gas" },    
  3261. { "I7", "Ammo" },    
  3262. { "I8", "Tools" },    
  3263. { "M1", "Cargo Mass:" },  
  3264. // oxygen    
  3265. { "O1", "Leaking" },    
  3266. { "O2", "Oxygen Farms" },    
  3267. { "O3", "No oxygen blocks found." },    
  3268. { "O4", "Oxygen Tanks" },    
  3269. // position    
  3270. { "P1", "Block not found" },    
  3271. { "P2", "Location" },    
  3272. // power    
  3273. { "P3", "Stored" },    
  3274. { "P4", "Output" },    
  3275. { "P5", "Input" },    
  3276. { "P6", "No power source found!" },    
  3277. { "P7", "Batteries" },    
  3278. { "P8", "Total Output" },    
  3279. { "P9", "Reactors" },    
  3280. { "P10", "Solars" },    
  3281. { "P11", "Power" },    
  3282. { "PT1", "Power Time:" },  
  3283. { "PT2", "Charge Time:" },    
  3284. { "S1", "Speed:" },  
  3285. // text    
  3286. { "T1", "Source LCD not found: " },    
  3287. { "T2", "Missing source LCD name" },    
  3288. { "T3", "LCD Private Text is empty" },    
  3289. // tanks    
  3290. { "T4", "Missing tank type. eg: 'Tanks * Hydrogen'" },    
  3291. { "T5", "No {0} tanks found." }, // {0} is tank type    
  3292. { "T6", "Tanks" },    
  3293. { "UC", "Unknown command" },    
  3294. // occupied & dampeners  
  3295. { "SC1", "Cannot find control block." }, // NEW  
  3296. { "SCD", "Dampeners: " }, // NEW  
  3297. { "SCO", "Occupied: " }, // NEW  
  3298. // working    
  3299. { "W1", "OFF" },    
  3300. { "W2", "WORK" },    
  3301. { "W3", "IDLE" },    
  3302. { "W4", "LEAK" },    
  3303. { "W5", "OPEN" },    
  3304. { "W6", "CLOSED" },    
  3305. { "W7", "LOCK" },    
  3306. { "W8", "UNLOCK" },    
  3307. { "W9", "ON" },    
  3308. { "W10", "READY" }    
  3309. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement