feat(room): mòmies surten emergint quan comença text-exit (fase 4)

Tres canvis coordinats que tanquen la cinemàtica desitjada de
ROOM_INTRO:

1. `spawn.duration_s` de mummy.yaml passa de 0.6 a 1.0 s. Les mòmies
   tarden ~1 segon a "emergir" — temps suficient perquè el jugador
   noti que estan apareixent, no que ja eren a la sala.

2. El disparador es mou de fase 5 (music_tail) a fase 4 (text-exit).
   Ara, just quan el text "PIRÀMIDE X, SALA Y" comença a sortir de
   pantalla, GameScene crida `entity_manager_.spawnPendingActors()`
   i les mòmies s'instancien ja en EMERGING. Visualment apareixen
   alhora que el text desapareix; durant la fase 5 acaben d'emergir
   i a l'entrada a PLAYING ja són ACTIVE — coincidint amb la caiguda
   aèria dels jugadors.

3. `completeIntro` afegeix un fallback: si arribem a PLAYING sense
   haver passat per fase 4 (config patològica, fases molt curtes),
   instanciem els pending igualment per garantir que la sala mai no
   queda sense enemics.

Renomenat: `hazards_spawn_triggered_` → `pending_actors_spawned_`,
nom que reflecteix què representa el flag al model nou.

El mètode privat `triggerHazardSpawnExit()` desapareix: era un
wrapper que ja només cridava `spawnPendingActors()`. Crida directa
des de `updateRoomTransition`, `respawnPlayersInstant` i
`completeIntro` (fallback).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
JailDesignerandClaude Opus 4.7 committed 2026-05-11 10:40:28 +02:00
1 parent 6a6a1a52c7
commit 881e0ea1f6
3 files changed
+39 -39

No files matched your search

+7 -14
View File
@@ -118,17 +118,6 @@ class GameScene : public Scene {
// el futur.
void triggerPlayerSpawn(std::size_t slot_index);
// Allibera tots els DynamicHazards de la sala (típicament mòmies)
// del seu estat SPAWN inicial: arma el comptador via
// `DynamicHazard::triggerSpawnExit()`. Es crida a `updateRoomTransition`
// quan ROOM_INTRO entra a la fase 5 (post text-exit), perquè les mòmies
// surten visualment "del terra" just després que el text desapareix
// i abans que caiguin els jugadors. Idempotent dins el cicle
// (`hazards_spawn_triggered_`); reset a `enterRoomIntro`. També
// cridada des de `respawnPlayersInstant` perquè el salt debug
// a sala no deixi les mòmies congelades.
void triggerHazardSpawnExit();
// Cos del callback de fi de música d'INTRO. Idempotent: si ja s'ha
// disparat aquest cicle (`intro_completed_`), no fa res. Marca el
// flag, reseteja el timer post-callback i intenta spawn dels slots
@@ -213,9 +202,13 @@ class GameScene : public Scene {
// i a `setState(ROOM_INTRO)` (camí defensiu no canònic).
std::array<bool, 2> players_spawned_in_intro_{false, false};
// Idempotència de `triggerHazardSpawnExit` dins d'un cicle d'INTRO.
// Reset a `enterRoomIntro` i a `setState(ROOM_INTRO)`.
bool hazards_spawn_triggered_{false};
// Idempotència de la crida a `entity_manager_.spawnPendingActors()`
// dins d'un cicle d'INTRO. Es dispara una sola vegada quan
// ROOM_INTRO entra a la subfase text-exit (fase 4) i, defensivament,
// a `respawnPlayersInstant` i al fallback de `completeIntro` per a
// camins no canònics. Reset a `enterRoomIntro` i a
// `setState(ROOM_INTRO)`.
bool pending_actors_spawned_{false};
// Vista plana de punters crus — la fa servir Player com a llista
// d'obstacles mòbils a la callback de col·lisió. Es construeix un sol