// Process all requests - main thread (think while(true) in a microprocessor) // Note this assume a 1Hz clock cycle from a timer block public void mainLoop() { Echo("Hangar status:"); for (int i = 0; i < hangarOpen.Length; i++) { Echo("[" + groups[i] + "]: " + (hangarOpen[i] ? "Open" : "Closed")); } // Go through backwards so we can remove stuff without screwing our loop up // Note we must also use RemoveAt() for the same reason // Luckily this isn't Java! for (int i = requests.Count - 1; i >= 0; i--) { requestTicket req = requests[i]; int groupNo = req.groupNum; // For stuff that must be processed immediately if (!req.timed) { switch (req.action) { case "toggle": { // Case where hangar is depressurised: repressurize if (hangarOpen[groupNo]) { goto case "close"; } else { goto case "open"; } } // Start open procedure case "open": { // Flash lights, play warning sound foreach (IMyInteriorLight light in warningLights[groupNo]) { light.ApplyAction("OnOff_On"); } foreach (IMySoundBlock sound in soundBlocks[groupNo]) { sound.SetValueFloat("LoopableSlider", numberSecondsBeforeOpen + 2); sound.ApplyAction("PlaySound"); } requests.RemoveAt(i); //Make sure interior doors are on so we can close them foreach (IMyDoor door in interiorDoors[groupNo]) { door.ApplyAction("OnOff_On"); } // Lock the interior doors after some time requests.Add(new requestTicket(groupNo, "lockInterior_delay", true, numberSecondsBeforeOpen - 1)); break; } // Start close procedure case "close": { // Make sure lights are on (they should still be but just in case) foreach (IMyInteriorLight light in warningLights[groupNo]) { light.ApplyAction("OnOff_On"); } // Play sound foreach (IMySoundBlock sound in soundBlocks[groupNo]) { sound.SetValueFloat("LoopableSlider", numberSecondsBeforeClose); sound.ApplyAction("PlaySound"); } requests.RemoveAt(i); //Make sure all outside doors have power so we can close them foreach (IMyDoor door in hangarDoors[groupNo]) { door.ApplyAction("OnOff_On"); } foreach (IMyDoor door in exteriorDoors[groupNo]) { door.ApplyAction("OnOff_On"); } // Schedule close request requests.Add(new requestTicket(groupNo, "close_delay", true, numberSecondsBeforeClose)); break; } // Check pressurization and unlock interior doors/turn off emer. lights if OK case "checkPressurize": { // Get first airvent; they should all be in the room and hence have the same pressure IMyAirVent airvent = airVents[groupNo][0]; if (airvent.GetOxygenLevel() > 0.99) { // Ok we're pressurized, turn lights off and enable interior doors foreach (IMyInteriorLight light in warningLights[groupNo]) { light.ApplyAction("OnOff_Off"); } foreach (IMyDoor door in interiorDoors[groupNo]) { door.ApplyAction("OnOff_On"); } hangarOpen[groupNo] = false; requests.RemoveAt(i); } break; } // Lock all exterior doors case "lockExteriorDoors": { // Check door status Boolean doorClosed = true; foreach (IMyDoor door in exteriorDoors[groupNo]) { // If door is still closing or open... if (door.OpenRatio != 0) { door.ApplyAction("Open_Off"); doorClosed = false; } else { door.ApplyAction("OnOff_Off"); } } if (doorClosed) { requests.RemoveAt(i); } break; } // Lock interior doors case "lockInterior": { // Check door status Boolean doorClosed = true; foreach (IMyDoor door in interiorDoors[groupNo]) { // If door is still closing or open... if (door.OpenRatio != 0) { door.ApplyAction("Open_Off"); doorClosed = false; } else { door.ApplyAction("OnOff_Off"); } } if (doorClosed) { requests.RemoveAt(i); // Doors now locked, move onto opening main doors requests.Add(new requestTicket(groupNo, "open_delay")); } break; } case "open_delay": { // Make sure all outside doors turn on foreach (IMyDoor door in exteriorDoors[groupNo]) { door.ApplyAction("OnOff_On"); } foreach (IMyDoor door in hangarDoors[groupNo]) { door.ApplyAction("OnOff_On"); } requests.RemoveAt(i); // Queue new request to open doors soon // This is because we can't turn on and open a door at the same time - game ignore the open request requests.Add(new requestTicket(groupNo, "open_delay2")); break; } case "open_delay2": { // Actually open all outside doors now foreach (IMyDoor door in exteriorDoors[groupNo]) { door.ApplyAction("Open_On"); } foreach (IMyDoor door in hangarDoors[groupNo]) { door.ApplyAction("Open_On"); } hangarOpen[groupNo] = true; requests.RemoveAt(i); break; } } } // Deal with delayed stuff else { int timeLeft = req.timeRemainingInSeconds; // If it's not time yet just decrement the counter if (timeLeft > 0) { // Replace request with new one with one less second requests[i] = new requestTicket(groupNo, req.action, true, timeLeft - 1); } else { switch (req.action) { // Close outside doors case "close_delay": { foreach (IMyDoor door in exteriorDoors[groupNo]) { door.ApplyAction("Open_Off"); } foreach (IMyDoor door in hangarDoors[groupNo]) { door.ApplyAction("Open_Off"); } requests.RemoveAt(i); // Set events to unlock inside door when pressurized and make sure exterior doors are closed so we can actually pressurize requests.Add(new requestTicket(groupNo, "checkPressurize")); requests.Add(new requestTicket(groupNo, "lockExteriorDoors")); break; } // Lock interior doors - or at least schedule the procedure case "lockInterior_delay": { requests.RemoveAt(i); requests.Add(new requestTicket(groupNo, "lockInterior")); break; } } } } } }
// Process all requests - main thread (think while(true) in a microprocessor) // Note this assume a 1Hz clock cycle from a timer block public void mainLoop() { Echo("Hangar status:"); for (int i = 0; i < hangarOpen.Length; i++) { Echo("[" + groups[i] + "]: " + (hangarOpen[i] ? "Open" : "Closed")); } // Go through backwards so we can remove stuff without screwing our loop up // Note we must also use RemoveAt() for the same reason // Luckily this isn't Java! for (int i = requests.Count - 1; i >= 0; i--) { requestTicket req = requests[i]; int groupNo = req.groupNum; // For stuff that must be processed immediately if (!req.timed) { switch (req.action) { case "toggle": { // Case where hangar is depressurised: repressurize if (hangarOpen[groupNo]) goto case "close"; else goto case "open"; } // Start open procedure case "open": { // Flash lights, play warning sound foreach (IMyInteriorLight light in warningLights[groupNo]) light.ApplyAction("OnOff_On"); foreach (IMySoundBlock sound in soundBlocks[groupNo]) { sound.SetValueFloat("LoopableSlider", numberSecondsBeforeOpen + 2); sound.ApplyAction("PlaySound"); } requests.RemoveAt(i); //Make sure interior doors are on so we can close them foreach (IMyDoor door in interiorDoors[groupNo]) door.ApplyAction("OnOff_On"); // Lock the interior doors after some time requests.Add(new requestTicket(groupNo, "lockInterior_delay", true, numberSecondsBeforeOpen - 1)); break; } // Start close procedure case "close": { // Make sure lights are on (they should still be but just in case) foreach (IMyInteriorLight light in warningLights[groupNo]) light.ApplyAction("OnOff_On"); // Play sound foreach (IMySoundBlock sound in soundBlocks[groupNo]) { sound.SetValueFloat("LoopableSlider", numberSecondsBeforeClose); sound.ApplyAction("PlaySound"); } requests.RemoveAt(i); //Make sure all outside doors have power so we can close them foreach (IMyDoor door in hangarDoors[groupNo]) door.ApplyAction("OnOff_On"); foreach (IMyDoor door in exteriorDoors[groupNo]) door.ApplyAction("OnOff_On"); // Schedule close request requests.Add(new requestTicket(groupNo, "close_delay", true, numberSecondsBeforeClose)); break; } // Check pressurization and unlock interior doors/turn off emer. lights if OK case "checkPressurize": { // Get first airvent; they should all be in the room and hence have the same pressure IMyAirVent airvent = airVents[groupNo][0]; if (airvent.GetOxygenLevel() > 0.99) { // Ok we're pressurized, turn lights off and enable interior doors foreach (IMyInteriorLight light in warningLights[groupNo]) light.ApplyAction("OnOff_Off"); foreach (IMyDoor door in interiorDoors[groupNo]) door.ApplyAction("OnOff_On"); hangarOpen[groupNo] = false; requests.RemoveAt(i); } break; } // Lock all exterior doors case "lockExteriorDoors": { // Check door status Boolean doorClosed = true; foreach (IMyDoor door in exteriorDoors[groupNo]) { // If door is still closing or open... if (door.OpenRatio != 0) { door.ApplyAction("Open_Off"); doorClosed = false; } else { door.ApplyAction("OnOff_Off"); } } if (doorClosed) { requests.RemoveAt(i); } break; } // Lock interior doors case "lockInterior": { // Check door status Boolean doorClosed = true; foreach (IMyDoor door in interiorDoors[groupNo]) { // If door is still closing or open... if (door.OpenRatio != 0) { door.ApplyAction("Open_Off"); doorClosed = false; } else { door.ApplyAction("OnOff_Off"); } } if (doorClosed) { requests.RemoveAt(i); // Doors now locked, move onto opening main doors requests.Add(new requestTicket(groupNo, "open_delay")); } break; } case "open_delay": { // Make sure all outside doors turn on foreach (IMyDoor door in exteriorDoors[groupNo]) { door.ApplyAction("OnOff_On"); } foreach (IMyDoor door in hangarDoors[groupNo]) { door.ApplyAction("OnOff_On"); } requests.RemoveAt(i); // Queue new request to open doors soon // This is because we can't turn on and open a door at the same time - game ignore the open request requests.Add(new requestTicket(groupNo, "open_delay2")); break; } case "open_delay2": { // Actually open all outside doors now foreach (IMyDoor door in exteriorDoors[groupNo]) { door.ApplyAction("Open_On"); } foreach (IMyDoor door in hangarDoors[groupNo]) { door.ApplyAction("Open_On"); } hangarOpen[groupNo] = true; requests.RemoveAt(i); break; } } } // Deal with delayed stuff else { int timeLeft = req.timeRemainingInSeconds; // If it's not time yet just decrement the counter if (timeLeft > 0) { // Replace request with new one with one less second requests[i] = new requestTicket(groupNo, req.action, true, timeLeft - 1); } else { switch (req.action) { // Close outside doors case "close_delay": { foreach (IMyDoor door in exteriorDoors[groupNo]) { door.ApplyAction("Open_Off"); } foreach (IMyDoor door in hangarDoors[groupNo]) { door.ApplyAction("Open_Off"); } requests.RemoveAt(i); // Set events to unlock inside door when pressurized and make sure exterior doors are closed so we can actually pressurize requests.Add(new requestTicket(groupNo, "checkPressurize")); requests.Add(new requestTicket(groupNo, "lockExteriorDoors")); break; } // Lock interior doors - or at least schedule the procedure case "lockInterior_delay": { requests.RemoveAt(i); requests.Add(new requestTicket(groupNo, "lockInterior")); break; } } } } } }