feat(entities): andamiatge del sistema d'entitats (classes, factory, bus, YAML, placeholders, smoke tests)
This commit is contained in:
1 parent
984cc820c0
commit
96b71b0f65
48 files changed
+1957
No files matched your search
@@ -0,0 +1,86 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <unordered_set>
|
||||
|
||||
#include "external/fkyaml_node.hpp"
|
||||
#include "game/entities/animation_component.hpp"
|
||||
#include "game/entities/interactable.hpp"
|
||||
|
||||
// Sarcòfag: rectangle de tiles que el jugador ha de rodar completament pel
|
||||
// perímetre per "obrir". Tres estats (com la porta):
|
||||
// CLOSED → inicial; `visited_` s'acumula amb les notificacions.
|
||||
// OPENING → `visited_ == perimeter_tiles_`; reprodueix animació d'obertura.
|
||||
// OPEN → emitit l'event `sarcophagus_opened`.
|
||||
//
|
||||
// El càlcul de `perimeter_tiles_` es fa al ctor a partir de la posició del
|
||||
// sarcòfag a la graella del Map (`anchor_col`, `anchor_row`) i de les
|
||||
// dimensions en tiles (`tile_size_w_`, `tile_size_h_`, llegits del YAML
|
||||
// plantilla). Es recorren els tiles adjacents per N/S/E/O; els que
|
||||
// cauen dins d'un altre sarcòfag es descarten (predicat opcional). Si no
|
||||
// s'aporta el predicat, s'inclouen tots.
|
||||
class Sarcophagus : public Interactable {
|
||||
public:
|
||||
enum class State : std::uint8_t { CLOSED,
|
||||
OPENING,
|
||||
OPEN };
|
||||
|
||||
// `is_blocked` rep un (col,row) i retorna true si el tile està ocupat
|
||||
// per un altre sarcòfag o és fora del playfield (és a dir, NO és un
|
||||
// tile de corredor vàlid). L'usa `EntityManager` passant-li
|
||||
// `Map::collides` traduït a tiles. Si és nullptr, cap tile es descarta
|
||||
// i el perímetre es computa purament geomètric (útil als tests).
|
||||
using BlockedPredicate = std::function<bool(int col, int row)>;
|
||||
|
||||
Sarcophagus(const fkyaml::node& yaml, int anchor_col, int anchor_row, const BlockedPredicate& is_blocked);
|
||||
explicit Sarcophagus(const fkyaml::node& yaml); // variant sense ancoratge (usat pel factory)
|
||||
|
||||
// Configura ancoratge i (re)calcula perímetre. Útil quan el factory
|
||||
// crea l'instància abans de conèixer la posició; el `EntityLoader`
|
||||
// invoca aquesta funció amb les coordenades del spawn.
|
||||
void place(int anchor_col, int anchor_row, const BlockedPredicate& is_blocked);
|
||||
|
||||
void update(float delta_time) override;
|
||||
void notifyTileEntered(int col, int row) override;
|
||||
|
||||
[[nodiscard]] auto getState() const -> State { return state_; }
|
||||
[[nodiscard]] auto getPerimeterSize() const -> std::size_t { return perimeter_tiles_.size(); }
|
||||
[[nodiscard]] auto getVisitedCount() const -> std::size_t { return visited_.size(); }
|
||||
|
||||
// Dimensions del rectangle en tiles (p.ex. 3×1 per al sarcòfag
|
||||
// estàndard). Exposat per al smoke test i per al render futur.
|
||||
[[nodiscard]] auto getTileWidth() const -> int { return tile_size_w_; }
|
||||
[[nodiscard]] auto getTileHeight() const -> int { return tile_size_h_; }
|
||||
|
||||
private:
|
||||
struct TileKey {
|
||||
int col;
|
||||
int row;
|
||||
auto operator==(const TileKey& o) const -> bool { return col == o.col && row == o.row; }
|
||||
};
|
||||
struct TileKeyHash {
|
||||
auto operator()(const TileKey& k) const -> std::size_t {
|
||||
// Combinació simple; els valors són petits (<100) i el set no és gran.
|
||||
return (static_cast<std::size_t>(k.col) * 131U) ^ static_cast<std::size_t>(k.row);
|
||||
}
|
||||
};
|
||||
|
||||
void computePerimeter(const BlockedPredicate& is_blocked);
|
||||
|
||||
int tile_size_w_{1};
|
||||
int tile_size_h_{1};
|
||||
int anchor_col_{0};
|
||||
int anchor_row_{0};
|
||||
|
||||
std::unordered_set<TileKey, TileKeyHash> perimeter_tiles_;
|
||||
std::unordered_set<TileKey, TileKeyHash> visited_;
|
||||
|
||||
State state_{State::CLOSED};
|
||||
|
||||
AnimationComponent anim_closed_;
|
||||
AnimationComponent anim_opening_;
|
||||
AnimationComponent anim_open_;
|
||||
|
||||
bool opened_event_emitted_{false};
|
||||
};
|
||||
Reference in new issue
Block a user