From b7811180baef172af645bcf0c7cd053af00e80f7 Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Mon, 11 May 2026 07:53:56 +0200 Subject: [PATCH] feat(game): spawn inicial de ROOM_INTRO sense immunitat --- source/game/entities/player.cpp | 11 +++++++---- source/game/entities/player.hpp | 8 ++++---- source/game/scenes/game_scene.cpp | 8 ++++++++ 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/source/game/entities/player.cpp b/source/game/entities/player.cpp index 09b4e6f..d20d0b2 100644 --- a/source/game/entities/player.cpp +++ b/source/game/entities/player.cpp @@ -1589,10 +1589,13 @@ void Player::respawn(float x, float y) { setPosX(x); setPosY(y); // Immunitat post-spawn: armem la finestra de gràcia amb la durada del - // YAML. Cobreix l'aparició inicial (`spawnFromAir` → `respawn`) i el - // respawn post-mort (`respawnFromDying` → `respawn`). Si el bloc - // `immunity:` manca al YAML, `duration_ms` és 0 i `setImmunity` és - // no-op — comportament idèntic al d'abans. + // YAML. Cobreix el join mid-partida (`joinPlayer` → `spawnFromAir` → + // `respawn`) i el respawn post-mort (`respawnFromDying` → `respawn`). + // L'spawn inicial de ROOM_INTRO també hi passa, però `triggerPlayerSpawn` + // crida `setImmunity(0)` immediatament després per cancel·lar-la (els + // enemics ja estan apareixent i el jugador no ha de tindre gràcia). + // Si el bloc `immunity:` manca al YAML, `duration_ms` és 0 i el timer + // queda a 0 — sense gràcia, comportament idèntic al d'abans. setImmunity(immunity_config.duration_ms); } diff --git a/source/game/entities/player.hpp b/source/game/entities/player.hpp index 4c1611a..a574873 100644 --- a/source/game/entities/player.hpp +++ b/source/game/entities/player.hpp @@ -331,11 +331,11 @@ class Player : public AnimatedSprite { // sortida lògica del món. Idempotent: una segona crida reescriu el // timer (no acumula). Visualment, el render alterna la paleta del // sprite amb una paleta plana cada `immunity_config.blink_period_ms` - // ms. Si `duration_ms <= 0` és no-op (manera de cancel·lar - // explícitament la immunitat seria `setImmunity(0)` — equivalent al - // comportament natural quan el timer s'esgota). + // ms. `setImmunity(0)` cancel·la la immunitat activa (sobreescriu el + // timer a 0) — equivalent al comportament natural quan el timer + // s'esgota. Valors negatius es clampejen a 0. void setImmunity(float duration_ms) { - if (duration_ms > 0.0F) { immunity_remaining_ms_ = duration_ms; } + immunity_remaining_ms_ = duration_ms > 0.0F ? duration_ms : 0.0F; } // Cert mentre el jugador té immunitat activa. Comprovat per diff --git a/source/game/scenes/game_scene.cpp b/source/game/scenes/game_scene.cpp index a59f496..022078d 100644 --- a/source/game/scenes/game_scene.cpp +++ b/source/game/scenes/game_scene.cpp @@ -701,6 +701,14 @@ void GameScene::triggerPlayerSpawn(std::size_t slot_index) { // pot canviar de geometria de porta entre cicles. players_[slot_index]->setSpawnPoint(x, SPAWN.y); players_[slot_index]->spawnFromAir(x, SPAWN.y); + // Spawn inicial sense gràcia: l'aparició coincideix amb el moment + // en què comencen a aparèixer els enemics, i la finestra d'immunitat + // que arma `respawn` deixaria al jugador immune just quan ja hauria + // de poder ser tocat. Cancel·lem el timer recent armat. Els altres + // camins (`joinPlayer` mid-partida i `respawnFromDying`) sí que + // mantenen la immunitat: són situacions on el jugador apareix enmig + // de l'acció ja en curs i necessita la finestra de gràcia. + players_[slot_index]->setImmunity(0.0F); // Arma el reverb del primer LAND com a part de la cinemàtica // d'INTRO. Una sola vegada per spawn aeri: el respawn post-mort // (que no passa per ací) cau al camí sec. Si el preset està buit