fase 1 de zones
This commit is contained in:
@@ -95,6 +95,7 @@ set(APP_SOURCES
|
|||||||
source/game/gameplay/room.cpp
|
source/game/gameplay/room.cpp
|
||||||
source/game/gameplay/scoreboard.cpp
|
source/game/gameplay/scoreboard.cpp
|
||||||
source/game/gameplay/tilemap_renderer.cpp
|
source/game/gameplay/tilemap_renderer.cpp
|
||||||
|
source/game/gameplay/zone_manager.cpp
|
||||||
|
|
||||||
# Game - Scenes
|
# Game - Scenes
|
||||||
source/game/scenes/game.cpp
|
source/game/scenes/game.cpp
|
||||||
|
|||||||
@@ -63,6 +63,11 @@ assets:
|
|||||||
DATA:
|
DATA:
|
||||||
- ${PREFIX}/data/console/commands.yaml
|
- ${PREFIX}/data/console/commands.yaml
|
||||||
|
|
||||||
|
# ZONES
|
||||||
|
zones:
|
||||||
|
DATA:
|
||||||
|
- ${PREFIX}/data/zones/zones.yaml
|
||||||
|
|
||||||
# ROOMS
|
# ROOMS
|
||||||
rooms:
|
rooms:
|
||||||
ROOM:
|
ROOM:
|
||||||
|
|||||||
BIN
data/tilesets/cave.gif
Normal file
BIN
data/tilesets/cave.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 8.1 KiB |
BIN
data/tilesets/neighborhood.gif
Normal file
BIN
data/tilesets/neighborhood.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 7.7 KiB |
13
data/zones/zones.yaml
Normal file
13
data/zones/zones.yaml
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
# Zonas del juego
|
||||||
|
# Cada zona define un tileset y una pista de música compartidos por todas las
|
||||||
|
# habitaciones que pertenecen a ella. Las habitaciones individuales pueden
|
||||||
|
# sobreescribir tileSetFile y/o music en su propio yaml.
|
||||||
|
|
||||||
|
zones:
|
||||||
|
- name: neighborhood
|
||||||
|
tileSetFile: neighborhood.gif
|
||||||
|
music: 574070_KUVO_Farewell_to_school.ogg
|
||||||
|
|
||||||
|
- name: cave
|
||||||
|
tileSetFile: cave.gif
|
||||||
|
music: 574071_EA_DTV.ogg
|
||||||
22
source/game/gameplay/zone.hpp
Normal file
22
source/game/gameplay/zone.hpp
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string> // Para string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Datos de una zona del juego
|
||||||
|
*
|
||||||
|
* Una zona agrupa un conjunto de habitaciones que comparten tileset y música.
|
||||||
|
* Las habitaciones pueden hacer override individual de tile_set_file y/o music
|
||||||
|
* en su propio yaml; los valores aquí son la fuente por defecto.
|
||||||
|
*
|
||||||
|
* Las zonas se cargan desde data/zones/zones.yaml por el ZoneManager.
|
||||||
|
*/
|
||||||
|
namespace Zone {
|
||||||
|
|
||||||
|
struct Data {
|
||||||
|
std::string name; // Nombre único de la zona (ej. "neighborhood", "cave")
|
||||||
|
std::string tile_set_file; // Fichero de tileset por defecto (ej. "neighborhood.gif")
|
||||||
|
std::string music; // Pista de música por defecto (ej. "574070_KUVO_Farewell_to_school.ogg")
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Zone
|
||||||
98
source/game/gameplay/zone_manager.cpp
Normal file
98
source/game/gameplay/zone_manager.cpp
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
#include "game/gameplay/zone_manager.hpp"
|
||||||
|
|
||||||
|
#include <exception> // Para exception
|
||||||
|
#include <iostream> // Para cerr, cout
|
||||||
|
#include <string> // Para string
|
||||||
|
|
||||||
|
#include "core/resources/resource_helper.hpp" // Para Resource::Helper::loadFile
|
||||||
|
#include "external/fkyaml_node.hpp" // Para fkyaml::node
|
||||||
|
|
||||||
|
// [SINGLETON]
|
||||||
|
ZoneManager* ZoneManager::zone_manager = nullptr;
|
||||||
|
|
||||||
|
// [SINGLETON] Inicialización: crea la instancia y carga el yaml de zonas
|
||||||
|
void ZoneManager::init() {
|
||||||
|
if (ZoneManager::zone_manager != nullptr) { return; }
|
||||||
|
ZoneManager::zone_manager = new ZoneManager();
|
||||||
|
ZoneManager::zone_manager->loadFromFile("data/zones/zones.yaml");
|
||||||
|
}
|
||||||
|
|
||||||
|
// [SINGLETON]
|
||||||
|
void ZoneManager::destroy() {
|
||||||
|
delete ZoneManager::zone_manager;
|
||||||
|
ZoneManager::zone_manager = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// [SINGLETON]
|
||||||
|
auto ZoneManager::get() -> ZoneManager* {
|
||||||
|
return ZoneManager::zone_manager;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Carga zones.yaml usando Resource::Helper (soporta pack + filesystem)
|
||||||
|
void ZoneManager::loadFromFile(const std::string& file_path) {
|
||||||
|
auto file_data = Resource::Helper::loadFile(file_path);
|
||||||
|
if (file_data.empty()) {
|
||||||
|
std::cerr << "ZoneManager: Unable to load " << file_path << "\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const std::string YAML_CONTENT(file_data.begin(), file_data.end());
|
||||||
|
auto yaml = fkyaml::node::deserialize(YAML_CONTENT);
|
||||||
|
|
||||||
|
if (!yaml.contains("zones") || yaml["zones"].is_null()) {
|
||||||
|
std::cerr << "ZoneManager: " << file_path << " has no 'zones' section\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& zone_node : yaml["zones"]) {
|
||||||
|
Zone::Data zone;
|
||||||
|
|
||||||
|
if (zone_node.contains("name")) {
|
||||||
|
zone.name = zone_node["name"].get_value<std::string>();
|
||||||
|
}
|
||||||
|
if (zone_node.contains("tileSetFile")) {
|
||||||
|
zone.tile_set_file = zone_node["tileSetFile"].get_value<std::string>();
|
||||||
|
}
|
||||||
|
if (zone_node.contains("music")) {
|
||||||
|
zone.music = zone_node["music"].get_value<std::string>();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (zone.name.empty()) {
|
||||||
|
std::cerr << "ZoneManager: skipping zone without name\n";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
zones_.push_back(zone);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "ZoneManager: loaded " << zones_.size() << " zones from " << file_path << "\n";
|
||||||
|
} catch (const fkyaml::exception& e) {
|
||||||
|
std::cerr << "ZoneManager: YAML parsing error in " << file_path << ": " << e.what() << "\n";
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
std::cerr << "ZoneManager: Error loading " << file_path << ": " << e.what() << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto ZoneManager::getZone(const std::string& name) const -> const Zone::Data* {
|
||||||
|
for (const auto& zone : zones_) {
|
||||||
|
if (zone.name == name) {
|
||||||
|
return &zone;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto ZoneManager::getDefaultZone() const -> const Zone::Data* {
|
||||||
|
if (zones_.empty()) { return nullptr; }
|
||||||
|
return &zones_.front();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto ZoneManager::getZoneNames() const -> std::vector<std::string> {
|
||||||
|
std::vector<std::string> names;
|
||||||
|
names.reserve(zones_.size());
|
||||||
|
for (const auto& zone : zones_) {
|
||||||
|
names.push_back(zone.name);
|
||||||
|
}
|
||||||
|
return names;
|
||||||
|
}
|
||||||
55
source/game/gameplay/zone_manager.hpp
Normal file
55
source/game/gameplay/zone_manager.hpp
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string> // Para string
|
||||||
|
#include <vector> // Para vector
|
||||||
|
|
||||||
|
#include "game/gameplay/zone.hpp" // Para Zone::Data
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Singleton que carga y gestiona el catálogo de zonas
|
||||||
|
*
|
||||||
|
* Carga data/zones/zones.yaml en init() y permite consultar zonas por nombre.
|
||||||
|
* El loader usa Resource::Helper::loadFile, que soporta tanto el resource pack
|
||||||
|
* como el filesystem (modo desarrollo). Por eso ZoneManager no depende del
|
||||||
|
* Resource::Cache y puede inicializarse en cualquier momento antes de
|
||||||
|
* RoomLoader::loadYAML.
|
||||||
|
*/
|
||||||
|
class ZoneManager {
|
||||||
|
public:
|
||||||
|
// Gestión singleton
|
||||||
|
static void init(); // Carga zones.yaml y crea el singleton
|
||||||
|
static void destroy(); // Destruye el singleton
|
||||||
|
static auto get() -> ZoneManager*; // Acceso al singleton
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Devuelve la zona con el nombre indicado, o nullptr si no existe
|
||||||
|
*/
|
||||||
|
[[nodiscard]] auto getZone(const std::string& name) const -> const Zone::Data*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Devuelve la zona por defecto (primera del fichero), o nullptr si no hay zonas
|
||||||
|
*
|
||||||
|
* Se usa como fallback cuando una room.yaml no especifica zone o especifica
|
||||||
|
* una zona desconocida.
|
||||||
|
*/
|
||||||
|
[[nodiscard]] auto getDefaultZone() const -> const Zone::Data*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Devuelve la lista de nombres de todas las zonas (para validación en editor)
|
||||||
|
*/
|
||||||
|
[[nodiscard]] auto getZoneNames() const -> std::vector<std::string>;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Constantes singleton
|
||||||
|
static ZoneManager* zone_manager; // [SINGLETON] Objeto privado
|
||||||
|
|
||||||
|
// Constructor y destructor privados [SINGLETON]
|
||||||
|
ZoneManager() = default;
|
||||||
|
~ZoneManager() = default;
|
||||||
|
|
||||||
|
// Carga el yaml y rellena zones_
|
||||||
|
void loadFromFile(const std::string& file_path);
|
||||||
|
|
||||||
|
// Variables miembro
|
||||||
|
std::vector<Zone::Data> zones_; // Catálogo de zonas
|
||||||
|
};
|
||||||
@@ -25,6 +25,7 @@
|
|||||||
#include "game/gameplay/item_tracker.hpp" // Para ItemTracker
|
#include "game/gameplay/item_tracker.hpp" // Para ItemTracker
|
||||||
#include "game/gameplay/key_tracker.hpp" // Para KeyTracker
|
#include "game/gameplay/key_tracker.hpp" // Para KeyTracker
|
||||||
#include "game/gameplay/room.hpp" // Para Room, RoomData
|
#include "game/gameplay/room.hpp" // Para Room, RoomData
|
||||||
|
#include "game/gameplay/zone_manager.hpp" // Para ZoneManager
|
||||||
#include "game/gameplay/room_tracker.hpp" // Para RoomTracker
|
#include "game/gameplay/room_tracker.hpp" // Para RoomTracker
|
||||||
#include "game/gameplay/scoreboard.hpp" // Para Scoreboard::Data, Scoreboard
|
#include "game/gameplay/scoreboard.hpp" // Para Scoreboard::Data, Scoreboard
|
||||||
#include "game/options.hpp" // Para Options, options, Cheat, SectionState
|
#include "game/options.hpp" // Para Options, options, Cheat, SectionState
|
||||||
@@ -68,6 +69,7 @@ Game::Game(Mode mode)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Crea objetos e inicializa variables
|
// Crea objetos e inicializa variables
|
||||||
|
ZoneManager::init();
|
||||||
ItemTracker::init();
|
ItemTracker::init();
|
||||||
KeyTracker::init();
|
KeyTracker::init();
|
||||||
DoorTracker::init();
|
DoorTracker::init();
|
||||||
@@ -173,6 +175,7 @@ Game::~Game() {
|
|||||||
KeyTracker::destroy();
|
KeyTracker::destroy();
|
||||||
DoorTracker::destroy();
|
DoorTracker::destroy();
|
||||||
Inventory::destroy();
|
Inventory::destroy();
|
||||||
|
ZoneManager::destroy();
|
||||||
|
|
||||||
if (Console::get() != nullptr) { Console::get()->on_toggle = nullptr; }
|
if (Console::get() != nullptr) { Console::get()->on_toggle = nullptr; }
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user