From 6769b6a01b3595a0d9b94159e1cdc54b0bfadfa3 Mon Sep 17 00:00:00 2001 From: Alexander Petrov Date: Wed, 29 Jul 2026 16:29:01 +0300 Subject: [PATCH] =?UTF-8?q?PoP=20roomtest:=20loose-=D0=BF=D0=BB=D0=B8?= =?UTF-8?q?=D1=82=D0=B0=20=D0=B2=D0=BF=D0=B5=D1=80=D0=B5=D0=B4=D0=B8=20=3D?= =?UTF-8?q?=20=D0=9A=D0=A0=D0=9E=D0=9C=D0=9A=D0=90=20=D0=B2=20get=5Fedge?= =?UTF-8?q?=5Fdistance?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Осторожный шаг к проваливающемуся полу проваливал Kid с первого же шага: в pop_edge_distance не было ветки оригинала (seg004:067C) if (tiletype == tiles_11_loose) goto loc_59FB; // CLOSER + до кромки — плита читалась как обычный пол (EDGE_FLOOR, 11), и весь механизм «проверки ногой» пролетал мимо. С веткой safe_step (seg005) отрабатывает три фазы, как в оригинале: (1) укороченный шаг РОВНО до кромки плиты (seq 29..42 по distance), (2) seq_44 testfoot — щуп ногой, плита трясётся по SEQ_KNOCK_DOWN, Kid остаётся на месте (Char.repeat), (3) только третье нажатие — шаг на плиту и падение вместе с ней. Заодно портированы соседние ветки той же функции: верх двери лицом вправо (проверяется ДО wall_type) и closer/меч/зелье (кромка, пока есть зазор). Проверено вручную в MAME: все три фазы. Co-Authored-By: Claude Opus 5 --- applications/PoP/roomtest/pop_map.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/applications/PoP/roomtest/pop_map.c b/applications/PoP/roomtest/pop_map.c index ef46da3..819e92d 100644 --- a/applications/PoP/roomtest/pop_map.c +++ b/applications/PoP/roomtest/pop_map.c @@ -34,6 +34,8 @@ #define TILE_DEBRIS 14 /* щебень (упавший loose) */ #define TILE_SPIKE 2 /* пики */ #define TILE_CLOSER 6 /* кнопка-закрывалка (DROP) */ +#define TILE_POTION 10 /* зелье */ +#define TILE_SWORD 22 /* меч на полу */ #define TILE_OPENER 15 /* кнопка-открывалка (RAISE, 0x0F) */ #define ACT_STAND 0 #define ACT_RUNJUMP 1 @@ -575,10 +577,33 @@ int pop_edge_distance(void) if (d >= 0) return edge_classify(d); } t = get_tile_infrontof_char(); + /* Верх двери лицом ВПРАВО — кромка (в оригинале ПЕРВОЙ проверкой, до + * wall_type: у doortop wall_type != 0). */ + if (t == TILE_DOORTOP && Kid.direction >= 0) { + g_edge_type = EDGE_CLOSER; + return distance_to_edge_weight(); + } if (wall_type(t)) { d = dist_from_wall_forward(t, g_infrontx); if (d >= 0) return edge_classify(d); } + /* ПРОВАЛИВАЮЩИЙСЯ пол впереди — КРОМКА, хотя tile_is_floor считает его + * полом. Это и есть механизм «проверки ногой»: осторожный шаг доводит + * Kid ровно до границы плиты (distance -> 0), там safe_step играет + * seq_44 (testfoot) — Kid щупает плиту ногой, та трясётся (SEQ_KNOCK_DOWN), + * и он остаётся на месте; шаг НА плиту — только со второго нажатия + * (Kid.repeat). Без этой ветки плита читалась как обычный пол, и Kid + * заходил на неё первым же осторожным шагом и падал вместе с ней. */ + if (t == TILE_LOOSE) { + g_edge_type = EDGE_CLOSER; + return distance_to_edge_weight(); + } + /* Кнопка-закрывалка/меч/зелье: кромка, пока до границы есть зазор. */ + if (t == TILE_CLOSER || t == TILE_SWORD || t == TILE_POTION) { + d = distance_to_edge_weight(); + if (d) { g_edge_type = EDGE_CLOSER; return d; } + g_edge_type = EDGE_FLOOR; return 11; + } if (tile_is_floor(t)) { g_edge_type = EDGE_FLOOR; return 11; } g_edge_type = EDGE_CLOSER; /* яма впереди — до кромки уступа */ return distance_to_edge_weight();