feat(debug): starting_level a debug.yaml

Nova clau opcional al debug.yaml:
    starting_level: { pyramid: 2, room: 3 }
DebugConfig::resolveStartingLevel retorna optional<StartingLevel>; el
Director, abans de crear el GameScene, demana al LevelManager
setStartingPoint(pyramid, room) — que cerca l'entrada al levels.yaml
i hi posiciona l'índex. Si la clau no està (cas habitual) o
(pyramid, room) no existeix, la progressió arrenca a la primera sala
amb un avís a stderr. createDefaultIfMissing documenta la nova clau
sense escriure-la (la deixem opcional).

Drive-by: NOLINT puntual al capture de STARTING_PLAYERS al Director.
És pre-existent i s'ha activat ara perquè el commit toca director.cpp;
la captura és imprescindible en Debug (valor runtime), clang la veu
redundant en Release on és constexpr literal.
This commit is contained in:
JailDesigner committed 2026-04-26 15:07:34 +02:00
1 parent b147590a39
commit 738cde12bb
5 files changed
+81 -1

No files matched your search

+31
View File
@@ -103,6 +103,34 @@ namespace DebugConfig {
return parseStartingPlayers(CONTENT);
}
auto parseStartingLevel(const std::string& yaml_content) -> std::optional<StartingLevel> {
if (yaml_content.empty()) { return std::nullopt; }
try {
auto yaml = fkyaml::node::deserialize(yaml_content);
if (!yaml.contains("starting_level")) { return std::nullopt; }
const auto& sl = yaml["starting_level"];
if (!sl.contains("pyramid") || !sl.contains("room")) {
std::cerr << "debug.yaml: starting_level necessita els camps `pyramid` i `room` — ignorat\n";
return std::nullopt;
}
return StartingLevel{
.pyramid = sl["pyramid"].get_value<int>(),
.room = sl["room"].get_value<int>(),
};
} catch (const std::exception& e) {
std::cerr << "debug.yaml: error parsejant starting_level: " << e.what() << " — ignorat\n";
return std::nullopt;
}
}
auto resolveStartingLevel(const std::string& file_path) -> std::optional<StartingLevel> {
std::error_code error;
if (!std::filesystem::exists(file_path, error)) { return std::nullopt; }
const auto CONTENT = readFile(file_path);
if (CONTENT.empty()) { return std::nullopt; }
return parseStartingLevel(CONTENT);
}
auto toString(StartScene scene) -> const char* {
switch (scene) {
case StartScene::LOGO:
@@ -140,6 +168,9 @@ namespace DebugConfig {
file << "# debug.yaml — ajust personal de dev (no versionat).\n";
file << "# start_scene: LOGO | TITLE | INTRO | GAME\n";
file << "# starting_players: P1 | P2 | BOTH\n";
file << "# starting_level (opcional): { pyramid: N, room: M } — salta a la sala\n";
file << "# corresponent del levels.yaml. Sense la\n";
file << "# clau, comença a la primera (P1-R1).\n";
file << "start_scene: GAME\n";
file << "starting_players: BOTH\n";
std::cout << "debug.yaml: creat a " << file_path << " amb start_scene=GAME starting_players=BOTH\n";