Уровни 12 и 13: тень, Джафар, падающие плиты + разбор слоёв
Уровень 12 (тень) — порт seg002/seg006: - check_shadow: подъём тени в комнате 15 по условию «меч подобран», init_shad_12, вход падением (seq 7); - autocontrol_shadow_level12: ждать Кида, бой, сближение, СЛИЯНИЕ; - общий урон (ранил тень — ранил себя) и check_killed_shadow (убил тень — убил себя); - таймер вспышки слияния 42 -> -1, sword_disappears при уходе из комнаты 18, появление плит в комнатах 2/13 после слияния. Переход 12 -> 13 бесшовный: двери у уровня нет, он кончается фактом попадания в комнату 23 (tbl_seamless_exit); флаг pop_seamless не даёт сбросить HP. Чит навигации по комнатам этот триггер придерживает — иначе комнату 23 двенадцатого уровня не посмотреть в принципе. Уровень 13 (Джафар): guard_notice_timer (фора после встречи), on_guard_killed + Jaffar_exit, check_fall_flo (гряда плит сверху) и три исключения loose-механики. Плюс спрайты визиря VIZIER.DAT — без них он рисовался обычным стражем; заодно цвет из данных комнаты применяется только к обычному стражу, как в оригинале. Падающие плиты — семь дефектов, найденных прогонами: - MOB_MAX 4 -> 14: check_fall_flo роняет шесть плит разом, лишние терялись без щебня; - одиночные сигналы посадки/провала больше не затираются в кадре; - честный loose_fall: сбитая плита рождается в том же кадре, от места удара, с половинной скоростью; - при снятии плиты метится и сосед справа (висел передний торец); - heal и отрисовка кусков разнесены на два прохода; - куски рисуются ПОСЛЕ фона, порядок между собой — по убыванию y (compare_curr_objs для пары 0x80 сортирует наоборот); - wall_pattern убран из ceil_over_kid_tile: у оригинала узор из draw_tile_bottom идёт в фон, а не в передний слой. Хост-тесты: два новых набора, t_shadow (45 проверок) и t_jaffar (44). TK_ROOMS 8 -> 24 — спецсобытия адресуют комнаты по реальным номерам. Осознанные расхождения (docs/impl_diff.md): нет мигания Кида спрайтами тени при слиянии, чит навигации не запускает бесшовный переход, чит K убивает через штатный путь смерти. Открытым остаётся разбор слоёв: MOB-CLIP-RIGHT, MID-OVERLAY-LAYER, GUARD-FALLOUT-VICTORY, BG-ONCE (BUGS_OPEN.md / TASKS_OPEN.md). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -109,7 +109,15 @@ void pop_start_level(void) __banked
|
||||
pop_level_reset_tiles();
|
||||
pop_level_reset_guards();
|
||||
pop_guard_reset(); /* start_level: Guard.direction = none */
|
||||
/* united_with_shadow = 0 (seg003:95) — состояние ПЕРСОНАЖА уровня, а не
|
||||
* комнаты: pop_guard_reset зовётся и при каждом входе в комнату (из
|
||||
* pop_guard_enter), поэтому гасить слияние надо здесь. */
|
||||
pop_united_shadow = 0;
|
||||
pop_shadow_init = 0;
|
||||
pop_guard_notice_timer = 0; /* фора Джафара — не переживает рестарт */
|
||||
pop_nav_hold = 0; /* старт уровня снимает и держатель чита */
|
||||
pop_loose_mob_reset(); /* start_level: mobs_count = 0 (seg003:88) */
|
||||
pop_loose_forget(); /* ...и фазы плит — уровень восстановлен целиком */
|
||||
/* «Особое событие: убрать loose-плиту» (do_startpos): без этого путь в
|
||||
* комнату-чекпойнт после респавна остался бы непройденным. */
|
||||
if (chkp)
|
||||
@@ -155,7 +163,11 @@ void pop_start_level(void) __banked
|
||||
/* play_level (seg003:106): have_sword = level >= have_sword_from_level
|
||||
* (=2) — начиная со второго уровня меч у Кида уже есть. */
|
||||
pop_have_sword = (uint8_t)(pop_current_level >= 2);
|
||||
pop_kid_hp_reset();
|
||||
/* seamless (seg003:158): пришли БЕЗ двери уровня, прямо на бегу — HP не
|
||||
* трогаем, оно переезжает как есть. Флаг одноразовый: у оригинала его
|
||||
* гасит заставка «LEVEL N», которую этот же переход и пропускает. */
|
||||
if (pop_seamless) { pop_seamless = 0; pop_kid_hp_carry(); }
|
||||
else pop_kid_hp_reset();
|
||||
}
|
||||
|
||||
/* ---- ОТЛАДКА: обход комнат по номеру -------------------------------- *
|
||||
@@ -234,6 +246,16 @@ uint8_t pop_dbg_roomnav(uint8_t dir) __banked
|
||||
holding_sword = 0;
|
||||
offguard = 0;
|
||||
guard_refrac = 0;
|
||||
|
||||
/* ПРОВАЛ НА СЛЕДУЮЩИЙ УРОВЕНЬ ПО ЧИТУ (та же болезнь, что выше).
|
||||
* Уровень 12 кончается ФАКТОМ попадания в комнату 23 — двери у него нет
|
||||
* (pop_seamless, seg000:0900). А навигация перебирает комнаты ПО
|
||||
* НОМЕРУ, то есть любой обход рано или поздно наступает на 23-ю, и
|
||||
* уровень молча меняется на 13-й: комнату 23 двенадцатого уровня читом
|
||||
* не посмотреть в принципе, а прогон «съезжает» на соседний уровень
|
||||
* незаметно для проверяющего (поймано 2026-08-13 на первом же прогоне).
|
||||
* Держим триггер, пока Кид не сменит комнату НОГАМИ. */
|
||||
pop_nav_hold = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -276,6 +298,10 @@ void enter_room_side(uint8_t room, uint8_t side) __banked
|
||||
* enter звать нельзя: он уже перенесён и живёт дальше как есть. */
|
||||
uint8_t follow = (uint8_t)(side <= 3 ? pop_guard_follow(room, side) : 0);
|
||||
if (!follow) pop_guard_leave(); /* запомнить стража уходящей комнаты */
|
||||
/* ...и так же запомнить НЕДОСЧИТАННЫЕ loose: пока карта ещё описывает
|
||||
* СТАРУЮ комнату, фаза уезжает в персистентный room_modif + trob, и
|
||||
* плита доваливается заочно (см. pop_loose_leave_room / animate_loose). */
|
||||
pop_loose_leave_room();
|
||||
uint8_t *room_mod;
|
||||
pop_room_load(room, room_fg, room_bg, lcol_fg, lcol_bg, rcol_fg, rcol_bg, below_fg);
|
||||
pop_map_set(room_fg);
|
||||
@@ -317,6 +343,7 @@ void enter_room_side(uint8_t room, uint8_t side) __banked
|
||||
pop_trob_room_changed(); /* отложенные перерисовки пик — не из старой комнаты */
|
||||
pop_trob_anim_room(room); /* факелы/зелья: стартовая фаза + trob */
|
||||
pop_start_chompers(room, Kid.curr_row); /* seg000:1288: чомперы РЯДА Кида */
|
||||
pop_check_fall_flo(); /* спецсобытие ур.13: гряда плит сверху */
|
||||
/* check_shadow (seg002:0064) стоит ПЕРЕД enter_guard и на «шадоу»-
|
||||
* уровнях забирает слот соперника себе: вернула 1 — стража поднимать
|
||||
* НЕЛЬЗЯ (в комнате 24 уровня 5 он есть в данных, но оригинал его туда
|
||||
|
||||
Reference in New Issue
Block a user