refactor(maps): pyramid.yaml per piràmide amb merge a sala
This commit is contained in:
1 parent
5f206e03c8
commit
125cdd0c74
45 files changed
+331
-1085
No files matched your search
@@ -0,0 +1,66 @@
|
||||
#include "game/map/room_yaml.hpp"
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
#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<std::string>();
|
||||
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<const char*>(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<const char*>(pyramid_bytes.data());
|
||||
const auto* end = begin + pyramid_bytes.size();
|
||||
auto merged = fkyaml::node::deserialize(begin, end);
|
||||
deepMerge(merged, room);
|
||||
return merged;
|
||||
}
|
||||
|
||||
} // namespace RoomYaml
|
||||
Reference in new issue
Block a user