roomtest: фикс провала сквозь пол при беге с кромки (порт start_fall/in_wall)
Тап-бег с кромки [1,3] вправо -> Kid проваливался в стену col2/3 -> респавн, вместо посадки на [2,4]. Сверено с SDLPoP seg006: - start_fall: frame 9 -> seq_7_fall (был ошибочно seq_19 как у 13); frame 13 -> seq_19 (лишний dx(1)). + хвост seg006:1099: тайл ПЕРЕД персонажем — стена -> Char.x = char_dx_forward(-1); - in_wall переписан аутентично (seg006:1292): выталкивает ВПЕРЁД из стены (delta+4) на соседний тайл, а не назад вглубь (наш старый через dist_from_wall_forward давал отрицательный сдвиг -> Kid уходил в стену col2 -> проваливался). distance_to_edge_weight + 6-delta/+4. Проверено в MAME (пользователь): бег с кромки [1,3] -> посадка на [2,4]. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -225,21 +225,21 @@ static int dist_from_wall_forward(uint8_t tiletype, int8_t tcol)
|
||||
return wall_dl[type] + coll_left - cx;
|
||||
}
|
||||
|
||||
/* Выровнять передний край РОВНО к грани стены, если он зашёл за неё (bumped:
|
||||
* Char.x += dist; char_dx_forward отражает знак для обоих направлений).
|
||||
* Стена ищется под персонажем, иначе перед ним. */
|
||||
/* in_wall (seg006:1292): персонаж оказался ВНУТРИ стены (тайл под ним =
|
||||
* стена) — вытолкнуть. Аутентично SDLPoP: если он глубоко (delta>=8) ИЛИ
|
||||
* перед ним тоже стена — двигаем НАЗАД к грани (6-delta), иначе ВПЕРЁД из
|
||||
* стены на соседний тайл (delta+4). Вызывать ТОЛЬКО когда
|
||||
* get_tile_at_char()==стена (проверяет вызывающий). */
|
||||
static void in_wall(void)
|
||||
{
|
||||
uint8_t t; int8_t tcol; int d;
|
||||
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;
|
||||
d = dist_from_wall_forward(t, tcol);
|
||||
if (d < 0) {
|
||||
Kid.x = (uint8_t)char_dx_forward((int8_t)d); /* край -> грань */
|
||||
int d = distance_to_edge_weight();
|
||||
if (d >= 8 || get_tile_infrontof_char() == TILE_WALL)
|
||||
d = 6 - d;
|
||||
else
|
||||
d += 4;
|
||||
Kid.x = (uint8_t)char_dx_forward((int8_t)d);
|
||||
determine_col();
|
||||
get_tile_at_char();
|
||||
}
|
||||
}
|
||||
|
||||
/* ---- Падение ------------------------------------------------------- */
|
||||
@@ -264,17 +264,29 @@ static void land(void)
|
||||
|
||||
static void start_fall(void)
|
||||
{
|
||||
uint8_t frame = Kid.frame, seq;
|
||||
uint8_t frame = Kid.frame, seq, tile;
|
||||
inc_curr_row();
|
||||
if (frame == 9 || frame == 13) seq = SEQ_19_FALL; /* падение из бега */
|
||||
/* seg006:1044 start_fall: frame 9 -> seq_7, 13 -> seq_19 (лишний dx(1)) */
|
||||
if (frame == 13) seq = SEQ_19_FALL;
|
||||
else if (frame == 26) seq = SEQ_18_FALL_STANDJUMP;
|
||||
else if (frame == 44) seq = SEQ_21_FALL_RUNJUMP;
|
||||
else seq = SEQ_7_FALL; /* stand/step/crouch */
|
||||
else seq = SEQ_7_FALL; /* frame 9 + stand/step/crouch */
|
||||
kid_set_seq(seq);
|
||||
play_seq();
|
||||
determine_col();
|
||||
if (get_tile_at_char() == TILE_WALL)
|
||||
if (get_tile_at_char() == TILE_WALL) {
|
||||
in_wall();
|
||||
return;
|
||||
}
|
||||
/* Хвост seg006:1099: тайл ПЕРЕД персонажем — стена → отодвинуть на 1
|
||||
* назад (иначе передний край зайдёт в грань). (seq_104 для frame 44 с
|
||||
* малым зазором не портирован — в этом тесте не встречается.) */
|
||||
tile = get_tile_infrontof_char();
|
||||
if (tile == TILE_WALL) {
|
||||
if (frame != 44 || distance_to_edge_weight() >= 6)
|
||||
Kid.x = (uint8_t)char_dx_forward(-1);
|
||||
determine_col();
|
||||
}
|
||||
}
|
||||
|
||||
/* ---- Зацеп (seg006 can_grab/check_grab) --------------------------- *
|
||||
|
||||
Reference in New Issue
Block a user