L6-SHADOW: тень роняет решётку + кромка ряда ниже
1. L6-SHADOW (seg002:0090 + seg002:1064). Тень встаёт при каждом входе в комнату 1 уровня 6 и делает ОДИН осторожный шаг (Shift+вперёд) в тот кадр, когда Кид прыгает к решётке (Kid.frame == 43, Kid.x < 128): встаёт на closer (1,1) и роняет решётку (1,2), за порожек которой Кид цепляется. do_init_shad переписан под таблицы init_shad_5/6 — первые 7 полей Char, как memcpy(&Char, source, 7) у оригинала. Проверено в MAME: «Кид прыгнул, зацепился, Тень сделал шаг, решётка упала». Тем самым закрыт остаток GUARD-PHYS — нажатие плиты НЕ-Кидом работает. 2. BUG-BELOWROW-WALL. При отсутствующей комнате снизу load_rowbelow (seg008:368) подставляет tiles_0_empty колонкам 1..9 и tiles_20_wall только левому краю; у нас стеной забивались все 11 позиций, и её topright лез жёлтыми треугольниками под пустые тайлы нижнего ряда (видно в шахте падения, комната 3). Комнаты 1 и 3 уровня 6 сверены с картой SDLPoP: расхождения только силуэты персонажей. tests-host 5/5, size-check чист. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -224,18 +224,25 @@ static uint8_t demo_index; /* текущая запись
|
||||
#define SEQ_2_STAND 2
|
||||
#define TILE_POTION 10
|
||||
|
||||
/* init_shad_5 (data:0EF2): frame 15, x 55, y 55, direction 0 (вправо),
|
||||
* curr_col −1 (ещё за левым краем), curr_row 0, action 0 (стоит). */
|
||||
static void do_init_shad_5(uint8_t room)
|
||||
/* Таблицы init_shad_N (data:0EEA/0EF2) — ПЕРВЫЕ СЕМЬ полей Char в том же
|
||||
* порядке, в каком их копирует оригинал (`memcpy(&Char, source, 7)`):
|
||||
* frame, x, y, direction, curr_col, curr_row, action.
|
||||
* 5: x 55, y 55, вправо, колонка −1 (ещё за левым краем экрана), ряд 0;
|
||||
* 6: x 81, y 118, вправо, колонка 0, ряд 1 — тень стоит на границе
|
||||
* (1,0)-(1,1), одного осторожного шага хватает, чтобы встать на плиту. */
|
||||
static const uint8_t init_shad_5[7] = { 0x0F, 0x37, 0x37, 0, 0xFF, 0, 0 };
|
||||
static const uint8_t init_shad_6[7] = { 0x0F, 0x51, 0x76, 0, 0x00, 1, 0 };
|
||||
|
||||
static void do_init_shad(const uint8_t *tbl, uint8_t room)
|
||||
{
|
||||
pop_loadshad();
|
||||
Char.frame = 0x0F;
|
||||
Char.x = 0x37;
|
||||
Char.y = 0x37;
|
||||
Char.direction = 0;
|
||||
Char.curr_col = -1;
|
||||
Char.curr_row = 0;
|
||||
Char.action = 0;
|
||||
Char.frame = tbl[0];
|
||||
Char.x = tbl[1];
|
||||
Char.y = tbl[2];
|
||||
Char.direction = (int8_t)tbl[3];
|
||||
Char.curr_col = (int8_t)tbl[4];
|
||||
Char.curr_row = (int8_t)tbl[5];
|
||||
Char.action = tbl[6];
|
||||
Char.room = room;
|
||||
Char.charid = CHARID_1_SHADOW;
|
||||
Char.alive = Kid.alive; /* наследование от Кида, см. шапку */
|
||||
@@ -254,12 +261,22 @@ static void do_init_shad_5(uint8_t room)
|
||||
|
||||
uint8_t pop_check_shadow(uint8_t room) __banked
|
||||
{
|
||||
/* Уровень 6 (seg002:0090): условий на содержимое комнаты нет вовсе —
|
||||
* тень встаёт при КАЖДОМ входе в комнату 1. Оригинал здесь ещё играет
|
||||
* sound_25_presentation один раз, отмечая это `leveldoor_open = 0x4D`
|
||||
* (переменная двери используется как флаг); звука у нас нет, а чужую
|
||||
* переменную портить незачем — TODO вместе со звуком. */
|
||||
if (pop_current_level == SHADOW_STEP_LEVEL) {
|
||||
if (room != SHADOW_STEP_ROOM) return 0;
|
||||
do_init_shad(init_shad_6, room);
|
||||
return 1;
|
||||
}
|
||||
if (pop_current_level != SHADOW_STEAL_LEVEL) return 0;
|
||||
if (room != SHADOW_STEAL_ROOM) return 0;
|
||||
/* Зелья уже нет — тень своё дело сделала. Возвращаем 1 и здесь: стража
|
||||
* комнаты 24 оригинал не поднимает НИКОГДА (return до enter_guard). */
|
||||
if (pop_level_tile(room, SHADOW_POTION_TILEPOS) != TILE_POTION) return 1;
|
||||
do_init_shad_5(room);
|
||||
do_init_shad(init_shad_5, room);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -604,12 +621,30 @@ static void autocontrol_shadow_level5(void)
|
||||
if (Char.x < 15) clear_char();
|
||||
}
|
||||
|
||||
/* autocontrol_shadow (seg002:081D) — по уровням. Ветки 6 (шагает по плите)
|
||||
* и 12 появятся со своими уровнями. */
|
||||
/* autocontrol_shadow_level6 (seg002:1064). Вся логика — один осторожный шаг
|
||||
* (Shift + вперёд) в тот кадр, когда Кид прыгает к решётке: тень встаёт на
|
||||
* closer (1,1) и роняет решётку (1,2), за порожек которой Кид в этот момент
|
||||
* цепляется. Условие смотрит на КИДА: кадр 43 — четвёртый кадр бег-прыжка,
|
||||
* x < 128 отсекает прыжки в правой половине комнаты (там Кид ещё разбегается
|
||||
* и до решётки ему далеко). */
|
||||
#define FRAME_43_RUNJUMP 43
|
||||
|
||||
static void autocontrol_shadow_level6(void)
|
||||
{
|
||||
if (Char.room != SHADOW_STEP_ROOM) return;
|
||||
if (Kid.frame != FRAME_43_RUNJUMP) return;
|
||||
if (Kid.x >= 128) return;
|
||||
move_6_shift();
|
||||
move_1_forward();
|
||||
}
|
||||
|
||||
/* autocontrol_shadow (seg002:081D) — по уровням. Ветка 12 появится со своим
|
||||
* уровнем. */
|
||||
static void autocontrol_shadow(void)
|
||||
{
|
||||
if (pop_current_level == MIRROR_LEVEL) autocontrol_shadow_level4();
|
||||
if (pop_current_level == SHADOW_STEAL_LEVEL) autocontrol_shadow_level5();
|
||||
if (pop_current_level == SHADOW_STEP_LEVEL) autocontrol_shadow_level6();
|
||||
}
|
||||
|
||||
/* autocontrol_guard (seg002:701) + autocontrol_opponent (seg002:628). */
|
||||
|
||||
Reference in New Issue
Block a user