internal void build() { List <IMyBlockGroup> groups = new List <IMyBlockGroup>(); Dictionary <string, List <IMyTerminalBlock> > blocks = new Dictionary <string, List <IMyTerminalBlock> >(); caller.GridTerminalSystem.GetBlocksOfType <IMyTerminalBlock>(new List <IMyTerminalBlock>(), b => cacheBlock(b, blocks)); foreach (var entry in blocks) { SectionBlocks sec = new SectionBlocks(shipGrid, entry.Key, entry.Value); sections.Add(sec.sectionName, sec); sectionSorting.Add(sec.sectionName); } sectionSorting.Sort(new SectionComparator(sections)); caller.GridTerminalSystem.GetBlocksOfType <IMyAirVent>(externalVents, b => b.CustomName.Contains(EXTERNAL_BLOCK_ID) && b.CubeGrid == caller.Me.CubeGrid); caller.GridTerminalSystem.GetBlocksOfType <IMyGasTank>(o2Tanks, b => b.CubeGrid == caller.Me.CubeGrid && (b.BlockDefinition.SubtypeName.ToLower().Contains("oxygen") || b.BlockDefinition.SubtypeName.ToLower().Contains("o2"))); List <IMyDoor> li = new List <IMyDoor>(); caller.GridTerminalSystem.GetBlocksOfType <IMyDoor>(li, b => b.CubeGrid == caller.Me.CubeGrid); foreach (IMyDoor door in li) { if (isExternalDoor(door.CustomName)) { externalDoors.Add(door); } else { System.Text.RegularExpressions.MatchCollection mc = System.Text.RegularExpressions.Regex.Matches(door.CustomName, INTERFACE_DOOR_SECTION_PATTERN); if (mc != null && mc.Count > 0 && mc[0].Groups.Count > 0) { string ids = mc[0].Groups[1].ToString(); string[] parts = ids.Split(INTERFACE_DOOR_SECTION_SPLIT); interDoors.Add(new InterfaceDoor(door, parts[0], parts[1])); } else { extraDoors.Add(door); } } } List <IMyTextPanel> li2 = new List <IMyTextPanel>(); caller.GridTerminalSystem.GetBlocksOfType <IMyTextPanel>(li2, b => b.CustomName.Contains(DISPLAY_TAG) && b.CubeGrid == caller.Me.CubeGrid); foreach (IMyTextPanel scr in li2) { displays.Add(new Display(scr)); } }
public int Compare(string s1, string s2) { SectionBlocks sec1 = null; SectionBlocks sec2 = null; data.TryGetValue(s1, out sec1); data.TryGetValue(s2, out sec2); if (sec1 == null || sec2 == null) { return(0); } return(sec1.getRelativeCenter().Length().CompareTo(sec2.getRelativeCenter().Length())); }
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 build() { List <IMyBlockGroup> groups = new List <IMyBlockGroup>(); caller.GridTerminalSystem.GetBlockGroups(groups, g => g.Name.StartsWith(GROUP_ID, StringComparison.InvariantCulture)); foreach (IMyBlockGroup group in groups) { string name = group.Name.Substring(GROUP_ID.Length); while (name[0] == ' ') { name = name.Substring(1); } SectionBlocks sec = new SectionBlocks(caller.GridTerminalSystem, group); sections.Add(name, sec); } caller.GridTerminalSystem.GetBlocksOfType <IMyAirVent>(externalVents, b => b.CustomName.Contains(EXTERNAL_BLOCK_ID)); caller.GridTerminalSystem.GetBlocksOfType <IMyGasTank>(o2Tanks, b => b.BlockDefinition.SubtypeName.ToLower().Contains("oxygen") || b.BlockDefinition.SubtypeName.ToLower().Contains("o2")); List <IMyDoor> li = new List <IMyDoor>(); caller.GridTerminalSystem.GetBlocksOfType <IMyDoor>(li); foreach (IMyDoor door in li) { if (isExternalDoor(door.CustomName)) { externalDoors.Add(door); } else { System.Text.RegularExpressions.MatchCollection mc = System.Text.RegularExpressions.Regex.Matches(door.CustomName, INTERFACE_DOOR_SECTION_PATTERN); if (mc != null && mc.Count > 0 && mc[0].Groups.Count > 0) { string ids = mc[0].Groups[1].ToString(); string[] parts = ids.Split(INTERFACE_DOOR_SECTION_SPLIT); interDoors.Add(new InterfaceDoor(door, parts[0], parts[1])); } else { extraDoors.Add(door); } } } caller.GridTerminalSystem.GetBlocksOfType <IMyTextPanel>(displays, b => b.CustomName.Contains(DISPLAY_TAG)); }
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; }