Зацеп за кромку нижнего ряда: do_fall пускает ряд до 3 + check_grab в midair
Уровень 7, комната 14: спуск с ряда 0 на ряд 2 через зацеп (повис на кромке кнопки (0,2), отпустил, взялся за (2,2)) не работал ни при какой фазе и задержке — Кид пролетал мимо и разгонялся до fall_y = 33, после чего окно зацепа закрыто уже по скорости. Корень: do_fall не давал curr_row выйти за 2, а check_grab целится в тайл ряда curr_row-1 — то есть ряд 2 своей комнаты становится целью только при curr_row == 3. В оригинале (seg005:0030) inc_curr_row безусловный, а get_tile для ряда 3 уходит по links.down (find_room_of_tile, seg006:005D). - pop_map.c do_fall: inc_curr_row теперь 2 -> 3; ветка «достиг y_land» гейтится по curr_row <= 2 (при ряде 3 ни in_wall, ни land звать нельзя — тайлов своей комнаты там нет, а до y_land[4] дело не доходит: комнату меняет check_leave_below на y >= 211). - pop_map.c check_action: восстановлена ветка ACT_MIDAIR (кадры 102..105, seg006:0619) — первые четыре кадра падения, где fall_y ещё не разогнан, зацеп не работал вовсе. Отсюда же «иногда цепляется, иногда нет». - tests-host/t_grab.c: регресс grab_below_room_edge_window_exists — сцена комнаты 14 + переход в 15 по pop_fell_out. До фикса ни одного зацепа, после — окно из 8 фаз X при задержках 0..5 кадров; проверяется и играбельность (зацеп при «отпустил и сразу зажал Shift»). - roomtest.c + pop_guard.h: чит-навигация ставит Кида на верхний ряд в комнате 14 уровня 7 (GRAB_DOWN_LEVEL/ROOM) — снизу этот спуск не проверить. Общее правило (снизу вверх) не тронуто: в верхнем ряду пола чаще нет и Кид проваливается сразу после телепорта. Проверено: tests-host 5/5 (55 в [grab]), size-check OK, живьём в MAME — Кид повис на кромке (2,2): frame=91 y=55 row=0 room=15. Доски: GRAB-BELOW-ROOM в BUGS_CLOSED, GRAB-KBD-TIMING в BUGS_OPEN (отложен пользователем до готовности всех уровней), план L7-FEATHER в TASKS_OPEN. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -87,6 +87,56 @@ MEM-BANK2, MEM-BANK5, CLIP-1, KBD-1, DBG-CHEATS.
|
||||
|
||||
## P0 — делаем сейчас
|
||||
|
||||
### <a id="l7-feather"></a>L7-FEATHER. Зелье МЕДЛЕННОГО ПАДЕНИЯ (уровень 7, комната 1)
|
||||
|
||||
**Задача (пользователь, 2026-08-12): составить план — здесь он и есть; код
|
||||
следующим заходом.**
|
||||
|
||||
Зелье на `(2,8)` комнаты 1 уровня 7 (сверено по `res2007.bin`: modifier 3, то
|
||||
есть `potion_type = 3` — «slow fall»). Сейчас `pop_proc_get_object`
|
||||
(`pop_map.c`) для типов 3/4/6 не делает НИЧЕГО (явный TODO): зелье выпивается
|
||||
без эффекта.
|
||||
|
||||
Механика оригинала (прочитана в SDLPoP до планирования, правило проекта):
|
||||
|
||||
| что | где в SDLPoP | значение |
|
||||
|---|---|---|
|
||||
| включение | `feather_fall()`, seg000:15F8 | `is_feather_fall = 1`, зелёная вспышка (`flash_color = 2`, `flash_time = 3`), `stop_sounds` + `sound_39_low_weight` |
|
||||
| физика | `fall_accel()`, seg006:057C | ускорение **1** вместо 3, потолок скорости **4** вместо 33 (`FALLING_SPEED_*_FEATHER`, types.h:1435) |
|
||||
| анимация | опкод `SEQ_JMP_IF_FEATHER`, seg006:586 | в seqtbl есть ветки `stepfloat` / `bumpfloat` — «плавные» кадры падения и удара; таблица у нас из данных оригинала, ветки УЖЕ ЛЕЖАТ в ней |
|
||||
| длительность | `do_timers`, seg003:517 | ваниль: пока играет звук (или 225 тиков); фикс SDLPoP `fix_quicksave_during_feather` — таймер `FEATHER_FALL_LENGTH = 18.75 c` |
|
||||
| сброс | seg003:189 (`start_level`) | на старте уровня и, по фиксу, при смерти Кида |
|
||||
| вид склянки | `draw_tile_fore`, seg008:740 | типы 2..4 — БОЛЬШАЯ склянка (id 13) — **у нас уже так** |
|
||||
| цвет пузырьков | `draw_tile_anim`, seg008:652 | типы 3/4 — **зелёный** (`color = 10`), 5/6 — синий, остальные — красный (12) |
|
||||
|
||||
Шаги (в порядке выполнения, каждый проверяем отдельно):
|
||||
|
||||
1. **Состояние.** `pop_feather` (счётчик кадров) в `pop_map.c` рядом с
|
||||
`fall_accel`; экспорт в `pop_map.h` для `play_seq`. Длительность — по
|
||||
таймеру (ванильная привязка к звуку нам не подходит: звука нет), значение
|
||||
пересчитать из 18,75 с в наши кадры и завести в `pop_tune.h`. Сброс — в
|
||||
`pop_start_level` и по смерти Кида.
|
||||
2. **Физика.** `fall_accel()`: при `pop_feather` — `FALL_ACCEL_FEATHER 1` /
|
||||
`FALL_MAX_FEATHER 4`. Только для Кида (`charid == CHARID_0_KID`) — так
|
||||
правильнее по смыслу, но это ОСОЗНАННОЕ расхождение с ванилью (там эффект
|
||||
ловят все, и SDLPoP чинит это опцией) → запись в `../docs/impl_diff.md`.
|
||||
3. **Анимация.** Опкод `0xF7` в `play_seq` (`pop_kid.c`) сейчас БЕЗУСЛОВНО
|
||||
пропускает адрес; сделать как в оригинале: при `pop_feather` — прыжок по
|
||||
адресу (это и даёт `stepfloat`/`bumpfloat`, то есть отсутствие урона и
|
||||
«парение»). Правка на 3 строки, но именно она даёт весь визуальный эффект
|
||||
падения.
|
||||
4. **Вспышка.** Сейчас цвет вспышки — булев `pop_flash_red` (жёлтая/красная);
|
||||
расширить до кода цвета и добавить ЗЕЛЁНУЮ (`flash_time = 3`).
|
||||
5. **Зелёные пузырьки.** `pop_pack_bg.py` уже красит пузырёк mono-цветом
|
||||
(`POT_BUBBLE_COLOR = VGA16 + 12`, красный). Добавить второй набор кадров
|
||||
16..22 в зелёном (`+10`) под своими id в атласе `pop_pot` и выбирать набор
|
||||
по `potion_type` в `pop_potion_draw` (`pop_room.c`): 3/4 — зелёный, 5/6 —
|
||||
синий, иначе красный. Цена — 7 маленьких спрайтов.
|
||||
6. **Проверка.** Хост-тест: падение с трёх рядов под пером — скорость не выше
|
||||
4, урона нет, Кид жив (сцена в `t_phys`/`t_char`). MAME: комната 1 уровня
|
||||
7 — выпить, спрыгнуть в шахту, убедиться в плавном спуске и в том, что
|
||||
эффект кончается по таймеру.
|
||||
|
||||
### <a id="l3-color"></a>L3-COLOR. Палитра КЛАДКИ уровня 3 (в оригинале он зелёный)
|
||||
|
||||
**Наблюдение (пользователь, 2026-08-07, со сравнением карт VGA).** В
|
||||
|
||||
Reference in New Issue
Block a user