PoP roomtest: loose-плита впереди = КРОМКА в get_edge_distance

Осторожный шаг к проваливающемуся полу проваливал 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 <noreply@anthropic.com>
This commit is contained in:
2026-07-29 16:29:01 +03:00
parent 5f5eefc9fc
commit 6769b6a01b
+25
View File
@@ -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();