diff --git a/applications/SprPoP/src/guards.c b/applications/SprPoP/src/guards.c index f7579d6..59e4ef1 100644 --- a/applications/SprPoP/src/guards.c +++ b/applications/SprPoP/src/guards.c @@ -1102,8 +1102,6 @@ static void check_hurting(void) (of != FRAME_161_PARRY && of != FRAME_150_PARRY)) { /* Соперник НЕ парирует. */ if (cf == FRAME_154_POKING) { - /* seg002:0DAE — свист клинка мимо цели. */ - pop_sfx_play(11); min_range = (uint8_t)(Opp.sword < SWORD_2_DRAWN ? 8 : 12); distance = pop_char_opp_dist(); if (distance >= (int16_t)min_range && distance < 29) @@ -1116,6 +1114,29 @@ static void check_hurting(void) pop_char_set_seq(SEQ_69_ATTACK_WAS_PARRIED); play_seq(); } + + /* СВИСТ КЛИНКА МИМО ЦЕЛИ (seg002:1039..1044) — в оригинале он стоит в + * ХВОСТЕ функции, после ОБЕИХ веток, а не внутри ветки «не парировано». + * Мы его туда и переносим; раньше он звучал раньше времени и без двух + * условий оригинала, отчего на подъёме Кида шёл непрерывный взмах + * клинка у безоружного (наблюдение пользователя 2026-09-02, звук + * опознан по snd_curr == 11 в живой сессии). + * + * Три отличия от прежнего кода, все из оригинала: + * + * 1. Ранний выход по dir_56_none — это ИМЕННО анти-зацикливание, автор + * SDLPoP так его и подписал («Fix looping sword moving sound»). + * Направление dir_56_none означает «персонаж выключен» (clear_char), + * и махать клинком ему нечем. + * 2. Условие `Opp.action != ACTION_99_HURT`: попали — играет звук боли, + * а не свист мимо. Поэтому звук обязан идти ПОСЛЕ присвоения выше. + * 3. Кадры перечитываются у персонажей, а не берутся из cf/of: ветка + * парирования только что записала Opp.frame, а play_seq в ней — + * Char.frame, и снимки выше уже устарели. */ + if (Char.direction == DIR_56_NONE) return; + if (Char.frame == FRAME_154_POKING && Opp.frame != FRAME_161_PARRY && + Opp.action != ACTION_99_HURT) + pop_sfx_play(11); } /* check_sword_hurting (seg002:0D1A): прогнать проверку с ОБЕИХ сторон. */