From faae650a53ae398b5f1265f70523140768382c43 Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Fri, 10 Apr 2026 14:14:01 +0200 Subject: [PATCH] fase 5 de zones --- config/assets.yaml | 1 - data/tilesets/standard.gif | Bin 8335 -> 0 bytes source/core/resources/resource_cache.cpp | 7 ++- source/game/editor/map_editor.cpp | 57 ++++++++++++++++++++++- source/game/editor/room_saver.cpp | 13 +++++- 5 files changed, 72 insertions(+), 6 deletions(-) delete mode 100644 data/tilesets/standard.gif diff --git a/config/assets.yaml b/config/assets.yaml index 746c4fb..ca5ebaa 100644 --- a/config/assets.yaml +++ b/config/assets.yaml @@ -80,7 +80,6 @@ assets: # TILESETS tilesets: BITMAP: - - ${PREFIX}/data/tilesets/standard.gif - ${PREFIX}/data/tilesets/neighborhood.gif - ${PREFIX}/data/tilesets/cave.gif - ${PREFIX}/data/tilesets/collision.gif diff --git a/data/tilesets/standard.gif b/data/tilesets/standard.gif deleted file mode 100644 index 5ed1b04e153457b3ebb9bf158145e7765f33a738..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8335 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 diff --git a/source/core/resources/resource_cache.cpp b/source/core/resources/resource_cache.cpp index ad6952f..745809c 100644 --- a/source/core/resources/resource_cache.cpp +++ b/source/core/resources/resource_cache.cpp @@ -338,8 +338,11 @@ namespace Resource { } } - // Reconfigura el color transparente de algunas surfaces - getSurface("standard.gif")->setTransparentColor(16); + // Reconfigura el color transparente de las surfaces de tilesets de zona. + // Los tilesets del juego usan el índice 16 como transparente (las surfaces + // arrancan con 0 por defecto; los tilesets lo marcan a 16). + getSurface("neighborhood.gif")->setTransparentColor(16); + getSurface("cave.gif")->setTransparentColor(16); } // Carga las paletas diff --git a/source/game/editor/map_editor.cpp b/source/game/editor/map_editor.cpp index 46afc84..ba01054 100644 --- a/source/game/editor/map_editor.cpp +++ b/source/game/editor/map_editor.cpp @@ -26,6 +26,8 @@ #include "game/gameplay/item_manager.hpp" // Para ItemManager #include "game/gameplay/platform_manager.hpp" // Para PlatformManager #include "game/gameplay/room.hpp" // Para Room +#include "game/gameplay/zone.hpp" // Para Zone::Data +#include "game/gameplay/zone_manager.hpp" // Para ZoneManager #include "game/options.hpp" // Para Options #include "game/ui/console.hpp" // Para Console #include "utils/defines.hpp" // Para Tile::SIZE, PlayArea @@ -1214,7 +1216,9 @@ void MapEditor::updateStatusBarInfo() { // NOLINT(readability-function-cognitiv conv = "right"; } - line2 = "zone:" + room_data_.zone + " conv:" + conv; + 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 + " conv:" + conv; 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) + " itm:" + std::to_string(room_data_.item_color1) + "/" + std::to_string(room_data_.item_color2); @@ -1460,15 +1464,64 @@ auto MapEditor::setRoomProperty(const std::string& property, const std::string& return "conveyor: " + val; } + if (property == "ZONE") { + const Zone::Data* zone = ZoneManager::get()->getZone(val); + if (zone == nullptr) { return "Unknown zone: " + val; } + room_data_.zone = val; + // Si no hay overrides, propagar el tileset y la música de la nueva zona + if (!room_data_.tile_set_overridden) { + room_data_.tile_set_file = zone->tile_set_file; + room_->setTileSet(zone->tile_set_file); + } + if (!room_data_.music_overridden) { + room_data_.music = zone->music; + } + autosave(); + return "zone: " + val; + } + if (property == "TILESET") { + // "reset" / "none" limpia el override y vuelve a heredar de la zona + if (val == "reset" || val == "none") { + room_data_.tile_set_overridden = false; + const Zone::Data* zone = ZoneManager::get()->getZone(room_data_.zone); + if (zone != nullptr) { + room_data_.tile_set_file = zone->tile_set_file; + room_->setTileSet(zone->tile_set_file); + } + autosave(); + return "tileset: (inherit from zone)"; + } std::string tileset = val; if (tileset.find('.') == std::string::npos) { tileset += ".gif"; } room_data_.tile_set_file = tileset; + room_data_.tile_set_overridden = true; room_->setTileSet(tileset); autosave(); return "tileset: " + tileset; } + if (property == "MUSIC") { + // "reset" / "none" limpia el override y vuelve a heredar de la zona + if (val == "reset" || val == "none") { + room_data_.music_overridden = false; + const Zone::Data* zone = ZoneManager::get()->getZone(room_data_.zone); + if (zone != nullptr) { + room_data_.music = zone->music; + } + autosave(); + return "music: (inherit from zone)"; + } + // Nota: el valor se guarda tal cual (case-sensitive). val ya está en lower. + // Usamos el value original para respetar mayúsculas del nombre del fichero. + std::string music = value; + if (music.find('.') == std::string::npos) { music += ".ogg"; } + room_data_.music = music; + room_data_.music_overridden = true; + autosave(); + return "music: " + music; + } + // Conexiones: UP, DOWN, LEFT, RIGHT if (property == "UP" || property == "DOWN" || property == "LEFT" || property == "RIGHT") { std::string connection = "0"; @@ -1567,7 +1620,7 @@ auto MapEditor::setRoomProperty(const std::string& property, const std::string& return toLower(property) + ": " + connection; } - return "Unknown property: " + property + " (use: itemcolor1, itemcolor2, conveyor, tileset, up, down, left, right)"; + return "Unknown property: " + property + " (use: zone, itemcolor1, itemcolor2, conveyor, tileset, music, up, down, left, right)"; } // Crea una nueva habitación diff --git a/source/game/editor/room_saver.cpp b/source/game/editor/room_saver.cpp index a3055d3..3527e0e 100644 --- a/source/game/editor/room_saver.cpp +++ b/source/game/editor/room_saver.cpp @@ -43,8 +43,19 @@ auto RoomSaver::buildYAML(const fkyaml::node& original_yaml, const Room::Data& r // --- Sección room --- out << "room:\n"; + // zone es siempre obligatoria + out << " zone: " << room_data.zone << "\n"; + // bgColor ya no se escribe en el YAML - out << " tileSetFile: " << room_data.tile_set_file << "\n"; + // tileSetFile solo si es override explícito del valor heredado de la zona + if (room_data.tile_set_overridden) { + out << " tileSetFile: " << room_data.tile_set_file << "\n"; + } + + // music solo si es override explícito del valor heredado de la zona + if (room_data.music_overridden) { + out << " music: " << room_data.music << "\n"; + } // Conexiones out << "\n";