private void showStatus(SectionBlocks sec, bool depressure, bool breach, int tick) { int lines = sections.Count; float size = 1; if (lines > 18) { size -= (lines - 18) * 0.04F; } size = Math.Min(size, 0.67F); int maxSections = 44; //assuming zero padding and zero name length float ds = size - 0.5F; maxSections = (int)(maxSections - 16F * ds); int maxw = (maxSections / 2); int pad = maxw - sec.sectionName.Length; int barSize = maxw; float f = breach ? 0 : sec.getAirPressureFraction(); int fill = (int)(f * barSize + 0.5); int red = barSize / 4; int yellow = barSize / 2; foreach (Display scr in getUpdatingDisplays(tick)) { scr.display.FontSize = size; scr.display.Font = "Monospace"; String line = sec.sectionName + ":"; for (int i = 0; i < pad; i++) { int p = i + sec.sectionName.Length; line = line + (i == 0 || i == pad - 1 || p % 2 == 0 ? " " : dot); } for (int i = 0; i < barSize; i++) { bool has = i < fill; string color = has ? (i < red ? redArrow : (i < yellow ? yellowArrow : greenArrow)) : whiteArrow; if (depressure) { color = has || i % 2 == 1 ? cyanArrow : whiteArrow; } else if (breach) { color = scr.update % 2 == 0 ? magentaArrow : whiteArrow; } line = line + color; } scr.display.WriteText(line + "\n", true); } caller.Echo(sec.sectionName + " Status: " + (depressure ? "Depressurized" : (breach ? "Breached!" : "Pressurized @ " + sec.getAirPressureFraction() * 100 + "%"))); }
internal void tick(int tick) { bool atmo = noAtmo(); foreach (Display scr in getUpdatingDisplays(tick)) { scr.display.WriteText(""); //clear } bool logic = tick % 5 == 0; if (atmo) { showText("No external atmosphere present.", tick); if (atmoLastTick != atmo) //accidentally left outside doors open? But only want to fire this once, not continuously, or it keeps closing airlocks { setExternalDoors(false); } if (logic) { breachedSections.Clear(); HashSet <string> noAir = new HashSet <string>(); HashSet <string> depressure = new HashSet <string>(); foreach (string name in sectionSorting) { SectionBlocks sec = null; sections.TryGetValue(name, out sec); bool flag = false; if (sec.isDepressurized()) //airlocks reguarly get opened to space; this is not a problem { showStatus(sec, true, false, tick); if (sec.getAirPressureFraction() <= 0.01) { noAir.Add(name); } depressure.Add(name); } else if (sec.isBreached()) { showStatus(sec, false, true, tick); flag = true; } else { showStatus(sec, false, false, tick); } if (flag) { breachedSections.Add(name); noAir.Add(name); sec.onBreach(); } else { sec.reset(); } } foreach (InterfaceDoor inter in interDoors) { bool noAirA = noAir.Contains(inter.sectionA); bool noAirB = noAir.Contains(inter.sectionB); bool noSplit = (SEPARATE_BREACHES ? (!noAirA && !noAirB) : noAirA == noAirB); //close any doors that interface with a breached section, but open any that are sealed on both sides, provided neither section is not actively attempting to depressurize //but close all doors the first cycle, to try to determine which sections are actually breached (not just exposed via door access) inter.setState(noSplit && depressure.Contains(inter.sectionA) == depressure.Contains(inter.sectionB) && breachedSectionsLastTick.SetEquals(breachedSections)); } if (breachedSections.Count > 0) { if (o2Tanks.Count > 0) { showText("Oxygen Reserves at " + getOxygenReserves() * 100 + "%", tick); if (CLOSE_ALL_DOORS) { setAllDoors(false); } } } } else { foreach (string name in sectionSorting) { SectionBlocks sec = null; sections.TryGetValue(name, out sec); showStatus(sec, sec.isDepressurized(), sec.isBreached(), tick); } } } else { showText("Usable external atmosphere present.", tick); if (logic) { foreach (IMyAirVent vent in externalVents) //fill O2 tanks, if present { vent.Depressurize = true; } setAllDoors(true); //fresh air } showText("All doors open.", tick); } atmoLastTick = atmo; breachedSectionsLastTick = new HashSet <string>(breachedSections); }
internal void tick() { bool atmo = noAtmo(); foreach (IMyTextPanel scr in displays) { scr.WritePublicText(""); //clear } if (atmo) { show("No external atmosphere present."); if (atmoLastTick != atmo) //accidentally left outside doors open? But only want to fire this once, not continuously, or it keeps closing airlocks { setExternalDoors(false); } breachedSections.Clear(); HashSet <string> depressurizing = new HashSet <string>(); foreach (var entry in sections) { string name = entry.Key; SectionBlocks sec = entry.Value; bool flag = false; if (sec.isDepressurized()) //airlocks reguarly get opened to space; this is not a problem { show("Section '" + name + "' is depressurized."); depressurizing.Add(name); } else if (sec.isBreached()) { show("Section '" + name + "' is breached!"); flag = true; } else { show("Section '" + name + "' is pressurized at " + Math.Round(sec.getAirPressureFraction() * 100, 1) + "% atmosphere."); } if (flag) { breachedSections.Add(name); sec.onBreach(); } else { sec.reset(); } } foreach (InterfaceDoor inter in interDoors) { //close any doors that interface with a breached section, but open any that are sealed on both sides, provided neither section is not actively attempting to depressurize inter.setState(!breachedSections.Contains(inter.sectionA) && !breachedSections.Contains(inter.sectionB) && !depressurizing.Contains(inter.sectionA) && !depressurizing.Contains(inter.sectionB)); } if (breachedSections.Count > 0) { if (o2Tanks.Count > 0) { show("Oxygen Reserves at " + getOxygenReserves() * 100 + "%"); if (CLOSE_ALL_DOORS) { setAllDoors(false); } } } } else { show("Usable external atmosphere present."); foreach (IMyAirVent vent in externalVents) //fill O2 tanks, if present { vent.Depressurize = true; } setAllDoors(true); //fresh air show("All doors open."); } atmoLastTick = atmo; }