Files
aee-arcade/source/game/map/paint_layer.hpp
T

73 lines
2.6 KiB
C++

#pragma once
#include <cstdint>
#include <string>
#include <vector>
#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, int player_id = -1) -> 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<std::vector<int>> painted_;
std::vector<std::uint32_t> pixels_;
};