Files
jaildoctors_dilemma/source/game/editor/map_editor.hpp
2026-04-02 23:01:39 +02:00

163 lines
5.8 KiB
C++

#pragma once
#ifdef _DEBUG
#include <SDL3/SDL.h>
#include <memory> // Para shared_ptr, unique_ptr
#include <string> // Para string
#include "external/fkyaml_node.hpp" // Para fkyaml::node
#include "game/editor/mini_map.hpp" // Para MiniMap
#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> room, std::shared_ptr<Player> player, const std::string& room_path, std::shared_ptr<Scoreboard::Data> 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;
auto createNewRoom(const std::string& direction = "") -> std::string;
auto deleteRoom() -> 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; }
void toggleMiniMap();
void setReenter(bool value) { reenter_ = value; }
auto setMiniMapBg(const std::string& color) -> std::string;
auto setMiniMapConn(const std::string& color) -> std::string;
// 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};
std::string minimap_bg{"blue"};
std::string minimap_conn{"white"};
};
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();
auto getAssetsYamlPath() -> std::string;
void addRoomToAssetsYaml(const std::string& room_name);
void removeRoomFromAssetsYaml(const std::string& room_name);
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> room_;
std::shared_ptr<Player> player_;
std::shared_ptr<Scoreboard::Data> scoreboard_data_;
// Barra de estado del editor
std::unique_ptr<EditorStatusBar> statusbar_;
// Tile picker y mini mapa
TilePicker tile_picker_;
std::unique_ptr<MiniMap> mini_map_;
bool mini_map_visible_{false};
// 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};
bool reenter_{false}; // true cuando es un re-enter tras cambio de room (no tocar render_info)
};
#endif // _DEBUG