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

+25 -2
View File
@@ -83,6 +83,15 @@ Sarcophagus::Sarcophagus(const fkyaml::node& yaml)
opening_pitch_spread_ = s["opening_pitch_spread"].get_value<float>();
}
}
// Bloc `reward:` opcional — la recompensa que rebrà el jugador que
// tanqui el sarcòfag. Si no hi és, els camps queden a 0 i el GameScene
// simplement no aplica res al consumir `sarcophagus_opened`.
if (yaml.contains("reward")) {
const auto& r = yaml["reward"];
if (r.contains("points")) { points_reward_ = r["points"].get_value<int>(); }
if (r.contains("treasures")) { treasures_reward_ = r["treasures"].get_value<int>(); }
}
}
void Sarcophagus::place(int anchor_col, int anchor_row, const BlockedPredicate& is_blocked) {
@@ -135,18 +144,32 @@ void Sarcophagus::update(float delta_time) {
anim_ = anim_open_;
if (anim_.has_value()) { anim_->reset(); }
if (!opened_event_emitted_ && bus_ != nullptr) {
bus_->publish("sarcophagus_opened", static_cast<Entity*>(this));
// Publica amb `player_id = last_closer_player_id_` perquè el
// GameScene pugui atribuir la recompensa al jugador correcte.
// El payload manté el punter al sarc perquè el consumidor
// pugui llegir `getPointsReward()` i `getTreasuresReward()`.
bus_->publish(Event{
.name = "sarcophagus_opened",
.payload = static_cast<Entity*>(this),
.player_id = last_closer_player_id_,
});
opened_event_emitted_ = true;
}
}
}
void Sarcophagus::notifyTilePainted(int col, int row) {
void Sarcophagus::notifyTilePainted(int col, int row, int player_id) {
if (state_ != State::CLOSED) { return; }
const TileKey KEY{.col = col, .row = row};
if (perimeter_tiles_.find(KEY) == perimeter_tiles_.end()) { return; }
visited_.insert(KEY);
if (visited_.size() >= perimeter_tiles_.size()) {
// Atribució: el jugador que pinta el tile que tanca el cercle es
// queda amb la recompensa. Si el broadcast inicial de càrrega
// arribara a tancar un sarc (no hauria de passar perquè els tiles
// d'aquest broadcast són decals/murs, no de corredor), `player_id`
// seria -1 i el GameScene saltarà el repartiment.
last_closer_player_id_ = player_id;
state_ = State::OPENING;
anim_ = anim_opening_;
if (anim_.has_value()) { anim_->reset(); }