4.3 KiB
Mission preparation presentation
The successor now places persistent status text inside the native respawn loading placeholder while its own mission remains PREPARING. Normal preparation displays Preparing mission and the existing shared explanation that the prisoner will spawn when sites and equipment are ready. A replicated preparation failure changes the title to Mission could not start, displays the shared restart/administrator guidance, and hides the loading spinner. The administrator's existing /esc status response retains the specific cause. This is presentation only: it neither retries preparation nor authorizes spawning or restart.
Previously the scenario inherited the vanilla opaque loading splash, but the only successor preparation/failure guidance was a 15-second hint. No native mission task is created before the first successful phase transition. Failed preparation stops admission and cannot activate the normal survivor observer path which removes the loading placeholder. The new status therefore belongs to that existing loading surface instead of relying on an expiring hint or a player camera.
ERR_PreparationStatus.c extends the installed SCR_RespawnSystemComponent.UpdateLoadingPlaceholder(float dt) callback. Vanilla's DeployMenuSystem already invokes it; no new timer is added. The adapter compares vanilla's protected m_pGameMode field (assigned from owner by SCR_RespawnSystemComponent.OnInit(IEntity owner)) with the exact current ERR_GameMode; it runs only for that owner, with a live native placeholder, outside a console application and during PREPARING. It preserves the superclass update and all other modes. The newly authored child layout uses its own identity, {BCCAE287751344D9}UI/layouts/ERR/PreparationStatus.layout, and native default fonts; it adds no vanilla resource reference.
The adapter remembers the exact placeholder, owned status widgets and original spinner visibility. Replacing or deleting the placeholder, moving the owned child away, leaving preparation, or calling native DestroyLoadingPlaceholder clears the child and cached text. A hidden spinner is restored to its recorded visibility when still alive. Normal native placeholder destruction remains responsible for its own audio and parent-widget lifecycle. No camera, audio, input, actor, mission state or inventory is changed by the adapter.
tests/test_preparation_status.py executes the actual presentation and cleanup methods through widget/native-boundary adapters. It checks unchanged behavior for unrelated/console modes, persistent text without repeated creation or text writes, preparation-to-failure changes, stale state clearing, missing UI resources/children, parent replacement, deleted weak widget references, reparenting, phase exit, native destruction and restoration of an initially hidden spinner. It also executes the actual native observation probe's continuous-time, reset and timeout rules. These are source-policy checks, not native rendering evidence.
The existing opt-in Core startup-failure fixture now waits up to 30 seconds for actual production-created loading widgets. It requires the expected title and shared body text, correct parent ownership, visible nonzero-sized title/body/root widgets, a visible loading parent and a hidden native spinner. It observes these continuously for 17 seconds, exceeding the old hint duration, then requests $logs:err-preparation-failure and waits another half-second before its original negative-path assertions complete. It does not create or update the widgets itself. The deliberate faction setup error remains a native ERROR and must retain the negative fixture's failed/error verdict; a successful UI assertion does not turn that run into a clean mission startup. The first native compilation rejected an assumed GetOwner() API, which this native respawn system does not expose. That call has been replaced with its installed vanilla m_pGameMode owner field; the second native run compiled and passed the continuous 17-second checks on the actual title/body/root widgets, parent ownership and hidden spinner. Its captured Workbench image was a blank blue editor viewport, so it provides no visual proof that the status is readable in an ordinary player view. Ordinary-player visual inspection remains pending; the deliberately failed setup still retains its negative engine-error verdict.