Страж возвращался в комнату не туда: колонку несёт guards_x, а не тайл
Уровень 8 комната 24: после первого же выхода Кида страж телепортировался в колонку 0, а ряд 0 там пустой в колонках 1..3 — страж падал с ряда 0 на ряд 2 и разбивался. leave_guard (seg002:02F5) кладёт в guards_tile get_tilepos(0, row), то есть обнуляет колонку НАМЕРЕННО: позицию по горизонтали несёт guards_x, туда же она и пишется. enter_guard берёт x оттуда всегда. Мы же считали x из tile % 10 (то есть из нуля), а запомненную брали только у трупа. Заодно портирован pos_guards (seg003:0913): при загрузке уровня guards_x пересчитывается из колонки тайла, а файловое значение выбрасывается — в комнате 24 уровня 8 там 255. Проверено в MAME: три входа подряд дают одну и ту же позицию (x 156, ряд 0), страж стоит на полу. Host-тесты 5106 проверок без расхождений. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -3085,3 +3085,70 @@ else died_on_button(...); /* мёртв — кнопка С
|
||||
досчитать до 0 и снять trob. С фиксом сцена так не воспроизводится
|
||||
(решётка уходит в `FF`), проверить нечем; если всплывёт где-то ещё — это
|
||||
отдельный баг, к `died_on_button` отношения не имеющий.
|
||||
|
||||
---
|
||||
|
||||
<a id="guard-respawn-col0"></a>
|
||||
## GUARD-RESPAWN-COL0. Страж при возврате в комнату телепортировался в колонку 0 и падал
|
||||
|
||||
**Наблюдение (пользователь, 2026-08-18).** Уровень 8, комната 24. Первый
|
||||
вход из левой комнаты — страж около `(0,7)`, стоит. Кид уходит вправо и
|
||||
возвращается — страж уже «в `(0,-1)`». Ещё раз туда-обратно — страж на
|
||||
`(0,0)`, идёт биться, падает на два ряда и разбивается. Второй сценарий:
|
||||
вход из комнаты 23, страж на `(0,7)` неподвижен; Кид уходит влево и
|
||||
возвращается — страж падает на `(2,1)` и разбивается.
|
||||
|
||||
Формулировка пользователя — «страж, если не может биться с Кидом, не должен
|
||||
менять позиции; иначе он будет ждать Кида прямо на входе, и тот не успеет
|
||||
достать меч» — совпадает с тем, что гарантирует оригинал.
|
||||
|
||||
**Как это устроено в оригинале.** Позиция стража живёт в ТРЁХ полях данных
|
||||
уровня, и колонки среди них нет:
|
||||
|
||||
- `pos_guards` (seg003:0913), один раз сразу после `load_level`:
|
||||
`guards_x[room] = x_bump[(tile % 10) + FIRST_ONSCREEN_COLUMN] + TILE_SIZEX`.
|
||||
То, что лежит в `guards_x` В ФАЙЛЕ, оригинал ВЫБРАСЫВАЕТ (в комнате 24
|
||||
уровня 8 там 255);
|
||||
- `leave_guard` (seg002:02F5) при уходе Кида:
|
||||
`guards_tile = get_tilepos(0, row)` — колонка обнуляется НАМЕРЕННО, тайл
|
||||
несёт только РЯД, — и `guards_x = Guard.x`, то есть настоящая позиция;
|
||||
- `enter_guard` (seg002:0112) при возврате: `curr_row = tile / 10`,
|
||||
`y = y_land[row + 1]`, **`x = guards_x`**, `curr_col = f(x)`.
|
||||
|
||||
Носитель колонки — `guards_x`, и только она.
|
||||
|
||||
**Что было у нас.** `pop_guard_leave` тайл обнуляла верно, а
|
||||
`pop_guard_enter` считала X из `tile % 10` — из колонки, которой там уже нет.
|
||||
Запомненную X брали ТОЛЬКО у трупа. Значит после ПЕРВОГО же выхода из
|
||||
комнаты живой страж возвращался в колонку 0.
|
||||
|
||||
Численно: тайл стража комнаты 24 = 6 (ряд 0, колонка 6), ряд 0 =
|
||||
`13 00 00 00 0F 01 01 01 01 01`, то есть **колонки 1..3 ПУСТЫЕ**, а в
|
||||
колонке 0 факел. Телепорт давал `x = x_bump[5] + 14 = 72`, а 72 по таблице
|
||||
деления — это колонка **1**: страж оказывался над дырой, падал с ряда 0 на
|
||||
ряд 2 (щебень в `(2,1)`) — два ряда, смерть. Оба сценария пользователя
|
||||
ложатся сюда ровно, включая «упал на 2,1».
|
||||
|
||||
**Фикс.** Два места, оба — приведение к оригиналу:
|
||||
|
||||
- `pop_gstate_init` — порт `pos_guards`: при загрузке уровня `GS_X`
|
||||
считается из колонки тайла, а не читается из файла;
|
||||
- `pop_guard_enter` — `Guard.x` берётся из запомненной ВСЕГДА, не только у
|
||||
трупа; колонка, как и раньше, считается из X.
|
||||
|
||||
**Проверка в MAME** (уровень 8, комната 24, три входа через `enter_room`):
|
||||
|
||||
| | room | x | y | col | row | alive |
|
||||
|---|---|---|---|---|---|---|
|
||||
| первый вход | 24 | 156 | 55 | 7 | 0 | жив |
|
||||
| возврат | 24 | 156 | 55 | 7 | 0 | жив |
|
||||
| второй возврат | 24 | 156 | 55 | 7 | 0 | жив |
|
||||
|
||||
Позиция не меняется, страж стоит на полу. Host-тесты — 5106 проверок без
|
||||
расхождений. Резидент без изменений, банк 8 −15 Б.
|
||||
|
||||
**Что осталось невыясненным.** Наблюдение «страж был в `(0,-1)`» отдельно
|
||||
не воспроизведено: телепорт даёт колонку 0/1, а −1 требует `x < 65`.
|
||||
Вероятнее всего это кадр уже НАЧАВШЕГОСЯ падения (при падении X сносит), но
|
||||
доказательства нет. Если `(0,-1)` появится на исправленном билде — это
|
||||
отдельный баг.
|
||||
|
||||
Reference in New Issue
Block a user