diff --git a/data/room/03.yaml b/data/room/03.yaml index 75b531c..b08fe88 100644 --- a/data/room/03.yaml +++ b/data/room/03.yaml @@ -4,14 +4,14 @@ enemies: boundaries: position1: x: 5 - y: 10 + y: 13 position2: - x: 14 - y: 10 + x: 16 + y: 13 color: yellow position: - x: 12 - y: 10 + x: 11 + y: 13 velocity: x: 24.0 y: 0 diff --git a/source/core/resources/resource_cache.cpp b/source/core/resources/resource_cache.cpp index 68779b3..830d313 100644 --- a/source/core/resources/resource_cache.cpp +++ b/source/core/resources/resource_cache.cpp @@ -4,6 +4,7 @@ #include // Para find_if #include // Para exit, size_t +#include // Para ifstream, istreambuf_iterator #include // Para basic_ostream, operator<<, endl, cout #include // Para runtime_error #include @@ -15,6 +16,7 @@ #include "core/resources/resource_list.hpp" // Para List, List::Type #include "game/defaults.hpp" // Para Defaults namespace #include "game/gameplay/room.hpp" // Para RoomData, loadRoomFile, loadRoomTileFile +#include "game/gameplay/room_loader.hpp" // Para RoomLoader::loadFromString #include "game/options.hpp" // Para Options, OptionsGame, options #include "utils/defines.hpp" // Para WINDOW_CAPTION #include "utils/utils.hpp" // Para getFileName, printWithDots, PaletteColor @@ -173,6 +175,34 @@ namespace Resource { throw std::runtime_error("Habitación no encontrada: " + name); } +#ifdef _DEBUG + // Recarga una habitación desde disco (para el editor de mapas) + // Lee directamente del filesystem (no del resource pack) para obtener los cambios del editor + void Cache::reloadRoom(const std::string& name) { + auto file_path = List::get()->get(name); + if (file_path.empty()) { + std::cerr << "reloadRoom: Cannot resolve path for " << name << '\n'; + return; + } + + // Leer directamente del filesystem (evita el resource pack que tiene datos antiguos) + std::ifstream file(file_path); + if (!file.is_open()) { + std::cerr << "reloadRoom: Cannot open " << file_path << '\n'; + return; + } + std::string content((std::istreambuf_iterator(file)), std::istreambuf_iterator()); + file.close(); + + // Parsear y actualizar el cache + auto it = std::ranges::find_if(rooms_, [&name](const auto& r) -> bool { return r.name == name; }); + if (it != rooms_.end()) { + *(it->room) = RoomLoader::loadFromString(content, name); + std::cout << "reloadRoom: " << name << " reloaded from filesystem\n"; + } + } +#endif + // Obtiene todas las habitaciones auto Cache::getRooms() -> std::vector& { return rooms_; diff --git a/source/core/resources/resource_cache.hpp b/source/core/resources/resource_cache.hpp index 793f399..83d628d 100644 --- a/source/core/resources/resource_cache.hpp +++ b/source/core/resources/resource_cache.hpp @@ -25,7 +25,10 @@ namespace Resource { auto getRoom(const std::string& name) -> std::shared_ptr; auto getRooms() -> std::vector&; - void reload(); // Recarga todos los recursos + void reload(); // Recarga todos los recursos +#ifdef _DEBUG + void reloadRoom(const std::string& name); // Recarga una habitación desde disco +#endif private: // Estructura para llevar la cuenta de los recursos cargados diff --git a/source/game/editor/room_saver.cpp b/source/game/editor/room_saver.cpp index 6e4c88a..9b0eae8 100644 --- a/source/game/editor/room_saver.cpp +++ b/source/game/editor/room_saver.cpp @@ -3,21 +3,21 @@ #include "game/editor/room_saver.hpp" #include // Para std::round -#include // Para ofstream +#include // Para ifstream, ofstream, istreambuf_iterator #include // Para cout, cerr -#include "core/resources/resource_helper.hpp" // Para Resource::Helper -#include "utils/defines.hpp" // Para Tile::SIZE +#include "utils/defines.hpp" // Para Tile::SIZE -// Carga el YAML original desde disco +// Carga el YAML original directamente del filesystem (no del resource pack) auto RoomSaver::loadYAML(const std::string& file_path) -> fkyaml::node { - auto file_data = Resource::Helper::loadFile(file_path); - if (file_data.empty()) { - std::cerr << "RoomSaver: Cannot load " << file_path << "\n"; + std::ifstream file(file_path); + if (!file.is_open()) { + std::cerr << "RoomSaver: Cannot open " << file_path << "\n"; return {}; } - std::string content(file_data.begin(), file_data.end()); + std::string content((std::istreambuf_iterator(file)), std::istreambuf_iterator()); + file.close(); return fkyaml::node::deserialize(content); } diff --git a/source/game/game_control.hpp b/source/game/game_control.hpp index 84c0124..d42acf3 100644 --- a/source/game/game_control.hpp +++ b/source/game/game_control.hpp @@ -27,5 +27,6 @@ namespace GameControl { inline std::function enter_editor; inline std::function exit_editor; inline std::function revert_editor; + inline std::function reload_current_room; // Recarga la habitación actual desde disco } // namespace GameControl #endif diff --git a/source/game/gameplay/room_loader.cpp b/source/game/gameplay/room_loader.cpp index 1767a3e..0410662 100644 --- a/source/game/gameplay/room_loader.cpp +++ b/source/game/gameplay/room_loader.cpp @@ -316,6 +316,25 @@ void RoomLoader::parseItems(const fkyaml::node& yaml, Room::Data& room, bool ver } } +#ifdef _DEBUG +// Carga una habitación desde un string YAML (para el editor de mapas, evita el resource pack) +auto RoomLoader::loadFromString(const std::string& yaml_content, const std::string& file_name) -> Room::Data { + Room::Data room; + try { + auto yaml = fkyaml::node::deserialize(yaml_content); + parseRoomConfig(yaml, room, file_name); + parseTilemap(yaml, room, file_name, false); + parseEnemies(yaml, room, false); + parseItems(yaml, room, false); + } catch (const fkyaml::exception& e) { + std::cerr << "YAML parsing error in " << file_name << ": " << e.what() << '\n'; + } catch (const std::exception& e) { + std::cerr << "Error loading room " << file_name << ": " << e.what() << '\n'; + } + return room; +} +#endif + // Carga un archivo de room en formato YAML auto RoomLoader::loadYAML(const std::string& file_path, bool verbose) -> Room::Data { // NOLINT(readability-convert-member-functions-to-static) Room::Data room; diff --git a/source/game/gameplay/room_loader.hpp b/source/game/gameplay/room_loader.hpp index 6397a2f..d7774af 100644 --- a/source/game/gameplay/room_loader.hpp +++ b/source/game/gameplay/room_loader.hpp @@ -46,6 +46,9 @@ class RoomLoader { * - items: lista de items (opcional) */ static auto loadYAML(const std::string& file_path, bool verbose = false) -> Room::Data; +#ifdef _DEBUG + static auto loadFromString(const std::string& yaml_content, const std::string& file_name) -> Room::Data; +#endif private: /** diff --git a/source/game/scenes/game.cpp b/source/game/scenes/game.cpp index 4bbe1f2..eee4d7c 100644 --- a/source/game/scenes/game.cpp +++ b/source/game/scenes/game.cpp @@ -123,8 +123,12 @@ Game::Game(Mode mode) GameControl::enter_editor = [this]() -> void { MapEditor::get()->enter(room_, player_, current_room_, scoreboard_data_); }; - GameControl::exit_editor = []() -> void { + GameControl::exit_editor = [this]() -> void { MapEditor::get()->exit(); + // Recargar la habitación desde disco (con los cambios del editor) + Resource::Cache::get()->reloadRoom(current_room_); + changeRoom(current_room_); + player_->setRoom(room_); }; GameControl::revert_editor = []() -> std::string { return MapEditor::get()->revert(); @@ -153,6 +157,7 @@ Game::~Game() { GameControl::enter_editor = nullptr; GameControl::exit_editor = nullptr; GameControl::revert_editor = nullptr; + GameControl::reload_current_room = nullptr; #endif }