feat(level-manager): HUD i text d'INTRO segueixen el LevelManager

HUD: la GameScene crida hud_->setPyramidRoom amb els valors del
LevelManager al ctor i a cada loadRoom — el marcador deixa de
mostrar 1/1 fix i s'actualitza en avançar de sala, en saltar amb
[/] i en arrencar amb starting_level del debug.yaml.

INTRO a dues línies: substitueix la clau game.room_intro per
game.room_intro_pyramid ("Piramide {p}") i game.room_intro_room
("Sala {r}") als locale ca/en. RoomFsm::formatRoomTitle(int)
desapareix i el reemplacen formatIntroPyramidLine(int) +
formatIntroRoomLine(int). renderRoomText es refactoritza per
dibuixar les dues línies (piràmide damunt, sala davall) amb
writeDX independents — comparteixen animació ara mateix però el
disseny ja les deixa preparades per ser desacoblades en el futur.

Drive-by: elimina el membre room_index_ de GameScene; les tres
ubicacions que el sincronitzaven amb el LevelManager (ctor,
advanceToNextRoom, salt debug) ja no fan falta — renderRoomText
i el HUD pregunten directament al singleton, evitant qualsevol
mirror local desincronitzable.

Test: T9/T10 actualitzats per a les dues noves formatadores.
This commit is contained in:
JailDesigner committed 2026-04-26 15:25:22 +02:00
1 parent b18bd4d021
commit e2f6d326aa
7 files changed
+149 -99

No files matched your search

+16 -10
View File
@@ -8,8 +8,8 @@
// T6 advance — PLAYING és sumidor: no avança res ni canvia d'estat.
// T7 advance — ROOM_OUTRO consumeix les 4 sub-fases i recau a ROOM_INTRO.
// T8 advance — un delta gran salta més d'una sub-fase en un sol pas.
// T9 formatRoomTitle — substitueix `{n}` quan el Locale té la clau.
// T10 formatRoomTitle — sense Locale, retorna la pròpia clau (fallback).
// T9 formatIntroPyramidLine / formatIntroRoomLine — substitució amb Locale.
// T10 formatIntroPyramidLine / formatIntroRoomLine — fallback sense Locale.
// T11 stateName — strings esperats per a cada State.
//
// El render no es testeja: la FSM és pura i no pinta res. Les regles de
@@ -189,23 +189,29 @@ namespace {
}
void testFormatRoomTitleWithLocale() {
std::cout << "T9 formatRoomTitle — substitució amb Locale\n";
std::cout << "T9 formatIntroPyramidLine / formatIntroRoomLine — substitució amb Locale\n";
const auto PATH = (std::filesystem::temp_directory_path() / "aee_test_locale.yaml").string();
writeTemp(PATH, "game:\n room_intro: \"Sala {n}\"\n");
writeTemp(PATH,
"game:\n"
" room_intro_pyramid: \"Piramide {p}\"\n"
" room_intro_room: \"Sala {r}\"\n");
Locale::get().load(PATH);
CHECK(RoomFsm::formatRoomTitle(1) == "Sala 1");
CHECK(RoomFsm::formatRoomTitle(7) == "Sala 7");
CHECK(RoomFsm::formatIntroPyramidLine(1) == "Piramide 1");
CHECK(RoomFsm::formatIntroPyramidLine(5) == "Piramide 5");
CHECK(RoomFsm::formatIntroRoomLine(1) == "Sala 1");
CHECK(RoomFsm::formatIntroRoomLine(7) == "Sala 7");
std::filesystem::remove(PATH);
}
void testFormatRoomTitleNoLocale() {
std::cout << "T10 formatRoomTitle — fallback sense traducció\n";
std::cout << "T10 formatIntroPyramidLine / formatIntroRoomLine — fallback sense traducció\n";
const auto PATH = (std::filesystem::temp_directory_path() / "aee_test_locale_empty.yaml").string();
writeTemp(PATH, "other: foo\n");
Locale::get().load(PATH);
// Sense la clau "game.room_intro", Locale retorna la pròpia clau,
// i com que no porta `{n}`, la substitució no canvia res.
CHECK(RoomFsm::formatRoomTitle(3) == "game.room_intro");
// Sense les claus, Locale retorna la pròpia clau i com que no
// porten `{p}`/`{r}`, la substitució no canvia res.
CHECK(RoomFsm::formatIntroPyramidLine(3) == "game.room_intro_pyramid");
CHECK(RoomFsm::formatIntroRoomLine(2) == "game.room_intro_room");
std::filesystem::remove(PATH);
}