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
@@ -174,6 +174,49 @@ namespace {
|
||||
return out;
|
||||
}
|
||||
|
||||
// Combina els defaults del tipus amb l'override de sala (si n'hi ha).
|
||||
// Forma 1: la sala no diu res del tipus → es retornen els defaults
|
||||
// del tipus tal qual (cas habitual / retrocompat).
|
||||
// Forma 2: la sala declara `<tipus>: false` → radi 0 (entitat sense
|
||||
// llum encara que el seu YAML en declari).
|
||||
// Forma 3: la sala declara `<tipus>: true` o `<tipus>: { ... }` → els
|
||||
// camps presents a l'override sobreescriuen el default; els absents
|
||||
// (`std::nullopt`) cauen al default del tipus.
|
||||
auto resolveLightWithRoom(const std::string& type, LightTemplate type_default) -> LightTemplate {
|
||||
const auto* room = Map::getRoomEmitterOverride(type);
|
||||
if (room == nullptr) { return type_default; }
|
||||
if (!room->enabled) { return {.radius = 0, .flicker = false}; }
|
||||
LightTemplate out = type_default;
|
||||
if (room->radius.has_value()) { out.radius = *room->radius; }
|
||||
if (room->flicker.has_value()) { out.flicker = *room->flicker; }
|
||||
return out;
|
||||
}
|
||||
|
||||
// Aplica l'override per-spawn (si existeix) per damunt del que ja
|
||||
// viu a l'entitat (defaults del tipus + override de sala). Tres formes
|
||||
// a l'entry del YAML de nivell:
|
||||
// `light: false` → apaga aquesta instància
|
||||
// `light: true` → no canvia res; la línia és
|
||||
// informativa (la llum ja la donen
|
||||
// les capes inferiors)
|
||||
// `light: { radius, flicker }` → els camps presents sobreescriuen;
|
||||
// els absents respecten el que ja
|
||||
// duia l'entitat
|
||||
void applySpawnLightOverride(Entity& entity, const fkyaml::node& spawn) {
|
||||
if (!spawn.contains("light")) { return; }
|
||||
const auto& l = spawn["light"];
|
||||
if (l.is_boolean()) {
|
||||
if (!l.get_value<bool>()) {
|
||||
entity.setLightRadius(0);
|
||||
entity.setLightFlicker(false);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (!l.is_mapping()) { return; }
|
||||
if (l.contains("radius")) { entity.setLightRadius(l["radius"].get_value<int>()); }
|
||||
if (l.contains("flicker")) { entity.setLightFlicker(l["flicker"].get_value<bool>()); }
|
||||
}
|
||||
|
||||
// Bloc `collision: { size: [w, h], base_size: [bw, bh]?, offset: [x, y]? }`
|
||||
// de la plantilla d'entitat.
|
||||
// - Sense `base_size` ni `offset`: la caja queda alineada a la vora
|
||||
@@ -296,7 +339,11 @@ namespace {
|
||||
entity->setCollisionBox(*BOX);
|
||||
}
|
||||
entity->setHeight(readHeight(tmpl));
|
||||
const auto LIGHT = readLight(tmpl);
|
||||
// Defaults del tipus → resolució amb override de sala. El layer
|
||||
// del spawn (per-instància) viu fora de `buildEntity`, perquè
|
||||
// aquí encara no tenim el node del spawn — el sobreposem a
|
||||
// `addSpawn` just després.
|
||||
const auto LIGHT = resolveLightWithRoom(type, readLight(tmpl));
|
||||
entity->setLightRadius(LIGHT.radius);
|
||||
entity->setLightFlicker(LIGHT.flicker);
|
||||
anchor_out = readAnchor(tmpl);
|
||||
@@ -461,6 +508,10 @@ auto EntityManager::addSpawn(const fkyaml::node& spawn) -> Entity* {
|
||||
std::string anchor;
|
||||
auto entity = buildEntity(TYPE, sprite, anchor);
|
||||
if (entity == nullptr) { return nullptr; }
|
||||
// Tercera capa de resolució de llum: override per-instància declarat
|
||||
// al spawn del YAML de la sala. Capes prèvies (tipus, sala) ja viuen
|
||||
// dins de l'entitat. Aplica abans del std::move per no perdre l'accés.
|
||||
applySpawnLightOverride(*entity, spawn);
|
||||
Entity* observer = entity.get();
|
||||
|
||||
bool ok = false;
|
||||
|
||||
Reference in new issue
Block a user