#pragma once #include #include #include #include "game/entities/event_bus.hpp" class Tilemap; // Capa visual de "pintat" sobre el tilemap base. Quan el jugador (o // qualsevol altre actor futur) publica `on_tile_entered` amb payload // `PaintedTile{col, row, tile_index}`, el PaintLayer filtra per // `Map::isPaintable`, marca el tile i re-publica `tile_painted` amb // només `TilePos` — abstracció del "el tile s'ha pintat" independent de // qui ho ha fet. Els sarcòfags escolten aquest segon event per comptar // el seu perímetre. // // Font única de veritat del pintat: evita duplicar l'estat dins de cada // sarcòfag i permet que el render mostri l'efecte al instant. // // Geometria: hereta `tile_size`, origen i dimensions del Tilemap // (mateixa graella). Reutilitza el tileset del Tilemap per blitejar els // tiles pintats a un buffer ARGB propi, anàleg a `Tilemap::pixels_`. // // Política de repintat: el primer que pinta un tile guanya. Intents // posteriors (amb el mateix índex o un altre) no tenen efecte — // garanteix coherència visual i evita notificar dos cops al mateix sarc. class PaintLayer { public: PaintLayer(const Tilemap& tilemap, EventBus* bus); ~PaintLayer(); PaintLayer(const PaintLayer&) = delete; PaintLayer(PaintLayer&&) = delete; auto operator=(const PaintLayer&) -> PaintLayer& = delete; auto operator=(PaintLayer&&) -> PaintLayer& = delete; // Còpia del buffer ARGB sobre el canvas del Screen, respectant alpha // (píxels no pintats queden al buffer amb alpha=0 i no s'escriuen). // Pensat per cridar entre `Tilemap::render()` i el bloc d'actors. void render() const; // Intent de pintat directe (exposat per a tests i actors que pinten // sense passar pel bus). Retorna true si el tile és pintable i no // estava ja pintat; en aquest cas, publica `tile_painted`. auto tryPaint(int col, int row, int tile_index) -> bool; [[nodiscard]] auto isPainted(int col, int row) const -> bool; private: void blitPaintTile(int col, int row, int tile_index); EventBus* bus_{nullptr}; EventBus::SubId on_tile_sub_{0}; int cols_{0}; int rows_{0}; int tile_size_{0}; int origin_x_{0}; int origin_y_{0}; int width_px_{0}; int height_px_{0}; int tileset_cols_{0}; std::string tileset_path_; // `-1` = no pintat. Altres valors = índex de tile del tileset usat // per pintar. No cal per al render (el buffer `pixels_` ja el conté), // però facilita consultes ràpides d'estat i futures extensions. std::vector> painted_; std::vector pixels_; };