L1: фиксы прогона уровня 1 — уровень мутабелен, стражи, loose-плиты, порядок

Одиннадцать наблюдений первого прогона свелись к шести корням, четыре
наблюдения второго — ещё к четырём.  Разбор каждого — bug_closed.md.

Первая волна:
- BUG-LVLSTATE-1: уровень стал мутабельным (эталонная копия foretable для
  рестарта, pop_level_set_tile вместо таблицы оверрайдов);
- BUG-RESPAWN-1: рестарт = load_level, тайлы возвращаются из эталона;
- BUG-DEATH-1: смерть от меча доигрывается (порт control_kid, seg006:0CD1);
- BUG-GATE-ANIM-1: ворота в отрисованной комнате перерисовываются
  (POP_RD_GATE, порт draw_trob seg007:01E6);
- BUG-COLL-1: полный порт check_collisions/bumped (seg004) вместо поиска
  стены только в колонке переднего края;
- BUG-STANDUP-1: убран лишний guard в bumped_floor — вставание у стены
  роняло Кида сквозь пол.

Вторая волна:
- BUG-RESPAWN-2: рестарт возвращает и СТРАЖЕЙ (в оригинале play_level на
  каждой итерации делает load_level + pos_guards);
- BUG-LOOSE-2: падающий кусок привязан к своей комнате и долетает после
  ухода Кида (do_mobs крутит mobs[] независимо от drawn_room);
- BUG-DRAWORDER-1: порядок «Кид / страж» задаётся обходом тайлов
  (redraw_needed_tiles: ряды 2,1,0, колонки 0..9), а не ролью персонажа.

По BUG-DRAWORDER-1 понадобилось три захода, и два первых были неполны:
  1) сам порядок — но общее окно fore-клипа осталось стражьим, и Кид
     нарисовался поверх передних столбов (kid_fore_clip_restore);
  2) enter_guard брал curr_col из тайла, а leave_guard пишет туда
     get_tilepos(0,row) — у запомненного ТРУПА колонка была 0 при
     настоящей X.  Теперь колонка выводится из X, как в оригинале;
  3) ветка actions_1_run_jump в set_objtile_at_char оказалась не
     «упрощаемой»: в беге тайл берётся из нижнего ряда и ЛЕВОЙ колонки
     габарита, поэтому бегущий Кид уходит за объекты справа.  Считается
     для обоих персонажей — enter_guard ставит action=1 и стражу.

Проверено в MAME: зелья/меч/плиты переживают выход из комнаты и
восстанавливаются после смерти; кнопка room5 поднимает решётку; падение с
кнопки больше не роняет в комнату 6; убитый страж жив после respawn;
Кид проходит за телом стража.  make size-check — роста нет.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Александр Петров
2026-08-03 22:35:41 +03:00
parent 1f16e8fa70
commit b5d2a81ee3
21 changed files with 1070 additions and 164 deletions
+18
View File
@@ -359,6 +359,7 @@ static uint8_t char_dx_forward(int8_t dx)
/* Аксессоры к текущему кадру (для pop_map): читают cur_frame, НЕ таблицу —
* их дёргают несколько раз за кадр, маппинг страницы тут недопустим. */
int8_t kid_cur_dx(void) { return cur_frame.dx; }
int8_t kid_cur_dy(void) { return cur_frame.dy; }
uint8_t kid_cur_flags(void) { return cur_frame.flags; }
/* seqtbl_offset_char: сменить последовательность Kid (единая точка —
@@ -740,3 +741,20 @@ void kid_draw(void)
* нулевое окно = fore-проход не трогает экран, что и правильно. */
kid_fore_clip(gfx_get_draw_page() & 1);
}
/* Вернуть окно fore-клипа на прямоугольник ПОСЛЕДНЕГО кадра Kid.
*
* Окно (pop_fore_set_clip) — одно на всех, и его ставит КАЖДЫЙ, кто рисует
* персонажа: kid_draw в конце — своё, pop_guard_draw в конце — своё. Пока
* страж рисовался строго ДО Кида, к моменту pop_fore_over_kid в окне
* оказывался Kid, и всё сходилось само. Как только порядок стал
* переменным (guard_over_kid в roomtest.c — порядок задаёт обход тайлов),
* при «страж поверх» окно оставалось СТРАЖЬИМ и fore-проход Кида отсекался
* целиком: Кид рисовался поверх передних столбов.
*
* Поэтому окно восстанавливается явно перед pop_fore_over_kid, а не
* держится «по счастливому порядку вызовов». */
void kid_fore_clip_restore(void)
{
kid_fore_clip(gfx_get_draw_page() & 1);
}