diff --git a/source/game/scenes/game_scene.cpp b/source/game/scenes/game_scene.cpp index 838c7cc..614607f 100644 --- a/source/game/scenes/game_scene.cpp +++ b/source/game/scenes/game_scene.cpp @@ -466,12 +466,13 @@ auto GameScene::computeSpawn() -> PlayerSpawn { }; } -void GameScene::resetRoom() { - // Recarregar les entitats des del YAML del mapa: la porta torna a +void GameScene::loadRoom(const std::string& yaml_path) { + // Recarregar les entitats des del YAML donat: la porta torna a // CLOSED (amb l'open=false a Map al loadFrom), els sarcs tornen a // CLOSED amb visited buit, momies i altres actors a la posició inicial. - Map::loadFrom(config_.map_yaml); - entity_manager_.reload(config_.map_yaml); + config_.map_yaml = yaml_path; + Map::loadFrom(yaml_path); + entity_manager_.reload(yaml_path); // Tornem a fixar el comptador de "esperats" amb només els slots // actius — un slot DISABLED permanent (single-player) no compta. const int ACTIVE_COUNT = std::ranges::count(players_starts_active_, true); @@ -485,10 +486,22 @@ void GameScene::resetRoom() { // el primer. for (auto& p : players_) { p->disable(); } - std::cout << "[ROOM] reset: entities reloaded, paint cleared, " + std::cout << "[ROOM] load " << yaml_path << ": entities reloaded, paint cleared, " << ACTIVE_COUNT << " active player(s) disabled (awaiting spawn cinematic)\n"; } +void GameScene::advanceToNextRoom() { + auto& mgr = Levels::LevelManager::get(); + if (!mgr.advance()) { + // Política temporal mentre no hi haja pantalla de "Fi de joc": + // arribar al final del levels.yaml fa loop a la primera sala. + std::cout << "[ROOM] final del levels.yaml — bucle a la primera sala\n"; + mgr.restart(); + } + room_index_ = mgr.currentRoom(); + loadRoom(mgr.currentPath()); +} + void GameScene::triggerActivePlayerSpawn() { if (players_spawned_in_intro_) { return; } players_spawned_in_intro_ = true; @@ -524,12 +537,14 @@ void GameScene::setState(RoomFsm::State new_state) { room_intro_elapsed_ms_ = 0; players_spawned_in_intro_ = false; } - // En tornar a ROOM_INTRO des de ROOM_OUTRO (placeholder de - // "torna a la mateixa sala"), reseteja completament l'estat del - // nivell. Si la transició és la inicial (PREV també és ROOM_INTRO, - // imposible amb el guard de dalt) o ve d'un altre estat, no fa res. + // En tornar a ROOM_INTRO des de ROOM_OUTRO ja hi ha itinerari: el + // jugador acaba de creuar la porta, així que avancem al següent + // nivell del LevelManager i carreguem la nova sala. Si era l'última, + // `advanceToNextRoom` fa loop a la primera. Per a la transició + // inicial (PREV també és ROOM_INTRO, impossible amb el guard de dalt) + // o vinguda d'un altre estat, no fem res. if (new_state == RoomFsm::State::ROOM_INTRO && PREV == RoomFsm::State::ROOM_OUTRO) { - resetRoom(); + advanceToNextRoom(); } } diff --git a/source/game/scenes/game_scene.hpp b/source/game/scenes/game_scene.hpp index e588cf7..63deb0b 100644 --- a/source/game/scenes/game_scene.hpp +++ b/source/game/scenes/game_scene.hpp @@ -208,11 +208,20 @@ class GameScene : public Scene { }; [[nodiscard]] static auto computeSpawn() -> PlayerSpawn; - // Reset complet de la sala: reload de l'EntityManager (sarcs/porta/ - // momies des de zero), neteja del PaintLayer i respawn dels jugadors - // a la posició calculada per `computeSpawn`. Cridat des de - // `setState(ROOM_INTRO)` quan la transició anterior era OUTRO. - void resetRoom(); + // Recarrega la sala apuntada per `yaml_path`: refresca Map (geometria, + // porta tancada), entitats (sarcs/porta/momies des de zero), neteja + // el PaintLayer i deixa els jugadors a DISABLED esperant la cinemàtica + // d'spawn aeri del nou cicle d'INTRO. També actualitza + // `config_.map_yaml` perquè futurs consumidors (l'Editor en guardar, + // logs, etc.) sàpiguen quina sala està viva. + void loadRoom(const std::string& yaml_path); + + // Demana al LevelManager el següent nivell i el carrega via + // `loadRoom`. Si ja era a l'última entrada, fa loop a la primera + // (política temporal mentre no hi haja pantalla de fi de joc). + // Cridat des de `setState(ROOM_INTRO)` quan la transició anterior + // era OUTRO — és la conseqüència de creuar la porta. + void advanceToNextRoom(); #ifdef _DEBUG // Editor modal del tilemap. Mútuament excloent amb la pausa: si la diff --git a/source/game/scenes/room_fsm.cpp b/source/game/scenes/room_fsm.cpp index 1016108..0b4dfdb 100644 --- a/source/game/scenes/room_fsm.cpp +++ b/source/game/scenes/room_fsm.cpp @@ -99,10 +99,10 @@ namespace RoomFsm { t.elapsed_ms -= DURS[t.phase]; ++t.phase; } - // Placeholder fins a l'itinerari de sales: l'OUTRO recau a INTRO. - // TODO(itinerari): aquest mateix retorn sortirà cap a una nova - // sala (incrementant `room_index_` i recreant tilemap/entitats al - // GameScene) abans de tornar a ROOM_INTRO. + // Final de l'OUTRO → ROOM_INTRO de la sala SEGÜENT. La FSM no + // sap quina és — només avisa del canvi d'estat. La GameScene, + // dins `setState(ROOM_INTRO)` amb PREV=OUTRO, demana al + // LevelManager el següent nivell i recarrega tilemap/entitats. if (t.phase >= static_cast(DURS.size())) { return State::ROOM_INTRO; } return current; }