BUG-GUARD-DEAF-1 закрыт: страж оборачивается на вернувшегося Кида
Проверено в игре: комната 11 уровня 2, страж выталкивает Кида в 22, Кид возвращается бегом — страж оборачивается и достаёт меч. Разбор корня (is_guard_notice не взводился ни в одном из пяти мест оригинала) переехал в bug_closed.md. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -11,6 +11,89 @@
|
||||
|
||||
---
|
||||
|
||||
## BUG-GUARD-DEAF-1. Страж не оборачивался на вернувшегося Кида — **ЗАКРЫТ 2026-08-05**
|
||||
|
||||
**Наблюдение (пользователь, 2026-08-05).** Уровень 2, комната 11, идёт бой
|
||||
со стражем. Страж **выталкивает Кида в правую комнату 22**. Кид заходит
|
||||
обратно в комнату 11 — страж стоит на (1,1), **повёрнут налево и Кида не
|
||||
видит**. Предположение пользователя: это часть большой задачи «полностью
|
||||
переделать поведение стража по образцу Кида».
|
||||
|
||||
**Диагноз: большая переделка тут ни при чём, корень маленький и точный.**
|
||||
Само возвращение стража в исходную позу — ПРАВИЛЬНОЕ поведение, порт верен;
|
||||
не хватает ровно одного сигнала.
|
||||
|
||||
Разбор по SDLPoP:
|
||||
|
||||
1. **Выход Кида из комнаты «усыпляет» стража — так и в оригинале.**
|
||||
`leave_guard` (seg002:02F5) складывает стража обратно в данные уровня
|
||||
(тайл, `x`, **направление**, skill, HP), а `enter_guard` (seg002:0112)
|
||||
при возврате поднимает живого стража **с УБРАННЫМ мечом**
|
||||
(`sword_0_sheathed` + `seq_77_guard_stand_inactive`) и обнуляет
|
||||
`is_guard_notice`/`guard_refrac`. То есть страж после возврата ВСЕГДА
|
||||
неактивен и смотрит в запомненную сторону — у нас так же
|
||||
(`pop_guard_enter`, `pop_guard.c:127`).
|
||||
2. **Дальше решает `autocontrol_guard_inactive` (seg002:0876), и он Кида за
|
||||
спиной ИГНОРИРУЕТ.** Кид вернулся справа, страж смотрит влево →
|
||||
`char_opp_dist()` отрицательна → ветка `else if (distance < 0) return;`.
|
||||
Единственный выход из неё — флаг **`is_guard_notice`**: «Кид нашумел».
|
||||
При нём страж оборачивается (`move_4_down`). Направление в
|
||||
`check_can_guard_see_kid` НЕ участвует вовсе, так что «не видит» — это
|
||||
не про луч видимости, а именно про этот флаг.
|
||||
3. **У нас `is_guard_notice` не взводится НИГДЕ.** `grep` по всем исходникам
|
||||
roomtest: объявление (`pop_guard.c:20`), сброс (`pop_guard.c:47`) и одно
|
||||
чтение (`guards.c:171`). Присваивания `= 1` нет ни одного — флаг мёртв,
|
||||
поэтому неактивный страж не обернётся НИКОГДА, что бы Кид ни делал.
|
||||
|
||||
**Где его взводит оригинал** (это и есть объём фикса):
|
||||
|
||||
| место | событие |
|
||||
|-------|---------|
|
||||
| `seg006:633..641` — `play_seq`, опкод SOUND | звук `SND_SILENT`(0), `SND_FOOTSTEP`(1), `SND_BUMP`(2). `SND_DRINK`(3)/`SND_LEVEL`(4) — НЕ шум. Главный источник: шаги бега/приземления |
|
||||
| `seg004:05F1` `bumped_sound` | удар в стену |
|
||||
| `seg005:185,195` | мягкое и среднее приземление (**только `charid_0_kid`**) |
|
||||
| `seg006:1294`, `seg006:1734` | Кид обрушил loose-плиту (зацепом и наступив) |
|
||||
| `seg007:766` | нажата кнопка |
|
||||
|
||||
У нас опкод SOUND в `play_seq` (`pop_kid.c:426`) просто съедает байт
|
||||
аргумента — звука нет, и флаг вместе с ним потерялся. Именно эта строка —
|
||||
90 % фикса: `SND_SILENT` называется «silent» потому, что звука не издаёт,
|
||||
**но стражи его всё равно замечают**, и в `seqtbl` он стоит, например, в
|
||||
`ready` (доставание меча).
|
||||
|
||||
**Ожидаемое поведение после фикса.** Кид возвращается в комнату 11 бегом →
|
||||
первый же `SND_FOOTSTEP` взводит флаг → страж оборачивается и достаёт меч.
|
||||
Стоя на месте, Кид может подкрасться к стражу со спины — это НЕ баг, а
|
||||
механика оригинала.
|
||||
|
||||
**Оговорка (не проверено вживую).** Разбор построен на том, что страж после
|
||||
возврата неактивен (меч убран, кадр 166). Это следует из кода
|
||||
`pop_guard_enter`, но в MAME не снималось; если окажется, что меч у него
|
||||
ОБНАЖЁН, то работает другая ветка (`autocontrol_guard_active`, где
|
||||
`can_guard_see_kid == 2` направления не спрашивает) — и тогда корень другой.
|
||||
Снять при фиксе: `Guard.sword`, `Guard.frame`, `can_guard_see_kid` сразу
|
||||
после входа в комнату.
|
||||
|
||||
**Фикс (2026-08-05): все пять мест портированы.** Опкод SOUND в `play_seq`
|
||||
(`pop_kid.c`) взводит флаг для звуков 0..2; `bumped_fall`/`bumped_floor`,
|
||||
мягкое и среднее приземление, обрушенная плита (все три пути `check_press`)
|
||||
— в `pop_map.c`; щелчок кнопки — в `pop_trob.c`. Заглушка `is_guard_notice`
|
||||
добавлена в `tests-host/stubs.c` (автопилота стража в наборах нет).
|
||||
|
||||
**Проверено в игре (пользователь, 2026-08-05):** тот же сценарий — страж
|
||||
выталкивает Кида в комнату 22, Кид возвращается бегом — **страж
|
||||
оборачивается**.
|
||||
|
||||
**Что осталось «как в оригинале» и багом не является:** подкрасться к
|
||||
стражу СТОЯ по-прежнему можно (шумит движение, а не присутствие), и после
|
||||
возврата в комнату страж всегда поднимается с УБРАННЫМ мечом в неактивной
|
||||
стойке, повёрнутый туда же, куда смотрел при выходе Кида — это `enter_guard`
|
||||
(seg002:0112), а не потеря состояния.
|
||||
|
||||
---
|
||||
|
||||
---
|
||||
|
||||
## BUG-JUMPWALL-1. Недолетевший прыжок проходил СКВОЗЬ стену — **ЗАКРЫТ 2026-08-05**
|
||||
|
||||
**Симптом (пользователь, приёмка уровня 3).** Комната 14: Кид на (0,8)
|
||||
|
||||
Reference in New Issue
Block a user