Sub-FSM nova `GameOverFsm` (CONTINUE_PROMPT → GAME_OVER → FADE_OUT →
DONE) que viu en paral·lel a la `RoomFsm`. Es dispara quan tots els
jugadors queden DISABLED durant PLAYING, mostra el rètol "Continuar?"
amb countdown reusant el panel del room text, i si ningú pulsa START
acaba en "Fi del Joc" + fade negre i sol·licita la transició a LOGO.
Pulsar START durant CONTINUE? cancel·la el countdown i fa join (revive)
del jugador. Després de GAME OVER, el HUD passa a "ESPERA / PER JUGAR"
i el START queda bloquejat fins a la transició d'escena.
Els helpers d'animació del room text (X i altura del panel) ara reben
phase + elapsed_ms per paràmetre per poder ser reaprofitats per les
dues sub-FSMs sense duplicar la lògica visual.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Lligua el reverb al moment de la cinemàtica d'entrada de sala, no als
salts en general. La sala dóna "més detall" sonor a l'INTRO; un cop el
joc està en marxa, els salts (i els respawns post-mort) tornen al so
sec. Així el primer aterratge es percep com a part de l'animació
d'arribada, no com una propietat permanent del personatge.
- RoomFsm::Config: nou camp `intro_land_reverb_preset` carregat des
de `room_intro.land_reverb` a `data/scenes/game.yaml` (per defecte
'stone_hall'). Buit = sense reverb a l'INTRO.
- Player: membre `next_land_reverb_preset_` consumit per
`integrateJump` al primer aterratge que el trobe armat. Setter
públic `armNextLandReverb(preset)` per a GameScene. Cap altre punt
(respawn, exit, disable) el toca: el reverb és estrictament
one-shot lligat al spawn aeri d'INTRO.
- GameScene::triggerPlayerSpawn: arma el preset al jugador just
després de `spawnFromAir`, així cada slot rep el seu reverb un
sol cop per cinemàtica.
- JumpConfig perd `land_reverb_preset` i els YAMLs de Sam/Morcus
perden `land_reverb`: la decisió ja no viu al personatge.
Nova fase 4 a ROOM_OUTRO: black_hold. Va just després del fade_out;
durant aquesta fase la pantalla queda completament en negre opac i
la FSM espera abans de transitar a INTRO. Permet donar respir entre
el final del rètol Fase/Completada i el rellançament del Piramide/Sala
de la sala següent, sense necessitat d'un estat nou.
Implementacio:
- RoomFsm::Config guanya outro_black_hold_ms (default 0 — backward
compatible). YAML key room_outro.black_hold_ms al data/scenes/game.yaml
(default visible 500 ms; lo afines sense recompilar).
- L'array DURS de l'OUTRO passa de 4 a 5 elements; el while-loop
consumeix la fase exactament igual.
- renderRoomFade detecta fase 4 i dibuixa alpha=255 fix; sense aquesta
branca, el fade s'apagaria a final de la fase 3 i el món tornaria
a ser visible durant la pausa.
- renderRoomText no canvia: phases 3 i 4 ja queden fora del rang
0..2 on dibuixa el rètol.
Backward compat: black_hold_ms=0 fa que el while-loop avance
immediatament la fase i recauen tots els tests existents (T7 i
companys) sense modificacions.
Mateixa tècnica que l'INTRO: la línia 1 ("Fase") entra per
l'esquerra, la línia 2 ("Completada") per la dreta, i surten cap
al costat oposat al d'entrada. Centrades verticalment al voltant
del CENTER_Y amb el gap configurable ( a
data/scenes/game.yaml; 0 per defecte, paral·lel a la del room_intro).
Locale: la clau game.room_complete es divideix en
game.room_complete_line1 / room_complete_line2 als ca.yaml i en.yaml
("Fase"/"Completada" i "Stage"/"Complete"). Cada línia es
tradueix per separat — útil si demà voleu paraules de longitud o
ordre distint en altres idiomes.
Dues claus noves a data/ui.yaml > colors:
room_text (relleno, default 232)
room_text_outline (contorn, default 255)
Abans el relleno reciclava notification_text (compartit amb les
notificacions del HUD) i el contorn estava hardcodejat a 255 dins
renderRoomText. Ara són canals separats: tocar el rètol no afecta
les notificacions i tot viu al YAML.
UiConfig guanya roomText() / roomTextOutline(); Defaults::UI hi posa
els fallbacks; renderRoomText els consumeix.
Drive-by: torna a posar la clau room_intro.line_gap_px: 8 al
data/scenes/game.yaml — s'havia perdut en una edició manual del
fitxer per afinar timings.