L2: переход между уровнями и игра уровня 2
Порт levels_plan.md §2 (шаг 1) — машинерия смены уровня целиком. - Номер уровня стал состоянием: pop_current_level (порт current_level), pop_next_level больше не флаг, а НОМЕР; главный цикл срабатывает по расхождению next != current (порт play_level_2, seg003:0386). - pop_level_load_num(n): LEVELS\res20NN.bin (fallback a:\), старая EMM-страница отпускается только после успешной загрузки новой. На диск кладутся все 15 уровней (34 КБ). - Потабличные различия (data.h:840..848) — таблицы по 16 в pop_level.c: tbl_entry_pose, tbl_guard_hp (HP стража ушло из хардкода 3), tbl_guard_type (−1 = стражей на уровне нет), tbl_level_type. - find_start_level_door (seg003:02E6): на уровне 2 стартовый тайл — правая половина двери уровня, без modif=43 + add_trob(...,3) Кид материализуется внутри глухой створки. Тип 3 = дверь захлопывается за спиной, как в оригинале. - HP через уровень: hitp_beg_lev (seg003) — рестарт уровня откатывает HP к нему, пройденный уровень подтягивает его к hitp_max. Заодно большая склянка add_life (тип зелья 2: +1 к потолку HP до 10) — на уровне 2 она есть, комната 20. - have_sword = level >= 2 (play_level, seg003:106). - Чит Shift+L — следующий уровень (seg000:698). Проверено в MAME: уровень 1 → Shift+L → уровень 2 (комната 5, новые для нас тайлы 8/9 «большая колонна» на месте, дверь захлопнута, HP 3) → влево в комнату 4 со стражем → Shift+L → уровень 3. Вход в стартовую дверь уровня 2 по Up не срабатывает — как и должно (start_room-гард). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -117,6 +117,14 @@ uint8_t pop_kid_dead; /* 1 = Kid мёртв (напоролся на
|
||||
uint8_t pop_kid_hurt; /* 1 = в этом кадре убавилось HP → «брызги» */
|
||||
uint8_t hitp_curr; /* текущее HP (0 = мёртв); pop_kid_hp_reset ставит старт */
|
||||
uint8_t hitp_max; /* стартовое HP Кида (для индикатора) */
|
||||
/* hitp_beg_lev (seg003 init_game/play_level_2): HP, с которым НАЧАТ уровень.
|
||||
* Смерть/рестарт уровня возвращают ровно его (do_startpos: hitp_max =
|
||||
* hitp_curr = hitp_beg_lev), а по ПРОХОЖДЕНИИ уровня он подтягивается к
|
||||
* достигнутому максимуму (hitp_beg_lev = hitp_max) — так «жизнь» из большой
|
||||
* склянки переносится на следующий уровень, а из мёртвых прогонов — нет.
|
||||
* Стартовое значение (custom->start_hitp = 3) ставит main через
|
||||
* pop_kid_hp_newgame — инициализатором нельзя: модуль банкованный. */
|
||||
uint8_t hitp_beg_lev;
|
||||
/* Дельта HP Кида за кадр (порт hitp_delta). Её ставит СВОРД-путь боёвки
|
||||
* (guards.c), а применяет pop_do_delta_hp раз в кадр — как в оригинале.
|
||||
* Путь пик/падения (take_hp ниже) правит hitp_curr сразу: он был написан и
|
||||
@@ -162,7 +170,27 @@ void pop_map_set(uint8_t *fg) __banked { g_fg = fg; }
|
||||
|
||||
void pop_map_set_room(uint8_t room) __banked { g_room = room; }
|
||||
|
||||
void pop_kid_hp_reset(void) __banked { hitp_curr = hitp_max = 3; hitp_delta = 0; pop_kid_dead = 0; }
|
||||
/* do_startpos (seg003:0160): HP уровня = hitp_beg_lev, а не константа —
|
||||
* иначе большая склянка теряется на границе уровня. */
|
||||
void pop_kid_hp_reset(void) __banked
|
||||
{
|
||||
hitp_curr = hitp_max = hitp_beg_lev;
|
||||
hitp_delta = 0;
|
||||
pop_kid_dead = 0;
|
||||
}
|
||||
|
||||
/* init_game (seg003:0043): начало ИГРЫ, а не уровня — стартовое HP. */
|
||||
void pop_kid_hp_newgame(void) __banked { hitp_beg_lev = POP_START_HITP; }
|
||||
|
||||
/* add_life (seg000:11EC) + set_health_life (seg000:1200): большая склянка
|
||||
* поднимает ПОТОЛОК HP (до max_hitp_allowed = 10) и доливает до него. */
|
||||
static void pop_kid_add_life(void)
|
||||
{
|
||||
uint8_t hpmax = (uint8_t)(hitp_max + 1);
|
||||
if (hpmax > POP_MAX_HITP) hpmax = POP_MAX_HITP;
|
||||
hitp_max = hpmax;
|
||||
hitp_delta = (int8_t)(hitp_max - hitp_curr);
|
||||
}
|
||||
|
||||
/* take_hp (seg006:06BD, только Kid): count>=hitp → смерть (return 1). */
|
||||
static uint8_t take_hp(uint8_t count)
|
||||
@@ -906,13 +934,18 @@ void pop_proc_get_object(void) __banked
|
||||
pop_flash_time = 2;
|
||||
}
|
||||
break;
|
||||
case 2: /* большая склянка: +1 к ПОТОЛКУ HP */
|
||||
pop_kid_add_life();
|
||||
pop_flash_red = 1;
|
||||
pop_flash_time = 4; /* seg006:1878 — вспышка длиннее */
|
||||
break;
|
||||
case 5: /* «злое» зелье: −1 HP */
|
||||
hitp_delta = -1;
|
||||
pop_flash_red = 1;
|
||||
pop_flash_time = 2;
|
||||
break;
|
||||
default: /* 2 жизнь / 3 перо / 4 переворот /
|
||||
* 6 открыть — TODO с их уровнями */
|
||||
default: /* 3 перо / 4 переворот / 6 открыть —
|
||||
* TODO вместе с их уровнями (7/9) */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user