feat(lighting): offset del centre de la llum per emissor
This commit is contained in:
1 parent
dacc4a9909
commit
3a42c7958a
9 files changed
+114
-25
No files matched your search
@@ -157,12 +157,14 @@ namespace {
|
||||
return c["height"].get_value<int>();
|
||||
}
|
||||
|
||||
// Bloc opcional `light: { radius: N, flicker: bool, color: [r,g,b] }`
|
||||
// Bloc opcional `light: { radius: N, flicker: bool, color: [r,g,b], offset: [x,y] }`
|
||||
// de la plantilla. Si manca, el radi és 0 i l'entitat no entra a la
|
||||
// pasada d'il·luminació. `flicker` activa la modulació "tipus foc"
|
||||
// del radi (només antorxes l'haurien d'usar). `color` només té
|
||||
// efecte en mode additive — defecte blanc (255,255,255). La forma
|
||||
// del gradient (3 anells) i els paràmetres del flicker viuen a
|
||||
// efecte en mode additive — defecte blanc (255,255,255). `offset`
|
||||
// desplaça el centre del cercle de llum respecte el centre del
|
||||
// sprite (default (0, 0); Y creix cap avall). La forma del gradient
|
||||
// (3 anells) i els paràmetres del flicker viuen a
|
||||
// data/config/lighting.yaml — no cal declarar-los per entitat.
|
||||
struct LightTemplate {
|
||||
int radius{0};
|
||||
@@ -170,6 +172,8 @@ namespace {
|
||||
std::uint8_t color_r{255};
|
||||
std::uint8_t color_g{255};
|
||||
std::uint8_t color_b{255};
|
||||
int offset_x{0};
|
||||
int offset_y{0};
|
||||
};
|
||||
|
||||
// Helper compartit entre les tres capes (tipus, sala via Map, spawn)
|
||||
@@ -182,6 +186,16 @@ namespace {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Helper paral·lel a `readColorTriplet` per a `offset: [x, y]` —
|
||||
// píxels enters, sense clamp (offsets negatius són legítims; Y
|
||||
// creix cap avall).
|
||||
auto readOffsetPair(const fkyaml::node& seq, int& x, int& y) -> bool {
|
||||
if (!seq.is_sequence() || seq.size() != 2) { return false; }
|
||||
x = seq[0].get_value<int>();
|
||||
y = seq[1].get_value<int>();
|
||||
return true;
|
||||
}
|
||||
|
||||
auto readLight(const fkyaml::node& tmpl) -> LightTemplate {
|
||||
if (!tmpl.contains("light")) { return {}; }
|
||||
const auto& l = tmpl["light"];
|
||||
@@ -189,6 +203,7 @@ namespace {
|
||||
if (l.contains("radius")) { out.radius = l["radius"].get_value<int>(); }
|
||||
if (l.contains("flicker")) { out.flicker = l["flicker"].get_value<bool>(); }
|
||||
if (l.contains("color")) { readColorTriplet(l["color"], out.color_r, out.color_g, out.color_b); }
|
||||
if (l.contains("offset")) { readOffsetPair(l["offset"], out.offset_x, out.offset_y); }
|
||||
return out;
|
||||
}
|
||||
|
||||
@@ -203,7 +218,7 @@ namespace {
|
||||
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, .color_r = 255, .color_g = 255, .color_b = 255}; }
|
||||
if (!room->enabled) { return LightTemplate{}; }
|
||||
LightTemplate out = type_default;
|
||||
if (room->radius.has_value()) { out.radius = *room->radius; }
|
||||
if (room->flicker.has_value()) { out.flicker = *room->flicker; }
|
||||
@@ -212,17 +227,21 @@ namespace {
|
||||
out.color_g = (*room->color)[1];
|
||||
out.color_b = (*room->color)[2];
|
||||
}
|
||||
if (room->offset.has_value()) {
|
||||
out.offset_x = (*room->offset)[0];
|
||||
out.offset_y = (*room->offset)[1];
|
||||
}
|
||||
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` → informatiu (cau a capes inferiors)
|
||||
// `light: { radius, flicker, color: [r,g,b] }` → camps presents sobreescriuen;
|
||||
// els absents respecten el que
|
||||
// ja duia l'entitat
|
||||
// `light: false` → apaga aquesta instància
|
||||
// `light: true` → informatiu (cau a capes inferiors)
|
||||
// `light: { radius, flicker, color: [r,g,b], offset: [x,y] }` → 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"];
|
||||
@@ -242,6 +261,11 @@ namespace {
|
||||
std::uint8_t b{};
|
||||
if (readColorTriplet(l["color"], r, g, b)) { entity.setLightColor(r, g, b); }
|
||||
}
|
||||
if (l.contains("offset")) {
|
||||
int x{};
|
||||
int y{};
|
||||
if (readOffsetPair(l["offset"], x, y)) { entity.setLightOffset(x, y); }
|
||||
}
|
||||
}
|
||||
|
||||
// Bloc `collision: { size: [w, h], base_size: [bw, bh]?, offset: [x, y]? }`
|
||||
@@ -374,6 +398,7 @@ namespace {
|
||||
entity->setLightRadius(LIGHT.radius);
|
||||
entity->setLightFlicker(LIGHT.flicker);
|
||||
entity->setLightColor(LIGHT.color_r, LIGHT.color_g, LIGHT.color_b);
|
||||
entity->setLightOffset(LIGHT.offset_x, LIGHT.offset_y);
|
||||
anchor_out = readAnchor(tmpl);
|
||||
return entity;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user