Уровни 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:
@@ -14,6 +14,7 @@
|
||||
* пометки, поэтому pop_process_trobs — единственная функция модуля, которую
|
||||
* нельзя звать из __banked-кода. */
|
||||
#include "pop_bg.h"
|
||||
#include "pop_tile.h" /* pop_palace — тип уровня как модификатор дыры */
|
||||
#include "pop_guard.h" /* is_guard_notice — нажатая кнопка слышна стражу */
|
||||
#include "pop_kid.h" /* Kid.curr_row/alive — условие остановки чомпера */
|
||||
#include "pop_tune.h" /* POP_DBG_GATE_HOLD — отладочное растягивание окна */
|
||||
@@ -31,6 +32,7 @@
|
||||
#define TILE_CHOMP 0x12 /* чомпер (челюсти) */
|
||||
#define TILE_TORCH 0x13
|
||||
#define TILE_TORCH_DEBRIS 0x1E
|
||||
#define TILE_EMPTY 0x00 /* remove_loose: на месте провалившейся плиты */
|
||||
|
||||
/* ---- Персистентное per-room modifier-состояние -------------------- */
|
||||
static uint8_t room_modif[POP_NROOMS][POP_ROOMTILES];
|
||||
@@ -305,6 +307,54 @@ static void animate_spike(uint8_t *m, int8_t *type)
|
||||
*m = mod;
|
||||
}
|
||||
|
||||
/* animate_loose (seg007:0CBA) — для плиты в НЕ отрисованной комнате.
|
||||
*
|
||||
* ЗАЧЕМ. В оригинале loose-пол — обычный trob, а do_trobs крутит весь
|
||||
* список независимо от drawn_room: расшатанная плита доваливается, даже если
|
||||
* Кид уже убежал в соседнюю комнату. У нас фаза живёт в pop_loose_modif[30]
|
||||
* — массиве ТЕКУЩЕЙ комнаты, — и смена комнаты её обнуляла: плита,
|
||||
* пробежав по которой Кид уходил вправо, оставалась целой (уровень 10,
|
||||
* комната 2, тайл 2,9).
|
||||
*
|
||||
* Разделение обязанностей: пока комната отрисована, фазой владеет
|
||||
* pop_loose_tick (ему нужны перерисовка, звук, mob-порядок), и trob здесь
|
||||
* сразу снимается. На выходе из комнаты pop_loose_leave_room (pop_map.c)
|
||||
* сбрасывает фазу в ПЕРСИСТЕНТНЫЙ room_modif и заводит trob — дальше плита
|
||||
* досчитывает здесь, а на входе обратно pop_loose_reset забирает фазу
|
||||
* назад. Персистентный модификатор и есть curr_room_modif оригинала, так
|
||||
* что расхождения с SDLPoP нет — только двухуровневое хранение.
|
||||
*
|
||||
* Рисовать тут нечего (комната не на экране), поэтому от оригинала остаётся
|
||||
* ровно счёт фазы и провал: тайл в EMPTY + отрыв падающего куска. */
|
||||
static void animate_loose(uint8_t *m, int8_t *type, uint8_t room, uint8_t tp,
|
||||
uint8_t cur_room)
|
||||
{
|
||||
uint8_t ph;
|
||||
if (room == cur_room) { *type = -1; return; } /* хозяин — pop_loose_tick */
|
||||
ph = (uint8_t)(*m + 1);
|
||||
if (ph == 0) ph = 1; /* перескок нуля, см. pop_loose_tick */
|
||||
if (ph & 0x80) { /* тряска (do_knock): 0x80..0x83 */
|
||||
/* Спецкейс уровня 13 (seg007:823) — тот же, что в pop_loose_tick:
|
||||
* отложенный старт от check_fall_flo живёт в старшем бите, и гасить
|
||||
* его нельзя. Здесь он тоже нужен: гряда лежит в комнате СВЕРХУ, и
|
||||
* пока Кид не вошёл в комнату под ней, счёт идёт заочно. */
|
||||
if (pop_current_level == POP_LOOSE_TILES_LEVEL) { /* ждём молча */ }
|
||||
else if (ph >= 0x84) { ph = 0; *type = -1; }
|
||||
} else if (ph >= 11) { /* loose_floor_delay — провал */
|
||||
/* remove_loose (seg007:0EB8): тайл → EMPTY, модификатором пустой
|
||||
* клетки становится ТИП УРОВНЯ (по нему draw_tile_right выбирает
|
||||
* blueline у дыры). Тот же порядок, что в pop_loose_tick. */
|
||||
pop_level_set_tile(room, tp, TILE_EMPTY);
|
||||
/* Комната не на экране, но её колонка 9 ВИДНА в шве текущей и лежит
|
||||
* в кромочных снимках — попросить главный цикл их перечитать. */
|
||||
pop_neigh_dirty = 1;
|
||||
pop_loose_mob_spawn_at(room, TP_ROW[tp], TP_COL[tp]);
|
||||
ph = pop_palace;
|
||||
*type = -1;
|
||||
}
|
||||
*m = ph;
|
||||
}
|
||||
|
||||
/* ---- Кнопки/ворота (seg007) --------------------------------------- *
|
||||
* Таблицы связей LINKLOC/LINKMAP — в pop_level (мутабельная копия в W2).
|
||||
* doorlink1 (d1) = LINKLOC, doorlink2 (d2) = LINKMAP. */
|
||||
@@ -574,6 +624,9 @@ void pop_process_trobs(uint8_t cur_room) __banked
|
||||
case TILE_GATE:
|
||||
animate_door(&mod[tp], &type);
|
||||
break;
|
||||
case TILE_LOOSE:
|
||||
animate_loose(&mod[tp], &type, room, tp, cur_room);
|
||||
break;
|
||||
case TILE_LEVELDOOR:
|
||||
animate_leveldoor(&mod[tp], &type, cur_room);
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user