feat(levels): LevelManager amb índex de sales
Nou singleton Levels::LevelManager que llig data/maps/levels.yaml a la primera get() i exposa currentPath/currentPyramid/currentRoom/ currentLabel + advance/restart/setIndex. És pur estat 'on sóc' — no orquestra cap reload; la GameScene i l'Editor li preguntaran al pas següent. Afegida constant Defaults::Pyramid::LEVELS_YAML al costat de la MAP_YAML antiga (la substitució completa va al Step 3).
This commit is contained in:
1 parent
8fd06887d1
commit
fe17c35c67
4 files changed
+169
No files matched your search
@@ -0,0 +1,74 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace Levels {
|
||||
|
||||
// Font de veritat de la progressió de sales del joc. Carrega
|
||||
// `data/maps/levels.yaml` a la primera crida a `get()` i exposa l'estat
|
||||
// "on sóc ara" + les operacions per moure'm. La GameScene, l'Editor i
|
||||
// els salts de debug consulten aquest singleton; ningú no manté el seu
|
||||
// propi índex de progressió.
|
||||
//
|
||||
// Meyers singleton: la destrucció estàtica només toca std::string i
|
||||
// std::vector, així que és segura sense ordenació explícita.
|
||||
class LevelManager {
|
||||
public:
|
||||
static auto get() -> LevelManager&;
|
||||
|
||||
LevelManager(const LevelManager&) = delete;
|
||||
LevelManager(LevelManager&&) = delete;
|
||||
auto operator=(const LevelManager&) -> LevelManager& = delete;
|
||||
auto operator=(LevelManager&&) -> LevelManager& = delete;
|
||||
|
||||
// Una entrada del `levels.yaml`. `file` és la ruta relativa al data
|
||||
// root (mateixa convenció que la resta de YAML del joc); pyramid i
|
||||
// room són purament informatius (logs i text d'intro).
|
||||
struct Entry {
|
||||
int pyramid{0};
|
||||
int room{0};
|
||||
std::string file;
|
||||
};
|
||||
|
||||
// Ruta del nivell actualment apuntat. Sempre vàlida un cop carregat
|
||||
// l'índex (entries_ no pot estar buit). Pensada per a `Map::loadFrom`,
|
||||
// `EntityManager::reload` i l'Editor.
|
||||
[[nodiscard]] auto currentPath() const -> const std::string&;
|
||||
[[nodiscard]] auto currentPyramid() const -> int;
|
||||
[[nodiscard]] auto currentRoom() const -> int;
|
||||
// "P1-R3" — útil per a logs i el text d'intro de sala.
|
||||
[[nodiscard]] auto currentLabel() const -> std::string;
|
||||
|
||||
// Posició dins de la seqüència. `count()` és el total de sales
|
||||
// carregades del YAML (no necessàriament 30: si afegeixes/treus
|
||||
// entrades de `levels.yaml`, el manager s'adapta).
|
||||
[[nodiscard]] auto index() const -> int;
|
||||
[[nodiscard]] auto count() const -> int;
|
||||
|
||||
// Avança al següent nivell. Retorna true si avança, false si ja
|
||||
// estava a l'últim. NO fa loop — la GameScene decideix la política
|
||||
// (loop a la primera, fi de joc, etc.) segons el context.
|
||||
auto advance() -> bool;
|
||||
|
||||
// Torna al primer nivell.
|
||||
void restart();
|
||||
|
||||
// Salta a un índex concret. Clamp als bordes [0, count()-1].
|
||||
// Pensat per als hotkeys debug i per `debug.yaml.starting_level`.
|
||||
void setIndex(int new_index);
|
||||
|
||||
private:
|
||||
LevelManager();
|
||||
~LevelManager() = default;
|
||||
|
||||
// Carrega `data/maps/levels.yaml` via `Resource::Helper::loadFile`.
|
||||
// Si manca, és invàlid o té la seqüència buida, llança — no té sentit
|
||||
// continuar sense progressió de sales.
|
||||
void loadIndex();
|
||||
|
||||
std::vector<Entry> entries_;
|
||||
int index_{0};
|
||||
};
|
||||
|
||||
} // namespace Levels
|
||||
Reference in new issue
Block a user