// Shared player-facing copy; reads replicated mission state and never changes it. class ERR_ObjectiveText { static string Title(ERR_Phase phase) { if (phase == ERR_Phase.PRISON) return "Escape the prison"; if (phase == ERR_Phase.RADIO_SEARCH) return "Locate the radio station"; if (phase == ERR_Phase.RADIO_DEFENCE) return "Hold while the escape route is prepared"; if (phase == ERR_Phase.EXTRACTION) return "Signal the rescue helicopters"; return "Escape the island"; } static string Extraction(float radius) { return "The map marks the exact extraction pickup point. Throw a burning smoke grenade within 25 metres to call the rescue transport and armed escorts. Any smoke colour works. Clear the landing point, then board with every living prisoner, including wounded teammates. The AI crew will fly you to safety. Use the casualty-loading action beside the grounded, stationary transport to load unconscious survivors."; } static string RadioFeedbackMessage(ERR_RadioFeedback feedback) { if (feedback == ERR_RadioFeedback.WAITING) return "Waiting for a conscious defender near the radio. Keep someone within 60 metres to start the transmission."; if (feedback == ERR_RadioFeedback.TRANSMITTING) return "Transmission in progress. Keep a conscious survivor within 60 metres of the radio. Leaving the area resets progress."; if (feedback == ERR_RadioFeedback.INTERRUPTED) return "Transmission interrupted. Progress has reset. Return a conscious survivor to within 60 metres of the radio to resume."; return "Keep a conscious survivor within 60 metres of the radio until the transmission finishes. Leaving the area resets the defence timer."; } static string Description(ERR_GameMode mode, bool progress = true) { string description = PhaseDescription(mode, progress); if (mode && mode.Active() && !mode.RecoveryStatus().IsEmpty()) description += "\n" + mode.RecoveryStatus(); return description; } protected static string PhaseDescription(ERR_GameMode mode, bool progress) { if (!mode) return ""; ERR_Phase phase = mode.Phase(); if (phase == ERR_Phase.PREPARING) { if (!mode.PreparationError().IsEmpty()) return "Reason: " + mode.PreparationError() + "\n\nAn administrator must correct the problem and restart the scenario before players can spawn."; return "Preparing mission sites and equipment. You will spawn when the mission is ready."; } if (phase == ERR_Phase.PRISON) return "Search the supply backpack inside the prison for weapons and a field map. Pick the gate lock, then get clear of the guards."; if (phase == ERR_Phase.RADIO_SEARCH) { array locations = {}; mode.Locations(locations); bool roughRadio; foreach (ERR_LocationComponent location : locations) { if (!location || location.Kind() != ERR_LocationKind.RADIO) continue; if (location.Knowledge() == 2) return "The radio station is identified on your map. Reach its radio and complete the 'Contact extraction HQ' action to start the transmission."; if (location.Knowledge() == 1) roughRadio = true; } // The frozen radio-intel gate is server-owned; conditional guidance remains // correct on clients, with the gate disabled and on sparse terrains. string intelRequirement = "Keep any radio document that cannot yet be deciphered. If radio intel is locked, fully identify more distinct non-radio sites; the starting clue markers do not count. Kept radio documents are read automatically when the requirement is met. "; // Scan all sites before acknowledging rough intel: an identified radio wins. if (roughRadio) return "Intel recovered: a question mark shows an approximate location, but its type is still unknown. Take a different intelligence folder into your inventory to pinpoint the radio; a folder already recovered cannot provide another clue. Try the other marked clue site if needed. A close approach with a clear view can also identify the station. " + intelRequirement; string startHint; if (mode.StartMode() == 1) startHint = "Search the salvage backpack at the crash site for weapons and a field map. "; return startHint + "Choose either marked clue site and take its intelligence folders into your own inventory. " + intelRequirement + "After radio intel unlocks, a different folder can refine a rough location. Use the other clue site if folders are lost. Even if every folder is lost, a close approach with a clear view can identify the station itself. Nearby medical and guard sites can also be discovered by approaching with a clear view."; } if (phase == ERR_Phase.RADIO_DEFENCE) { if (!progress) return RadioFeedbackMessage(mode.RadioFeedback()); int seconds = mode.DefenceSecondsRemaining(); if (!mode.DefenceOccupied()) { if (mode.RadioFeedback() == ERR_RadioFeedback.WAITING) return string.Format("Waiting for a conscious defender near the radio. Keep someone within 60 metres for %1 seconds to finish the transmission. Leaving resets progress.", seconds); return string.Format("Transmission interrupted. Keep a conscious survivor within 60 metres of the radio for %1 seconds. Leaving resets progress.", seconds); } int displayed = Math.Ceil(seconds / 5.0) * 5; return string.Format("Transmission in progress: up to %1 seconds remaining. Keep a conscious survivor within 60 metres of the radio. Leaving resets progress.", displayed); } if (phase == ERR_Phase.EXTRACTION) { if (mode.PickupStage() == 2 || mode.PickupStage() == 3) return "Smoke accepted. Armed rescue helicopters are approaching. Keep the marked landing point clear and gather everyone nearby."; if (mode.PickupStage() == 4) return "Board the rescue transport. It waits for all living prisoners, including unconscious or disconnected survivors. Escorts cover the landing zone. After everyone is aboard for eight seconds, the pilot takes off."; if (mode.PickupStage() == 5) return "Stay aboard. Escape completes after all rescue transports have remained airborne for 30 continuous seconds."; return Extraction(mode.EscapeRadius()); } return ""; } }