diff --git a/data/player/morcus.yaml b/data/player/morcus.yaml index 716dd65..2f8bca4 100644 --- a/data/player/morcus.yaml +++ b/data/player/morcus.yaml @@ -157,6 +157,7 @@ jump: hurt: speed: 120 brake_time_ms: 500 + sound: hurt.wav # Configuració del látigo. Mateixos valors que Sam de moment; # diferenciar quan equilibrem cada personatge. @@ -165,3 +166,4 @@ whip: swing_ms: 200 cooldown_ms: 200 damage: 1 + sound: whip.wav diff --git a/data/player/sam.yaml b/data/player/sam.yaml index 31cacf2..07d663c 100644 --- a/data/player/sam.yaml +++ b/data/player/sam.yaml @@ -157,6 +157,7 @@ jump: hurt: speed: 120 brake_time_ms: 500 + sound: hurt.wav # Configuració del látigo. `range_tiles` és la longitud de la hitbox # abans de retallar contra murs/sarcs (3 tiles ≈ 48 px). `swing_ms` és @@ -170,3 +171,4 @@ whip: swing_ms: 200 cooldown_ms: 200 damage: 1 + sound: whip.wav diff --git a/source/game/entities/player.cpp b/source/game/entities/player.cpp index 443294f..ffa6b5f 100644 --- a/source/game/entities/player.cpp +++ b/source/game/entities/player.cpp @@ -179,6 +179,11 @@ void Player::readHurtBlock(const fkyaml::node& yaml) { const auto& h = yaml["hurt"]; if (h.contains("speed")) { hurt_config.initial_speed_px_per_s = h["speed"].get_value(); } if (h.contains("brake_time_ms")) { hurt_config.brake_time_ms = h["brake_time_ms"].get_value(); } + // So d'entrada a HURT — mateix patró que `jump.sound` i `whip.sound`. + if (h.contains("sound")) { + hurt_config.sound_key = h["sound"].get_value(); + Resource::Cache::get().loadSound(hurt_config.sound_key, "data/sounds/" + hurt_config.sound_key); + } } void Player::readWhipBlock(const fkyaml::node& yaml) { @@ -189,6 +194,12 @@ void Player::readWhipBlock(const fkyaml::node& yaml) { if (w.contains("swing_ms")) { whip_config.swing_ms = w["swing_ms"].get_value(); } if (w.contains("cooldown_ms")) { whip_config.cooldown_ms = w["cooldown_ms"].get_value(); } if (w.contains("damage")) { whip_config.damage = w["damage"].get_value(); } + // So del swing: mateix patró que `jump.sound` — basename val de + // clau al cache i de path. Si manca, queda buit i no es dispara. + if (w.contains("sound")) { + whip_config.sound_key = w["sound"].get_value(); + Resource::Cache::get().loadSound(whip_config.sound_key, "data/sounds/" + whip_config.sound_key); + } } void Player::applyCardinal(Cardinal c) { @@ -662,6 +673,13 @@ void Player::enterAttacking(Cardinal facing) { if (facing == Cardinal::NONE) { return; } + // So del swing — disparat ací (no des del WhipAttack) perquè és el + // jugador qui executa l'acció; si demà el spawn falla per qualsevol + // motiu, el so del gest segueix sonant. + if (!whip_config.sound_key.empty() && Audio::get() != nullptr) { + Audio::get()->playSound(whip_config.sound_key, Audio::Group::GAME); + } + // Mapa de Cardinal → int al payload (vegeu `WhipSpawnPayload`). int dir_int = 0; switch (facing) { @@ -802,6 +820,9 @@ void Player::enterHurt(Cardinal preferred) { // Activem l'estat i fixem la velocitat segons la direcció triada. state_ = State::HURT; + if (!hurt_config.sound_key.empty() && Audio::get() != nullptr) { + Audio::get()->playSound(hurt_config.sound_key, Audio::Group::GAME); + } applyCardinal(CHOSEN); last_input_cardinal_ = CHOSEN; turning_remaining_ms_ = 0.0F; diff --git a/source/game/entities/player.hpp b/source/game/entities/player.hpp index ad2ad3e..6f0558e 100644 --- a/source/game/entities/player.hpp +++ b/source/game/entities/player.hpp @@ -511,6 +511,11 @@ class Player : public AnimatedSprite { struct HurtConfig { float initial_speed_px_per_s{0.0F}; // Velocitat amb què surt projectat (px/s). int brake_time_ms{0}; // Temps en que la velocitat decau a 0. + // Fitxer .wav reproduït en entrar a HURT (relatiu a `data/sounds/`). + // Mateixa convenció que la resta de sons del jugador: el basename val + // de clau al Resource::Cache i de path. Buit o absent = entrada + // silenciosa. + std::string sound_key; }; static HurtConfig hurt_config; @@ -529,6 +534,10 @@ class Player : public AnimatedSprite { int swing_ms{0}; int cooldown_ms{0}; int damage{0}; + // Fitxer .wav reproduït al moment de disparar el swing (relatiu a + // `data/sounds/`). Convenció: el basename val tant de clau al + // Resource::Cache com de path. Buit o absent = swing silenciós. + std::string sound_key; }; static WhipConfig whip_config;