fce3e58830
Разбор SDLPoP (seg007 loose/trob/mob, seg008 draw_loose): хранение состояния (tile 11 + curr_room_modif: 0 покой / 0x80.. тряска / 1..11 отсчёт падения), триггеры тряски (do_knock на приземлении → shake ряда) и падения (make_loose_fall при стойке/зацепе на loose), падающий кусок (mob → debris снизу, empty сверху), отрисовка по статусу (loose_fram_* через get_loose_frame). Порядок реализации L1..L5 + что нужно в нашем движке (динамический тайловый слой: room_modif[], trob-очередь, mob). ПЛАН — не реализация. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
6.4 KiB
6.4 KiB
Loose floors (проваливающиеся полы) — план порта
Разбор SDLPoP (seg007 loose/trob/mob, seg008 draw_loose). ПЛАН, ещё не
реализовано. Тайл в комнате 1: [2,6] = 0x0B = tiles_11_loose.
1. Хранение состояния
- Тип тайла:
curr_room_tiles[tilepos] & 0x1F == 11(tiles_11_loose). Бит0x20= «solid» loose (авто-падающий вариант, ур.13 — от шага НЕ падает). После падения тайл →0(tiles_0_empty). - Модификатор
curr_room_modif[tilepos]= состояние анимации:0— покой (обычный loose-пол);0x80..0x83— трясётся (бит7); за ~4 кадра затухает обратно в 0;1..11— обратный отсчёт до падения (на нём что-то стоит); достигаетloose_floor_delay = 11→ падает.
2. Анимация тряски (shake) — когда включается
- Триггер = do_knock (seg007:0FE0): на ЖЁСТКОМ приземлении в кадрах
посадки играет
SEQ_KNOCK_DOWN→ взводитknock→check_knock()→do_knock(room, curr_row − (knock>0)). do_knock(room, row): по всем колонкам ряда — если тайл loose →loose_make_shake().loose_make_shake()(seg007:0FB4): еслиmodif==0(и не ур.13) →modif = 0x80,add_trob(type 1).- Отсюда кейс пользователя: Kid падает/приземляется на
[2,4]→ do_knock трясёт ВСЕ loose-тайлы ряда 2 →[2,6]трясётся. (Через knock-смещение ряда может задеть и соседний ряд.) animate_loose(кадрово):++modif; при бите7 трясёт до>=0x84→ сброс в 0,trob.type=-1.loose_shake()играет звук (sound 20/21/22) по таблицеloose_sound[].
3. Анимация падения (fall) — когда включается
- Триггер = make_loose_fall(1) (seg007:0EF6), вызывается когда:
- Kid СТОИТ на loose-тайле —
check_press()(seg006): кадр с FRAME_NEEDS_FLOOR над loose → make_loose_fall(1); - зацеп/подтягивание на loose (
check_grab,check_jump_up); - пробой сверху: кадр 79 (jumphang) над loose → make_loose_fall(1);
- авто-падающие (ур.13) —
make_loose_fall(-(prandom&0x0F)).
- Kid СТОИТ на loose-тайле —
make_loose_fall(modifier): если НЕ solid (tiles & 0x20 == 0) и(sbyte)modif <= 0→modif = modifier,add_trob(type 0).animate_loose:++modif; когдаmodif >= 11(loose_floor_delay) →remove_loose()(тайл → empty) +add_mob()(спавн падающего куска).
4. Падающий кусок (mob)
add_mob()кладётcurmobвmobs[](до 14).do_mobs()каждый кадр:move_mob()(гравитация, y растёт) +check_loose_fall_on_kid()(урон Киду/страже, если попал).- Приземление куска → тайл под ним
curr_room_tiles[...] = tiles_14_debris(seg007 move_mob:1053). Т.е. loose(11) упал → сверху empty(0), снизу debris(14).
5. Отрисовка по статусу
- Куски тайла:
loose_fram_left[]={41,69,41,70,70,41,41,41,70,70,70,0},loose_fram_right[]={42,71,...},loose_fram_bottom[]={43,73,...}(env-спрайты, seg008:518/596/608). - Индекс кадра =
get_loose_frame(modifier)(seg008):0= ровный (41/42/43);1..10= дрожащие варианты (69–74); при бите7/большой задержке — низкие индексы. - До падения: рисуем loose с
get_loose_frame(modif)(0 = ровно, иначе колеблется). После: сверху empty, снизу debris(14) — обычная статическая отрисовка (у нас уже есть tile 0x0E/14 debris в tile_table).
6. Что нужно в нашем движке (сейчас НЕТ)
Наш pop_bg рисует комнату СТАТИЧЕСКИ один раз. Loose-полы требуют
динамического тайлового слоя:
- Массив модификаторов
room_modif[30](у нас естьbg[30]— можно переиспользовать/рядом) — состояние каждого тайла. - Очередь trob (список анимируемых тайлов) +
animate_looseпер-кадр → перерисовка ТОЛЬКО изменившихся тайлов (как heal-прямоугольник Kid). - make_loose_fall / do_knock / loose_make_shake — триггеры (из физики Kid: приземление→knock, стойка на loose→fall).
- mob-система (падающий кусок): минимум 1–2 mob'а, гравитация,
приземление → debris. Урон Киду (
check_loose_fall_on_kid) — можно Фазой 2. - Перерисовка тайла:
draw_tile(row,col)у нас уже умеет loose (code==11,loose_fram_*в env) — нужно вызывать его выборочно с текущим модификатором (сейчас draw_tile берёт статический bg).
Порядок реализации (предложение):
- L1: room_modif[] + выборочная перерисовка тайла по модификатору (draw_loose с get_loose_frame) — статика→динамика одного тайла.
- L2: trob-очередь + animate_loose (тряска по do_knock на приземлении).
- L3: make_loose_fall (стойка на loose) + отсчёт + remove → empty.
- L4: mob (падающий кусок → debris снизу).
- L5: урон Киду от падающего куска.
Связанные
Триггеры завязаны на физику Kid (pop_hang_state check_press/check_grab, приземление land/SEQ_KNOCK_DOWN). Отрисовка — pop_fore_layer / pop_background_strategy (draw_tile уже знает loose_fram_*).