feat(lighting): override d'emissors per sala i per spawn
This commit is contained in:
1 parent
b76a3eb1f3
commit
9d0dde38f9
5 files changed
+203
-9
No files matched your search
+63
-2
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <cmath>
|
||||
#include <stdexcept>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "core/resources/resource_helper.hpp"
|
||||
#include "external/fkyaml_node.hpp"
|
||||
@@ -28,12 +29,65 @@ namespace Map {
|
||||
// (debris, columnes). El TU local manté l'estat sense exposar-lo
|
||||
// al header.
|
||||
std::function<bool(const SDL_FRect&)> g_entity_collider;
|
||||
|
||||
// Overrides d'emissor declarats al bloc `lighting.emitters` del YAML
|
||||
// de la sala. Clau = tipus d'entitat en singular (per concordar amb
|
||||
// el camp `type:` de cada plantilla). Buit per defecte: una sala
|
||||
// sense bloc `lighting.emitters` deixa que cada entitat utilitze els
|
||||
// seus propis defaults del seu YAML de tipus.
|
||||
std::unordered_map<std::string, RoomEmitterOverride> g_room_emitters;
|
||||
|
||||
// Plural → singular per a tipus coneguts. El YAML de sala fa servir
|
||||
// el plural perquè es llegeix natural ("mummies: false"); el codi
|
||||
// treballa amb la forma singular que coincideix amb el camp `type:`
|
||||
// del spawn ("type: mummy"). Si la clau no és reconeguda, passa tal
|
||||
// qual (suposa que l'autor ja l'ha escrit en singular).
|
||||
auto normalizeEmitterKey(const std::string& yaml_key) -> std::string {
|
||||
if (yaml_key == "players") { return "player"; }
|
||||
if (yaml_key == "mummies") { return "mummy"; }
|
||||
if (yaml_key == "torches") { return "torch"; }
|
||||
return yaml_key;
|
||||
}
|
||||
|
||||
// Llegeix el bloc opcional `lighting:` del YAML d'una sala i
|
||||
// actualitza `light_level` (si declara `level`) i el mapping
|
||||
// `g_room_emitters`. Idempotent: cada `Map::loadFrom` neteja el
|
||||
// mapping abans de poblar-lo, així no s'arrosseguen overrides
|
||||
// d'una sala anterior.
|
||||
void loadLightingBlock(const fkyaml::node& yaml) {
|
||||
g_room_emitters.clear();
|
||||
if (!yaml.contains("lighting")) { return; }
|
||||
const auto& lighting = yaml["lighting"];
|
||||
if (lighting.contains("level")) {
|
||||
light_level = lighting["level"].get_value<float>();
|
||||
}
|
||||
if (!lighting.contains("emitters") || !lighting["emitters"].is_mapping()) { return; }
|
||||
const auto& em = lighting["emitters"];
|
||||
for (auto it = em.begin(); it != em.end(); ++it) {
|
||||
const auto KEY = normalizeEmitterKey(it.key().get_value<std::string>());
|
||||
const auto& val = it.value();
|
||||
RoomEmitterOverride ov;
|
||||
if (val.is_boolean()) {
|
||||
ov.enabled = val.get_value<bool>();
|
||||
} else if (val.is_mapping()) {
|
||||
ov.enabled = true;
|
||||
if (val.contains("radius")) { ov.radius = val["radius"].get_value<int>(); }
|
||||
if (val.contains("flicker")) { ov.flicker = val["flicker"].get_value<bool>(); }
|
||||
}
|
||||
g_room_emitters[KEY] = ov;
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
void setEntityCollider(std::function<bool(const SDL_FRect&)> fn) {
|
||||
g_entity_collider = std::move(fn);
|
||||
}
|
||||
|
||||
auto getRoomEmitterOverride(const std::string& type) -> const RoomEmitterOverride* {
|
||||
const auto IT = g_room_emitters.find(type);
|
||||
return IT == g_room_emitters.end() ? nullptr : &IT->second;
|
||||
}
|
||||
|
||||
void loadFrom(const std::string& yaml_path) {
|
||||
auto bytes = Resource::Helper::loadFile(yaml_path);
|
||||
if (bytes.empty()) {
|
||||
@@ -103,9 +157,16 @@ namespace Map {
|
||||
// canviarà el flag a true quan transiti a OPEN.
|
||||
door_open = false;
|
||||
|
||||
// Llum base de la sala. La clau és opcional a l'arrel del YAML;
|
||||
// per defecte 1.0 (sala totalment il·luminada, comportament hui).
|
||||
// Llum base de la sala. Dues formes acceptades:
|
||||
// - `light_level: <float>` a l'arrel (forma antiga, encara
|
||||
// suportada per retrocompat).
|
||||
// - `lighting.level: <float>` dins del bloc nou `lighting:`,
|
||||
// que també hostatja `lighting.emitters` (overrides per tipus).
|
||||
// Si manca tot, queda al default 1.0 (sala totalment il·luminada).
|
||||
// `loadLightingBlock` aplica el `lighting.level` per damunt del
|
||||
// `light_level:` antic, així el nou bloc guanya si conviuen.
|
||||
light_level = yaml.contains("light_level") ? yaml["light_level"].get_value<float>() : Defaults::Lighting::ROOM_LIGHT_DEFAULT;
|
||||
loadLightingBlock(yaml);
|
||||
|
||||
Log::info("Map", "geometria {}x{} sarcs {}x{} pitch {}x{} door_col {} des de {}", grid_cols, grid_rows, sarc_w, sarc_h, pitch_x, pitch_y, door_col, yaml_path);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user