#include "game/map/room_yaml.hpp" #include #include "core/resources/resource_helper.hpp" namespace RoomYaml { namespace { // Fusiona `overlay` damunt `base` in-place. Recursió només per a // mapes; per a la resta (escalars, sequences) la `overlay` substitueix // l'entrada de `base`. Manté l'ordre de claus de `base` per a les // que ja hi eren; les noves s'afegeixen al final. void deepMerge(fkyaml::node& base, const fkyaml::node& overlay) { if (!overlay.is_mapping()) { return; } for (const auto& kv : overlay.as_map()) { const auto KEY = kv.first.get_value(); const auto& val = kv.second; if (base.contains(KEY) && base[KEY].is_mapping() && val.is_mapping()) { deepMerge(base[KEY], val); } else { base[KEY] = val; } } } auto deserializeFile(const std::string& path) -> fkyaml::node { auto bytes = Resource::Helper::loadFile(path); if (bytes.empty()) { throw std::runtime_error("RoomYaml: no s'ha pogut obrir " + path); } const auto* begin = reinterpret_cast(bytes.data()); const auto* end = begin + bytes.size(); return fkyaml::node::deserialize(begin, end); } // Retorna el directori del path (sense barra final). Si no hi ha // separador, retorna cadena buida. auto dirOf(const std::string& path) -> std::string { const auto POS = path.find_last_of('/'); if (POS == std::string::npos) { return ""; } return path.substr(0, POS); } } // namespace auto loadMerged(const std::string& room_yaml_path) -> fkyaml::node { const auto DIR = dirOf(room_yaml_path); const auto PYRAMID_PATH = DIR.empty() ? std::string{"pyramid.yaml"} : (DIR + "/pyramid.yaml"); // El pyramid.yaml és opcional: si Resource::Helper::loadFile el // troba (disc o pack), el fem servir com a base; si no, només // retornem el YAML de sala tal qual. auto pyramid_bytes = Resource::Helper::loadFile(PYRAMID_PATH); auto room = deserializeFile(room_yaml_path); if (pyramid_bytes.empty()) { return room; } const auto* begin = reinterpret_cast(pyramid_bytes.data()); const auto* end = begin + pyramid_bytes.size(); auto merged = fkyaml::node::deserialize(begin, end); deepMerge(merged, room); return merged; } } // namespace RoomYaml