#pragma once #ifdef _DEBUG #include #include class Tilemap; // Mode editor modal del GameScene. Només disponible en Debug — en Release // aquesta classe no existeix (el .cpp es compila a un object buit i cap // codi del joc final en fa referència). // // L'editor NO gestiona la tecla de toggle pròpia (`editor_toggle`): això // ho fa GameScene per poder decidir la coexistència amb la pausa F11 // (mútuament excloents). L'editor s'encarrega de: // - Estat propi (mode actiu, brush per mode, picker obert). // - Input del ratolí i tecles internes (`T`, `E`, `H`, `Supr`, `ESC`). // - Render del border blau + brush preview + picker. // - Persistència del tilemap i de les entitats al YAML del repo en sortir. // // Modes del cursor (`Mode`): // - TILE : el clic esquerre pinta el `brush_tile_` al tilemap. // - ENTITY : el clic esquerre col·loca una instància de `brush_entity_`. // - HAND : selecciona/mou/borra entitats existents. // // Pickers (`Picker`): // - TILE_PICKER (`T`) : selecciona índex de tile. // - ENTITY_PICKER (`E`) : selecciona tipus d'entitat (nom registrat al // factory). // Mútuament excloents: obrir un tanca l'altre. class Editor { public: // Entra al mode editor: notifica i marca `active=true`. La congelació // d'entitats / jugador la gestiona GameScene consultant `active()`. void enter(); // Surt del mode editor: persisteix el tilemap al YAML (writer surgical) // i notifica. Si la persistència falla, emet la notificació d'error. void exit(Tilemap& tilemap); // Helper: enter() si no actiu, exit() si actiu. Útil des de GameScene // quan detecta la tecla de toggle. void toggle(Tilemap& tilemap); [[nodiscard]] auto active() const -> bool { return active_; } // Processa input propi (brush, picker). No-op si no actiu. void update(int delta_ms, Tilemap& tilemap); // Pinta el border blau i, segons mode i picker, brush preview, marc // d'entitat seleccionada o el picker. No-op si no actiu. void render(const Tilemap& tilemap) const; private: // Mode del cursor: determina què fa el clic esquerre sobre el mapa. enum class Mode : std::uint8_t { TILE, ENTITY, HAND }; // Quin picker està obert (si n'hi ha). Mútuament excloents. enum class Picker : std::uint8_t { NONE, TILE, ENTITY }; // Consum de hotkeys pròpies (T, E, H, ESC). Modifica `mode_` / `picker_`. // Es crida al principi d'`update` perquè altres handlers no vegin // tecles ja interpretades pel propi editor. void handleHotkeys(); // Aplica una tecla i retorna true si l'editor l'ha consumit. Aïllat // per mantenir baixa la complexitat cognitiva de `handleHotkeys` — // l'iteració del buffer queda neta i la lògica de transició viu en // un sol lloc. auto applyHotkey(int scancode) -> bool; // Branques d'update segons (mode, picker). Només té sentit cridar-les // des d'`update`. void updateTileBrush(Tilemap& tilemap, int canvas_x, int canvas_y); void updateEntityBrush(int canvas_x, int canvas_y); void updateHand(int canvas_x, int canvas_y); void updateTilePicker(const Tilemap& tilemap, int canvas_x, int canvas_y); void updateEntityPicker(int canvas_x, int canvas_y); void renderTilePicker(const Tilemap& tilemap) const; void renderEntityPicker(const Tilemap& tilemap) const; bool active_{false}; Mode mode_{Mode::TILE}; Picker picker_{Picker::NONE}; // Cursor en cel·les del tilemap. -1/-1 = fora del mapa. int cursor_col_{-1}; int cursor_row_{-1}; // Brush actiu per Mode::TILE (índex al tileset; -1 = sense brush). int brush_tile_{-1}; // Estat del TilePicker. int tile_picker_scroll_{0}; int tile_picker_hover_{-1}; // Brush actiu per Mode::ENTITY (nom registrat al factory; "" = cap). std::string brush_entity_; // Estat de l'EntityPicker. int entity_picker_scroll_{0}; int entity_picker_hover_{-1}; // Índex a la llista de noms. // Selecció en Mode::HAND (índex dins de l'EntityManager; -1 = cap). int hand_selected_idx_{-1}; }; #endif // _DEBUG