map_editor:

- tilepicker s'obri ara amb la T
- brush de varios tiles
- eyedropper amb botó dret (de uno o varios tiles)
This commit is contained in:
2026-04-10 21:33:57 +02:00
parent 342b46ca32
commit fadc3b03c9
5 changed files with 363 additions and 88 deletions

View File

@@ -6,6 +6,7 @@
#include <memory> // Para shared_ptr, unique_ptr
#include <string> // Para string
#include <vector> // Para vector
#include "game/editor/mini_map.hpp" // Para MiniMap
#include "game/editor/tile_picker.hpp" // Para TilePicker
@@ -41,6 +42,40 @@ struct Selection {
[[nodiscard]] auto is(EntityType t) const -> bool { return type == t && index >= 0; }
};
// Brush rectangular para pintar tiles. Una sola estructura cubre:
// - brush vacío (width=0, height=0)
// - single tile (width=1, height=1, tiles={N})
// - borrador explícito (width=1, height=1, tiles={ERASE})
// - patrón rectangular sampleado del nivel o del tileset
struct BrushPattern {
static constexpr int TRANSPARENT = -2; // celda no se escribe al estampar
static constexpr int ERASE = -1; // celda escribe -1 (vacía el destino)
int width{0};
int height{0};
std::vector<int> tiles; // size = width*height, row-major
[[nodiscard]] auto isEmpty() const -> bool { return width <= 0 || height <= 0; }
[[nodiscard]] auto at(int dx, int dy) const -> int { return tiles[(dy * width) + dx]; }
void clear() {
width = 0;
height = 0;
tiles.clear();
}
void setSingle(int tile) {
width = 1;
height = 1;
tiles = {tile};
}
};
// Estado del eyedropper (clic derecho con drag para samplear el nivel)
struct EyedropperState {
bool active{false};
int start_tile_x{0};
int start_tile_y{0};
};
class MapEditor {
public:
static void init(); // [SINGLETON] Crea el objeto
@@ -152,9 +187,15 @@ class MapEditor {
void renderEntityBoundaries();
static void renderBoundaryMarker(float x, float y, Uint8 color);
void renderSelectionHighlight();
void renderBrushPreview();
void renderEyedropperRect();
void renderGrid() const;
void handleMouseDown(float game_x, float game_y);
void handleMouseUp();
void stampBrushAt(int tile_x, int tile_y);
void commitEyedropper();
[[nodiscard]] auto sampleBrush(int x1, int y1, int x2, int y2) const -> BrushPattern;
[[nodiscard]] auto buildPatternFromTileset(const std::string& tileset_name, int col, int row, int width, int height) const -> BrushPattern;
// Reconstruye todas las puertas vivas desde room_data_, limpiando primero
// los WALLs antiguos del CollisionMap. Lo usa setDoorProperty cuando un
@@ -184,12 +225,11 @@ class MapEditor {
// Estado del editor
bool active_{false};
DragState drag_;
Selection selection_; // Entidad seleccionada (unificada: enemy, item o platform)
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
bool editing_collision_{false}; // true = editando collision tilemap, false = editando draw tilemap
Selection selection_; // Entidad seleccionada (unificada: enemy, item o platform)
BrushPattern brush_; // Brush activo (vacío = sin brush)
EyedropperState eyedropper_; // Estado del eyedropper (clic derecho)
bool painting_{false}; // true mientras se está pintando con click izquierdo mantenido
bool editing_collision_{false}; // true = editando collision tilemap, false = editando draw tilemap
// Datos de la habitación
Room::Data room_data_;