#pragma once #ifdef _DEBUG #include #include // Para shared_ptr, unique_ptr #include // Para string #include "external/fkyaml_node.hpp" // Para fkyaml::node #include "game/editor/tile_picker.hpp" // Para TilePicker #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; // Comandos para enemigos (llamados desde console_commands) auto setEnemyProperty(const std::string& property, const std::string& value) -> std::string; auto addEnemy() -> std::string; auto deleteEnemy() -> std::string; auto duplicateEnemy() -> std::string; [[nodiscard]] auto hasSelectedEnemy() const -> bool; // Comandos para propiedades de la habitación auto setRoomProperty(const std::string& property, const std::string& value) -> std::string; // Opciones del editor (llamados desde console_commands / teclas) auto showInfo(bool show) -> std::string; auto showGrid(bool show) -> std::string; [[nodiscard]] auto isGridEnabled() const -> bool { return settings_.grid; } // Comandos para items auto setItemProperty(const std::string& property, const std::string& value) -> std::string; auto addItem() -> std::string; auto deleteItem() -> std::string; auto duplicateItem() -> std::string; [[nodiscard]] auto hasSelectedItem() const -> bool; void openTilePicker(const std::string& tileset_name, int current_tile); private: static MapEditor* instance_; // [SINGLETON] Objeto privado MapEditor(); // Constructor ~MapEditor(); // Destructor // Opciones persistentes del editor struct Settings { bool grid{false}; bool show_render_info{false}; }; Settings settings_; void loadSettings(); void saveSettings(); // Tipos para drag & drop y selección enum class DragTarget { NONE, PLAYER, ENEMY_INITIAL, ENEMY_BOUND1, ENEMY_BOUND2, ITEM }; struct DragState { DragTarget target{DragTarget::NONE}; int index{-1}; float offset_x{0.0F}; float offset_y{0.0F}; float snap_x{0.0F}; float snap_y{0.0F}; bool moved{false}; // true si el ratón se movió durante el drag }; // Métodos internos void updateMousePosition(); void renderEnemyBoundaries(); void renderBoundaryMarker(float x, float y, Uint8 color); void renderSelectionHighlight(); void renderGrid(); void handleMouseDown(float game_x, float game_y); void handleMouseUp(); void updateDrag(); void autosave(); void updateStatusBarInfo(); static auto snapToGrid(float value) -> float; static auto pointInRect(float px, float py, const SDL_FRect& rect) -> bool; // Estado del editor bool active_{false}; DragState drag_; int selected_enemy_{-1}; // Índice del enemigo seleccionado (-1 = ninguno) int selected_item_{-1}; // Índice del item seleccionado (-1 = ninguno) static constexpr int NO_BRUSH = -2; // Sin brush activo static constexpr int ERASER_BRUSH = -1; // Brush borrador (pinta tile vacío = -1) int brush_tile_{NO_BRUSH}; // Tile activo para pintar bool painting_{false}; // true mientras se está pintando con click izquierdo mantenido // Datos de la habitación Room::Data room_data_; std::string room_path_; std::string file_path_; // YAML: nodo original (para campos que no se editan: name_ca, etc.) fkyaml::node yaml_; fkyaml::node yaml_backup_; // Referencias a objetos vivos std::shared_ptr room_; std::shared_ptr player_; std::shared_ptr scoreboard_data_; // Barra de estado del editor std::unique_ptr statusbar_; // Tile picker (para seleccionar tiles de un tileset) TilePicker tile_picker_; // Estado del ratón float mouse_game_x_{0.0F}; float mouse_game_y_{0.0F}; int mouse_tile_x_{0}; int mouse_tile_y_{0}; // Estado previo (para restaurar al salir) Options::Cheat::State invincible_before_editor_{Options::Cheat::State::DISABLED}; bool render_info_before_editor_{false}; }; #endif // _DEBUG