#pragma once #ifdef _DEBUG #include #include // Para shared_ptr, unique_ptr #include // Para string #include "external/fkyaml_node.hpp" // Para fkyaml::node #include "game/entities/enemy.hpp" // Para Enemy::Data #include "game/entities/item.hpp" // Para Item::Data #include "game/entities/player.hpp" // Para Player::SpawnData #include "game/gameplay/room.hpp" // Para Room::Data #include "game/gameplay/scoreboard.hpp" // Para Scoreboard::Data #include "game/options.hpp" // Para Options::Cheat class EditorStatusBar; class MapEditor { public: static void init(); // [SINGLETON] Crea el objeto static void destroy(); // [SINGLETON] Destruye el objeto static auto get() -> MapEditor*; // [SINGLETON] Obtiene el objeto void enter(std::shared_ptr room, std::shared_ptr player, const std::string& room_path, std::shared_ptr scoreboard_data); void exit(); [[nodiscard]] auto isActive() const -> bool { return active_; } void update(float delta_time); void render(); void handleEvent(const SDL_Event& event); auto revert() -> std::string; // Revierte todos los cambios al estado original private: static MapEditor* instance_; // [SINGLETON] Objeto privado MapEditor(); // Constructor ~MapEditor(); // Destructor // Tipos para drag & drop enum class DragTarget { NONE, PLAYER, ENEMY_INITIAL, ENEMY_BOUND1, ENEMY_BOUND2, ITEM }; struct DragState { DragTarget target{DragTarget::NONE}; int index{-1}; // Índice del enemigo o item en room_data_ float offset_x{0.0F}; // Offset entre el cursor y el origen de la entidad al inicio del drag float offset_y{0.0F}; float snap_x{0.0F}; // Posición snapped actual (para preview) float snap_y{0.0F}; }; // Métodos internos void updateMousePosition(); // Convierte coordenadas de ventana a coordenadas de juego y tile void renderEnemyBoundaries(); // Dibuja marcadores de boundaries y líneas de ruta void renderBoundaryMarker(float x, float y, Uint8 color); // Dibuja un marcador de boundary en una posición void renderSelectionHighlight(); // Dibuja highlight del elemento seleccionado/arrastrado void handleMouseDown(float game_x, float game_y); // Procesa click del ratón (hit test + inicio de drag) void handleMouseUp(); // Procesa soltar el ratón (commit del drag + autosave) void updateDrag(); // Actualiza la posición snapped durante el drag void autosave(); // Guarda los cambios puntuales al YAML static auto snapToGrid(float value) -> float; // Alinea un valor a la cuadrícula de 8x8 static auto pointInRect(float px, float py, const SDL_FRect& rect) -> bool; // Hit test punto en rectángulo // Estado del editor bool active_{false}; DragState drag_; // Datos de la habitación Room::Data room_data_; // Copia mutable (para boundaries y edición) std::string room_path_; // Nombre del fichero (ej: "06.yaml") std::string file_path_; // Ruta completa del fichero en disco // YAML: nodo vivo (se edita parcialmente) y backup para revert fkyaml::node yaml_; // Nodo YAML actual (editado parcialmente) fkyaml::node yaml_backup_; // Backup del YAML original al entrar // Referencias a objetos vivos (para rendering) std::shared_ptr room_; std::shared_ptr player_; std::shared_ptr scoreboard_data_; // Barra de estado del editor std::unique_ptr statusbar_; // Estado del ratón en coordenadas de juego float mouse_game_x_{0.0F}; float mouse_game_y_{0.0F}; int mouse_tile_x_{0}; int mouse_tile_y_{0}; // Estado previo de invencibilidad (para restaurar al salir) Options::Cheat::State invincible_before_editor_{Options::Cheat::State::DISABLED}; }; #endif // _DEBUG