From 49f6ed41e626cfb031e92af9cc7c29436cfe2fd1 Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Sat, 11 Apr 2026 09:16:39 +0200 Subject: [PATCH] ajustos de qualitat, canvi de tecles, persistencia de opcions, etc --- config/assets.yaml | 112 +------------------------- data/room/03.yaml | 6 +- data/room/06.yaml | 35 ++++---- data/tilesets/city.gif | Bin 0 -> 8098 bytes data/tilesets/forest.gif | Bin 0 -> 8474 bytes data/tilesets/lab.gif | Bin 0 -> 8098 bytes data/tilesets/sewers.gif | Bin 0 -> 8098 bytes data/zones/zones.yaml | 22 +++++ source/core/input/global_inputs.cpp | 14 +++- source/core/system/debug.cpp | 7 ++ source/core/system/debug.hpp | 1 + source/game/editor/map_editor.cpp | 62 +++++++++----- source/game/editor/map_editor.hpp | 4 +- source/game/gameplay/room.cpp | 11 +++ source/game/gameplay/room.hpp | 2 + source/game/gameplay/room_format.cpp | 17 +++- source/game/gameplay/zone.hpp | 3 + source/game/gameplay/zone_manager.cpp | 3 + source/game/ui/console_commands.cpp | 7 ++ 19 files changed, 149 insertions(+), 157 deletions(-) create mode 100644 data/tilesets/city.gif create mode 100644 data/tilesets/forest.gif create mode 100644 data/tilesets/lab.gif create mode 100644 data/tilesets/sewers.gif diff --git a/config/assets.yaml b/config/assets.yaml index 0dc7b3a..ed30514 100644 --- a/config/assets.yaml +++ b/config/assets.yaml @@ -82,127 +82,23 @@ assets: tilesets: BITMAP: - ${PREFIX}/data/tilesets/neighborhood.gif + - ${PREFIX}/data/tilesets/city.gif + - ${PREFIX}/data/tilesets/forest.gif + - ${PREFIX}/data/tilesets/lab.gif + - ${PREFIX}/data/tilesets/sewers.gif - ${PREFIX}/data/tilesets/cave.gif - ${PREFIX}/data/tilesets/collision.gif # ENEMIES enemies: ANIMATION: - - ${PREFIX}/data/enemies/abad_bell.yaml - - ${PREFIX}/data/enemies/abad.yaml - - ${PREFIX}/data/enemies/amstrad_cs.yaml - - ${PREFIX}/data/enemies/flying_arounder.yaml - - ${PREFIX}/data/enemies/stopped_arounder.yaml - - ${PREFIX}/data/enemies/walking_arounder.yaml - - ${PREFIX}/data/enemies/arounders_door.yaml - - ${PREFIX}/data/enemies/arounders_machine.yaml - - ${PREFIX}/data/enemies/bat.yaml - - ${PREFIX}/data/enemies/batman_bell.yaml - - ${PREFIX}/data/enemies/batman_fire.yaml - - ${PREFIX}/data/enemies/batman.yaml - - ${PREFIX}/data/enemies/bell.yaml - ${PREFIX}/data/enemies/bin.yaml - - ${PREFIX}/data/enemies/bird.yaml - - ${PREFIX}/data/enemies/breakout.yaml - - ${PREFIX}/data/enemies/bry.yaml - - ${PREFIX}/data/enemies/chip.yaml - ${PREFIX}/data/enemies/code.yaml - - ${PREFIX}/data/enemies/congo.yaml - - ${PREFIX}/data/enemies/crosshair.yaml - - ${PREFIX}/data/enemies/demon.yaml - - ${PREFIX}/data/enemies/dimallas.yaml - - ${PREFIX}/data/enemies/floppy.yaml - - ${PREFIX}/data/enemies/dong.yaml - - ${PREFIX}/data/enemies/guitar.yaml - - ${PREFIX}/data/enemies/heavy.yaml - - ${PREFIX}/data/enemies/jailer1.yaml - - ${PREFIX}/data/enemies/jailer2.yaml - - ${PREFIX}/data/enemies/jailer3.yaml - - ${PREFIX}/data/enemies/jailbattle_alien.yaml - - ${PREFIX}/data/enemies/jailbattle_human.yaml - - ${PREFIX}/data/enemies/jeannine.yaml - - ${PREFIX}/data/enemies/lamp.yaml - - ${PREFIX}/data/enemies/lord_abad.yaml - - ${PREFIX}/data/enemies/matatunos.yaml - - ${PREFIX}/data/enemies/mummy.yaml - - ${PREFIX}/data/enemies/paco.yaml - - ${PREFIX}/data/enemies/elsa.yaml - - ${PREFIX}/data/enemies/qvoid.yaml - - ${PREFIX}/data/enemies/robot.yaml - - ${PREFIX}/data/enemies/sam.yaml - - ${PREFIX}/data/enemies/shock.yaml - - ${PREFIX}/data/enemies/sigmasua.yaml - - ${PREFIX}/data/enemies/spark.yaml - - ${PREFIX}/data/enemies/special/aerojailer.yaml - - ${PREFIX}/data/enemies/special/arounder.yaml - - ${PREFIX}/data/enemies/special/pepe_rosita_job.yaml - - ${PREFIX}/data/enemies/special/shooting_star.yaml - - ${PREFIX}/data/enemies/spider.yaml - - ${PREFIX}/data/enemies/tree_thing.yaml - - ${PREFIX}/data/enemies/tuno.yaml - - ${PREFIX}/data/enemies/tv_panel.yaml - - ${PREFIX}/data/enemies/tv.yaml - ${PREFIX}/data/enemies/upv_student.yaml - - ${PREFIX}/data/enemies/wave.yaml - - ${PREFIX}/data/enemies/z80.yaml BITMAP: - - ${PREFIX}/data/enemies/abad_bell.gif - - ${PREFIX}/data/enemies/abad.gif - - ${PREFIX}/data/enemies/amstrad_cs.gif - - ${PREFIX}/data/enemies/flying_arounder.gif - - ${PREFIX}/data/enemies/stopped_arounder.gif - - ${PREFIX}/data/enemies/walking_arounder.gif - - ${PREFIX}/data/enemies/arounders_door.gif - - ${PREFIX}/data/enemies/arounders_machine.gif - - ${PREFIX}/data/enemies/bat.gif - - ${PREFIX}/data/enemies/batman_bell.gif - - ${PREFIX}/data/enemies/batman_fire.gif - - ${PREFIX}/data/enemies/batman.gif - - ${PREFIX}/data/enemies/bell.gif - ${PREFIX}/data/enemies/bin.gif - - ${PREFIX}/data/enemies/bird.gif - - ${PREFIX}/data/enemies/breakout.gif - - ${PREFIX}/data/enemies/bry.gif - - ${PREFIX}/data/enemies/chip.gif - ${PREFIX}/data/enemies/code.gif - - ${PREFIX}/data/enemies/congo.gif - - ${PREFIX}/data/enemies/crosshair.gif - - ${PREFIX}/data/enemies/demon.gif - - ${PREFIX}/data/enemies/dimallas.gif - - ${PREFIX}/data/enemies/floppy.gif - - ${PREFIX}/data/enemies/dong.gif - - ${PREFIX}/data/enemies/guitar.gif - - ${PREFIX}/data/enemies/heavy.gif - - ${PREFIX}/data/enemies/jailer1.gif - - ${PREFIX}/data/enemies/jailer2.gif - - ${PREFIX}/data/enemies/jailer3.gif - - ${PREFIX}/data/enemies/jailbattle_alien.gif - - ${PREFIX}/data/enemies/jailbattle_human.gif - - ${PREFIX}/data/enemies/jeannine.gif - - ${PREFIX}/data/enemies/lamp.gif - - ${PREFIX}/data/enemies/lord_abad.gif - - ${PREFIX}/data/enemies/matatunos.gif - - ${PREFIX}/data/enemies/mummy.gif - - ${PREFIX}/data/enemies/paco.gif - - ${PREFIX}/data/enemies/elsa.gif - - ${PREFIX}/data/enemies/qvoid.gif - - ${PREFIX}/data/enemies/robot.gif - - ${PREFIX}/data/enemies/sam.gif - - ${PREFIX}/data/enemies/shock.gif - - ${PREFIX}/data/enemies/sigmasua.gif - - ${PREFIX}/data/enemies/spark.gif - - ${PREFIX}/data/enemies/special/aerojailer.gif - - ${PREFIX}/data/enemies/special/arounder.gif - - ${PREFIX}/data/enemies/special/pepe_rosita_job.gif - - ${PREFIX}/data/enemies/special/shooting_star.gif - - ${PREFIX}/data/enemies/spider.gif - - ${PREFIX}/data/enemies/tree_thing.gif - - ${PREFIX}/data/enemies/tuno.gif - - ${PREFIX}/data/enemies/tv_panel.gif - - ${PREFIX}/data/enemies/tv.gif - ${PREFIX}/data/enemies/upv_student.gif - - ${PREFIX}/data/enemies/wave.gif - - ${PREFIX}/data/enemies/z80.gif # PLATFORMS platforms: diff --git a/data/room/03.yaml b/data/room/03.yaml index bc3030a..0093c7b 100644 --- a/data/room/03.yaml +++ b/data/room/03.yaml @@ -40,9 +40,9 @@ tilemap: - [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1] - [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1] - [1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -1, 0, 0, 4, 1, 1, 1, 1, 1, 1, 1, 1] - - [1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0, 0, 0, 0, 0, 0, 1, 1] - - [1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1] - - [1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1] + - [1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1] + - [1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1] + - [1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1] - [1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1] - [1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1] - [1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1] diff --git a/data/room/06.yaml b/data/room/06.yaml index f1c73cf..956915e 100644 --- a/data/room/06.yaml +++ b/data/room/06.yaml @@ -1,5 +1,5 @@ room: - zone: cave + zone: forest # Conexiones de la habitación (null = sin conexión) connections: @@ -8,21 +8,12 @@ room: left: null right: 01.yaml - # Colores de los objetos - itemColor1: 11 - itemColor2: 12 - - # Dirección de la cinta transportadora: left, none, right - conveyorBelt: none - # Tilemap: 21 filas x 32 columnas @ 8px/tile tilemap: # Mapa de dibujo (indices de tiles, -1 = vacio) draw: - - [25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25] - - [25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25] - - [25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25] - - [49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49] + - [15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15] + - [13, 14, 13, 14, 13, 13, 13, 14, 13, 13, 13, 13, 14, 13, 13, 13, 14, 13, 14, 13, 14, 13, 13, 13, 13, 14, 14, 13, 13, 13, 14, 13] - [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1] - [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1] - [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1] @@ -34,19 +25,21 @@ tilemap: - [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1] - [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1] - [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1] - - [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 513, 25] - - [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 513, 25, 25] - - [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 513, 25, 25, 25] - - [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 513, 25, 25, 25, 25] + - [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1] + - [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1] + - [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 9, 1] + - [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 9, 11, 57] + - [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 9, 11, 57, 25] + - [54, 54, 55, 61, 54, 55, 56, 54, 61, 55, 54, 55, 62, 54, 61, 61, 54, 54, 54, 54, 54, 61, 61, 54, 55, 56, 54, 9, 11, 57, 25, 25] - [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 25] - [25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25] # Mapa de colisiones (0 = vacio, 1 = solido) collision: - - [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] - - [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] - - [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] - - [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] - - [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] + - [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1] + - [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1] + - [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1] + - [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1] + - [0, 0, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] - [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] - [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] - [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] diff --git a/data/tilesets/city.gif b/data/tilesets/city.gif new file mode 100644 index 0000000000000000000000000000000000000000..e49707383c78c161531a40d8624eb918f6a5586f GIT binary patch literal 8098 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 literal 0 HcmV?d00001 diff --git a/data/tilesets/forest.gif b/data/tilesets/forest.gif new file mode 100644 index 0000000000000000000000000000000000000000..995ef1452a30dd6e39c80d3307a464e0269a4a7c GIT binary patch literal 8474 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 literal 0 HcmV?d00001 diff --git a/data/tilesets/sewers.gif b/data/tilesets/sewers.gif new file mode 100644 index 0000000000000000000000000000000000000000..e49707383c78c161531a40d8624eb918f6a5586f GIT binary patch literal 8098 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 literal 0 HcmV?d00001 diff --git a/data/zones/zones.yaml b/data/zones/zones.yaml index f76d28e..ceb49ee 100644 --- a/data/zones/zones.yaml +++ b/data/zones/zones.yaml @@ -7,7 +7,29 @@ zones: - name: neighborhood tileSetFile: neighborhood.gif music: 574070_KUVO_Farewell_to_school.ogg + bgColor: 0 - name: cave tileSetFile: cave.gif music: 574071_EA_DTV.ogg + bgColor: 0 + + - name: forest + tileSetFile: forest.gif + music: 574070_KUVO_Farewell_to_school.ogg + bgColor: 35 + + - name: sewers + tileSetFile: sewers.gif + music: 574071_EA_DTV.ogg + bgColor: 0 + + - name: lab + tileSetFile: lab.gif + music: 574071_EA_DTV.ogg + bgColor: 0 + + - name: city + tileSetFile: city.gif + music: 574071_EA_DTV.ogg + bgColor: 0 \ No newline at end of file diff --git a/source/core/input/global_inputs.cpp b/source/core/input/global_inputs.cpp index cae33a6..83fd1d7 100644 --- a/source/core/input/global_inputs.cpp +++ b/source/core/input/global_inputs.cpp @@ -9,6 +9,9 @@ #include "core/locale/locale.hpp" // Para Locale #include "core/rendering/render_info.hpp" // Para RenderInfo #include "core/rendering/screen.hpp" // Para Screen +#ifdef _DEBUG +#include "core/system/debug.hpp" // Para Debug (persistencia de render_info en debug.yaml) +#endif #include "game/options.hpp" // Para Options, options, OptionsVideo, Section #include "game/scene_manager.hpp" // Para SceneManager #include "game/ui/console.hpp" // Para Console @@ -292,7 +295,16 @@ namespace GlobalInputs { break; case InputAction::TOGGLE_INFO: - if (RenderInfo::get() != nullptr) { RenderInfo::get()->toggle(); } + if (RenderInfo::get() != nullptr) { + // Leemos la intención antes del toggle: isActive() incluye la + // animación VANISHING, así que justo después de un toggle ACTIVE→OFF + // seguiría devolviendo true y la persistencia no detectaría el cambio. + const bool WAS_ACTIVE = RenderInfo::get()->isActive(); + RenderInfo::get()->toggle(); +#ifdef _DEBUG + if (Debug::get() != nullptr) { Debug::get()->setRenderInfoEnabled(!WAS_ACTIVE); } +#endif + } break; case InputAction::NONE: diff --git a/source/core/system/debug.cpp b/source/core/system/debug.cpp index 37cda18..f2590f5 100644 --- a/source/core/system/debug.cpp +++ b/source/core/system/debug.cpp @@ -178,6 +178,13 @@ void Debug::loadFromFile() { if (needs_save) { saveToFile(); } } +// Persiste el estado del overlay RenderInfo en debug.yaml +void Debug::setRenderInfoEnabled(bool value) { + if (render_info_enabled_ == value) { return; } + render_info_enabled_ = value; + saveToFile(); +} + // Guarda la configuración de debug en debug.yaml void Debug::saveToFile() const { std::ofstream file(debug_file_path_); diff --git a/source/core/system/debug.hpp b/source/core/system/debug.hpp index b19a82e..e97e9b9 100644 --- a/source/core/system/debug.hpp +++ b/source/core/system/debug.hpp @@ -49,6 +49,7 @@ class Debug { void setInitialScene(SceneManager::Scene s) { initial_scene_ = s; } // Establece la escena inicial de debug [[nodiscard]] auto getLazyLoading() const -> bool { return lazy_loading_; } // Indica si el modo lazy de recursos está activo [[nodiscard]] auto getRenderInfoEnabled() const -> bool { return render_info_enabled_; } // Indica si el overlay RenderInfo arranca activo + void setRenderInfoEnabled(bool value); // Persiste el estado del overlay RenderInfo en debug.yaml private: static Debug* debug; // [SINGLETON] Objeto privado diff --git a/source/game/editor/map_editor.cpp b/source/game/editor/map_editor.cpp index ef1d30c..6faee10 100644 --- a/source/game/editor/map_editor.cpp +++ b/source/game/editor/map_editor.cpp @@ -20,6 +20,7 @@ #include "core/resources/resource_cache.hpp" // Para Resource::Cache #include "core/resources/resource_list.hpp" // Para Resource::List #include "core/resources/resource_types.hpp" // Para RoomResource +#include "core/system/debug.hpp" // Para Debug (persistencia de render_info) #include "external/fkyaml_node.hpp" // Para fkyaml::node (loadSettings) #include "game/editor/editor_statusbar.hpp" // Para EditorStatusBar #include "game/entities/player.hpp" // Para Player @@ -76,7 +77,6 @@ void MapEditor::loadSettings() { try { auto yaml = fkyaml::node::deserialize(content); if (yaml.contains("grid")) { settings_.grid = yaml["grid"].get_value(); } - if (yaml.contains("show_render_info")) { settings_.show_render_info = yaml["show_render_info"].get_value(); } if (yaml.contains("minimap_bg")) { if (yaml["minimap_bg"].is_integer()) { settings_.minimap_bg = static_cast(yaml["minimap_bg"].get_value()); @@ -106,19 +106,17 @@ void MapEditor::saveSettings() const { file << "# Map Editor Settings\n"; file << "grid: " << (settings_.grid ? "true" : "false") << "\n"; - file << "show_render_info: " << (settings_.show_render_info ? "true" : "false") << "\n"; file << "minimap_bg: " << static_cast(settings_.minimap_bg) << "\n"; file << "minimap_conn: " << static_cast(settings_.minimap_conn) << "\n"; file.close(); } -// Muestra/oculta render info (persistente) +// Muestra/oculta render info (persistente en debug.yaml, fuente de verdad global) auto MapEditor::showInfo(bool show) -> std::string { - settings_.show_render_info = show; if (RenderInfo::get()->isActive() != show) { RenderInfo::get()->toggle(); } - saveSettings(); + if (Debug::get() != nullptr) { Debug::get()->setRenderInfoEnabled(show); } return show ? "Info ON" : "Info OFF"; } @@ -203,18 +201,12 @@ void MapEditor::enter(std::shared_ptr room, std::shared_ptr player if (!reenter_) { // Solo guardar estado previo en el primer enter (no en re-enter tras cambio de room) invincible_before_editor_ = Options::cheats.invincible; - render_info_before_editor_ = RenderInfo::get()->isActive(); } reenter_ = false; // Forzar invencibilidad Options::cheats.invincible = Options::Cheat::State::ENABLED; - // Aplicar el setting de render_info del editor - if (settings_.show_render_info != RenderInfo::get()->isActive()) { - RenderInfo::get()->toggle(); - } - // Activar scope de la consola para el editor Console::get()->setScope("editor"); @@ -256,10 +248,6 @@ void MapEditor::exit() { if (!reenter_) { // Solo restaurar en el exit final (no en cambio de room) Options::cheats.invincible = invincible_before_editor_; - - if (RenderInfo::get()->isActive() != render_info_before_editor_) { - RenderInfo::get()->toggle(); - } } // Restaurar prompt y scope de la consola @@ -443,8 +431,13 @@ void MapEditor::render() { // Maneja eventos del editor void MapEditor::handleEvent(const SDL_Event& event) { // NOLINT(readability-function-cognitive-complexity) - // Si el tile picker está abierto, los eventos van a él + // Si el tile picker está abierto, los eventos van a él. + // Excepción: la T lo cierra como toggle (sin tocar el brush). if (tile_picker_.isOpen()) { + if (event.type == SDL_EVENT_KEY_DOWN && event.key.key == SDLK_T && static_cast(event.key.repeat) == 0) { + tile_picker_.close(); + return; + } tile_picker_.handleEvent(event); return; } @@ -528,7 +521,7 @@ void MapEditor::handleEvent(const SDL_Event& event) { // NOLINT(readability-fun } } - // T: abrir TilePicker + // T: abrir TilePicker (el cierre con T también se gestiona arriba, antes de delegar al picker) if (event.type == SDL_EVENT_KEY_DOWN && event.key.key == SDLK_T && static_cast(event.key.repeat) == 0) { // Deseleccionar entidades selection_.clear(); @@ -1464,7 +1457,8 @@ void MapEditor::updateStatusBarInfo() { // NOLINT(readability-function-cognitiv // Propiedades de la habitación std::string ts_marker = room_data_.tile_set_overridden ? " (ts*)" : ""; std::string mu_marker = room_data_.music_overridden ? " (mu*)" : ""; - line2 = "zone:" + room_data_.zone + ts_marker + mu_marker; + std::string bg_marker = room_data_.bg_color_overridden ? "*" : ""; + line2 = "zone:" + room_data_.zone + ts_marker + mu_marker + " bg:" + std::to_string(room_data_.bg_color) + bg_marker; line3 = "u:" + conn(room_data_.upper_room) + " d:" + conn(room_data_.lower_room) + " l:" + conn(room_data_.left_room) + " r:" + conn(room_data_.right_room); break; @@ -1509,7 +1503,7 @@ auto MapEditor::getSetCompletions() const -> std::vector { case EntityType::DOOR: return {"ID", "ANIMATION"}; default: - return {"ZONE", "TILESET", "MUSIC", "UP", "DOWN", "LEFT", "RIGHT"}; + return {"ZONE", "TILESET", "MUSIC", "BGCOLOR", "UP", "DOWN", "LEFT", "RIGHT"}; } } @@ -1733,6 +1727,10 @@ auto MapEditor::setRoomProperty(const std::string& property, const std::string& if (!room_data_.music_overridden) { room_data_.music = zone->music; } + if (!room_data_.bg_color_overridden) { + room_data_.bg_color = zone->bg_color; + room_->setBgColor(zone->bg_color); + } autosave(); return "zone: " + val; } @@ -1758,6 +1756,30 @@ auto MapEditor::setRoomProperty(const std::string& property, const std::string& return "tileset: " + tileset; } + if (property == "BGCOLOR") { + // "reset" / "none" limpia el override y vuelve a heredar de la zona + if (val == "reset" || val == "none") { + room_data_.bg_color_overridden = false; + const Zone::Data* zone = ZoneManager::get()->getZone(room_data_.zone); + if (zone != nullptr) { + room_data_.bg_color = zone->bg_color; + room_->setBgColor(zone->bg_color); + } + autosave(); + return "bgcolor: (inherit from zone)"; + } + int color = 0; + try { + color = std::stoi(val); + } catch (...) { return "usage: set bgcolor <0-255|reset>"; } + if (color < 0 || color > 255) { return "bgcolor must be 0-255"; } + room_data_.bg_color = static_cast(color); + room_data_.bg_color_overridden = true; + room_->setBgColor(static_cast(color)); + autosave(); + return "bgcolor: " + std::to_string(color); + } + if (property == "MUSIC") { // "reset" / "none" limpia el override y vuelve a heredar de la zona if (val == "reset" || val == "none") { @@ -1875,7 +1897,7 @@ auto MapEditor::setRoomProperty(const std::string& property, const std::string& return toLower(property) + ": " + connection; } - return "Unknown property: " + property + " (use: zone, itemcolor1, itemcolor2, conveyor, tileset, music, up, down, left, right)"; + return "Unknown property: " + property + " (use: zone, itemcolor1, itemcolor2, conveyor, tileset, music, bgcolor, up, down, left, right)"; } // Crea una nueva habitación diff --git a/source/game/editor/map_editor.hpp b/source/game/editor/map_editor.hpp index 649e2ca..524ccf9 100644 --- a/source/game/editor/map_editor.hpp +++ b/source/game/editor/map_editor.hpp @@ -156,7 +156,6 @@ class MapEditor { // Opciones persistentes del editor struct Settings { bool grid{false}; - bool show_render_info{false}; Uint8 minimap_bg{2}; Uint8 minimap_conn{14}; }; @@ -257,8 +256,7 @@ class MapEditor { // Estado previo (para restaurar al salir) Options::Cheat::State invincible_before_editor_{Options::Cheat::State::DISABLED}; - bool render_info_before_editor_{false}; - bool reenter_{false}; // true cuando es un re-enter tras cambio de room (no tocar render_info) + bool reenter_{false}; // true cuando es un re-enter tras cambio de room }; #endif // _DEBUG diff --git a/source/game/gameplay/room.cpp b/source/game/gameplay/room.cpp index 6604cd3..13bf605 100644 --- a/source/game/gameplay/room.cpp +++ b/source/game/gameplay/room.cpp @@ -198,6 +198,17 @@ void Room::setTileSet(const std::string& tile_set_file) { bg_color_); tilemap_renderer_->initialize(collision_map_->getCollisionTileMap()); } + +// Cambia el color de fondo en vivo (para editor) +void Room::setBgColor(Uint8 bg_color) { + bg_color_ = bg_color; + tilemap_renderer_ = std::make_unique( + tile_map_, + tile_set_width_, + surface_, + bg_color_); + tilemap_renderer_->initialize(collision_map_->getCollisionTileMap()); +} #endif // Actualiza las variables y objetos de la habitación diff --git a/source/game/gameplay/room.hpp b/source/game/gameplay/room.hpp index cea365f..0a2c4d5 100644 --- a/source/game/gameplay/room.hpp +++ b/source/game/gameplay/room.hpp @@ -47,6 +47,7 @@ class Room { std::string music; // Resuelto: zona o override del yaml bool tile_set_overridden{false}; // True si el yaml tenía tileSetFile explícito bool music_overridden{false}; // True si el yaml tenía music explícito + bool bg_color_overridden{false}; // True si el yaml tenía bgColor explícito std::vector tile_map; std::vector collision_tile_map; std::vector enemies; @@ -85,6 +86,7 @@ class Room { void setCollisionTile(int index, int value); void setConnection(Border border, const std::string& room_name); void setTileSet(const std::string& tile_set_file); + void setBgColor(Uint8 bg_color); [[nodiscard]] auto getTileSetWidth() const -> int { return tile_set_width_; } #endif void update(float delta_time); diff --git a/source/game/gameplay/room_format.cpp b/source/game/gameplay/room_format.cpp index 7b50999..0fe0c8a 100644 --- a/source/game/gameplay/room_format.cpp +++ b/source/game/gameplay/room_format.cpp @@ -136,6 +136,14 @@ void RoomFormat::parseRoomConfig(const fkyaml::node& yaml, Room::Data& room, con room.music = zone->music; } + // bgColor: zona, override si está en el yaml + if (room_node.contains("bgColor")) { + room.bg_color = readColorNode(room_node["bgColor"]); + room.bg_color_overridden = true; + } else if (zone != nullptr) { + room.bg_color = zone->bg_color; + } + // Room connections if (room_node.contains("connections")) { parseRoomConnections(room_node["connections"], room); @@ -508,15 +516,17 @@ auto RoomFormat::loadFromString(const std::string& yaml_content, const std::stri auto RoomFormat::createDefault() -> Room::Data { Room::Data data; - // Zona por defecto (resuelve tile_set_file y music desde ZoneManager) + // Zona por defecto (resuelve tile_set_file, music y bg_color desde ZoneManager) const Zone::Data* zone = ZoneManager::get()->getDefaultZone(); if (zone != nullptr) { data.zone = zone->name; data.tile_set_file = zone->tile_set_file; data.music = zone->music; + data.bg_color = zone->bg_color; } data.tile_set_overridden = false; data.music_overridden = false; + data.bg_color_overridden = false; // Conexiones a cero data.upper_room = "0"; @@ -559,6 +569,11 @@ auto RoomFormat::buildContent(const Room::Data& room_data) -> std::string { // out << " music: " << room_data.music << "\n"; } + // bgColor solo si es override explícito del valor heredado de la zona + if (room_data.bg_color_overridden) { + out << " bgColor: " << static_cast(room_data.bg_color) << "\n"; + } + // Conexiones out << "\n"; out << " # Conexiones de la habitación (null = sin conexión)\n"; diff --git a/source/game/gameplay/zone.hpp b/source/game/gameplay/zone.hpp index c278f41..1352efc 100644 --- a/source/game/gameplay/zone.hpp +++ b/source/game/gameplay/zone.hpp @@ -1,5 +1,7 @@ #pragma once +#include + #include // Para string /** @@ -17,6 +19,7 @@ namespace Zone { std::string name; // Nombre único de la zona (ej. "neighborhood", "cave") std::string tile_set_file; // Fichero de tileset por defecto (ej. "neighborhood.gif") std::string music; // Pista de música por defecto (ej. "574070_KUVO_Farewell_to_school.ogg") + Uint8 bg_color{0}; // Color de fondo por defecto (índice de paleta) }; } // namespace Zone diff --git a/source/game/gameplay/zone_manager.cpp b/source/game/gameplay/zone_manager.cpp index 926297b..4a4c215 100644 --- a/source/game/gameplay/zone_manager.cpp +++ b/source/game/gameplay/zone_manager.cpp @@ -57,6 +57,9 @@ void ZoneManager::loadFromFile(const std::string& file_path) { if (zone_node.contains("music")) { zone.music = zone_node["music"].get_value(); } + if (zone_node.contains("bgColor")) { + zone.bg_color = static_cast(zone_node["bgColor"].get_value()); + } if (zone.name.empty()) { std::cerr << "ZoneManager: skipping zone without name\n"; diff --git a/source/game/ui/console_commands.cpp b/source/game/ui/console_commands.cpp index 81bd10b..c9d1e6b 100644 --- a/source/game/ui/console_commands.cpp +++ b/source/game/ui/console_commands.cpp @@ -850,6 +850,9 @@ static auto cmdShow(const std::vector& args) -> std::string { #endif if (RenderInfo::get()->isActive()) { return "Info overlay already ON"; } RenderInfo::get()->toggle(); +#ifdef _DEBUG + if (Debug::get() != nullptr) { Debug::get()->setRenderInfoEnabled(true); } +#endif return "Info overlay ON"; } @@ -858,6 +861,9 @@ static auto cmdHide(const std::vector& args) -> std::string { if (args.empty() || args[0] != "INFO") { return "usage: hide [info]"; } if (!RenderInfo::get()->isActive()) { return "Info overlay already OFF"; } RenderInfo::get()->toggle(); +#ifdef _DEBUG + if (Debug::get() != nullptr) { Debug::get()->setRenderInfoEnabled(false); } +#endif return "Info overlay OFF"; } @@ -1087,6 +1093,7 @@ void CommandRegistry::registerHandlers() { // NOLINT(readability-function-cogni }; dynamic_providers_["SET ITEMCOLOR1"] = color_provider; dynamic_providers_["SET ITEMCOLOR2"] = color_provider; + dynamic_providers_["SET BGCOLOR"] = color_provider; // SET ANIMATION: animaciones disponibles para la entidad seleccionada en // el editor. La lista la calcula MapEditor escaneando data// del