#pragma once #include // Para string #include // Para vector #include "external/fkyaml_node.hpp" // Para fkyaml::node #include "game/entities/door.hpp" // Para Door::Data #include "game/entities/enemy.hpp" // Para Enemy::Data #include "game/entities/item.hpp" // Para Item::Data #include "game/entities/key.hpp" // Para Key::Data #include "game/entities/moving_platform.hpp" // Para MovingPlatform::Data #include "game/gameplay/room.hpp" // Para Room::Data /** * @brief Autoridad única del formato yaml de habitaciones * * Esta clase es el ÚNICO sitio del código que conoce la estructura del * fichero room.yaml. Combina parser (loadYAML) y serializador (saveYAML, en * builds de debug) en un mismo módulo para forzar que cuando se añada un * campo nuevo se actualicen ambos lados al mismo tiempo. * * Reemplaza al antiguo `RoomLoader` y `RoomSaver`. La versión nueva: * - Elimina la rama de retrocompatibilidad para tilemaps con formato antiguo * (un yaml sin `tilemap.draw`/`tilemap.collision` ahora da error claro, * no un crash diferido por collision_tile_map vacío). * - Simplifica saveYAML para no recibir el yaml original (ya no se usaba). * - Añade createDefault() para que MapEditor::createNewRoom no tenga que * conocer el formato. */ class RoomFormat { public: RoomFormat() = delete; ~RoomFormat() = delete; RoomFormat(const RoomFormat&) = delete; auto operator=(const RoomFormat&) -> RoomFormat& = delete; RoomFormat(RoomFormat&&) = delete; auto operator=(RoomFormat&&) -> RoomFormat& = delete; /** * @brief Carga un room.yaml desde disco/pack y devuelve Room::Data * * Usa Resource::Helper::loadFile, que soporta tanto el resource pack * como el filesystem. Disponible en runtime (lo usa Resource::Cache). */ static auto loadYAML(const std::string& file_path, bool verbose = false) -> Room::Data; #ifdef _DEBUG /** * @brief Carga un room desde un string yaml (usado por reloadRoom del cache) */ static auto loadFromString(const std::string& yaml_content, const std::string& file_name) -> Room::Data; /** * @brief Serializa Room::Data al disco. Solo el editor escribe rooms. * @return mensaje de éxito o error (prefijo "Error" si falla) */ static auto saveYAML(const std::string& file_path, const Room::Data& data) -> std::string; /** * @brief Construye un Room::Data válido y completo con valores por defecto * * Lo usa MapEditor::createNewRoom para no tener que conocer el formato. * El campo `number` y las conexiones recíprocas los rellena el caller. */ static auto createDefault() -> Room::Data; #endif private: // --- Parsing helpers (siempre disponibles, los usa loadYAML) --- static auto convertRoomConnection(const std::string& value) -> std::string; static auto convertAutoSurface(const fkyaml::node& node) -> int; static auto flattenTilemap(const std::vector>& tilemap_2d) -> std::vector; // NOLINT(readability-avoid-const-params-in-decls) static void parseRoomConfig(const fkyaml::node& yaml, Room::Data& room, const std::string& file_name); static void parseRoomConnections(const fkyaml::node& conn_node, Room::Data& room); static void parseTilemap(const fkyaml::node& yaml, Room::Data& room, const std::string& file_name, bool verbose); static void parseEnemies(const fkyaml::node& yaml, Room::Data& room, bool verbose); static auto parseEnemyData(const fkyaml::node& enemy_node) -> Enemy::Data; static void parseEnemyBoundaries(const fkyaml::node& bounds_node, Enemy::Data& enemy); static void parseItems(const fkyaml::node& yaml, Room::Data& room, bool verbose); static auto parseItemData(const fkyaml::node& item_node) -> Item::Data; static void parsePlatforms(const fkyaml::node& yaml, Room::Data& room, bool verbose); static auto parsePlatformData(const fkyaml::node& platform_node) -> MovingPlatform::Data; static void parseKeys(const fkyaml::node& yaml, Room::Data& room, bool verbose); static auto parseKeyData(const fkyaml::node& key_node) -> Key::Data; static void parseDoors(const fkyaml::node& yaml, Room::Data& room, bool verbose); static auto parseDoorData(const fkyaml::node& door_node) -> Door::Data; static void parseAll(const fkyaml::node& yaml, Room::Data& room, const std::string& file_name, bool verbose); #ifdef _DEBUG // --- 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; #endif };