From 125cdd0c74b0290aafd5937449083dd15a33c60d Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Wed, 13 May 2026 22:38:42 +0200 Subject: [PATCH] =?UTF-8?q?refactor(maps):=20pyramid.yaml=20per=20pir?= =?UTF-8?q?=C3=A0mide=20amb=20merge=20a=20sala?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CMakeLists.txt | 3 + data/maps/p1/pyramid.yaml | 42 ++++++++ data/maps/p1/r1.yaml | 56 ---------- data/maps/p1/r2.yaml | 34 +----- data/maps/p1/r3.yaml | 29 ------ data/maps/p1/r4.yaml | 29 ------ data/maps/p1/r5.yaml | 29 ------ data/maps/p1/r6.yaml | 29 ------ data/maps/p2/pyramid.yaml | 42 ++++++++ data/maps/p2/r1.yaml | 29 ------ data/maps/p2/r2.yaml | 29 ------ data/maps/p2/r3.yaml | 29 ------ data/maps/p2/r4.yaml | 29 ------ data/maps/p2/r5.yaml | 29 ------ data/maps/p2/r6.yaml | 29 ------ data/maps/p3/pyramid.yaml | 42 ++++++++ data/maps/p3/r1.yaml | 29 ------ data/maps/p3/r2.yaml | 29 ------ data/maps/p3/r3.yaml | 29 ------ data/maps/p3/r4.yaml | 29 ------ data/maps/p3/r5.yaml | 29 ------ data/maps/p3/r6.yaml | 29 ------ data/maps/p4/pyramid.yaml | 42 ++++++++ data/maps/p4/r1.yaml | 29 ------ data/maps/p4/r2.yaml | 29 ------ data/maps/p4/r3.yaml | 29 ------ data/maps/p4/r4.yaml | 29 ------ data/maps/p4/r5.yaml | 29 ------ data/maps/p4/r6.yaml | 29 ------ data/maps/p5/pyramid.yaml | 42 ++++++++ data/maps/p5/r1.yaml | 29 ------ data/maps/p5/r2.yaml | 29 ------ data/maps/p5/r3.yaml | 29 ------ data/maps/p5/r4.yaml | 29 ------ data/maps/p5/r5.yaml | 29 ------ data/maps/p5/r6.yaml | 29 ------ data/maps/pyramid.yaml | 138 ------------------------- source/game/entities/entity_loader.cpp | 9 +- source/game/map/map.cpp | 10 +- source/game/map/room_yaml.cpp | 66 ++++++++++++ source/game/map/room_yaml.hpp | 23 +++++ source/game/map/tilemap.cpp | 10 +- source/game/scenes/game_scene.cpp | 13 +-- tests/test_entities_smoke.cpp | 16 +-- tests/test_whip_attack.cpp | 16 +-- 45 files changed, 331 insertions(+), 1085 deletions(-) create mode 100644 data/maps/p1/pyramid.yaml create mode 100644 data/maps/p2/pyramid.yaml create mode 100644 data/maps/p3/pyramid.yaml create mode 100644 data/maps/p4/pyramid.yaml create mode 100644 data/maps/p5/pyramid.yaml delete mode 100644 data/maps/pyramid.yaml create mode 100644 source/game/map/room_yaml.cpp create mode 100644 source/game/map/room_yaml.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 0364b04..b8747d5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -131,6 +131,7 @@ set(APP_SOURCES # al TilemapWriter. Només Debug. source/game/map/map_writer.cpp source/game/map/paint_layer.cpp + source/game/map/room_yaml.cpp source/game/levels/level_manager.cpp # Mòdul editor (només activa contingut en Debug via `#ifdef _DEBUG`). # En Release els fitxers compilen a object buit i l'enllaçador no @@ -374,6 +375,7 @@ if(BUILD_TESTS) source/core/resources/resource_helper.cpp source/core/resources/resource_pack.cpp source/game/map/map.cpp + source/game/map/room_yaml.cpp source/utils/log.cpp ${ENTITY_SOURCES_BASE} ) @@ -405,6 +407,7 @@ if(BUILD_TESTS) source/core/resources/resource_pack.cpp source/game/gameplay_config.cpp source/game/map/map.cpp + source/game/map/room_yaml.cpp source/utils/log.cpp ${ENTITY_SOURCES_BASE} source/game/entities/concrete/whip_attack.cpp diff --git a/data/maps/p1/pyramid.yaml b/data/maps/p1/pyramid.yaml new file mode 100644 index 0000000..d358413 --- /dev/null +++ b/data/maps/p1/pyramid.yaml @@ -0,0 +1,42 @@ +# Configuració compartida per totes les sales de la piràmide 1. Cada sala +# (r1..r6) hereta aquests camps via el merge recursiu de `RoomYaml::loadMerged`: +# el YAML de sala només declara el que canvia (room, geometry, data, entities, +# i opcionalment overrides puntuals de `lighting`). + +pyramid: 1 +tileset: data/tilesets/pyramid_1.gif +tile_size: 16 +origin: [-8, 0] + +# Índex de tile amb què cada jugador deixa rastre en trepitjar un sòl +# pintable. Un índex per jugador perquè a multijugador local el recorregut +# es distingeix a simple vista. Provisional fins que l'art del pintat +# estigui definit; canviar aquí l'índex és tot el que cal. Omet el camp +# per desactivar el pintat per a aquest jugador. +player1_paint_tile: 0 +player2_paint_tile: 1 + +# Física del contacte entre jugadors. Quan un jugador està quiet i l'altre +# el topa, el segon l'empenta a aquesta fracció de la velocitat normal (i +# ell mateix es ralentitza per mantenir el grup). En head-on, ambdós +# s'anul·len (sense push, sense moviment). +push_factor: 0.30 + +# Il·luminació per defecte: additive amb halos càlids subtils a les +# antorxes. Les sales que vulguin l'estil "fosc amb forats" (subtractive) +# poden redeclarar `lighting:` sencer; el merge no fusiona "additive" +# amb "subtractive", la sala guanya. +lighting: + mode: additive + level: 1.0 + emitters: + torches: + radius: 23 + color: [255, 170, 60] + flicker_params: + wave_amplitude_ratio: 0.04 + wave_frequency_hz: 3.0 + noise_amplitude_ratio: 0.025 + noise_frequency_hz: 0 + players: false + mummies: false diff --git a/data/maps/p1/r1.yaml b/data/maps/p1/r1.yaml index 218db16..1276f88 100644 --- a/data/maps/p1/r1.yaml +++ b/data/maps/p1/r1.yaml @@ -1,60 +1,4 @@ -# Mapa de la piràmide: graella 21×15 de tiles 16×16 sobre pyramid_1.gif. -# Overscan horitzontal: 8 px per banda (les parets laterals ocupen 2 tiles -# en el tilemap però només 1.5 visibles al canvas, així que la textura es -# dibuixa amb un origen de x=-8). Vertical no cal overscan: 15·16 = 240. -# -# Format del tilemap: -# `data` és una llista de files; cada fila és una llista d'índexs del -# tileset (lineal esq→dre, dalt→baix). Amb un tileset de 512×256 i tiles -# de 16×16 hi ha 32 tiles per fila. Un valor negatiu (p.ex. -1) deixa -# la cel·la buida (transparent), útil per caselles que ocuparà un actor. - -pyramid: 1 room: 2 -tileset: data/tilesets/pyramid_1.gif -tile_size: 16 -origin: [-8, 0] - -# Banc de proves del mode `additive` d'il·luminació. La sala es veu -# "normal" (level 1.0, el GIF intacte fora del cercle de les torxes) -# i només les antorxes hi sumen un halo càlid suau. Player i mummies -# desactivats explícitament perquè aquí no volem cap halo al voltant -# d'actors — el toc cromàtic és només l'antorxa. La corba additiva -# (intensitats baixes a propòsit perquè additive satura ràpid) viu a -# `gradient_additive:` de data/config/lighting.yaml. -lighting: - mode: additive - level: 1.0 - emitters: - torches: - radius: 23 - color: [255, 170, 60] - # Valors default del flicker explicitats per anar-los ajustant - # in-situ. Coincideixen amb els del global a data/config/lighting.yaml; - # baixar wave_frequency_hz fa el "palpitar" més lent, baixar les - # ratios fa l'oscil·lació més subtil. Qualsevol camp es pot - # eliminar i caurà al valor del global. - flicker_params: - wave_amplitude_ratio: 0.04 - wave_frequency_hz: 3.0 - noise_amplitude_ratio: 0.025 - noise_frequency_hz: 0 - players: false - mummies: false - -# Índex de tile amb què cada jugador deixa rastre en trepitjar un sòl -# pintable. Un índex per jugador perquè a multijugador local el recorregut -# es distingeix a simple vista. Provisional fins que l'art del pintat -# estigui definit; canviar aquí l'índex és tot el que cal. Omet el camp -# per desactivar el pintat per a aquest jugador. -player1_paint_tile: 0 -player2_paint_tile: 1 - -# Física del contacte entre jugadors. Quan un jugador està quiet i l'altre -# el topa, el segon l'empenta a aquesta fracció de la velocitat normal (i -# ell mateix es ralentitza per mantenir el grup). En head-on, ambdós -# s'anul·len (sense push, sense moviment). -push_factor: 0.30 # Geometria lògica de la piràmide (separada del render visual del tileset). # La graella de sarcòfags, el pitch entre ells i les amplades dels murs diff --git a/data/maps/p1/r2.yaml b/data/maps/p1/r2.yaml index b1e55af..02b1154 100644 --- a/data/maps/p1/r2.yaml +++ b/data/maps/p1/r2.yaml @@ -1,19 +1,4 @@ -# Mapa de la piràmide: graella 21×15 de tiles 16×16 sobre pyramid_1.gif. -# Overscan horitzontal: 8 px per banda (les parets laterals ocupen 2 tiles -# en el tilemap però només 1.5 visibles al canvas, així que la textura es -# dibuixa amb un origen de x=-8). Vertical no cal overscan: 15·16 = 240. -# -# Format del tilemap: -# `data` és una llista de files; cada fila és una llista d'índexs del -# tileset (lineal esq→dre, dalt→baix). Amb un tileset de 512×256 i tiles -# de 16×16 hi ha 32 tiles per fila. Un valor negatiu (p.ex. -1) deixa -# la cel·la buida (transparent), útil per caselles que ocuparà un actor. - -pyramid: 1 room: 1 -tileset: data/tilesets/pyramid_1.gif -tile_size: 16 -origin: [-8, 0] # Il·luminació de la sala. Bloc opcional; si manca, la sala queda # totalment il·luminada (1.0) i tots els tipus d'entitat emeten amb els @@ -37,24 +22,13 @@ origin: [-8, 0] # (`light_level:` plà a l'arrel) també segueix sent vàlida per # retrocompatibilitat. lighting: + # Sala fosca de proves. La piràmide declara additive per defecte; aquí + # tornem a subtractive perquè volem la dinàmica "negre amb forats de + # llum". `level: 0.15` és l'atenuació base de la sala fora dels emissors. + mode: subtractive level: 0.15 emitters: players: true - mummies: false - -# Índex de tile amb què cada jugador deixa rastre en trepitjar un sòl -# pintable. Un índex per jugador perquè a multijugador local el recorregut -# es distingeix a simple vista. Provisional fins que l'art del pintat -# estigui definit; canviar aquí l'índex és tot el que cal. Omet el camp -# per desactivar el pintat per a aquest jugador. -player1_paint_tile: 0 -player2_paint_tile: 1 - -# Física del contacte entre jugadors. Quan un jugador està quiet i l'altre -# el topa, el segon l'empenta a aquesta fracció de la velocitat normal (i -# ell mateix es ralentitza per mantenir el grup). En head-on, ambdós -# s'anul·len (sense push, sense moviment). -push_factor: 0.30 # Geometria lògica de la piràmide (separada del render visual del tileset). # La graella de sarcòfags, el pitch entre ells i les amplades dels murs diff --git a/data/maps/p1/r3.yaml b/data/maps/p1/r3.yaml index 32c0655..788a809 100644 --- a/data/maps/p1/r3.yaml +++ b/data/maps/p1/r3.yaml @@ -1,33 +1,4 @@ -# Mapa de la piràmide: graella 21×15 de tiles 16×16 sobre pyramid_1.gif. -# Overscan horitzontal: 8 px per banda (les parets laterals ocupen 2 tiles -# en el tilemap però només 1.5 visibles al canvas, així que la textura es -# dibuixa amb un origen de x=-8). Vertical no cal overscan: 15·16 = 240. -# -# Format del tilemap: -# `data` és una llista de files; cada fila és una llista d'índexs del -# tileset (lineal esq→dre, dalt→baix). Amb un tileset de 512×256 i tiles -# de 16×16 hi ha 32 tiles per fila. Un valor negatiu (p.ex. -1) deixa -# la cel·la buida (transparent), útil per caselles que ocuparà un actor. - -pyramid: 1 room: 3 -tileset: data/tilesets/pyramid_1.gif -tile_size: 16 -origin: [-8, 0] - -# Índex de tile amb què cada jugador deixa rastre en trepitjar un sòl -# pintable. Un índex per jugador perquè a multijugador local el recorregut -# es distingeix a simple vista. Provisional fins que l'art del pintat -# estigui definit; canviar aquí l'índex és tot el que cal. Omet el camp -# per desactivar el pintat per a aquest jugador. -player1_paint_tile: 0 -player2_paint_tile: 1 - -# Física del contacte entre jugadors. Quan un jugador està quiet i l'altre -# el topa, el segon l'empenta a aquesta fracció de la velocitat normal (i -# ell mateix es ralentitza per mantenir el grup). En head-on, ambdós -# s'anul·len (sense push, sense moviment). -push_factor: 0.30 # Geometria lògica de la piràmide (separada del render visual del tileset). # La graella de sarcòfags, el pitch entre ells i les amplades dels murs diff --git a/data/maps/p1/r4.yaml b/data/maps/p1/r4.yaml index f75f32a..ad2a8d7 100644 --- a/data/maps/p1/r4.yaml +++ b/data/maps/p1/r4.yaml @@ -1,33 +1,4 @@ -# Mapa de la piràmide: graella 21×15 de tiles 16×16 sobre pyramid_1.gif. -# Overscan horitzontal: 8 px per banda (les parets laterals ocupen 2 tiles -# en el tilemap però només 1.5 visibles al canvas, així que la textura es -# dibuixa amb un origen de x=-8). Vertical no cal overscan: 15·16 = 240. -# -# Format del tilemap: -# `data` és una llista de files; cada fila és una llista d'índexs del -# tileset (lineal esq→dre, dalt→baix). Amb un tileset de 512×256 i tiles -# de 16×16 hi ha 32 tiles per fila. Un valor negatiu (p.ex. -1) deixa -# la cel·la buida (transparent), útil per caselles que ocuparà un actor. - -pyramid: 1 room: 4 -tileset: data/tilesets/pyramid_1.gif -tile_size: 16 -origin: [-8, 0] - -# Índex de tile amb què cada jugador deixa rastre en trepitjar un sòl -# pintable. Un índex per jugador perquè a multijugador local el recorregut -# es distingeix a simple vista. Provisional fins que l'art del pintat -# estigui definit; canviar aquí l'índex és tot el que cal. Omet el camp -# per desactivar el pintat per a aquest jugador. -player1_paint_tile: 0 -player2_paint_tile: 1 - -# Física del contacte entre jugadors. Quan un jugador està quiet i l'altre -# el topa, el segon l'empenta a aquesta fracció de la velocitat normal (i -# ell mateix es ralentitza per mantenir el grup). En head-on, ambdós -# s'anul·len (sense push, sense moviment). -push_factor: 0.30 # Geometria lògica de la piràmide (separada del render visual del tileset). # La graella de sarcòfags, el pitch entre ells i les amplades dels murs diff --git a/data/maps/p1/r5.yaml b/data/maps/p1/r5.yaml index bce33ee..d534f00 100644 --- a/data/maps/p1/r5.yaml +++ b/data/maps/p1/r5.yaml @@ -1,33 +1,4 @@ -# Mapa de la piràmide: graella 21×15 de tiles 16×16 sobre pyramid_1.gif. -# Overscan horitzontal: 8 px per banda (les parets laterals ocupen 2 tiles -# en el tilemap però només 1.5 visibles al canvas, així que la textura es -# dibuixa amb un origen de x=-8). Vertical no cal overscan: 15·16 = 240. -# -# Format del tilemap: -# `data` és una llista de files; cada fila és una llista d'índexs del -# tileset (lineal esq→dre, dalt→baix). Amb un tileset de 512×256 i tiles -# de 16×16 hi ha 32 tiles per fila. Un valor negatiu (p.ex. -1) deixa -# la cel·la buida (transparent), útil per caselles que ocuparà un actor. - -pyramid: 1 room: 5 -tileset: data/tilesets/pyramid_1.gif -tile_size: 16 -origin: [-8, 0] - -# Índex de tile amb què cada jugador deixa rastre en trepitjar un sòl -# pintable. Un índex per jugador perquè a multijugador local el recorregut -# es distingeix a simple vista. Provisional fins que l'art del pintat -# estigui definit; canviar aquí l'índex és tot el que cal. Omet el camp -# per desactivar el pintat per a aquest jugador. -player1_paint_tile: 0 -player2_paint_tile: 1 - -# Física del contacte entre jugadors. Quan un jugador està quiet i l'altre -# el topa, el segon l'empenta a aquesta fracció de la velocitat normal (i -# ell mateix es ralentitza per mantenir el grup). En head-on, ambdós -# s'anul·len (sense push, sense moviment). -push_factor: 0.30 # Geometria lògica de la piràmide (separada del render visual del tileset). # La graella de sarcòfags, el pitch entre ells i les amplades dels murs diff --git a/data/maps/p1/r6.yaml b/data/maps/p1/r6.yaml index b97836c..5634c99 100644 --- a/data/maps/p1/r6.yaml +++ b/data/maps/p1/r6.yaml @@ -1,33 +1,4 @@ -# Mapa de la piràmide: graella 21×15 de tiles 16×16 sobre pyramid_1.gif. -# Overscan horitzontal: 8 px per banda (les parets laterals ocupen 2 tiles -# en el tilemap però només 1.5 visibles al canvas, així que la textura es -# dibuixa amb un origen de x=-8). Vertical no cal overscan: 15·16 = 240. -# -# Format del tilemap: -# `data` és una llista de files; cada fila és una llista d'índexs del -# tileset (lineal esq→dre, dalt→baix). Amb un tileset de 512×256 i tiles -# de 16×16 hi ha 32 tiles per fila. Un valor negatiu (p.ex. -1) deixa -# la cel·la buida (transparent), útil per caselles que ocuparà un actor. - -pyramid: 1 room: 6 -tileset: data/tilesets/pyramid_1.gif -tile_size: 16 -origin: [-8, 0] - -# Índex de tile amb què cada jugador deixa rastre en trepitjar un sòl -# pintable. Un índex per jugador perquè a multijugador local el recorregut -# es distingeix a simple vista. Provisional fins que l'art del pintat -# estigui definit; canviar aquí l'índex és tot el que cal. Omet el camp -# per desactivar el pintat per a aquest jugador. -player1_paint_tile: 0 -player2_paint_tile: 1 - -# Física del contacte entre jugadors. Quan un jugador està quiet i l'altre -# el topa, el segon l'empenta a aquesta fracció de la velocitat normal (i -# ell mateix es ralentitza per mantenir el grup). En head-on, ambdós -# s'anul·len (sense push, sense moviment). -push_factor: 0.30 # Geometria lògica de la piràmide (separada del render visual del tileset). # La graella de sarcòfags, el pitch entre ells i les amplades dels murs diff --git a/data/maps/p2/pyramid.yaml b/data/maps/p2/pyramid.yaml new file mode 100644 index 0000000..4cdde79 --- /dev/null +++ b/data/maps/p2/pyramid.yaml @@ -0,0 +1,42 @@ +# Configuració compartida per totes les sales de la piràmide 2. Cada sala +# (r1..r6) hereta aquests camps via el merge recursiu de `RoomYaml::loadMerged`: +# el YAML de sala només declara el que canvia (room, geometry, data, entities, +# i opcionalment overrides puntuals de `lighting`). + +pyramid: 2 +tileset: data/tilesets/pyramid_2.gif +tile_size: 16 +origin: [-8, 0] + +# Índex de tile amb què cada jugador deixa rastre en trepitjar un sòl +# pintable. Un índex per jugador perquè a multijugador local el recorregut +# es distingeix a simple vista. Provisional fins que l'art del pintat +# estigui definit; canviar aquí l'índex és tot el que cal. Omet el camp +# per desactivar el pintat per a aquest jugador. +player1_paint_tile: 0 +player2_paint_tile: 1 + +# Física del contacte entre jugadors. Quan un jugador està quiet i l'altre +# el topa, el segon l'empenta a aquesta fracció de la velocitat normal (i +# ell mateix es ralentitza per mantenir el grup). En head-on, ambdós +# s'anul·len (sense push, sense moviment). +push_factor: 0.30 + +# Il·luminació per defecte: additive amb halos càlids subtils a les +# antorxes. Les sales que vulguin l'estil "fosc amb forats" (subtractive) +# poden redeclarar `lighting:` sencer; el merge no fusiona "additive" +# amb "subtractive", la sala guanya. +lighting: + mode: additive + level: 1.0 + emitters: + torches: + radius: 23 + color: [255, 170, 60] + flicker_params: + wave_amplitude_ratio: 0.04 + wave_frequency_hz: 3.0 + noise_amplitude_ratio: 0.025 + noise_frequency_hz: 0 + players: false + mummies: false diff --git a/data/maps/p2/r1.yaml b/data/maps/p2/r1.yaml index 567c8f7..b4c73b6 100644 --- a/data/maps/p2/r1.yaml +++ b/data/maps/p2/r1.yaml @@ -1,33 +1,4 @@ -# Mapa de la piràmide: graella 21×15 de tiles 16×16 sobre pyramid_2.gif. -# Overscan horitzontal: 8 px per banda (les parets laterals ocupen 2 tiles -# en el tilemap però només 1.5 visibles al canvas, així que la textura es -# dibuixa amb un origen de x=-8). Vertical no cal overscan: 15·16 = 240. -# -# Format del tilemap: -# `data` és una llista de files; cada fila és una llista d'índexs del -# tileset (lineal esq→dre, dalt→baix). Amb un tileset de 512×256 i tiles -# de 16×16 hi ha 32 tiles per fila. Un valor negatiu (p.ex. -1) deixa -# la cel·la buida (transparent), útil per caselles que ocuparà un actor. - -pyramid: 2 room: 1 -tileset: data/tilesets/pyramid_2.gif -tile_size: 16 -origin: [-8, 0] - -# Índex de tile amb què cada jugador deixa rastre en trepitjar un sòl -# pintable. Un índex per jugador perquè a multijugador local el recorregut -# es distingeix a simple vista. Provisional fins que l'art del pintat -# estigui definit; canviar aquí l'índex és tot el que cal. Omet el camp -# per desactivar el pintat per a aquest jugador. -player1_paint_tile: 0 -player2_paint_tile: 1 - -# Física del contacte entre jugadors. Quan un jugador està quiet i l'altre -# el topa, el segon l'empenta a aquesta fracció de la velocitat normal (i -# ell mateix es ralentitza per mantenir el grup). En head-on, ambdós -# s'anul·len (sense push, sense moviment). -push_factor: 0.30 # Geometria lògica de la piràmide (separada del render visual del tileset). # La graella de sarcòfags, el pitch entre ells i les amplades dels murs diff --git a/data/maps/p2/r2.yaml b/data/maps/p2/r2.yaml index 1a9c71c..d8e8c41 100644 --- a/data/maps/p2/r2.yaml +++ b/data/maps/p2/r2.yaml @@ -1,33 +1,4 @@ -# Mapa de la piràmide: graella 21×15 de tiles 16×16 sobre pyramid_2.gif. -# Overscan horitzontal: 8 px per banda (les parets laterals ocupen 2 tiles -# en el tilemap però només 1.5 visibles al canvas, així que la textura es -# dibuixa amb un origen de x=-8). Vertical no cal overscan: 15·16 = 240. -# -# Format del tilemap: -# `data` és una llista de files; cada fila és una llista d'índexs del -# tileset (lineal esq→dre, dalt→baix). Amb un tileset de 512×256 i tiles -# de 16×16 hi ha 32 tiles per fila. Un valor negatiu (p.ex. -1) deixa -# la cel·la buida (transparent), útil per caselles que ocuparà un actor. - -pyramid: 2 room: 2 -tileset: data/tilesets/pyramid_2.gif -tile_size: 16 -origin: [-8, 0] - -# Índex de tile amb què cada jugador deixa rastre en trepitjar un sòl -# pintable. Un índex per jugador perquè a multijugador local el recorregut -# es distingeix a simple vista. Provisional fins que l'art del pintat -# estigui definit; canviar aquí l'índex és tot el que cal. Omet el camp -# per desactivar el pintat per a aquest jugador. -player1_paint_tile: 0 -player2_paint_tile: 1 - -# Física del contacte entre jugadors. Quan un jugador està quiet i l'altre -# el topa, el segon l'empenta a aquesta fracció de la velocitat normal (i -# ell mateix es ralentitza per mantenir el grup). En head-on, ambdós -# s'anul·len (sense push, sense moviment). -push_factor: 0.30 # Geometria lògica de la piràmide (separada del render visual del tileset). # La graella de sarcòfags, el pitch entre ells i les amplades dels murs diff --git a/data/maps/p2/r3.yaml b/data/maps/p2/r3.yaml index 2aa333d..788a809 100644 --- a/data/maps/p2/r3.yaml +++ b/data/maps/p2/r3.yaml @@ -1,33 +1,4 @@ -# Mapa de la piràmide: graella 21×15 de tiles 16×16 sobre pyramid_2.gif. -# Overscan horitzontal: 8 px per banda (les parets laterals ocupen 2 tiles -# en el tilemap però només 1.5 visibles al canvas, així que la textura es -# dibuixa amb un origen de x=-8). Vertical no cal overscan: 15·16 = 240. -# -# Format del tilemap: -# `data` és una llista de files; cada fila és una llista d'índexs del -# tileset (lineal esq→dre, dalt→baix). Amb un tileset de 512×256 i tiles -# de 16×16 hi ha 32 tiles per fila. Un valor negatiu (p.ex. -1) deixa -# la cel·la buida (transparent), útil per caselles que ocuparà un actor. - -pyramid: 2 room: 3 -tileset: data/tilesets/pyramid_2.gif -tile_size: 16 -origin: [-8, 0] - -# Índex de tile amb què cada jugador deixa rastre en trepitjar un sòl -# pintable. Un índex per jugador perquè a multijugador local el recorregut -# es distingeix a simple vista. Provisional fins que l'art del pintat -# estigui definit; canviar aquí l'índex és tot el que cal. Omet el camp -# per desactivar el pintat per a aquest jugador. -player1_paint_tile: 0 -player2_paint_tile: 1 - -# Física del contacte entre jugadors. Quan un jugador està quiet i l'altre -# el topa, el segon l'empenta a aquesta fracció de la velocitat normal (i -# ell mateix es ralentitza per mantenir el grup). En head-on, ambdós -# s'anul·len (sense push, sense moviment). -push_factor: 0.30 # Geometria lògica de la piràmide (separada del render visual del tileset). # La graella de sarcòfags, el pitch entre ells i les amplades dels murs diff --git a/data/maps/p2/r4.yaml b/data/maps/p2/r4.yaml index cc8d28b..ad2a8d7 100644 --- a/data/maps/p2/r4.yaml +++ b/data/maps/p2/r4.yaml @@ -1,33 +1,4 @@ -# Mapa de la piràmide: graella 21×15 de tiles 16×16 sobre pyramid_2.gif. -# Overscan horitzontal: 8 px per banda (les parets laterals ocupen 2 tiles -# en el tilemap però només 1.5 visibles al canvas, així que la textura es -# dibuixa amb un origen de x=-8). Vertical no cal overscan: 15·16 = 240. -# -# Format del tilemap: -# `data` és una llista de files; cada fila és una llista d'índexs del -# tileset (lineal esq→dre, dalt→baix). Amb un tileset de 512×256 i tiles -# de 16×16 hi ha 32 tiles per fila. Un valor negatiu (p.ex. -1) deixa -# la cel·la buida (transparent), útil per caselles que ocuparà un actor. - -pyramid: 2 room: 4 -tileset: data/tilesets/pyramid_2.gif -tile_size: 16 -origin: [-8, 0] - -# Índex de tile amb què cada jugador deixa rastre en trepitjar un sòl -# pintable. Un índex per jugador perquè a multijugador local el recorregut -# es distingeix a simple vista. Provisional fins que l'art del pintat -# estigui definit; canviar aquí l'índex és tot el que cal. Omet el camp -# per desactivar el pintat per a aquest jugador. -player1_paint_tile: 0 -player2_paint_tile: 1 - -# Física del contacte entre jugadors. Quan un jugador està quiet i l'altre -# el topa, el segon l'empenta a aquesta fracció de la velocitat normal (i -# ell mateix es ralentitza per mantenir el grup). En head-on, ambdós -# s'anul·len (sense push, sense moviment). -push_factor: 0.30 # Geometria lògica de la piràmide (separada del render visual del tileset). # La graella de sarcòfags, el pitch entre ells i les amplades dels murs diff --git a/data/maps/p2/r5.yaml b/data/maps/p2/r5.yaml index c028fd9..d534f00 100644 --- a/data/maps/p2/r5.yaml +++ b/data/maps/p2/r5.yaml @@ -1,33 +1,4 @@ -# Mapa de la piràmide: graella 21×15 de tiles 16×16 sobre pyramid_2.gif. -# Overscan horitzontal: 8 px per banda (les parets laterals ocupen 2 tiles -# en el tilemap però només 1.5 visibles al canvas, així que la textura es -# dibuixa amb un origen de x=-8). Vertical no cal overscan: 15·16 = 240. -# -# Format del tilemap: -# `data` és una llista de files; cada fila és una llista d'índexs del -# tileset (lineal esq→dre, dalt→baix). Amb un tileset de 512×256 i tiles -# de 16×16 hi ha 32 tiles per fila. Un valor negatiu (p.ex. -1) deixa -# la cel·la buida (transparent), útil per caselles que ocuparà un actor. - -pyramid: 2 room: 5 -tileset: data/tilesets/pyramid_2.gif -tile_size: 16 -origin: [-8, 0] - -# Índex de tile amb què cada jugador deixa rastre en trepitjar un sòl -# pintable. Un índex per jugador perquè a multijugador local el recorregut -# es distingeix a simple vista. Provisional fins que l'art del pintat -# estigui definit; canviar aquí l'índex és tot el que cal. Omet el camp -# per desactivar el pintat per a aquest jugador. -player1_paint_tile: 0 -player2_paint_tile: 1 - -# Física del contacte entre jugadors. Quan un jugador està quiet i l'altre -# el topa, el segon l'empenta a aquesta fracció de la velocitat normal (i -# ell mateix es ralentitza per mantenir el grup). En head-on, ambdós -# s'anul·len (sense push, sense moviment). -push_factor: 0.30 # Geometria lògica de la piràmide (separada del render visual del tileset). # La graella de sarcòfags, el pitch entre ells i les amplades dels murs diff --git a/data/maps/p2/r6.yaml b/data/maps/p2/r6.yaml index 1173fa8..5634c99 100644 --- a/data/maps/p2/r6.yaml +++ b/data/maps/p2/r6.yaml @@ -1,33 +1,4 @@ -# Mapa de la piràmide: graella 21×15 de tiles 16×16 sobre pyramid_2.gif. -# Overscan horitzontal: 8 px per banda (les parets laterals ocupen 2 tiles -# en el tilemap però només 1.5 visibles al canvas, així que la textura es -# dibuixa amb un origen de x=-8). Vertical no cal overscan: 15·16 = 240. -# -# Format del tilemap: -# `data` és una llista de files; cada fila és una llista d'índexs del -# tileset (lineal esq→dre, dalt→baix). Amb un tileset de 512×256 i tiles -# de 16×16 hi ha 32 tiles per fila. Un valor negatiu (p.ex. -1) deixa -# la cel·la buida (transparent), útil per caselles que ocuparà un actor. - -pyramid: 2 room: 6 -tileset: data/tilesets/pyramid_2.gif -tile_size: 16 -origin: [-8, 0] - -# Índex de tile amb què cada jugador deixa rastre en trepitjar un sòl -# pintable. Un índex per jugador perquè a multijugador local el recorregut -# es distingeix a simple vista. Provisional fins que l'art del pintat -# estigui definit; canviar aquí l'índex és tot el que cal. Omet el camp -# per desactivar el pintat per a aquest jugador. -player1_paint_tile: 0 -player2_paint_tile: 1 - -# Física del contacte entre jugadors. Quan un jugador està quiet i l'altre -# el topa, el segon l'empenta a aquesta fracció de la velocitat normal (i -# ell mateix es ralentitza per mantenir el grup). En head-on, ambdós -# s'anul·len (sense push, sense moviment). -push_factor: 0.30 # Geometria lògica de la piràmide (separada del render visual del tileset). # La graella de sarcòfags, el pitch entre ells i les amplades dels murs diff --git a/data/maps/p3/pyramid.yaml b/data/maps/p3/pyramid.yaml new file mode 100644 index 0000000..fcea992 --- /dev/null +++ b/data/maps/p3/pyramid.yaml @@ -0,0 +1,42 @@ +# Configuració compartida per totes les sales de la piràmide 3. Cada sala +# (r1..r6) hereta aquests camps via el merge recursiu de `RoomYaml::loadMerged`: +# el YAML de sala només declara el que canvia (room, geometry, data, entities, +# i opcionalment overrides puntuals de `lighting`). + +pyramid: 3 +tileset: data/tilesets/pyramid_3.gif +tile_size: 16 +origin: [-8, 0] + +# Índex de tile amb què cada jugador deixa rastre en trepitjar un sòl +# pintable. Un índex per jugador perquè a multijugador local el recorregut +# es distingeix a simple vista. Provisional fins que l'art del pintat +# estigui definit; canviar aquí l'índex és tot el que cal. Omet el camp +# per desactivar el pintat per a aquest jugador. +player1_paint_tile: 0 +player2_paint_tile: 1 + +# Física del contacte entre jugadors. Quan un jugador està quiet i l'altre +# el topa, el segon l'empenta a aquesta fracció de la velocitat normal (i +# ell mateix es ralentitza per mantenir el grup). En head-on, ambdós +# s'anul·len (sense push, sense moviment). +push_factor: 0.30 + +# Il·luminació per defecte: additive amb halos càlids subtils a les +# antorxes. Les sales que vulguin l'estil "fosc amb forats" (subtractive) +# poden redeclarar `lighting:` sencer; el merge no fusiona "additive" +# amb "subtractive", la sala guanya. +lighting: + mode: additive + level: 1.0 + emitters: + torches: + radius: 23 + color: [255, 170, 60] + flicker_params: + wave_amplitude_ratio: 0.04 + wave_frequency_hz: 3.0 + noise_amplitude_ratio: 0.025 + noise_frequency_hz: 0 + players: false + mummies: false diff --git a/data/maps/p3/r1.yaml b/data/maps/p3/r1.yaml index 2e26bca..b4c73b6 100644 --- a/data/maps/p3/r1.yaml +++ b/data/maps/p3/r1.yaml @@ -1,33 +1,4 @@ -# Mapa de la piràmide: graella 21×15 de tiles 16×16 sobre pyramid_3.gif. -# Overscan horitzontal: 8 px per banda (les parets laterals ocupen 2 tiles -# en el tilemap però només 1.5 visibles al canvas, així que la textura es -# dibuixa amb un origen de x=-8). Vertical no cal overscan: 15·16 = 240. -# -# Format del tilemap: -# `data` és una llista de files; cada fila és una llista d'índexs del -# tileset (lineal esq→dre, dalt→baix). Amb un tileset de 512×256 i tiles -# de 16×16 hi ha 32 tiles per fila. Un valor negatiu (p.ex. -1) deixa -# la cel·la buida (transparent), útil per caselles que ocuparà un actor. - -pyramid: 3 room: 1 -tileset: data/tilesets/pyramid_3.gif -tile_size: 16 -origin: [-8, 0] - -# Índex de tile amb què cada jugador deixa rastre en trepitjar un sòl -# pintable. Un índex per jugador perquè a multijugador local el recorregut -# es distingeix a simple vista. Provisional fins que l'art del pintat -# estigui definit; canviar aquí l'índex és tot el que cal. Omet el camp -# per desactivar el pintat per a aquest jugador. -player1_paint_tile: 0 -player2_paint_tile: 1 - -# Física del contacte entre jugadors. Quan un jugador està quiet i l'altre -# el topa, el segon l'empenta a aquesta fracció de la velocitat normal (i -# ell mateix es ralentitza per mantenir el grup). En head-on, ambdós -# s'anul·len (sense push, sense moviment). -push_factor: 0.30 # Geometria lògica de la piràmide (separada del render visual del tileset). # La graella de sarcòfags, el pitch entre ells i les amplades dels murs diff --git a/data/maps/p3/r2.yaml b/data/maps/p3/r2.yaml index dc002bb..d8e8c41 100644 --- a/data/maps/p3/r2.yaml +++ b/data/maps/p3/r2.yaml @@ -1,33 +1,4 @@ -# Mapa de la piràmide: graella 21×15 de tiles 16×16 sobre pyramid_3.gif. -# Overscan horitzontal: 8 px per banda (les parets laterals ocupen 2 tiles -# en el tilemap però només 1.5 visibles al canvas, així que la textura es -# dibuixa amb un origen de x=-8). Vertical no cal overscan: 15·16 = 240. -# -# Format del tilemap: -# `data` és una llista de files; cada fila és una llista d'índexs del -# tileset (lineal esq→dre, dalt→baix). Amb un tileset de 512×256 i tiles -# de 16×16 hi ha 32 tiles per fila. Un valor negatiu (p.ex. -1) deixa -# la cel·la buida (transparent), útil per caselles que ocuparà un actor. - -pyramid: 3 room: 2 -tileset: data/tilesets/pyramid_3.gif -tile_size: 16 -origin: [-8, 0] - -# Índex de tile amb què cada jugador deixa rastre en trepitjar un sòl -# pintable. Un índex per jugador perquè a multijugador local el recorregut -# es distingeix a simple vista. Provisional fins que l'art del pintat -# estigui definit; canviar aquí l'índex és tot el que cal. Omet el camp -# per desactivar el pintat per a aquest jugador. -player1_paint_tile: 0 -player2_paint_tile: 1 - -# Física del contacte entre jugadors. Quan un jugador està quiet i l'altre -# el topa, el segon l'empenta a aquesta fracció de la velocitat normal (i -# ell mateix es ralentitza per mantenir el grup). En head-on, ambdós -# s'anul·len (sense push, sense moviment). -push_factor: 0.30 # Geometria lògica de la piràmide (separada del render visual del tileset). # La graella de sarcòfags, el pitch entre ells i les amplades dels murs diff --git a/data/maps/p3/r3.yaml b/data/maps/p3/r3.yaml index 95dc0e2..788a809 100644 --- a/data/maps/p3/r3.yaml +++ b/data/maps/p3/r3.yaml @@ -1,33 +1,4 @@ -# Mapa de la piràmide: graella 21×15 de tiles 16×16 sobre pyramid_3.gif. -# Overscan horitzontal: 8 px per banda (les parets laterals ocupen 2 tiles -# en el tilemap però només 1.5 visibles al canvas, així que la textura es -# dibuixa amb un origen de x=-8). Vertical no cal overscan: 15·16 = 240. -# -# Format del tilemap: -# `data` és una llista de files; cada fila és una llista d'índexs del -# tileset (lineal esq→dre, dalt→baix). Amb un tileset de 512×256 i tiles -# de 16×16 hi ha 32 tiles per fila. Un valor negatiu (p.ex. -1) deixa -# la cel·la buida (transparent), útil per caselles que ocuparà un actor. - -pyramid: 3 room: 3 -tileset: data/tilesets/pyramid_3.gif -tile_size: 16 -origin: [-8, 0] - -# Índex de tile amb què cada jugador deixa rastre en trepitjar un sòl -# pintable. Un índex per jugador perquè a multijugador local el recorregut -# es distingeix a simple vista. Provisional fins que l'art del pintat -# estigui definit; canviar aquí l'índex és tot el que cal. Omet el camp -# per desactivar el pintat per a aquest jugador. -player1_paint_tile: 0 -player2_paint_tile: 1 - -# Física del contacte entre jugadors. Quan un jugador està quiet i l'altre -# el topa, el segon l'empenta a aquesta fracció de la velocitat normal (i -# ell mateix es ralentitza per mantenir el grup). En head-on, ambdós -# s'anul·len (sense push, sense moviment). -push_factor: 0.30 # Geometria lògica de la piràmide (separada del render visual del tileset). # La graella de sarcòfags, el pitch entre ells i les amplades dels murs diff --git a/data/maps/p3/r4.yaml b/data/maps/p3/r4.yaml index 4c8fcc4..ad2a8d7 100644 --- a/data/maps/p3/r4.yaml +++ b/data/maps/p3/r4.yaml @@ -1,33 +1,4 @@ -# Mapa de la piràmide: graella 21×15 de tiles 16×16 sobre pyramid_3.gif. -# Overscan horitzontal: 8 px per banda (les parets laterals ocupen 2 tiles -# en el tilemap però només 1.5 visibles al canvas, així que la textura es -# dibuixa amb un origen de x=-8). Vertical no cal overscan: 15·16 = 240. -# -# Format del tilemap: -# `data` és una llista de files; cada fila és una llista d'índexs del -# tileset (lineal esq→dre, dalt→baix). Amb un tileset de 512×256 i tiles -# de 16×16 hi ha 32 tiles per fila. Un valor negatiu (p.ex. -1) deixa -# la cel·la buida (transparent), útil per caselles que ocuparà un actor. - -pyramid: 3 room: 4 -tileset: data/tilesets/pyramid_3.gif -tile_size: 16 -origin: [-8, 0] - -# Índex de tile amb què cada jugador deixa rastre en trepitjar un sòl -# pintable. Un índex per jugador perquè a multijugador local el recorregut -# es distingeix a simple vista. Provisional fins que l'art del pintat -# estigui definit; canviar aquí l'índex és tot el que cal. Omet el camp -# per desactivar el pintat per a aquest jugador. -player1_paint_tile: 0 -player2_paint_tile: 1 - -# Física del contacte entre jugadors. Quan un jugador està quiet i l'altre -# el topa, el segon l'empenta a aquesta fracció de la velocitat normal (i -# ell mateix es ralentitza per mantenir el grup). En head-on, ambdós -# s'anul·len (sense push, sense moviment). -push_factor: 0.30 # Geometria lògica de la piràmide (separada del render visual del tileset). # La graella de sarcòfags, el pitch entre ells i les amplades dels murs diff --git a/data/maps/p3/r5.yaml b/data/maps/p3/r5.yaml index 8dad574..d534f00 100644 --- a/data/maps/p3/r5.yaml +++ b/data/maps/p3/r5.yaml @@ -1,33 +1,4 @@ -# Mapa de la piràmide: graella 21×15 de tiles 16×16 sobre pyramid_3.gif. -# Overscan horitzontal: 8 px per banda (les parets laterals ocupen 2 tiles -# en el tilemap però només 1.5 visibles al canvas, així que la textura es -# dibuixa amb un origen de x=-8). Vertical no cal overscan: 15·16 = 240. -# -# Format del tilemap: -# `data` és una llista de files; cada fila és una llista d'índexs del -# tileset (lineal esq→dre, dalt→baix). Amb un tileset de 512×256 i tiles -# de 16×16 hi ha 32 tiles per fila. Un valor negatiu (p.ex. -1) deixa -# la cel·la buida (transparent), útil per caselles que ocuparà un actor. - -pyramid: 3 room: 5 -tileset: data/tilesets/pyramid_3.gif -tile_size: 16 -origin: [-8, 0] - -# Índex de tile amb què cada jugador deixa rastre en trepitjar un sòl -# pintable. Un índex per jugador perquè a multijugador local el recorregut -# es distingeix a simple vista. Provisional fins que l'art del pintat -# estigui definit; canviar aquí l'índex és tot el que cal. Omet el camp -# per desactivar el pintat per a aquest jugador. -player1_paint_tile: 0 -player2_paint_tile: 1 - -# Física del contacte entre jugadors. Quan un jugador està quiet i l'altre -# el topa, el segon l'empenta a aquesta fracció de la velocitat normal (i -# ell mateix es ralentitza per mantenir el grup). En head-on, ambdós -# s'anul·len (sense push, sense moviment). -push_factor: 0.30 # Geometria lògica de la piràmide (separada del render visual del tileset). # La graella de sarcòfags, el pitch entre ells i les amplades dels murs diff --git a/data/maps/p3/r6.yaml b/data/maps/p3/r6.yaml index 09006c1..5634c99 100644 --- a/data/maps/p3/r6.yaml +++ b/data/maps/p3/r6.yaml @@ -1,33 +1,4 @@ -# Mapa de la piràmide: graella 21×15 de tiles 16×16 sobre pyramid_3.gif. -# Overscan horitzontal: 8 px per banda (les parets laterals ocupen 2 tiles -# en el tilemap però només 1.5 visibles al canvas, així que la textura es -# dibuixa amb un origen de x=-8). Vertical no cal overscan: 15·16 = 240. -# -# Format del tilemap: -# `data` és una llista de files; cada fila és una llista d'índexs del -# tileset (lineal esq→dre, dalt→baix). Amb un tileset de 512×256 i tiles -# de 16×16 hi ha 32 tiles per fila. Un valor negatiu (p.ex. -1) deixa -# la cel·la buida (transparent), útil per caselles que ocuparà un actor. - -pyramid: 3 room: 6 -tileset: data/tilesets/pyramid_3.gif -tile_size: 16 -origin: [-8, 0] - -# Índex de tile amb què cada jugador deixa rastre en trepitjar un sòl -# pintable. Un índex per jugador perquè a multijugador local el recorregut -# es distingeix a simple vista. Provisional fins que l'art del pintat -# estigui definit; canviar aquí l'índex és tot el que cal. Omet el camp -# per desactivar el pintat per a aquest jugador. -player1_paint_tile: 0 -player2_paint_tile: 1 - -# Física del contacte entre jugadors. Quan un jugador està quiet i l'altre -# el topa, el segon l'empenta a aquesta fracció de la velocitat normal (i -# ell mateix es ralentitza per mantenir el grup). En head-on, ambdós -# s'anul·len (sense push, sense moviment). -push_factor: 0.30 # Geometria lògica de la piràmide (separada del render visual del tileset). # La graella de sarcòfags, el pitch entre ells i les amplades dels murs diff --git a/data/maps/p4/pyramid.yaml b/data/maps/p4/pyramid.yaml new file mode 100644 index 0000000..c8d6cbe --- /dev/null +++ b/data/maps/p4/pyramid.yaml @@ -0,0 +1,42 @@ +# Configuració compartida per totes les sales de la piràmide 4. Cada sala +# (r1..r6) hereta aquests camps via el merge recursiu de `RoomYaml::loadMerged`: +# el YAML de sala només declara el que canvia (room, geometry, data, entities, +# i opcionalment overrides puntuals de `lighting`). + +pyramid: 4 +tileset: data/tilesets/pyramid_4.gif +tile_size: 16 +origin: [-8, 0] + +# Índex de tile amb què cada jugador deixa rastre en trepitjar un sòl +# pintable. Un índex per jugador perquè a multijugador local el recorregut +# es distingeix a simple vista. Provisional fins que l'art del pintat +# estigui definit; canviar aquí l'índex és tot el que cal. Omet el camp +# per desactivar el pintat per a aquest jugador. +player1_paint_tile: 0 +player2_paint_tile: 1 + +# Física del contacte entre jugadors. Quan un jugador està quiet i l'altre +# el topa, el segon l'empenta a aquesta fracció de la velocitat normal (i +# ell mateix es ralentitza per mantenir el grup). En head-on, ambdós +# s'anul·len (sense push, sense moviment). +push_factor: 0.30 + +# Il·luminació per defecte: additive amb halos càlids subtils a les +# antorxes. Les sales que vulguin l'estil "fosc amb forats" (subtractive) +# poden redeclarar `lighting:` sencer; el merge no fusiona "additive" +# amb "subtractive", la sala guanya. +lighting: + mode: additive + level: 1.0 + emitters: + torches: + radius: 23 + color: [255, 170, 60] + flicker_params: + wave_amplitude_ratio: 0.04 + wave_frequency_hz: 3.0 + noise_amplitude_ratio: 0.025 + noise_frequency_hz: 0 + players: false + mummies: false diff --git a/data/maps/p4/r1.yaml b/data/maps/p4/r1.yaml index 6c75cc5..b4c73b6 100644 --- a/data/maps/p4/r1.yaml +++ b/data/maps/p4/r1.yaml @@ -1,33 +1,4 @@ -# Mapa de la piràmide: graella 21×15 de tiles 16×16 sobre pyramid_4.gif. -# Overscan horitzontal: 8 px per banda (les parets laterals ocupen 2 tiles -# en el tilemap però només 1.5 visibles al canvas, així que la textura es -# dibuixa amb un origen de x=-8). Vertical no cal overscan: 15·16 = 240. -# -# Format del tilemap: -# `data` és una llista de files; cada fila és una llista d'índexs del -# tileset (lineal esq→dre, dalt→baix). Amb un tileset de 512×256 i tiles -# de 16×16 hi ha 32 tiles per fila. Un valor negatiu (p.ex. -1) deixa -# la cel·la buida (transparent), útil per caselles que ocuparà un actor. - -pyramid: 4 room: 1 -tileset: data/tilesets/pyramid_4.gif -tile_size: 16 -origin: [-8, 0] - -# Índex de tile amb què cada jugador deixa rastre en trepitjar un sòl -# pintable. Un índex per jugador perquè a multijugador local el recorregut -# es distingeix a simple vista. Provisional fins que l'art del pintat -# estigui definit; canviar aquí l'índex és tot el que cal. Omet el camp -# per desactivar el pintat per a aquest jugador. -player1_paint_tile: 0 -player2_paint_tile: 1 - -# Física del contacte entre jugadors. Quan un jugador està quiet i l'altre -# el topa, el segon l'empenta a aquesta fracció de la velocitat normal (i -# ell mateix es ralentitza per mantenir el grup). En head-on, ambdós -# s'anul·len (sense push, sense moviment). -push_factor: 0.30 # Geometria lògica de la piràmide (separada del render visual del tileset). # La graella de sarcòfags, el pitch entre ells i les amplades dels murs diff --git a/data/maps/p4/r2.yaml b/data/maps/p4/r2.yaml index a6577d8..d8e8c41 100644 --- a/data/maps/p4/r2.yaml +++ b/data/maps/p4/r2.yaml @@ -1,33 +1,4 @@ -# Mapa de la piràmide: graella 21×15 de tiles 16×16 sobre pyramid_4.gif. -# Overscan horitzontal: 8 px per banda (les parets laterals ocupen 2 tiles -# en el tilemap però només 1.5 visibles al canvas, així que la textura es -# dibuixa amb un origen de x=-8). Vertical no cal overscan: 15·16 = 240. -# -# Format del tilemap: -# `data` és una llista de files; cada fila és una llista d'índexs del -# tileset (lineal esq→dre, dalt→baix). Amb un tileset de 512×256 i tiles -# de 16×16 hi ha 32 tiles per fila. Un valor negatiu (p.ex. -1) deixa -# la cel·la buida (transparent), útil per caselles que ocuparà un actor. - -pyramid: 4 room: 2 -tileset: data/tilesets/pyramid_4.gif -tile_size: 16 -origin: [-8, 0] - -# Índex de tile amb què cada jugador deixa rastre en trepitjar un sòl -# pintable. Un índex per jugador perquè a multijugador local el recorregut -# es distingeix a simple vista. Provisional fins que l'art del pintat -# estigui definit; canviar aquí l'índex és tot el que cal. Omet el camp -# per desactivar el pintat per a aquest jugador. -player1_paint_tile: 0 -player2_paint_tile: 1 - -# Física del contacte entre jugadors. Quan un jugador està quiet i l'altre -# el topa, el segon l'empenta a aquesta fracció de la velocitat normal (i -# ell mateix es ralentitza per mantenir el grup). En head-on, ambdós -# s'anul·len (sense push, sense moviment). -push_factor: 0.30 # Geometria lògica de la piràmide (separada del render visual del tileset). # La graella de sarcòfags, el pitch entre ells i les amplades dels murs diff --git a/data/maps/p4/r3.yaml b/data/maps/p4/r3.yaml index 39189ba..788a809 100644 --- a/data/maps/p4/r3.yaml +++ b/data/maps/p4/r3.yaml @@ -1,33 +1,4 @@ -# Mapa de la piràmide: graella 21×15 de tiles 16×16 sobre pyramid_4.gif. -# Overscan horitzontal: 8 px per banda (les parets laterals ocupen 2 tiles -# en el tilemap però només 1.5 visibles al canvas, així que la textura es -# dibuixa amb un origen de x=-8). Vertical no cal overscan: 15·16 = 240. -# -# Format del tilemap: -# `data` és una llista de files; cada fila és una llista d'índexs del -# tileset (lineal esq→dre, dalt→baix). Amb un tileset de 512×256 i tiles -# de 16×16 hi ha 32 tiles per fila. Un valor negatiu (p.ex. -1) deixa -# la cel·la buida (transparent), útil per caselles que ocuparà un actor. - -pyramid: 4 room: 3 -tileset: data/tilesets/pyramid_4.gif -tile_size: 16 -origin: [-8, 0] - -# Índex de tile amb què cada jugador deixa rastre en trepitjar un sòl -# pintable. Un índex per jugador perquè a multijugador local el recorregut -# es distingeix a simple vista. Provisional fins que l'art del pintat -# estigui definit; canviar aquí l'índex és tot el que cal. Omet el camp -# per desactivar el pintat per a aquest jugador. -player1_paint_tile: 0 -player2_paint_tile: 1 - -# Física del contacte entre jugadors. Quan un jugador està quiet i l'altre -# el topa, el segon l'empenta a aquesta fracció de la velocitat normal (i -# ell mateix es ralentitza per mantenir el grup). En head-on, ambdós -# s'anul·len (sense push, sense moviment). -push_factor: 0.30 # Geometria lògica de la piràmide (separada del render visual del tileset). # La graella de sarcòfags, el pitch entre ells i les amplades dels murs diff --git a/data/maps/p4/r4.yaml b/data/maps/p4/r4.yaml index 95e62dd..ad2a8d7 100644 --- a/data/maps/p4/r4.yaml +++ b/data/maps/p4/r4.yaml @@ -1,33 +1,4 @@ -# Mapa de la piràmide: graella 21×15 de tiles 16×16 sobre pyramid_4.gif. -# Overscan horitzontal: 8 px per banda (les parets laterals ocupen 2 tiles -# en el tilemap però només 1.5 visibles al canvas, així que la textura es -# dibuixa amb un origen de x=-8). Vertical no cal overscan: 15·16 = 240. -# -# Format del tilemap: -# `data` és una llista de files; cada fila és una llista d'índexs del -# tileset (lineal esq→dre, dalt→baix). Amb un tileset de 512×256 i tiles -# de 16×16 hi ha 32 tiles per fila. Un valor negatiu (p.ex. -1) deixa -# la cel·la buida (transparent), útil per caselles que ocuparà un actor. - -pyramid: 4 room: 4 -tileset: data/tilesets/pyramid_4.gif -tile_size: 16 -origin: [-8, 0] - -# Índex de tile amb què cada jugador deixa rastre en trepitjar un sòl -# pintable. Un índex per jugador perquè a multijugador local el recorregut -# es distingeix a simple vista. Provisional fins que l'art del pintat -# estigui definit; canviar aquí l'índex és tot el que cal. Omet el camp -# per desactivar el pintat per a aquest jugador. -player1_paint_tile: 0 -player2_paint_tile: 1 - -# Física del contacte entre jugadors. Quan un jugador està quiet i l'altre -# el topa, el segon l'empenta a aquesta fracció de la velocitat normal (i -# ell mateix es ralentitza per mantenir el grup). En head-on, ambdós -# s'anul·len (sense push, sense moviment). -push_factor: 0.30 # Geometria lògica de la piràmide (separada del render visual del tileset). # La graella de sarcòfags, el pitch entre ells i les amplades dels murs diff --git a/data/maps/p4/r5.yaml b/data/maps/p4/r5.yaml index b356412..d534f00 100644 --- a/data/maps/p4/r5.yaml +++ b/data/maps/p4/r5.yaml @@ -1,33 +1,4 @@ -# Mapa de la piràmide: graella 21×15 de tiles 16×16 sobre pyramid_4.gif. -# Overscan horitzontal: 8 px per banda (les parets laterals ocupen 2 tiles -# en el tilemap però només 1.5 visibles al canvas, així que la textura es -# dibuixa amb un origen de x=-8). Vertical no cal overscan: 15·16 = 240. -# -# Format del tilemap: -# `data` és una llista de files; cada fila és una llista d'índexs del -# tileset (lineal esq→dre, dalt→baix). Amb un tileset de 512×256 i tiles -# de 16×16 hi ha 32 tiles per fila. Un valor negatiu (p.ex. -1) deixa -# la cel·la buida (transparent), útil per caselles que ocuparà un actor. - -pyramid: 4 room: 5 -tileset: data/tilesets/pyramid_4.gif -tile_size: 16 -origin: [-8, 0] - -# Índex de tile amb què cada jugador deixa rastre en trepitjar un sòl -# pintable. Un índex per jugador perquè a multijugador local el recorregut -# es distingeix a simple vista. Provisional fins que l'art del pintat -# estigui definit; canviar aquí l'índex és tot el que cal. Omet el camp -# per desactivar el pintat per a aquest jugador. -player1_paint_tile: 0 -player2_paint_tile: 1 - -# Física del contacte entre jugadors. Quan un jugador està quiet i l'altre -# el topa, el segon l'empenta a aquesta fracció de la velocitat normal (i -# ell mateix es ralentitza per mantenir el grup). En head-on, ambdós -# s'anul·len (sense push, sense moviment). -push_factor: 0.30 # Geometria lògica de la piràmide (separada del render visual del tileset). # La graella de sarcòfags, el pitch entre ells i les amplades dels murs diff --git a/data/maps/p4/r6.yaml b/data/maps/p4/r6.yaml index b098c80..5634c99 100644 --- a/data/maps/p4/r6.yaml +++ b/data/maps/p4/r6.yaml @@ -1,33 +1,4 @@ -# Mapa de la piràmide: graella 21×15 de tiles 16×16 sobre pyramid_4.gif. -# Overscan horitzontal: 8 px per banda (les parets laterals ocupen 2 tiles -# en el tilemap però només 1.5 visibles al canvas, així que la textura es -# dibuixa amb un origen de x=-8). Vertical no cal overscan: 15·16 = 240. -# -# Format del tilemap: -# `data` és una llista de files; cada fila és una llista d'índexs del -# tileset (lineal esq→dre, dalt→baix). Amb un tileset de 512×256 i tiles -# de 16×16 hi ha 32 tiles per fila. Un valor negatiu (p.ex. -1) deixa -# la cel·la buida (transparent), útil per caselles que ocuparà un actor. - -pyramid: 4 room: 6 -tileset: data/tilesets/pyramid_4.gif -tile_size: 16 -origin: [-8, 0] - -# Índex de tile amb què cada jugador deixa rastre en trepitjar un sòl -# pintable. Un índex per jugador perquè a multijugador local el recorregut -# es distingeix a simple vista. Provisional fins que l'art del pintat -# estigui definit; canviar aquí l'índex és tot el que cal. Omet el camp -# per desactivar el pintat per a aquest jugador. -player1_paint_tile: 0 -player2_paint_tile: 1 - -# Física del contacte entre jugadors. Quan un jugador està quiet i l'altre -# el topa, el segon l'empenta a aquesta fracció de la velocitat normal (i -# ell mateix es ralentitza per mantenir el grup). En head-on, ambdós -# s'anul·len (sense push, sense moviment). -push_factor: 0.30 # Geometria lògica de la piràmide (separada del render visual del tileset). # La graella de sarcòfags, el pitch entre ells i les amplades dels murs diff --git a/data/maps/p5/pyramid.yaml b/data/maps/p5/pyramid.yaml new file mode 100644 index 0000000..46820ca --- /dev/null +++ b/data/maps/p5/pyramid.yaml @@ -0,0 +1,42 @@ +# Configuració compartida per totes les sales de la piràmide 5. Cada sala +# (r1..r6) hereta aquests camps via el merge recursiu de `RoomYaml::loadMerged`: +# el YAML de sala només declara el que canvia (room, geometry, data, entities, +# i opcionalment overrides puntuals de `lighting`). + +pyramid: 5 +tileset: data/tilesets/pyramid_5.gif +tile_size: 16 +origin: [-8, 0] + +# Índex de tile amb què cada jugador deixa rastre en trepitjar un sòl +# pintable. Un índex per jugador perquè a multijugador local el recorregut +# es distingeix a simple vista. Provisional fins que l'art del pintat +# estigui definit; canviar aquí l'índex és tot el que cal. Omet el camp +# per desactivar el pintat per a aquest jugador. +player1_paint_tile: 0 +player2_paint_tile: 1 + +# Física del contacte entre jugadors. Quan un jugador està quiet i l'altre +# el topa, el segon l'empenta a aquesta fracció de la velocitat normal (i +# ell mateix es ralentitza per mantenir el grup). En head-on, ambdós +# s'anul·len (sense push, sense moviment). +push_factor: 0.30 + +# Il·luminació per defecte: additive amb halos càlids subtils a les +# antorxes. Les sales que vulguin l'estil "fosc amb forats" (subtractive) +# poden redeclarar `lighting:` sencer; el merge no fusiona "additive" +# amb "subtractive", la sala guanya. +lighting: + mode: additive + level: 1.0 + emitters: + torches: + radius: 23 + color: [255, 170, 60] + flicker_params: + wave_amplitude_ratio: 0.04 + wave_frequency_hz: 3.0 + noise_amplitude_ratio: 0.025 + noise_frequency_hz: 0 + players: false + mummies: false diff --git a/data/maps/p5/r1.yaml b/data/maps/p5/r1.yaml index 2410820..b4c73b6 100644 --- a/data/maps/p5/r1.yaml +++ b/data/maps/p5/r1.yaml @@ -1,33 +1,4 @@ -# Mapa de la piràmide: graella 21×15 de tiles 16×16 sobre pyramid_5.gif. -# Overscan horitzontal: 8 px per banda (les parets laterals ocupen 2 tiles -# en el tilemap però només 1.5 visibles al canvas, així que la textura es -# dibuixa amb un origen de x=-8). Vertical no cal overscan: 15·16 = 240. -# -# Format del tilemap: -# `data` és una llista de files; cada fila és una llista d'índexs del -# tileset (lineal esq→dre, dalt→baix). Amb un tileset de 512×256 i tiles -# de 16×16 hi ha 32 tiles per fila. Un valor negatiu (p.ex. -1) deixa -# la cel·la buida (transparent), útil per caselles que ocuparà un actor. - -pyramid: 5 room: 1 -tileset: data/tilesets/pyramid_5.gif -tile_size: 16 -origin: [-8, 0] - -# Índex de tile amb què cada jugador deixa rastre en trepitjar un sòl -# pintable. Un índex per jugador perquè a multijugador local el recorregut -# es distingeix a simple vista. Provisional fins que l'art del pintat -# estigui definit; canviar aquí l'índex és tot el que cal. Omet el camp -# per desactivar el pintat per a aquest jugador. -player1_paint_tile: 0 -player2_paint_tile: 1 - -# Física del contacte entre jugadors. Quan un jugador està quiet i l'altre -# el topa, el segon l'empenta a aquesta fracció de la velocitat normal (i -# ell mateix es ralentitza per mantenir el grup). En head-on, ambdós -# s'anul·len (sense push, sense moviment). -push_factor: 0.30 # Geometria lògica de la piràmide (separada del render visual del tileset). # La graella de sarcòfags, el pitch entre ells i les amplades dels murs diff --git a/data/maps/p5/r2.yaml b/data/maps/p5/r2.yaml index c3664ec..d8e8c41 100644 --- a/data/maps/p5/r2.yaml +++ b/data/maps/p5/r2.yaml @@ -1,33 +1,4 @@ -# Mapa de la piràmide: graella 21×15 de tiles 16×16 sobre pyramid_5.gif. -# Overscan horitzontal: 8 px per banda (les parets laterals ocupen 2 tiles -# en el tilemap però només 1.5 visibles al canvas, així que la textura es -# dibuixa amb un origen de x=-8). Vertical no cal overscan: 15·16 = 240. -# -# Format del tilemap: -# `data` és una llista de files; cada fila és una llista d'índexs del -# tileset (lineal esq→dre, dalt→baix). Amb un tileset de 512×256 i tiles -# de 16×16 hi ha 32 tiles per fila. Un valor negatiu (p.ex. -1) deixa -# la cel·la buida (transparent), útil per caselles que ocuparà un actor. - -pyramid: 5 room: 2 -tileset: data/tilesets/pyramid_5.gif -tile_size: 16 -origin: [-8, 0] - -# Índex de tile amb què cada jugador deixa rastre en trepitjar un sòl -# pintable. Un índex per jugador perquè a multijugador local el recorregut -# es distingeix a simple vista. Provisional fins que l'art del pintat -# estigui definit; canviar aquí l'índex és tot el que cal. Omet el camp -# per desactivar el pintat per a aquest jugador. -player1_paint_tile: 0 -player2_paint_tile: 1 - -# Física del contacte entre jugadors. Quan un jugador està quiet i l'altre -# el topa, el segon l'empenta a aquesta fracció de la velocitat normal (i -# ell mateix es ralentitza per mantenir el grup). En head-on, ambdós -# s'anul·len (sense push, sense moviment). -push_factor: 0.30 # Geometria lògica de la piràmide (separada del render visual del tileset). # La graella de sarcòfags, el pitch entre ells i les amplades dels murs diff --git a/data/maps/p5/r3.yaml b/data/maps/p5/r3.yaml index 094fea7..788a809 100644 --- a/data/maps/p5/r3.yaml +++ b/data/maps/p5/r3.yaml @@ -1,33 +1,4 @@ -# Mapa de la piràmide: graella 21×15 de tiles 16×16 sobre pyramid_5.gif. -# Overscan horitzontal: 8 px per banda (les parets laterals ocupen 2 tiles -# en el tilemap però només 1.5 visibles al canvas, així que la textura es -# dibuixa amb un origen de x=-8). Vertical no cal overscan: 15·16 = 240. -# -# Format del tilemap: -# `data` és una llista de files; cada fila és una llista d'índexs del -# tileset (lineal esq→dre, dalt→baix). Amb un tileset de 512×256 i tiles -# de 16×16 hi ha 32 tiles per fila. Un valor negatiu (p.ex. -1) deixa -# la cel·la buida (transparent), útil per caselles que ocuparà un actor. - -pyramid: 5 room: 3 -tileset: data/tilesets/pyramid_5.gif -tile_size: 16 -origin: [-8, 0] - -# Índex de tile amb què cada jugador deixa rastre en trepitjar un sòl -# pintable. Un índex per jugador perquè a multijugador local el recorregut -# es distingeix a simple vista. Provisional fins que l'art del pintat -# estigui definit; canviar aquí l'índex és tot el que cal. Omet el camp -# per desactivar el pintat per a aquest jugador. -player1_paint_tile: 0 -player2_paint_tile: 1 - -# Física del contacte entre jugadors. Quan un jugador està quiet i l'altre -# el topa, el segon l'empenta a aquesta fracció de la velocitat normal (i -# ell mateix es ralentitza per mantenir el grup). En head-on, ambdós -# s'anul·len (sense push, sense moviment). -push_factor: 0.30 # Geometria lògica de la piràmide (separada del render visual del tileset). # La graella de sarcòfags, el pitch entre ells i les amplades dels murs diff --git a/data/maps/p5/r4.yaml b/data/maps/p5/r4.yaml index e74ba8a..ad2a8d7 100644 --- a/data/maps/p5/r4.yaml +++ b/data/maps/p5/r4.yaml @@ -1,33 +1,4 @@ -# Mapa de la piràmide: graella 21×15 de tiles 16×16 sobre pyramid_5.gif. -# Overscan horitzontal: 8 px per banda (les parets laterals ocupen 2 tiles -# en el tilemap però només 1.5 visibles al canvas, així que la textura es -# dibuixa amb un origen de x=-8). Vertical no cal overscan: 15·16 = 240. -# -# Format del tilemap: -# `data` és una llista de files; cada fila és una llista d'índexs del -# tileset (lineal esq→dre, dalt→baix). Amb un tileset de 512×256 i tiles -# de 16×16 hi ha 32 tiles per fila. Un valor negatiu (p.ex. -1) deixa -# la cel·la buida (transparent), útil per caselles que ocuparà un actor. - -pyramid: 5 room: 4 -tileset: data/tilesets/pyramid_5.gif -tile_size: 16 -origin: [-8, 0] - -# Índex de tile amb què cada jugador deixa rastre en trepitjar un sòl -# pintable. Un índex per jugador perquè a multijugador local el recorregut -# es distingeix a simple vista. Provisional fins que l'art del pintat -# estigui definit; canviar aquí l'índex és tot el que cal. Omet el camp -# per desactivar el pintat per a aquest jugador. -player1_paint_tile: 0 -player2_paint_tile: 1 - -# Física del contacte entre jugadors. Quan un jugador està quiet i l'altre -# el topa, el segon l'empenta a aquesta fracció de la velocitat normal (i -# ell mateix es ralentitza per mantenir el grup). En head-on, ambdós -# s'anul·len (sense push, sense moviment). -push_factor: 0.30 # Geometria lògica de la piràmide (separada del render visual del tileset). # La graella de sarcòfags, el pitch entre ells i les amplades dels murs diff --git a/data/maps/p5/r5.yaml b/data/maps/p5/r5.yaml index 6ea2795..d534f00 100644 --- a/data/maps/p5/r5.yaml +++ b/data/maps/p5/r5.yaml @@ -1,33 +1,4 @@ -# Mapa de la piràmide: graella 21×15 de tiles 16×16 sobre pyramid_5.gif. -# Overscan horitzontal: 8 px per banda (les parets laterals ocupen 2 tiles -# en el tilemap però només 1.5 visibles al canvas, així que la textura es -# dibuixa amb un origen de x=-8). Vertical no cal overscan: 15·16 = 240. -# -# Format del tilemap: -# `data` és una llista de files; cada fila és una llista d'índexs del -# tileset (lineal esq→dre, dalt→baix). Amb un tileset de 512×256 i tiles -# de 16×16 hi ha 32 tiles per fila. Un valor negatiu (p.ex. -1) deixa -# la cel·la buida (transparent), útil per caselles que ocuparà un actor. - -pyramid: 5 room: 5 -tileset: data/tilesets/pyramid_5.gif -tile_size: 16 -origin: [-8, 0] - -# Índex de tile amb què cada jugador deixa rastre en trepitjar un sòl -# pintable. Un índex per jugador perquè a multijugador local el recorregut -# es distingeix a simple vista. Provisional fins que l'art del pintat -# estigui definit; canviar aquí l'índex és tot el que cal. Omet el camp -# per desactivar el pintat per a aquest jugador. -player1_paint_tile: 0 -player2_paint_tile: 1 - -# Física del contacte entre jugadors. Quan un jugador està quiet i l'altre -# el topa, el segon l'empenta a aquesta fracció de la velocitat normal (i -# ell mateix es ralentitza per mantenir el grup). En head-on, ambdós -# s'anul·len (sense push, sense moviment). -push_factor: 0.30 # Geometria lògica de la piràmide (separada del render visual del tileset). # La graella de sarcòfags, el pitch entre ells i les amplades dels murs diff --git a/data/maps/p5/r6.yaml b/data/maps/p5/r6.yaml index 2f92c2f..5634c99 100644 --- a/data/maps/p5/r6.yaml +++ b/data/maps/p5/r6.yaml @@ -1,33 +1,4 @@ -# Mapa de la piràmide: graella 21×15 de tiles 16×16 sobre pyramid_5.gif. -# Overscan horitzontal: 8 px per banda (les parets laterals ocupen 2 tiles -# en el tilemap però només 1.5 visibles al canvas, així que la textura es -# dibuixa amb un origen de x=-8). Vertical no cal overscan: 15·16 = 240. -# -# Format del tilemap: -# `data` és una llista de files; cada fila és una llista d'índexs del -# tileset (lineal esq→dre, dalt→baix). Amb un tileset de 512×256 i tiles -# de 16×16 hi ha 32 tiles per fila. Un valor negatiu (p.ex. -1) deixa -# la cel·la buida (transparent), útil per caselles que ocuparà un actor. - -pyramid: 5 room: 6 -tileset: data/tilesets/pyramid_5.gif -tile_size: 16 -origin: [-8, 0] - -# Índex de tile amb què cada jugador deixa rastre en trepitjar un sòl -# pintable. Un índex per jugador perquè a multijugador local el recorregut -# es distingeix a simple vista. Provisional fins que l'art del pintat -# estigui definit; canviar aquí l'índex és tot el que cal. Omet el camp -# per desactivar el pintat per a aquest jugador. -player1_paint_tile: 0 -player2_paint_tile: 1 - -# Física del contacte entre jugadors. Quan un jugador està quiet i l'altre -# el topa, el segon l'empenta a aquesta fracció de la velocitat normal (i -# ell mateix es ralentitza per mantenir el grup). En head-on, ambdós -# s'anul·len (sense push, sense moviment). -push_factor: 0.30 # Geometria lògica de la piràmide (separada del render visual del tileset). # La graella de sarcòfags, el pitch entre ells i les amplades dels murs diff --git a/data/maps/pyramid.yaml b/data/maps/pyramid.yaml deleted file mode 100644 index e8976f9..0000000 --- a/data/maps/pyramid.yaml +++ /dev/null @@ -1,138 +0,0 @@ -# Mapa de la piràmide: graella 21×15 de tiles 16×16 sobre tomb.gif. -# Overscan horitzontal: 8 px per banda (les parets laterals ocupen 2 tiles -# en el tilemap però només 1.5 visibles al canvas, així que la textura es -# dibuixa amb un origen de x=-8). Vertical no cal overscan: 15·16 = 240. -# -# Format del tilemap: -# `data` és una llista de files; cada fila és una llista d'índexs del -# tileset (lineal esq→dre, dalt→baix). Amb un tileset de 512×256 i tiles -# de 16×16 hi ha 32 tiles per fila. Un valor negatiu (p.ex. -1) deixa -# la cel·la buida (transparent), útil per caselles que ocuparà un actor. - -tileset: data/tilesets/tomb.gif -tile_size: 16 -origin: [-8, 0] - -# Índex de tile amb què cada jugador deixa rastre en trepitjar un sòl -# pintable. Un índex per jugador perquè a multijugador local el recorregut -# es distingeix a simple vista. Provisional fins que l'art del pintat -# estigui definit; canviar aquí l'índex és tot el que cal. Omet el camp -# per desactivar el pintat per a aquest jugador. -player1_paint_tile: 0 -player2_paint_tile: 1 - -# Física del contacte entre jugadors. Quan un jugador està quiet i l'altre -# el topa, el segon l'empenta a aquesta fracció de la velocitat normal (i -# ell mateix es ralentitza per mantenir el grup). En head-on, ambdós -# s'anul·len (sense push, sense moviment). -push_factor: 0.30 - -# Geometria lògica de la piràmide (separada del render visual del tileset). -# La graella de sarcòfags, el pitch entre ells i les amplades dels murs -# decideixen els límits del jugador i les seues caixes de col·lisió. Abans -# vivien com a `static constexpr` a map.hpp; ara cada piràmide pot definir -# la seua pròpia forma sense recompilar. -geometry: - grid_cols: 4 - grid_rows: 5 - sarc_w: 48 - sarc_h: 16 - pitch_x: 64 - pitch_y: 32 - hud_h: 24 - back_wall_h: 24 - side_wall_w: 24 - # Columna central del tile transitable de la porta. La porta es renderitza - # com a sprite 48×32 (3 tiles d'amplada) centrat sobre aquesta columna; els - # 16 px centrals (just aquesta columna) són el "forat" del mur trasser per - # on el jugador surt de la sala. Les 2 columnes flanquejants segueixen sent - # mur visible. El spawn dels jugadors també s'alinea amb aquesta columna. - door_col: 10 - -data: - - [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] - - [ 1, 91,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105, 92, 1] - - [ 1, 98,113,113, 95,113, 94,113,113,113,113,113,113,113, 94,113,102,113,113, 96, 1] - - [ 1, 98, 8, 8, 6, 8, 17, 8, 10, 8, 17, 8, 8, 8, 17, 8, 8, 8, 8, 96, 1] - - [ 1, 98, 8, 2, 2, 2, 8, 2, 2, 2, 8, 2, 2, 2, 8, 2, 2, 2, 8, 96, 1] - - [ 1, 98, 17, 8, 9, 2, 8, 10, 8, 8, 8, 8, 10, 8, 8, 26, 8, 8, 17, 96, 1] - - [ 1, 98, 8, 2, 2, 2, 2, 2, 2, 2, 8, 2, 2, 2, 8, 2, 2, 2, 8, 96, 1] - - [ 1, 98, 17, 8, 8, 26, 8, 8, 9, 8, 8, 8, 8, 8, 10, 8, 6, 8, 17, 96, 1] - - [ 1, 98, 8, 2, 2, 2, 8, 2, 2, 2, 8, 2, 2, 2, 8, 2, 2, 2, 8, 96, 1] - - [ 1, 98, 17, 8, 10, 8, 8, 8, 2, 8, 8, 8, 9, 8, 8, 8, 10, 8, 17, 96, 1] - - [ 1, 98, 8, 2, 2, 2, 8, 2, 2, 2, 6, 2, 2, 2, 8, 2, 2, 2, 8, 96, 1] - - [ 1, 98, 17, 8, 10, 8, 8, 10, 2, 8, 8, 26, 8, 8, 8, 8, 10, 8, 17, 96, 1] - - [ 1, 98, 8, 2, 2, 2, 8, 2, 2, 2, 8, 2, 2, 2, 8, 2, 2, 2, 8, 96, 1] - - [ 1, 98, 8, 10, 6, 6, 17, 8, 8, 8, 17, 8, 9, 8, 17, 8, 2, 8, 8, 96, 1] - - [ 1, 99, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,100, 1] - -# Spawns d'entitats per a aquest nivell. Es llegeixen des de -# EntityManager::loadFromLevel al GameScene. Convencions: -# - sarcophagus → `sarc_position: [sarc_col, sarc_row]` en la graella de -# sarcòfags (4×5). EntityManager calcula el rect píxel via -# Map::getSarcRect i l'ancoratge de tile per al perímetre. -# - la resta (torch, door, mummy, rolling_rock, wall_trap, floor_trap) -# → `position: [tile_col, tile_row]` en coordenades del tilemap -# (origen `[-8, 0]` per defecte). Pixel = tile*16 + tilemap_origin. -# -# Dos sarcòfags en cantonades oposades → perímetres aïllats (cap tile en -# comú). La porta va al centre inferior, on el tilemap té els tiles -# d'obertura (262/263). La momia al corredor central. L'antorxa al costat -# superior esquerre per verificar render d'una entitat decorativa. -entities: - - type: torch - position: [4, 2] - - type: torch - position: [8, 2] - - type: torch - position: [12, 2] - - type: torch - position: [16, 2] - - type: sarcophagus - sarc_position: [0, 0] - - type: sarcophagus - sarc_position: [1, 0] - - type: sarcophagus - sarc_position: [2, 0] - - type: sarcophagus - sarc_position: [3, 0] - - type: sarcophagus - sarc_position: [0, 1] - - type: sarcophagus - sarc_position: [1, 1] - - type: sarcophagus - sarc_position: [2, 1] - - type: sarcophagus - sarc_position: [3, 1] - - type: sarcophagus - sarc_position: [0, 2] - - type: sarcophagus - sarc_position: [1, 2] - - type: sarcophagus - sarc_position: [2, 2] - - type: sarcophagus - sarc_position: [3, 2] - - type: sarcophagus - sarc_position: [0, 3] - - type: sarcophagus - sarc_position: [1, 3] - - type: sarcophagus - sarc_position: [2, 3] - - type: sarcophagus - sarc_position: [3, 3] - - type: sarcophagus - sarc_position: [0, 4] - - type: sarcophagus - sarc_position: [1, 4] - - type: sarcophagus - sarc_position: [2, 4] - - type: sarcophagus - sarc_position: [3, 4] - - type: door - # Sense `position`: la porta sempre viu al mur trasser. La columna - # transitable la dicta `geometry.door_col`; el render i la caixa - # de col·lisió es deriven d'aquesta dada al loadFromLevel. - - type: mummy - position: [10, 7] - - type: mummy - position: [7, 9] diff --git a/source/game/entities/entity_loader.cpp b/source/game/entities/entity_loader.cpp index f03d7e3..934ed25 100644 --- a/source/game/entities/entity_loader.cpp +++ b/source/game/entities/entity_loader.cpp @@ -6,6 +6,7 @@ #include "core/resources/resource_helper.hpp" #include "game/entities/entity.hpp" #include "game/entities/entity_factory.hpp" +#include "game/map/room_yaml.hpp" #include "utils/defaults.hpp" namespace EntityLoader { @@ -44,13 +45,7 @@ namespace EntityLoader { } auto readSpawns(const std::string& level_yaml_path) -> std::vector { - auto bytes = Resource::Helper::loadFile(level_yaml_path); - if (bytes.empty()) { - throw std::runtime_error("EntityLoader: no s'ha pogut obrir " + level_yaml_path); - } - const auto* begin = reinterpret_cast(bytes.data()); - const auto* end = begin + bytes.size(); - fkyaml::node root = fkyaml::node::deserialize(begin, end); + fkyaml::node root = RoomYaml::loadMerged(level_yaml_path); std::vector spawns; if (!root.contains("entities")) { return spawns; } const auto& list = root["entities"]; diff --git a/source/game/map/map.cpp b/source/game/map/map.cpp index e4986c4..3dc72e4 100644 --- a/source/game/map/map.cpp +++ b/source/game/map/map.cpp @@ -5,8 +5,8 @@ #include #include -#include "core/resources/resource_helper.hpp" #include "external/fkyaml_node.hpp" +#include "game/map/room_yaml.hpp" #include "utils/defaults.hpp" #include "utils/log.hpp" @@ -157,13 +157,7 @@ namespace Map { } void loadFrom(const std::string& yaml_path) { - auto bytes = Resource::Helper::loadFile(yaml_path); - if (bytes.empty()) { - throw std::runtime_error("Map: no s'ha pogut obrir " + yaml_path); - } - const auto* begin = reinterpret_cast(bytes.data()); - const auto* end = begin + bytes.size(); - auto yaml = fkyaml::node::deserialize(begin, end); + auto yaml = RoomYaml::loadMerged(yaml_path); if (!yaml.contains("geometry")) { throw std::runtime_error("Map: manca bloc `geometry:` a " + yaml_path); } diff --git a/source/game/map/room_yaml.cpp b/source/game/map/room_yaml.cpp new file mode 100644 index 0000000..933856e --- /dev/null +++ b/source/game/map/room_yaml.cpp @@ -0,0 +1,66 @@ +#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 diff --git a/source/game/map/room_yaml.hpp b/source/game/map/room_yaml.hpp new file mode 100644 index 0000000..2e0e73d --- /dev/null +++ b/source/game/map/room_yaml.hpp @@ -0,0 +1,23 @@ +#pragma once + +#include + +#include "external/fkyaml_node.hpp" + +// Carregador de YAMLs de sala amb fusió per piràmide. Cada piràmide pot +// tenir un `pyramid.yaml` germà al directori de sala que aporta camps +// compartits (tileset, lighting, push_factor, paint_tiles...); el YAML +// de sala només declara el que canvia (data, entities, geometry, room). +// +// Regles de fusió: +// - mapes: fusió recursiva, claus de la sala guanyen +// - sequences i escalars: la sala substitueix sencer +// +// Si no hi ha `pyramid.yaml` al directori, retorna només el YAML de sala +// sense modificacions — així rutes externes (tests, mapes solts) segueixen +// funcionant igual. +namespace RoomYaml { + + auto loadMerged(const std::string& room_yaml_path) -> fkyaml::node; + +} // namespace RoomYaml diff --git a/source/game/map/tilemap.cpp b/source/game/map/tilemap.cpp index 577d6c7..78426d0 100644 --- a/source/game/map/tilemap.cpp +++ b/source/game/map/tilemap.cpp @@ -9,8 +9,8 @@ #include "core/rendering/screen.hpp" #include "core/rendering/surface.hpp" #include "core/resources/resource_cache.hpp" -#include "core/resources/resource_helper.hpp" #include "external/fkyaml_node.hpp" +#include "game/map/room_yaml.hpp" #include "utils/log.hpp" #ifdef _DEBUG @@ -41,13 +41,7 @@ namespace { } // namespace Tilemap::Tilemap(const std::string& yaml_path) { - auto bytes = Resource::Helper::loadFile(yaml_path); - if (bytes.empty()) { - throw std::runtime_error("Tilemap: no s'ha pogut obrir " + yaml_path); - } - const auto* begin = reinterpret_cast(bytes.data()); - const auto* end = begin + bytes.size(); - auto yaml = fkyaml::node::deserialize(begin, end); + auto yaml = RoomYaml::loadMerged(yaml_path); tileset_path_ = yaml["tileset"].get_value(); tile_size_ = yaml["tile_size"].get_value(); diff --git a/source/game/scenes/game_scene.cpp b/source/game/scenes/game_scene.cpp index 12fe1fb..0e0a827 100644 --- a/source/game/scenes/game_scene.cpp +++ b/source/game/scenes/game_scene.cpp @@ -38,6 +38,7 @@ #include "game/gameplay_config.hpp" #include "game/levels/level_manager.hpp" #include "game/map/map.hpp" +#include "game/map/room_yaml.hpp" #include "game/options.hpp" #include "game/scenes/scene_flow.hpp" #include "game/scenes/start_input.hpp" @@ -65,21 +66,13 @@ namespace { // pinta amb l'índex declarat al mapa, i un mapa sense aquests camps // simplement no deixa rastre visual. auto readOptionalInt(const std::string& yaml_path, const std::string& key, int fallback = -1) -> int { - auto bytes = Resource::Helper::loadFile(yaml_path); - if (bytes.empty()) { return fallback; } - const auto* begin = reinterpret_cast(bytes.data()); - const auto* end = begin + bytes.size(); - auto yaml = fkyaml::node::deserialize(begin, end); + auto yaml = RoomYaml::loadMerged(yaml_path); if (!yaml.contains(key)) { return fallback; } return yaml[key].get_value(); } auto readOptionalFloat(const std::string& yaml_path, const std::string& key, float fallback) -> float { - auto bytes = Resource::Helper::loadFile(yaml_path); - if (bytes.empty()) { return fallback; } - const auto* begin = reinterpret_cast(bytes.data()); - const auto* end = begin + bytes.size(); - auto yaml = fkyaml::node::deserialize(begin, end); + auto yaml = RoomYaml::loadMerged(yaml_path); if (!yaml.contains(key)) { return fallback; } return yaml[key].get_value(); } diff --git a/tests/test_entities_smoke.cpp b/tests/test_entities_smoke.cpp index 7d2e1ce..1c04bde 100644 --- a/tests/test_entities_smoke.cpp +++ b/tests/test_entities_smoke.cpp @@ -383,7 +383,7 @@ animations: void testLoadFromLevel() { std::cout << "[T9] pyramid level load (globals + spawns + tile math + bus)\n"; // 1) Map::loadFrom carrega les tres globals noves (tile_size, origen). - Map::loadFrom("data/maps/pyramid.yaml"); + Map::loadFrom("data/maps/p1/r1.yaml"); REQUIRE(Map::tile_size == 16); REQUIRE(Map::tilemap_origin_x == -8); REQUIRE(Map::tilemap_origin_y == 0); @@ -392,7 +392,7 @@ animations: // menys un de cada tipus que el nivell ha de tenir sí o sí (no // fixem quants torches exactes perquè és decoratiu i pot // variar). Així afegir decoració al YAML no trenca el smoke. - const auto SPAWNS = EntityLoader::readSpawns("data/maps/pyramid.yaml"); + const auto SPAWNS = EntityLoader::readSpawns("data/maps/p1/r1.yaml"); REQUIRE(!SPAWNS.empty()); int torches = 0; int sarcs = 0; @@ -499,7 +499,7 @@ animations: std::cout << "[T13] momia step amb col·lisió i gir\n"; // Cal Map::loadFrom (T9 ja el carrega, però el rerrumigo ací per // aïllar la intenció del test). - Map::loadFrom("data/maps/pyramid.yaml"); + Map::loadFrom("data/maps/p1/r1.yaml"); // Momia al corredor exterior superior: playfield_y=48, alçada del // corredor exterior = outer_corridor (16). Així el base box 12×12 @@ -544,7 +544,7 @@ animations: void testMummyHurtState() { std::cout << "[T15] mummy enterHurt → fugida + recuperació\n"; - Map::loadFrom("data/maps/pyramid.yaml"); + Map::loadFrom("data/maps/p1/r1.yaml"); fkyaml::node tmpl = EntityLoader::loadTemplate("mummy"); Mummy mummy(tmpl); @@ -574,7 +574,7 @@ animations: void testMummyHurtAgainstWall() { std::cout << "[T16] mummy HURT contra mur → surt abans del timer\n"; - Map::loadFrom("data/maps/pyramid.yaml"); + Map::loadFrom("data/maps/p1/r1.yaml"); fkyaml::node tmpl = EntityLoader::loadTemplate("mummy"); Mummy mummy(tmpl); @@ -619,7 +619,7 @@ animations: // micro-overlap, retornant NONE i deixant la mòmia eternament quieta // amb l'animació de córrer activa. El fix és snap a la vora exacta // dins de `hurtStep` abans de transitar a ROAMING. - Map::loadFrom("data/maps/pyramid.yaml"); + Map::loadFrom("data/maps/p1/r1.yaml"); fkyaml::node tmpl = EntityLoader::loadTemplate("mummy"); Mummy mummy(tmpl); @@ -650,7 +650,7 @@ animations: // amb dir_x_/dir_y_ a zero, el `step()` anterior feia early return i // es quedava quieta per sempre. Ara re-decideix com a una intersecció // si troba alguna direcció vàlida. - Map::loadFrom("data/maps/pyramid.yaml"); + Map::loadFrom("data/maps/p1/r1.yaml"); fkyaml::node tmpl = EntityLoader::loadTemplate("mummy"); Mummy mummy(tmpl); @@ -677,7 +677,7 @@ animations: // (snap a hurtStep + recovery a step), o bé `chooseHurtDirection` // troba una direcció lliure des de la posició aliniada, o bé el // proper step la rescata. En cap cas pot quedar permanentment quieta. - Map::loadFrom("data/maps/pyramid.yaml"); + Map::loadFrom("data/maps/p1/r1.yaml"); fkyaml::node tmpl = EntityLoader::loadTemplate("mummy"); Mummy mummy(tmpl); diff --git a/tests/test_whip_attack.cpp b/tests/test_whip_attack.cpp index 8f03f81..19123db 100644 --- a/tests/test_whip_attack.cpp +++ b/tests/test_whip_attack.cpp @@ -62,7 +62,7 @@ namespace { void testWhipDrawRectPerDirection() { std::cout << "[W1] WhipAttack draw_rect per direcció\n"; - Map::loadFrom("data/maps/pyramid.yaml"); + Map::loadFrom("data/maps/p1/r1.yaml"); // Owner ben dins del playfield perquè el draw_rect (no es retalla) // tinga la mida nominal completa. @@ -94,7 +94,7 @@ namespace { void testWhipDrawRectOffsets() { std::cout << "[W7] offsets del draw_rect per direcció (taula del disseny)\n"; - Map::loadFrom("data/maps/pyramid.yaml"); + Map::loadFrom("data/maps/p1/r1.yaml"); // Posicionem el jugador amb la collision (bottom 16×16) al // corredor entre files 2 i 3 de sarcs (y∈[144,160]) i a la @@ -128,7 +128,7 @@ namespace { void testWhipFeetYDelegation() { std::cout << "[W8] feet_y delegat a la base de l'owner_box\n"; - Map::loadFrom("data/maps/pyramid.yaml"); + Map::loadFrom("data/maps/p1/r1.yaml"); // Posicionem el jugador amb la collision (bottom 16×16) al // corredor entre files 2 i 3 de sarcs (y∈[144,160]) i a la @@ -151,7 +151,7 @@ namespace { void testWhipHitboxClippedByWall() { std::cout << "[W2] damage_rect retallat per la paret del playfield\n"; - Map::loadFrom("data/maps/pyramid.yaml"); + Map::loadFrom("data/maps/p1/r1.yaml"); // Llancem un E des d'una posició a 10 px de la paret dreta del // playfield, amb un range de 48 px → la hitbox efectiva ha de @@ -170,7 +170,7 @@ namespace { void testWhipHitboxFreeAtFullRange() { std::cout << "[W3] damage_rect sense bloquejador → longitud completa\n"; - Map::loadFrom("data/maps/pyramid.yaml"); + Map::loadFrom("data/maps/p1/r1.yaml"); // Owner ben dins del playfield, range curt → 16 px lliures fins // a topar amb res. La longitud efectiva = RANGE. @@ -187,7 +187,7 @@ namespace { void testWhipHitsMummyInRange() { std::cout << "[W4] mòmia en rang entra a HURT\n"; - Map::loadFrom("data/maps/pyramid.yaml"); + Map::loadFrom("data/maps/p1/r1.yaml"); EntityManager manager; auto mummy_yaml = EntityLoader::loadTemplate("mummy"); @@ -226,7 +226,7 @@ namespace { void testWhipNoHitOutOfRange() { std::cout << "[W5] mòmia fora del rang no rep dany\n"; - Map::loadFrom("data/maps/pyramid.yaml"); + Map::loadFrom("data/maps/p1/r1.yaml"); EntityManager manager; auto mummy_yaml = EntityLoader::loadTemplate("mummy"); @@ -253,7 +253,7 @@ namespace { void testWhipSingleHitPerSwing() { std::cout << "[W6] una mòmia rep un sol impacte per swing\n"; - Map::loadFrom("data/maps/pyramid.yaml"); + Map::loadFrom("data/maps/p1/r1.yaml"); EntityManager manager; auto mummy_yaml = EntityLoader::loadTemplate("mummy");