d1bc97c589
Loose-пол room1(2,6) при падении даёт кусок, который в оригинале улетает в комнату снизу (links.down) и приземляется на первый floor, превращая его в debris (порт move_loose/loose_land seg007). Для room1(2,6): room2(0,6)=empty пролёт → room2(1,6)=floor приземление → debris. Минимальная реализация (без анимации полёта куска, только персистентный результат — мини-версия P0 из docs/gates_spikes_plan.md): - pop_map: сигнал pop_loose_fell (tilepos+1 упавшего loose). - pop_level: pop_room_col_landing(room,col) — ряд первого floor сверху вниз (пустые ряды пролетаются), иначе -1. - roomtest: при pop_loose_fell вычисляет debris-приземление в комнате снизу → персистентный override (dbr_room/dbr_pos, живёт между переходами) → enter_room применяет поверх загруженных тайлов (floor→debris 0x0E). Проверено в MAME: провал loose room1(2,6) → debris в room2(1,6), сохраняется при повторных входах. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
92 lines
6.2 KiB
C
92 lines
6.2 KiB
C
/*
|
||
* pop_map.h — коллизия Kid с картой комнаты (Фаза K3): тайловые запросы
|
||
* + физика падения + приземление. Порт SDLPoP seg005/seg006
|
||
* (check_on_floor/start_fall/do_fall/fall_accel/fall_speed/land/in_wall).
|
||
*
|
||
* K3.2 (падение): Kid, сойдя/сбежав с края пола (тайл под ним не floor),
|
||
* начинает падать (fall_y-ускорение, Char.y растёт), приземляется на пол
|
||
* ниже (soft/medium land) или продолжает вниз. Стена под персонажем —
|
||
* in_wall (выталкивание). Бег В стену (check_bumped) — отдельным шагом.
|
||
*/
|
||
#ifndef POP_MAP_H
|
||
#define POP_MAP_H
|
||
|
||
#include <stdint.h>
|
||
|
||
/* Задать карту текущей комнаты: fg[30] = коды тайлов (row*10+col, 3×10).
|
||
* col<0/>9 или row<0/>2 трактуются как стена (край уровня). Массив
|
||
* МУТАБЕЛЬНЫЙ (loose-пол при падении → empty) — передавать ту же копию,
|
||
* что и в pop_room_draw, чтобы отрисовка видела изменения. */
|
||
void pop_map_set(uint8_t *fg);
|
||
|
||
/* Связи комнаты (0=нет соседа; иначе номер) + кромки швов для коллизии:
|
||
* lcol_fg = col9 левого соседа (за col0), rcol_fg = col0 правого соседа
|
||
* (за col9). Звать в enter_room. */
|
||
void pop_map_set_edges(uint8_t left, uint8_t right, uint8_t up, uint8_t down,
|
||
const uint8_t *lcol_fg, const uint8_t *rcol_fg);
|
||
|
||
/* Уход из комнаты ВБОК/ВВЕРХ: 0=нет; 1=left,2=right,3=up (= side+1 для
|
||
* pop_room_link). Координаты Kid уже репроецированы (x∓140 / y+189).
|
||
* Приложение переключает комнату по соответствующей связи и снимает флаг. */
|
||
extern uint8_t pop_leave_dir;
|
||
|
||
/* Loose floors (проваливающиеся полы). pop_loose_modif[30] — состояние на
|
||
* тайл (0 покой / 0x80.. тряска / 1..11 отсчёт падения); читает pop_bg при
|
||
* отрисовке. pop_loose_tick() — анимация + перерисовка изменившихся тайлов
|
||
* на ТЕКУЩЕЙ странице; звать в основном цикле ПОСЛЕ set_draw_page(back),
|
||
* рядом с kid-отрисовкой. */
|
||
extern uint8_t pop_loose_modif[30];
|
||
void pop_loose_tick(void);
|
||
void pop_loose_reset(void); /* сброс loose-состояния при смене комнаты */
|
||
|
||
/* Установлен в tilepos+1 в кадре, когда loose-пол упал (кусок улетел ВНИЗ).
|
||
* Приложение: определить debris-приземление в комнате снизу. Снять (=0). */
|
||
extern uint8_t pop_loose_fell;
|
||
|
||
/* check_knock (seg003): по флагу knock (play_seq) тряхнуть loose-полы ряда
|
||
* приземления/удара. Зовётся из pop_phys_tick. */
|
||
void pop_check_knock(void);
|
||
|
||
/* Установлен в 1, когда Kid пересёк НИЖНЮЮ границу комнаты (провал в дыру
|
||
* или спуск-зацеп с кромки). Координаты Kid УЖЕ репроецированы в кадр
|
||
* комнаты снизу (y -= 189, curr_row = 0). Приложение решает: если есть
|
||
* links.down — сменить комнату (pop_room_load+перерисовка) и продолжить;
|
||
* иначе — выпал из уровня (респавн). Снять флаг после обработки. */
|
||
extern uint8_t pop_fell_out;
|
||
|
||
/* Пер-кадровая физика ПОСЛЕ kid_tick(play_seq): fall_accel + fall_speed +
|
||
* determine_col + check_action (триггер падения / do_fall / приземление).
|
||
* Порядок как в оригинале (seg000 play_kid_frame). */
|
||
void pop_phys_tick(void);
|
||
|
||
/* Тип препятствия/края ВПЕРЕДИ по направлению (pop_edge_type после
|
||
* pop_edge_distance): для control (бежать / осторожный шаг / стоп у стены). */
|
||
#define EDGE_CLOSER 0 /* край уступа над ямой (дистанция = до кромки) */
|
||
#define EDGE_WALL 1 /* стена впереди/под персонажем */
|
||
#define EDGE_FLOOR 2 /* пол (нет препятствия рядом, дистанция = 11) */
|
||
|
||
/* Расстояние до края/стены впереди + побочно g_edge_type (pop_edge_type). */
|
||
int pop_edge_distance(void);
|
||
uint8_t pop_edge_type(void);
|
||
|
||
/* Стена впереди в пределах стопа? Если да — прижимает Kid.x к корректной
|
||
* позиции (передний край у стены, симметрично) и возвращает 1. Для
|
||
* control_running (чистый стоп у стены). */
|
||
int pop_wall_ahead(void);
|
||
|
||
/* Прыжок вверх в стойке (↑): seq чистого прыжка (seq_28/seq_14) ЛИБО
|
||
* прыжка-с-зацепом за уступ выше (seq_8/24/16) + выравнивание Kid.x.
|
||
* check_jump_up/grab_up (K4.4). control_up гасит caller. */
|
||
uint8_t pop_jump_up_seq(void);
|
||
|
||
/* ---- Вис/зацеп/спуск (K4.2/K4.3) — тайловые решения для pop_ctrl --- *
|
||
* Управление (control_hanging/can_climb_up/hang_fall/down_pressed) в
|
||
* pop_ctrl; здесь — предикаты + выбор seq (+ выравнивание Kid.x). */
|
||
uint8_t pop_hang_grab_ready(void); /* grab_timer истёк — можно climb-up */
|
||
uint8_t pop_hang_climb_up_seq(void); /* seq_10 / seq_73 (подтягивание) */
|
||
int8_t pop_hang_wall(void); /* Shift в висе: 1=у стены,-1=fall,0=держ.*/
|
||
uint8_t pop_hang_fall_seq(void); /* seq_23 / seq_11 (сорваться), +Kid.x */
|
||
uint8_t pop_down_action(void); /* 1=обработано(спуск/отступ), 0=присед */
|
||
|
||
#endif
|