applications/PoP/roomtest: K4 — зацеп/вис/подтягивание/спуск
Порт SDLPoP seg004/005/006 «hang state»: - pop_map: check_grab (зацеп за уступ в падении по Shift → seq_15 → вис), can_grab/can_grab_front_above + tile-запросы над/за персонажем; pop_jump_up_seq (check_jump_up: ↑ в стойке = чистый прыжок seq_28/14 ЛИБО прыжок-с-зацепом seq_8/24/16 за уступ выше → запрыгнуть на этаж); pop_hang_* (climb_up seq_10/73, hang_fall seq_23/11, hang-у-стены); pop_down_action (спуск seq_68 у края лицом от края / отступ / присед). - pop_ctrl: control_hanging/can_climb_up/hang_fall, control_jumpup, jump_up через pop_jump_up_seq, down_pressed через pop_down_action; pop_ctrl_shift_held() для check_grab. Ключевой фикс check_bumped (seg004 guard'ы): не бампить при action hang_climb/hang_straight, на кадрах подъёма/спуска 135..148 И на кадрах виса 87..99. Без последнего спуск (seq_68) на кадре frame_91 (action ещё midair, act(hang_climb) идёт следующим опкодом) ловил отскок у стены и рвал цепочку hang→hang_fall→seq_11, приземляя не туда. Проверено в MAME (HDD-тест, покадровая трасса через мост): прыжок-с- зацепом [row2 col4]→вис→подтягивание→[row1 col3]; спуск [row1 col3]→ [row2 col4] с корректной позицией у стены (x=122, совпадает с SDLPoP). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -50,6 +50,7 @@
|
||||
#define SEQ_44_STEP_ON_EDGE 44
|
||||
#define SEQ_14_JUMP_INTO_CEILING 14 /* прыжок вверх: сверху стена/пол */
|
||||
#define SEQ_28_JUMP_NOTHING_ABOVE 28 /* прыжок вверх: сверху пусто */
|
||||
#define SEQ_25_HANG_AGAINST_WALL 25 /* вис у стены (Shift в висе) */
|
||||
|
||||
#define FRAME_7_RUN 7
|
||||
#define FRAME_11_RUN 11
|
||||
@@ -131,20 +132,19 @@ static void back_pressed(void)
|
||||
static void down_pressed(void)
|
||||
{
|
||||
control_down = CONTROL_IGNORE; /* без авто-повтора */
|
||||
/* climb-down у края (seq_68) — K4 (зацеп/спуск); пока просто присед. */
|
||||
/* У края пола (край сзади) со зацепом снизу — спуск на этаж (seq_68);
|
||||
* у передней кромки — отступ; иначе присед. Решает pop_down_action. */
|
||||
if (!pop_down_action())
|
||||
crouch();
|
||||
}
|
||||
|
||||
/* Вертикальный прыжок вверх (seg005 jump_up, упрощённо): сверху сплошное
|
||||
* (стена/пол) → seq_14 (в потолок), иначе seq_28 (пусто сверху). Зацеп за
|
||||
* уступ сверху-впереди (can_grab) — K4.2, пока чистый вертикальный прыжок. */
|
||||
/* Прыжок вверх в стойке (seg005 check_jump_up): чистый вертикальный прыжок
|
||||
* ЛИБО прыжок-с-зацепом за уступ выше (запрыгнуть на этаж вверх). Выбор seq
|
||||
* + выравнивание Kid.x — в pop_jump_up_seq (pop_map). */
|
||||
static void jump_up(void)
|
||||
{
|
||||
control_up = release_arrows();
|
||||
if (pop_above_solid())
|
||||
seqtbl_offset_char(SEQ_14_JUMP_INTO_CEILING);
|
||||
else
|
||||
seqtbl_offset_char(SEQ_28_JUMP_NOTHING_ABOVE);
|
||||
seqtbl_offset_char(pop_jump_up_seq());
|
||||
}
|
||||
|
||||
static void up_pressed(void)
|
||||
@@ -250,6 +250,43 @@ static void control_running(void)
|
||||
}
|
||||
}
|
||||
|
||||
/* ---- Вис (seg005 control_hanging/can_climb_up/hang_fall) ---------- *
|
||||
* Тайловые решения (можно ли подтянуться, куда сорваться) — в pop_map;
|
||||
* здесь управление осями control_*. */
|
||||
static void hang_fall(void)
|
||||
{
|
||||
control_down = release_arrows();
|
||||
seqtbl_offset_char(pop_hang_fall_seq()); /* seq_23/seq_11 (+ выравнивание x) */
|
||||
}
|
||||
|
||||
static void can_climb_up(void)
|
||||
{
|
||||
control_up = control_shift2 = release_arrows();
|
||||
seqtbl_offset_char(pop_hang_climb_up_seq()); /* seq_10 / seq_73 */
|
||||
}
|
||||
|
||||
static void control_hanging(void)
|
||||
{
|
||||
if (control_y == CONTROL_HELD && pop_hang_grab_ready()) {
|
||||
can_climb_up(); /* ↑ — подтянуться */
|
||||
} else if (control_shift == CONTROL_HELD) {
|
||||
int8_t w = pop_hang_wall();
|
||||
if (w > 0) seqtbl_offset_char(SEQ_25_HANG_AGAINST_WALL); /* у стены */
|
||||
else if (w < 0) hang_fall(); /* сорваться */
|
||||
/* w==0: сверху пол — держимся (ничего) */
|
||||
} else {
|
||||
hang_fall(); /* отпустил Shift — сорваться */
|
||||
}
|
||||
}
|
||||
|
||||
/* control_jumpup (seg005): в старте прыжка вверх ←/→ или forward → перевести
|
||||
* в прыжок с места. */
|
||||
static void control_jumpup(void)
|
||||
{
|
||||
if (control_x == CONTROL_HELD_FORWARD || control_forward == CONTROL_HELD)
|
||||
standing_jump();
|
||||
}
|
||||
|
||||
/* control() — диспетчер по кадру (seg005.c:252), Kid жив, без меча. */
|
||||
static void control(void)
|
||||
{
|
||||
@@ -261,11 +298,11 @@ static void control(void)
|
||||
else if (f < 4)
|
||||
control_startrun();
|
||||
else if (f >= FRAME_67_JUMPUP1 && f < FRAME_70_JUMPHANG)
|
||||
; /* control_jumpup — K4 */
|
||||
control_jumpup();
|
||||
else if (f < FRAME_15_STAND)
|
||||
control_running();
|
||||
else if (f >= FRAME_87_HANG1 && f < 100)
|
||||
; /* control_hanging — K4 */
|
||||
control_hanging();
|
||||
else if (f == FRAME_109_CROUCH)
|
||||
control_crouched();
|
||||
}
|
||||
@@ -358,6 +395,11 @@ void pop_ctrl_close(void)
|
||||
kbd_raw_close();
|
||||
}
|
||||
|
||||
int8_t pop_ctrl_shift_held(void)
|
||||
{
|
||||
return (int8_t)(control_shift == CONTROL_HELD);
|
||||
}
|
||||
|
||||
void pop_ctrl_tick(void)
|
||||
{
|
||||
rest_ctrl_1();
|
||||
|
||||
@@ -28,4 +28,8 @@ void pop_ctrl_close(void);
|
||||
* kid_tick() (play_seq продолжит с новой последовательности). */
|
||||
void pop_ctrl_tick(void);
|
||||
|
||||
/* control_shift зажат ПРЯМО СЕЙЧАС? — для check_grab в физике (pop_map):
|
||||
* зацеп за уступ в падении по Shift. Валидно после pop_ctrl_tick. */
|
||||
int8_t pop_ctrl_shift_held(void);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -18,9 +18,15 @@
|
||||
#include <stdint.h>
|
||||
#include "pop_kid.h"
|
||||
#include "pop_map.h"
|
||||
#include "pop_ctrl.h" /* pop_ctrl_shift_held() — для check_grab */
|
||||
|
||||
/* ---- Тайлы / действия / seq id (подмножество PoP) ------------------ */
|
||||
#define TILE_EMPTY 0
|
||||
#define TILE_GATE 4
|
||||
#define TILE_DOORTOP_FLOOR 7 /* tapestry (пол сверху) */
|
||||
#define TILE_DOORTOP 12 /* tapestry top */
|
||||
#define TILE_MIRROR 13
|
||||
#define TILE_CHOMPER 18
|
||||
#define TILE_WALL 20
|
||||
#define ACT_STAND 0
|
||||
#define ACT_RUNJUMP 1
|
||||
@@ -37,6 +43,18 @@
|
||||
#define SEQ_20_MEDIUM_LAND 20
|
||||
#define SEQ_21_FALL_RUNJUMP 21
|
||||
#define SEQ_47_BUMP 47 /* удар в стену: dx(-4) отскок + 50-52 + stand */
|
||||
/* K4 — зацеп/вис/подтягивание/спуск */
|
||||
#define SEQ_8_GRAB_STRAIGHT 8 /* прыжок вверх и зацеп (прямо) */
|
||||
#define SEQ_14_JUMP_INTO_CEILING 14 /* прыжок вверх: сверху стена/пол */
|
||||
#define SEQ_16_JUMP_UP_AND_GRAB 16 /* прыжок вверх и зацеп (нет пола сзади)*/
|
||||
#define SEQ_24_GRAB_FORWARD 24 /* прыжок вверх и зацеп (пол сзади) */
|
||||
#define SEQ_28_JUMP_NOTHING_ABOVE 28 /* прыжок вверх: сверху пусто */
|
||||
#define SEQ_10_CLIMB_UP 10 /* подтягивание из виса */
|
||||
#define SEQ_11_RELEASE_LEDGE_LAND 11 /* сорваться и встать (конец спуска) */
|
||||
#define SEQ_15_GRAB_LEDGE_MIDAIR 15 /* зацеп за уступ в падении */
|
||||
#define SEQ_23_RELEASE_LEDGE_FALL 23 /* отпустить уступ и падать */
|
||||
#define SEQ_68_CLIMB_DOWN 68 /* спуск через зацеп (не приседание) */
|
||||
#define SEQ_73_CLIMB_UP_TO_GATE 73 /* подъём к закрытой калитке */
|
||||
|
||||
#define FRAME_NEEDS_FLOOR 0x40
|
||||
#define FRAME_WEIGHT_X 0x1F
|
||||
@@ -52,6 +70,7 @@
|
||||
|
||||
static const int16_t y_land[5] = {-8, 55, 118, 181, 244};
|
||||
static const int8_t dir_front[2] = {-1, 1}; /* [dir+1]: dir=-1->-1, 0->+1 */
|
||||
static const int8_t dir_behind[2] = {1, -1}; /* [dir+1]: назад по направлению */
|
||||
static const int16_t x_bump[20] = {
|
||||
-12, 2, 16, 30, 44, 58, 72, 86, 100, 114,
|
||||
128, 142, 156, 170, 184, 198, 212, 226, 240, 254
|
||||
@@ -66,6 +85,7 @@ uint8_t pop_fell_out; /* 1 = Kid упал за низ комнаты
|
||||
static const uint8_t *g_fg; /* fg[30], row*10+col */
|
||||
static uint8_t g_curr_tile; /* = curr_tile2: тайл последнего get_tile */
|
||||
static uint8_t g_obj_xl; /* позиция внутри тайла (get_tile_div_mod) */
|
||||
static uint8_t grab_timer; /* после зацепа (12): блокирует climb-up */
|
||||
|
||||
void pop_map_set(const uint8_t *fg) { g_fg = fg; }
|
||||
|
||||
@@ -100,6 +120,30 @@ static uint8_t get_tile_infrontof_char(void)
|
||||
return get_tile(g_infrontx, Kid.curr_row);
|
||||
}
|
||||
|
||||
/* ---- Тайлы НАД/ЗА персонажем (для зацепа/спуска, seg006) ----------- */
|
||||
static uint8_t get_tile_above_char(void)
|
||||
{
|
||||
return get_tile(Kid.curr_col, (int8_t)(Kid.curr_row - 1));
|
||||
}
|
||||
|
||||
static uint8_t get_tile_behind_char(void)
|
||||
{
|
||||
return get_tile((int8_t)(dir_behind[Kid.direction + 1] + Kid.curr_col),
|
||||
Kid.curr_row);
|
||||
}
|
||||
|
||||
static uint8_t get_tile_front_above_char(void)
|
||||
{
|
||||
g_infrontx = (int8_t)(dir_front[Kid.direction + 1] + Kid.curr_col);
|
||||
return get_tile(g_infrontx, (int8_t)(Kid.curr_row - 1));
|
||||
}
|
||||
|
||||
static uint8_t get_tile_behind_above_char(void)
|
||||
{
|
||||
return get_tile((int8_t)(dir_behind[Kid.direction + 1] + Kid.curr_col),
|
||||
(int8_t)(Kid.curr_row - 1));
|
||||
}
|
||||
|
||||
static uint8_t wall_type(uint8_t t)
|
||||
{
|
||||
switch (t) {
|
||||
@@ -233,12 +277,59 @@ static void start_fall(void)
|
||||
in_wall();
|
||||
}
|
||||
|
||||
/* ---- Зацеп (seg006 can_grab/check_grab) --------------------------- *
|
||||
* can_grab: можно ли зацепиться за g_curr_tile (curr_tile2) СКВОЗЬ through-
|
||||
* тайл? Kid-only (без loose/opener-модификаторов). */
|
||||
static uint8_t can_grab(uint8_t through)
|
||||
{
|
||||
if (through == TILE_WALL) return 0; /* сквозь стену нельзя */
|
||||
if (through == TILE_DOORTOP && Kid.direction >= 0) return 0; /* верх двери, лицом вправо */
|
||||
if (tile_is_floor(through)) return 0; /* сквозь пол нельзя */
|
||||
if (g_curr_tile == TILE_DOORTOP_FLOOR && Kid.direction < 0) return 0;
|
||||
if (!tile_is_floor(g_curr_tile)) return 0; /* не за что цепляться */
|
||||
return 1;
|
||||
}
|
||||
|
||||
static uint8_t can_grab_front_above(void)
|
||||
{
|
||||
uint8_t through = get_tile_above_char();
|
||||
get_tile_front_above_char(); /* g_curr_tile = спереди-сверху */
|
||||
return can_grab(through);
|
||||
}
|
||||
|
||||
/* check_grab (seg006:0A28): в падении при зажатом Shift — зацепиться за
|
||||
* уступ спереди-сверху (seq_15), если скорость падения ещё мала и высота
|
||||
* подходящая. Выравнивает передний край по кромке, гасит fall_y, взводит
|
||||
* grab_timer (блок climb-up на несколько кадров). */
|
||||
static void check_grab(void)
|
||||
{
|
||||
uint8_t old_x;
|
||||
if (!pop_ctrl_shift_held()) return; /* Shift не зажат */
|
||||
if ((uint8_t)Kid.fall_y >= 32) return; /* падает слишком быстро */
|
||||
if ((uint16_t)y_land[Kid.curr_row + 1] > (uint16_t)(Kid.y + 25)) return;
|
||||
old_x = Kid.x;
|
||||
Kid.x = (uint8_t)char_dx_forward(-8);
|
||||
determine_col();
|
||||
if (!can_grab_front_above()) {
|
||||
Kid.x = old_x; /* не за что — назад */
|
||||
determine_col();
|
||||
} else {
|
||||
Kid.x = (uint8_t)char_dx_forward((int8_t)distance_to_edge_weight());
|
||||
Kid.y = (uint8_t)y_land[Kid.curr_row + 1];
|
||||
Kid.fall_y = 0;
|
||||
kid_set_seq(SEQ_15_GRAB_LEDGE_MIDAIR);
|
||||
play_seq();
|
||||
determine_col();
|
||||
grab_timer = 12; /* (TODO: sound grab) */
|
||||
}
|
||||
}
|
||||
|
||||
static void do_fall(void)
|
||||
{
|
||||
uint8_t nrow = (uint8_t)(Kid.curr_row + 1);
|
||||
if (nrow > 4) nrow = 4; /* защита y_land[] от выхода */
|
||||
if ((uint16_t)y_land[nrow] > (uint16_t)Kid.y) {
|
||||
/* ещё летит (check_grab — K4) */
|
||||
check_grab(); /* ещё летит — попытка зацепа */
|
||||
} else {
|
||||
if (get_tile_at_char() == TILE_WALL)
|
||||
in_wall();
|
||||
@@ -306,13 +397,68 @@ int pop_edge_distance(void)
|
||||
|
||||
uint8_t pop_edge_type(void) { return g_edge_type; }
|
||||
|
||||
/* Тайл НАД персонажем (curr_row-1, curr_col) сплошной (стена/пол)? — выбор
|
||||
* seq прыжка вверх: solid -> seq_14 (в потолок), иначе seq_28 (пусто сверху).
|
||||
* K4.1 упрощение: без grab-логики (уступ сверху-впереди) — та в K4.2. */
|
||||
uint8_t pop_above_solid(void)
|
||||
/* ---- Прыжок вверх с зацепом (seg005 check_jump_up и производные) --- *
|
||||
* pop_jump_up_seq выбирает seq для ↑ в стойке: чистый прыжок (seq_28 в
|
||||
* пустоту / seq_14 в потолок) ЛИБО прыжок-и-зацеп за уступ выше (seq_8/
|
||||
* 24 — с полом сзади, seq_16 — без), и выравнивает Kid.x. control_up
|
||||
* гасит caller (pop_ctrl). Порт: check_jump_up/grab_up_with_floor_behind/
|
||||
* jump_up_or_grab/grab_up_no_floor_behind/jump_up (без super-high-jump). */
|
||||
static uint8_t grab_up_with_floor_behind(void)
|
||||
{
|
||||
uint8_t t = get_tile(Kid.curr_col, (int8_t)(Kid.curr_row - 1));
|
||||
return (t == TILE_WALL || tile_is_floor(t));
|
||||
int distance = distance_to_edge_weight();
|
||||
int edge_distance = pop_edge_distance(); /* побочно ставит g_edge_type */
|
||||
if (distance < 4 && edge_distance < 4 && g_edge_type != EDGE_WALL) {
|
||||
Kid.x = (uint8_t)char_dx_forward((int8_t)distance);
|
||||
return SEQ_8_GRAB_STRAIGHT;
|
||||
}
|
||||
Kid.x = (uint8_t)char_dx_forward((int8_t)(distance - 4));
|
||||
return SEQ_24_GRAB_FORWARD;
|
||||
}
|
||||
|
||||
static uint8_t jump_up_plain(void) /* seg005 jump_up (без super) */
|
||||
{
|
||||
int distance = pop_edge_distance(); /* ставит g_edge_type */
|
||||
int8_t col;
|
||||
uint8_t t;
|
||||
if (distance < 4 && g_edge_type == EDGE_WALL)
|
||||
Kid.x = (uint8_t)char_dx_forward((int8_t)(distance - 3));
|
||||
col = get_tile_div_mod(dx_weight() - 6);
|
||||
t = get_tile(col, (int8_t)(Kid.curr_row - 1));
|
||||
if (t != TILE_WALL && !tile_is_floor(t))
|
||||
return SEQ_28_JUMP_NOTHING_ABOVE;
|
||||
return SEQ_14_JUMP_INTO_CEILING;
|
||||
}
|
||||
|
||||
static uint8_t grab_up_no_floor_behind(void)
|
||||
{
|
||||
get_tile_above_char();
|
||||
Kid.x = (uint8_t)char_dx_forward((int8_t)(distance_to_edge_weight() - 10));
|
||||
return SEQ_16_JUMP_UP_AND_GRAB;
|
||||
}
|
||||
|
||||
static uint8_t jump_up_or_grab(void)
|
||||
{
|
||||
int distance = distance_to_edge_weight();
|
||||
if (distance < 6)
|
||||
return jump_up_plain();
|
||||
if (!tile_is_floor(get_tile_behind_char()))
|
||||
return grab_up_no_floor_behind();
|
||||
Kid.x = (uint8_t)char_dx_forward((int8_t)(distance - TILE_SIZEX));
|
||||
determine_col(); /* load_fram_det_col */
|
||||
return grab_up_with_floor_behind();
|
||||
}
|
||||
|
||||
uint8_t pop_jump_up_seq(void)
|
||||
{
|
||||
uint8_t through = get_tile_above_char();
|
||||
get_tile_front_above_char(); /* g_curr_tile = спереди-сверху */
|
||||
if (can_grab(through))
|
||||
return grab_up_with_floor_behind();
|
||||
through = get_tile_behind_above_char();
|
||||
get_tile_above_char(); /* g_curr_tile = сверху */
|
||||
if (can_grab(through))
|
||||
return jump_up_or_grab();
|
||||
return jump_up_plain();
|
||||
}
|
||||
|
||||
/* Стена впереди достаточно близко для стопа бега? Детект (без сдвига —
|
||||
@@ -323,6 +469,78 @@ int pop_wall_ahead(void)
|
||||
return (g_edge_type == EDGE_WALL && d <= 2);
|
||||
}
|
||||
|
||||
/* ---- Вис (control_hanging из seg005) — тайловые решения ------------ *
|
||||
* Управление держится в pop_ctrl (control_*), сюда вынесены только
|
||||
* тайловые предикаты + выбор seq (+ выравнивание Kid.x). */
|
||||
|
||||
/* grab_timer истёк — можно подтягиваться? */
|
||||
uint8_t pop_hang_grab_ready(void) { return grab_timer == 0; }
|
||||
|
||||
/* can_climb_up: тайл над персонажем — обычный подъём (seq_10) либо подъём
|
||||
* к закрытой калитке/зеркалу/чомперу (seq_73). */
|
||||
uint8_t pop_hang_climb_up_seq(void)
|
||||
{
|
||||
uint8_t t = get_tile_above_char();
|
||||
if (((t == TILE_MIRROR || t == TILE_CHOMPER) && Kid.direction == 0) ||
|
||||
(t == TILE_GATE && Kid.direction != 0))
|
||||
return SEQ_73_CLIMB_UP_TO_GATE;
|
||||
return SEQ_10_CLIMB_UP;
|
||||
}
|
||||
|
||||
/* Shift в висе: 1 = висит у стены/двери (caller играет seq_25); -1 =
|
||||
* сорваться (hang_fall); 0 = сверху пол, остаётся висеть (ничего). */
|
||||
int8_t pop_hang_wall(void)
|
||||
{
|
||||
uint8_t t = get_tile_at_char();
|
||||
if (Kid.action != ACT_HANGSTRAIGHT &&
|
||||
(t == TILE_WALL ||
|
||||
(Kid.direction < 0 && (t == TILE_DOORTOP_FLOOR || t == TILE_DOORTOP))))
|
||||
return 1;
|
||||
if (!tile_is_floor(get_tile_above_char()))
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* hang_fall (seg005:0A46): сорваться. Нет пола ни сзади, ни под
|
||||
* персонажем — seq_23 (отпустить и падать); иначе прижать к стене (-7)
|
||||
* и seq_11 (встать, конец спуска). Меняет Kid.x, возвращает seq. */
|
||||
uint8_t pop_hang_fall_seq(void)
|
||||
{
|
||||
uint8_t behind = get_tile_behind_char();
|
||||
uint8_t at;
|
||||
if (!tile_is_floor(behind) && !tile_is_floor(get_tile_at_char()))
|
||||
return SEQ_23_RELEASE_LEDGE_FALL;
|
||||
at = get_tile_at_char();
|
||||
if (at == TILE_WALL ||
|
||||
(Kid.direction < 0 && (at == TILE_DOORTOP_FLOOR || at == TILE_DOORTOP)))
|
||||
Kid.x = (uint8_t)char_dx_forward(-7);
|
||||
return SEQ_11_RELEASE_LEDGE_LAND;
|
||||
}
|
||||
|
||||
/* down_pressed (seg005:04C7) tile-часть: 1 = обработано (НЕ приседать —
|
||||
* либо спуск seq_68 через зацеп, либо отступ от передней кромки), 0 =
|
||||
* приседать. Меняет Kid.x. Kid развёрнут от края (край сзади) у кромки
|
||||
* пола + под соседним тайлом есть за что зацепиться → спуск на этаж вниз. */
|
||||
uint8_t pop_down_action(void)
|
||||
{
|
||||
if (!tile_is_floor(get_tile_infrontof_char()) && distance_to_edge_weight() < 3) {
|
||||
Kid.x = (uint8_t)char_dx_forward(5); /* у передней кромки — отступ */
|
||||
determine_col();
|
||||
return 1;
|
||||
}
|
||||
if (!tile_is_floor(get_tile_behind_char()) && distance_to_edge_weight() >= 8) {
|
||||
uint8_t through = get_tile_behind_char();
|
||||
get_tile_at_char(); /* g_curr_tile = под персонажем */
|
||||
if (can_grab(through) &&
|
||||
(Kid.direction >= 0 || get_tile_at_char() != TILE_GATE)) {
|
||||
Kid.x = (uint8_t)char_dx_forward((int8_t)(distance_to_edge_weight() - 9));
|
||||
kid_set_seq(SEQ_68_CLIMB_DOWN);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ---- Диспетчер ----------------------------------------------------- */
|
||||
static void check_on_floor(void)
|
||||
{
|
||||
@@ -357,7 +575,17 @@ static void check_action(void)
|
||||
static void check_bumped(void)
|
||||
{
|
||||
uint8_t t; int8_t tcol; int d;
|
||||
if (Kid.action == ACT_FREEFALL || Kid.action == ACT_HANGCLIMB) return;
|
||||
/* Не бампим в падении/висе/подтягивании (seg004 check_bumped guard'ы:
|
||||
* action hang_climb/hang_straight + кадры подъёма 135..148 — иначе
|
||||
* climb-up у стены прерывается отскоком). FREEFALL — наш guard: стену
|
||||
* в падении держит do_fall/in_wall. */
|
||||
if (Kid.action == ACT_FREEFALL || Kid.action == ACT_HANGCLIMB ||
|
||||
Kid.action == ACT_HANGSTRAIGHT) return;
|
||||
if (Kid.frame >= 135 && Kid.frame < 149) return; /* кадры подъёма/спуска */
|
||||
/* Кадры виса 87..99: в спуске (seq_68) кадр frame_91 идёт ДО act(hang_climb),
|
||||
* т.е. action ещё midair — без этого guard'а bump у стены рвёт цепочку
|
||||
* hang->hang_fall->seq_11 (правильное приземление). */
|
||||
if (Kid.frame >= 87 && Kid.frame < 100) return;
|
||||
t = get_tile_at_char(); tcol = Kid.curr_col;
|
||||
if (!wall_type(t)) { t = get_tile_infrontof_char(); tcol = g_infrontx; }
|
||||
if (!wall_type(t)) return;
|
||||
@@ -374,6 +602,7 @@ static void check_bumped(void)
|
||||
|
||||
void pop_phys_tick(void)
|
||||
{
|
||||
if (grab_timer) grab_timer--;
|
||||
fall_accel();
|
||||
fall_speed();
|
||||
determine_col();
|
||||
|
||||
@@ -41,8 +41,18 @@ uint8_t pop_edge_type(void);
|
||||
* control_running (чистый стоп у стены). */
|
||||
int pop_wall_ahead(void);
|
||||
|
||||
/* Тайл над персонажем сплошной (стена/пол)? — выбор seq вертикального
|
||||
* прыжка вверх (K4.1). */
|
||||
uint8_t pop_above_solid(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
|
||||
|
||||
Reference in New Issue
Block a user