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;