From b106aba59bc9492bb6c5f2e80f58c4b5b2c4b947 Mon Sep 17 00:00:00 2001 From: Alexander Petrov Date: Tue, 28 Jul 2026 10:59:30 +0300 Subject: [PATCH] =?UTF-8?q?PoP=20roomtest:=20=D0=BF=D0=BE=D0=B4=D1=8A?= =?UTF-8?q?=D1=91=D0=BC/=D1=81=D0=BF=D1=83=D1=81=D0=BA=20=D0=BD=D0=B0=20?= =?UTF-8?q?=D0=9E=D0=A2=D0=9A=D0=A0=D0=AB=D0=A2=D0=AB=D0=A5=20=D0=B2=D0=BE?= =?UTF-8?q?=D1=80=D0=BE=D1=82=D0=B0=D1=85=20(=D0=BF=D0=BE=D1=82=D0=B5?= =?UTF-8?q?=D1=80=D1=8F=D0=BD=D0=BD=D0=B0=D1=8F=20=D0=BF=D1=80=D0=BE=D0=B2?= =?UTF-8?q?=D0=B5=D1=80=D0=BA=D0=B0=20openness)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Kid не мог залезть на тайл поднятой решётки: срывался обратно. can_climb_up (seg005:09DF) выбирает seq_73 («влез под решётку и съехал») только для ЗАКРЫТЫХ ворот — условие включает curr_room_modif[curr_tilepos] >> 2 < 6, а у нас его не было, и seq_73 играл при любой решётке над головой при взгляде влево. Та же дыра нашлась в спуске: down_pressed (seg005:482) запрещает climb-down с тайла ворот лицом влево тоже ТОЛЬКО пока они закрыты (|| curr_room_modif[curr_tilepos] >> 2 >= 6). Без этого Kid приседал вместо спуска даже под поднятой решёткой. Openness обеих проверок берётся общим хелпером gate_modif(col,row) (вынесен из gate_passable — умеет свою комнату и соседнюю через шов). Co-Authored-By: Claude Opus 5 --- applications/PoP/roomtest/pop_map.c | 35 ++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/applications/PoP/roomtest/pop_map.c b/applications/PoP/roomtest/pop_map.c index 00b7daa..fa8cc52 100644 --- a/applications/PoP/roomtest/pop_map.c +++ b/applications/PoP/roomtest/pop_map.c @@ -204,14 +204,21 @@ static uint8_t get_tile(int8_t col, int8_t row) * g_link_r col0; ВНУТРИ комнаты (0..9) — текущая комната g_room (иначе после * перехода Kid встаёт на ту же створку уже как на внутрикомнатную и его отбивает * обратно). Открыто ⇔ (modif>>2)+6 >= char_height (бары выше головы). */ +/* Живой модификатор (openness) ворот в (col,row): своя комната или соседняя + * через шов. 0xFF — тайла нет (за краем уровня). */ +static uint8_t gate_modif(int8_t col, int8_t row) +{ + if (row < 0 || row > 2) return 0xFF; + if (col == -1 && g_link_l) return pop_trob_modif(g_link_l)[row * 10 + 9]; + if (col == 10 && g_link_r) return pop_trob_modif(g_link_r)[row * 10 + 0]; + if (col >= 0 && col <= 9) return pop_trob_modif(g_room)[row * 10 + col]; + return 0xFF; +} + static uint8_t gate_passable(int8_t col, int8_t row) { - uint8_t gm; - if (row < 0 || row > 2) return 0; - if (col == -1 && g_link_l) gm = pop_trob_modif(g_link_l)[row * 10 + 9]; - else if (col == 10 && g_link_r) gm = pop_trob_modif(g_link_r)[row * 10 + 0]; - else if (col >= 0 && col <= 9) gm = pop_trob_modif(g_room)[row * 10 + col]; - else return 0; + uint8_t gm = gate_modif(col, row); + if (gm == 0xFF) return 0; return (uint8_t)((gm >> 2) + 6) >= (uint8_t)kid_fp_height(); } @@ -656,13 +663,18 @@ int pop_wall_ahead(void) /* grab_timer истёк — можно подтягиваться? */ uint8_t pop_hang_grab_ready(void) { return grab_timer == 0; } -/* can_climb_up: тайл над персонажем — обычный подъём (seq_10) либо подъём - * к закрытой калитке/зеркалу/чомперу (seq_73). */ +/* can_climb_up (seg005:09DF): тайл над персонажем — обычный подъём (seq_10) + * либо подъём к ЗАКРЫТОЙ калитке/зеркалу/чомперу (seq_73 = «влез и съехал + * обратно»). Для ворот условие включает ОТКРЫТОСТЬ: + * curr_tile2 == tiles_4_gate && direction != right && modif >> 2 < 6 + * — под поднятой решёткой (modif >> 2 >= 6) подъём обычный. Без проверки + * модификатора Kid срывался и с открытых ворот. */ 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)) + (t == TILE_GATE && Kid.direction != 0 && + (uint8_t)(gate_modif(Kid.curr_col, (int8_t)(Kid.curr_row - 1)) >> 2) < 6)) return SEQ_73_CLIMB_UP_TO_GATE; return SEQ_10_CLIMB_UP; } @@ -711,8 +723,11 @@ uint8_t pop_down_action(void) 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 = под персонажем */ + /* seg005:482: спуск с тайла-ворот лицом ВЛЕВО запрещён только пока они + * ЗАКРЫТЫ (modif >> 2 < 6); под поднятой решёткой спуск обычный. */ if (can_grab(through) && - (Kid.direction >= 0 || get_tile_at_char() != TILE_GATE)) { + (Kid.direction >= 0 || get_tile_at_char() != TILE_GATE || + (uint8_t)(gate_modif(Kid.curr_col, Kid.curr_row) >> 2) >= 6)) { Kid.x = (uint8_t)char_dx_forward((int8_t)(distance_to_edge_weight() - 9)); kid_set_seq(SEQ_68_CLIMB_DOWN); return 1;