feat(stats): Player com a font de veritat de vides/score/tresors i sarcs amb recompensa
This commit is contained in:
1 parent
d186f66c2c
commit
f5d251c33b
14 files changed
+226
-34
No files matched your search
+28
-9
@@ -135,10 +135,14 @@ Hud::Hud(EventBus& bus, std::shared_ptr<Text> font, int initial_lives)
|
||||
players_[1].active = false;
|
||||
players_[1].lives = initial_lives_;
|
||||
|
||||
// Subscripcions al bus de l'EntityManager. De moment només `player_hit`
|
||||
// afecta el HUD visualment: decrementa vides, dispara flash i shake al
|
||||
// bloc del jugador. Quan els events evolucionin per portar `player_id`
|
||||
// i puntuacions, ampliarem aquí sense tocar callers.
|
||||
// Subscripcions al bus de l'EntityManager.
|
||||
//
|
||||
// `player_hit` només fa feedback visual (flash + shake) al bloc del
|
||||
// jugador colpejat. **No** toca el comptador de vides — la veritat
|
||||
// viu al Player i arriba per `player_stats_changed`. Així si un hit
|
||||
// no és mortal (HURT recoverable) el flash es manté coherent sense
|
||||
// mentir el comptador, i si és mortal el comptador baixa pel canal
|
||||
// numèric quan el cicle DYING acaba a `respawnFromDying`.
|
||||
subs_.push_back(bus_.subscribe("player_hit", [this](const Event& ev) {
|
||||
const auto* dmg = std::get_if<int>(&ev.payload);
|
||||
// Dispatch pel `player_id` de l'event. 0 = P1 (bloc LEFT), 1 = P2
|
||||
@@ -147,14 +151,28 @@ Hud::Hud(EventBus& bus, std::shared_ptr<Text> font, int initial_lives)
|
||||
// publishers de `player_hit` actuals sí que porten id.
|
||||
const std::size_t IDX = (ev.player_id == 1) ? 1U : 0U;
|
||||
if (!players_[IDX].active) { return; }
|
||||
if (players_[IDX].lives > 0) { --players_[IDX].lives; }
|
||||
const std::size_t BLK_IDX = (IDX == 0) ? static_cast<std::size_t>(BlockId::LEFT)
|
||||
: static_cast<std::size_t>(BlockId::RIGHT);
|
||||
auto& blk = blocks_[BLK_IDX];
|
||||
blk.flash_ms_left = UiConfig::get().hudFlashMs();
|
||||
blk.shake_ms_left = UiConfig::get().hudShakeMs();
|
||||
blk.shake_intensity = 1.5F;
|
||||
Log::info("HUD", "player_hit p{} dmg={} lives={}", IDX + 1, dmg != nullptr ? *dmg : 0, players_[IDX].lives);
|
||||
Log::info("HUD", "player_hit p{} dmg={}", IDX + 1, dmg != nullptr ? *dmg : 0);
|
||||
}));
|
||||
|
||||
// `player_stats_changed`: snapshot total (vides/score/tresors) emès
|
||||
// pel Player cada vegada que muta qualsevol dels tres. El HUD el
|
||||
// consumeix com a estat absolut: sobreescriu la caché local sense
|
||||
// raonament addicional. Això unifica totes les fonts de canvi (mort
|
||||
// per qualsevol causa, recompensa de sarc, futurs pickups…) en un
|
||||
// únic canal.
|
||||
subs_.push_back(bus_.subscribe("player_stats_changed", [this](const Event& ev) {
|
||||
const auto* st = std::get_if<PlayerStatsPayload>(&ev.payload);
|
||||
if (st == nullptr) { return; }
|
||||
const std::size_t IDX = (ev.player_id == 1) ? 1U : 0U;
|
||||
players_[IDX].lives = st->lives;
|
||||
players_[IDX].score = st->score;
|
||||
players_[IDX].treasures = st->treasures;
|
||||
}));
|
||||
|
||||
subs_.push_back(bus_.subscribe("level_complete", [](const Event& /*ev*/) {
|
||||
@@ -207,10 +225,11 @@ void Hud::activatePlayer(int player_one_based) {
|
||||
if (player_one_based < 1 || player_one_based > 2) { return; }
|
||||
auto& p = players_[static_cast<std::size_t>(player_one_based - 1)];
|
||||
p.active = true;
|
||||
p.lives = initial_lives_;
|
||||
p.score = 0;
|
||||
p.treasures = 0;
|
||||
p.join_prompt = JoinPromptMode::NONE;
|
||||
// Els camps numèrics (lives/score/treasures) ja els ha sobreescrit el
|
||||
// `player_stats_changed` que el Player publica dins de `resetForJoin`,
|
||||
// així que aquí no els toquem — evitem trepitjar la veritat del bus
|
||||
// amb defaults locals.
|
||||
}
|
||||
|
||||
void Hud::setJoinPrompt(int player_one_based, JoinPromptMode mode) {
|
||||
|
||||
Reference in new issue
Block a user