feat(stats): Player com a font de veritat de vides/score/tresors i sarcs amb recompensa

This commit is contained in:
JailDesigner committed 2026-05-12 19:51:42 +02:00
1 parent d186f66c2c
commit f5d251c33b
14 files changed
+226 -34

No files matched your search

+26 -3
View File
@@ -19,12 +19,21 @@ class Player;
// Event pub/sub minimalista. Hi ha un únic `EventBus` per mundus (propietat
// de l'`EntityManager`); les entitats que el necessiten en reben un punter
// via `Entity::setEventBus`. Aquest sistema cobreix les necessitats
// actuals (sarcophagus_opened, level_complete, player_hit, on_tile_entered)
// sense portar-hi senyalització més pesada.
// actuals (sarcophagus_opened, level_complete, player_hit, on_tile_entered,
// player_stats_changed) sense portar-hi senyalització més pesada.
//
// Decisió: `std::variant` per al payload — evita any/void* i facilita
// consumir events tipats amb `std::get_if`. Si apareixen més tipus de
// payload, s'amplia aquí sense tocar cridants existents.
//
// `player_stats_changed`: l'únic canal numèric que toca el HUD. El `Player`
// és la font de veritat de vides/score/tresors i el publica cada vegada
// que muta qualsevol d'aquests camps. El HUD el consumeix com a "snapshot
// total" (no com a delta) — sobreescriu la seua caché amb el payload. Així
// qualsevol via que modifique stats al Player (mort per forat, recompensa
// de sarc, etc.) queda automàticament reflectida sense que cada caller
// haja de recordar publicar res addicional. `player_hit` queda només per
// al feedback visual (flash/shake), separat del comptador.
// Tile (col, row) — payload de `tile_painted` (i altres events de tile sense
// metadada extra). No és un `pair<int,int>` per evitar alias ambigus al
@@ -74,9 +83,20 @@ struct WhipSpawnPayload {
float range_px{0.0F};
};
// Snapshot complet dels stats d'un jugador — payload de `player_stats_changed`.
// El Player publica un d'aquests cada vegada que muta vides/score/tresors.
// El HUD el consumeix com a estat absolut (no delta): sobreescriu la seua
// caché amb aquests valors. El `player_id` de l'`Event` indica a quin
// bloc del HUD va dirigit.
struct PlayerStatsPayload {
int lives{0};
int score{0};
int treasures{0};
};
struct Event {
std::string name;
using Payload = std::variant<std::monostate, int, std::string, Entity*, TilePos, PaintedTile, WorldPos, WhipSpawnPayload>;
using Payload = std::variant<std::monostate, int, std::string, Entity*, TilePos, PaintedTile, WorldPos, WhipSpawnPayload, PlayerStatsPayload>;
Payload payload;
// Jugador que ha originat (o provocat) l'event. -1 = sense jugador
// associat (events del món, com `sarcophagus_opened` des de la pròpia
@@ -129,6 +149,9 @@ class EventBus {
void publish(const std::string& name, const WhipSpawnPayload& whip) {
publish(Event{.name = name, .payload = whip});
}
void publish(const std::string& name, const PlayerStatsPayload& stats) {
publish(Event{.name = name, .payload = stats});
}
private:
struct Subscription {