From cbd7f1797856aeea6798b3f1ba88c95d6edbd40d Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Sun, 17 May 2026 22:02:49 +0200 Subject: [PATCH] refactor room_format: write*Section per cada part del YAML --- source/game/gameplay/room_format.cpp | 258 ++++++++++++--------------- source/game/gameplay/room_format.hpp | 12 +- 2 files changed, 123 insertions(+), 147 deletions(-) diff --git a/source/game/gameplay/room_format.cpp b/source/game/gameplay/room_format.cpp index b0da8f4..904798f 100644 --- a/source/game/gameplay/room_format.cpp +++ b/source/game/gameplay/room_format.cpp @@ -548,31 +548,17 @@ auto RoomFormat::roomConnectionToYAML(const std::string& connection) -> std::str return connection; } -auto RoomFormat::buildContent(const Room::Data& room_data) -> std::string { // NOLINT(readability-function-cognitive-complexity) - std::ostringstream out; - - // --- Sección room --- +void RoomFormat::writeRoomSection(std::ostringstream& out, const Room::Data& room_data) { out << "room:\n"; // zone es siempre obligatoria out << " zone: " << room_data.zone << "\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"; - } + // tileSetFile/music/bgColor solo si son override explícito del valor heredado de la zona + if (room_data.tile_set_overridden) { out << " tileSetFile: " << room_data.tile_set_file << "\n"; } + if (room_data.music_overridden) { out << " music: " << room_data.music << "\n"; } + if (room_data.bg_color_overridden) { out << " bgColor: " << static_cast(room_data.bg_color) << "\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"; - } - - // 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"; out << " connections:\n"; @@ -580,155 +566,137 @@ auto RoomFormat::buildContent(const Room::Data& room_data) -> std::string { // out << " down: " << roomConnectionToYAML(room_data.lower_room) << "\n"; out << " left: " << roomConnectionToYAML(room_data.left_room) << "\n"; out << " right: " << roomConnectionToYAML(room_data.right_room) << "\n"; +} - // --- Tilemap (MAP_HEIGHT filas × MAP_WIDTH columnas, formato flow) --- +void RoomFormat::writeTilemapSection(std::ostringstream& out, const Room::Data& room_data) { out << "\n"; out << "# Tilemap: " << Map::HEIGHT << " filas x " << Map::WIDTH << " columnas @ " << Tile::SIZE << "px/tile\n"; out << "tilemap:\n"; - // Mapa de dibujo - out << " # Mapa de dibujo (indices de tiles, -1 = vacio)\n"; - out << " draw:\n"; - for (int row = 0; row < Map::HEIGHT; ++row) { - out << " - ["; - for (int col = 0; col < Map::WIDTH; ++col) { - int index = (row * Map::WIDTH) + col; - if (index < static_cast(room_data.tile_map.size())) { - out << room_data.tile_map[index]; - } else { - out << -1; + auto write_grid = [&out](const auto& tilemap, const char* header, int empty_value) { + out << header; + for (int row = 0; row < Map::HEIGHT; ++row) { + out << " - ["; + for (int col = 0; col < Map::WIDTH; ++col) { + const int INDEX = (row * Map::WIDTH) + col; + out << (INDEX < static_cast(tilemap.size()) ? tilemap[INDEX] : empty_value); + if (col < Map::WIDTH - 1) { out << ", "; } } - if (col < Map::WIDTH - 1) { out << ", "; } + out << "]\n"; } - out << "]\n"; - } + }; - // Mapa de colisiones - out << " # Mapa de colisiones (0 = vacio, 1 = solido)\n"; - out << " collision:\n"; - for (int row = 0; row < Map::HEIGHT; ++row) { - out << " - ["; - for (int col = 0; col < Map::WIDTH; ++col) { - int index = (row * Map::WIDTH) + col; - if (index < static_cast(room_data.collision_tile_map.size())) { - out << room_data.collision_tile_map[index]; - } else { - out << 0; - } - if (col < Map::WIDTH - 1) { out << ", "; } - } - out << "]\n"; - } + write_grid(room_data.tile_map, " # Mapa de dibujo (indices de tiles, -1 = vacio)\n draw:\n", -1); + write_grid(room_data.collision_tile_map, " # Mapa de colisiones (0 = vacio, 1 = solido)\n collision:\n", 0); +} - // --- Enemigos --- - if (!room_data.enemies.empty()) { +void RoomFormat::writeEnemiesSection(std::ostringstream& out, const Room::Data& room_data) { + if (room_data.enemies.empty()) { return; } + out << "\n"; + out << "# Enemigos en esta habitación\n"; + out << "enemies:\n"; + for (const auto& enemy : room_data.enemies) { + out << " - animation: " << enemy.animation_path << "\n"; + if (enemy.type != "path") { out << " type: " << enemy.type << "\n"; } + + const int POS_X = static_cast(std::round(enemy.x / Tile::SIZE)); + const int POS_Y = static_cast(std::round(enemy.y / Tile::SIZE)); + out << " position: {x: " << POS_X << ", y: " << POS_Y << "}\n"; + out << " velocity: {x: " << enemy.vx << ", y: " << enemy.vy << "}\n"; + + const int B1_X = enemy.x1 / Tile::SIZE; + const int B1_Y = enemy.y1 / Tile::SIZE; + const int B2_X = enemy.x2 / Tile::SIZE; + const int B2_Y = enemy.y2 / Tile::SIZE; + out << " boundaries:\n"; + out << " position1: {x: " << B1_X << ", y: " << B1_Y << "}\n"; + out << " position2: {x: " << B2_X << ", y: " << B2_Y << "}\n"; + + if (enemy.flip) { out << " flip: true\n"; } + if (enemy.mirror) { out << " mirror: true\n"; } + if (enemy.frame != -1) { out << " frame: " << enemy.frame << "\n"; } out << "\n"; - out << "# Enemigos en esta habitación\n"; - out << "enemies:\n"; - for (const auto& enemy : room_data.enemies) { - out << " - animation: " << enemy.animation_path << "\n"; - if (enemy.type != "path") { out << " type: " << enemy.type << "\n"; } - - int pos_x = static_cast(std::round(enemy.x / Tile::SIZE)); - int pos_y = static_cast(std::round(enemy.y / Tile::SIZE)); - out << " position: {x: " << pos_x << ", y: " << pos_y << "}\n"; - - out << " velocity: {x: " << enemy.vx << ", y: " << enemy.vy << "}\n"; - - int b1_x = enemy.x1 / Tile::SIZE; - int b1_y = enemy.y1 / Tile::SIZE; - int b2_x = enemy.x2 / Tile::SIZE; - int b2_y = enemy.y2 / Tile::SIZE; - out << " boundaries:\n"; - out << " position1: {x: " << b1_x << ", y: " << b1_y << "}\n"; - out << " position2: {x: " << b2_x << ", y: " << b2_y << "}\n"; - - if (enemy.flip) { out << " flip: true\n"; } - if (enemy.mirror) { out << " mirror: true\n"; } - if (enemy.frame != -1) { out << " frame: " << enemy.frame << "\n"; } - - out << "\n"; - } } +} - // --- Items --- - if (!room_data.items.empty()) { - out << "# Objetos en esta habitación\n"; - out << "items:\n"; - for (const auto& item : room_data.items) { - out << " - tileSetFile: " << item.tile_set_file << "\n"; - out << " tile: " << item.tile << "\n"; +void RoomFormat::writeItemsSection(std::ostringstream& out, const Room::Data& room_data) { + if (room_data.items.empty()) { return; } + out << "# Objetos en esta habitación\n"; + out << "items:\n"; + for (const auto& item : room_data.items) { + out << " - tileSetFile: " << item.tile_set_file << "\n"; + out << " tile: " << item.tile << "\n"; - int item_x = static_cast(std::round(item.x / Tile::SIZE)); - int item_y = static_cast(std::round(item.y / Tile::SIZE)); - out << " position: {x: " << item_x << ", y: " << item_y << "}\n"; + const int ITEM_X = static_cast(std::round(item.x / Tile::SIZE)); + const int ITEM_Y = static_cast(std::round(item.y / Tile::SIZE)); + out << " position: {x: " << ITEM_X << ", y: " << ITEM_Y << "}\n"; - if (item.counter != 0) { - out << " counter: " << item.counter << "\n"; - } - - // color1/color2 solo si son override explícito del default - if (item.color1_overridden) { - out << " color1: " << static_cast(item.color1) << "\n"; - } - if (item.color2_overridden) { - out << " color2: " << static_cast(item.color2) << "\n"; - } - - out << "\n"; - } + if (item.counter != 0) { out << " counter: " << item.counter << "\n"; } + if (item.color1_overridden) { out << " color1: " << static_cast(item.color1) << "\n"; } + if (item.color2_overridden) { out << " color2: " << static_cast(item.color2) << "\n"; } + out << "\n"; } +} - // --- Plataformas --- - if (!room_data.platforms.empty()) { - out << "# Plataformas móviles en esta habitación\n"; - out << "platforms:\n"; - for (const auto& plat : room_data.platforms) { - out << " - animation: " << plat.animation_path << "\n"; - out << " speed: " << plat.speed << "\n"; - out << " loop: " << (plat.loop == LoopMode::CIRCULAR ? "circular" : "pingpong") << "\n"; - if (plat.easing != "linear") { out << " easing: " << plat.easing << "\n"; } - if (plat.frame != -1) { out << " frame: " << plat.frame << "\n"; } - out << " path:\n"; - for (const auto& wp : plat.path) { - int wx = static_cast(std::round(wp.x / Tile::SIZE)); - int wy = static_cast(std::round(wp.y / Tile::SIZE)); - out << " - {x: " << wx << ", y: " << wy; - if (wp.wait > 0.0F) { out << ", wait: " << wp.wait; } - out << "}\n"; - } - out << "\n"; +void RoomFormat::writePlatformsSection(std::ostringstream& out, const Room::Data& room_data) { + if (room_data.platforms.empty()) { return; } + out << "# Plataformas móviles en esta habitación\n"; + out << "platforms:\n"; + for (const auto& plat : room_data.platforms) { + out << " - animation: " << plat.animation_path << "\n"; + out << " speed: " << plat.speed << "\n"; + out << " loop: " << (plat.loop == LoopMode::CIRCULAR ? "circular" : "pingpong") << "\n"; + if (plat.easing != "linear") { out << " easing: " << plat.easing << "\n"; } + if (plat.frame != -1) { out << " frame: " << plat.frame << "\n"; } + out << " path:\n"; + for (const auto& wp : plat.path) { + const int WX = static_cast(std::round(wp.x / Tile::SIZE)); + const int WY = static_cast(std::round(wp.y / Tile::SIZE)); + out << " - {x: " << WX << ", y: " << WY; + if (wp.wait > 0.0F) { out << ", wait: " << wp.wait; } + out << "}\n"; } + out << "\n"; } +} - // --- Llaves --- - if (!room_data.keys.empty()) { - out << "# Llaves en esta habitación\n"; - out << "keys:\n"; - for (const auto& key : room_data.keys) { - out << " - animation: " << key.animation_path << "\n"; - out << " id: \"" << key.id << "\"\n"; - int kx = static_cast(std::round(key.x / Tile::SIZE)); - int ky = static_cast(std::round(key.y / Tile::SIZE)); - out << " position: {x: " << kx << ", y: " << ky << "}\n"; - out << "\n"; - } +void RoomFormat::writeKeysSection(std::ostringstream& out, const Room::Data& room_data) { + if (room_data.keys.empty()) { return; } + out << "# Llaves en esta habitación\n"; + out << "keys:\n"; + for (const auto& key : room_data.keys) { + out << " - animation: " << key.animation_path << "\n"; + out << " id: \"" << key.id << "\"\n"; + const int KX = static_cast(std::round(key.x / Tile::SIZE)); + const int KY = static_cast(std::round(key.y / Tile::SIZE)); + out << " position: {x: " << KX << ", y: " << KY << "}\n"; + out << "\n"; } +} - // --- Puertas --- - if (!room_data.doors.empty()) { - out << "# Puertas en esta habitación\n"; - out << "doors:\n"; - for (const auto& door : room_data.doors) { - out << " - animation: " << door.animation_path << "\n"; - out << " id: \"" << door.id << "\"\n"; - int dx = static_cast(std::round(door.x / Tile::SIZE)); - int dy = static_cast(std::round(door.y / Tile::SIZE)); - out << " position: {x: " << dx << ", y: " << dy << "}\n"; - out << "\n"; - } +void RoomFormat::writeDoorsSection(std::ostringstream& out, const Room::Data& room_data) { + if (room_data.doors.empty()) { return; } + out << "# Puertas en esta habitación\n"; + out << "doors:\n"; + for (const auto& door : room_data.doors) { + out << " - animation: " << door.animation_path << "\n"; + out << " id: \"" << door.id << "\"\n"; + const int DX = static_cast(std::round(door.x / Tile::SIZE)); + const int DY = static_cast(std::round(door.y / Tile::SIZE)); + out << " position: {x: " << DX << ", y: " << DY << "}\n"; + out << "\n"; } +} +auto RoomFormat::buildContent(const Room::Data& room_data) -> std::string { + std::ostringstream out; + writeRoomSection(out, room_data); + writeTilemapSection(out, room_data); + writeEnemiesSection(out, room_data); + writeItemsSection(out, room_data); + writePlatformsSection(out, room_data); + writeKeysSection(out, room_data); + writeDoorsSection(out, room_data); return out.str(); } diff --git a/source/game/gameplay/room_format.hpp b/source/game/gameplay/room_format.hpp index 94f72e7..2ce1479 100644 --- a/source/game/gameplay/room_format.hpp +++ b/source/game/gameplay/room_format.hpp @@ -1,7 +1,8 @@ #pragma once -#include // Para string -#include // Para vector +#include // Para ostringstream +#include // Para string +#include // Para vector #include "external/fkyaml_node.hpp" // Para fkyaml::node #include "game/entities/door.hpp" // Para Door::Data @@ -90,5 +91,12 @@ class RoomFormat { // --- Serialization helpers (solo en debug, los usa saveYAML) --- static auto buildContent(const Room::Data& room_data) -> std::string; static auto roomConnectionToYAML(const std::string& connection) -> std::string; + static void writeRoomSection(std::ostringstream& out, const Room::Data& room_data); + static void writeTilemapSection(std::ostringstream& out, const Room::Data& room_data); + static void writeEnemiesSection(std::ostringstream& out, const Room::Data& room_data); + static void writeItemsSection(std::ostringstream& out, const Room::Data& room_data); + static void writePlatformsSection(std::ostringstream& out, const Room::Data& room_data); + static void writeKeysSection(std::ostringstream& out, const Room::Data& room_data); + static void writeDoorsSection(std::ostringstream& out, const Room::Data& room_data); #endif };