From 52bcc65a62977e60d2157638842559e3327ff995 Mon Sep 17 00:00:00 2001 From: Alexander Petrov Date: Wed, 19 Aug 2026 16:23:41 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9E=D1=81=D0=BE=D0=B1=D0=B5=D0=BD=D0=BD?= =?UTF-8?q?=D0=BE=D1=81=D1=82=D1=8C:=20=D1=83=D0=B1=D0=B8=D1=82=D1=8B?= =?UTF-8?q?=D0=B9=20=D0=B7=D0=B0=20=D0=BF=D1=80=D0=B0=D0=B2=D1=8B=D0=BC=20?= =?UTF-8?q?=D0=BA=D1=80=D0=B0=D0=B5=D0=BC=20=D1=81=D1=82=D1=80=D0=B0=D0=B6?= =?UTF-8?q?=20=D0=BD=D0=B5=20=D0=B2=D0=B8=D0=B4=D0=B5=D0=BD=20=D0=BD=D0=B8?= =?UTF-8?q?=20=D0=B2=20=D0=BE=D0=B4=D0=BD=D0=BE=D0=B9=20=D0=BA=D0=BE=D0=BC?= =?UTF-8?q?=D0=BD=D0=B0=D1=82=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Вопрос пользователя после боя в комнате 15: Кид вытеснил стража вправо (из-за края торчал только меч), убил — труп не появился ни в 15, ни в соседней справа. Это не наш баг, а сложение трёх механизмов оригинала: физика стража работает только в полосе x 44..211, поэтому комнату он не менял; мёртвый за Кидом не идёт (follow_guard требует alive < 0), и leave_guard сохраняет его в прежнюю комнату; а из чужой комнаты страж не рисуется вовсе — при Guard.room != drawn_room оригинал гасит слот (seg000:422). Труп остаётся приписан комнате 15 с guards_x за правым краем: при возврате восстанавливается там же, то есть вне видимого поля. Живьём в SDLPoP сценарий не воспроизводился — вывод из чтения кода, о чём в записи сказано прямо. Co-Authored-By: Claude Opus 5 --- applications/PoP/docs/impl_diff.md | 41 ++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/applications/PoP/docs/impl_diff.md b/applications/PoP/docs/impl_diff.md index 2228031..0763856 100644 --- a/applications/PoP/docs/impl_diff.md +++ b/applications/PoP/docs/impl_diff.md @@ -439,3 +439,44 @@ BUG-CHEAT-FIGHT-1 (выход из боя), и лечится там же. **Что проверять при регрессе.** Уровень 13: `K` на Джафаре → белая вспышка, уход ВЛЕВО открывает дверь уровня. Честная победа в бою даёт то же самое. + +--- + +## Страж, вытесненный за правый край комнаты и там убитый, не виден нигде + +**Не расхождение, а особенность оригинала.** Записано, чтобы вопрос не +возникал повторно (спросил пользователь 2026-08-19: бой шёл в комнате 15, +Кид вытеснил стража вправо — из-за края торчал только меч, — убил его, и +труп не появился ни в комнате 15, ни в соседней справа). + +**Почему так.** Три механизма складываются: + +1. **комнату страж не менял.** Его физика работает только в полосе + `x ∈ [44, 211)` (`seg000:1254`, у нас то же условие в + `pop_guard_phys_tick`), поэтому своим ходом за край он не уходит — + Кид вытолкнул его туда толчком, а `Guard.room` остался прежним; +2. **мёртвый за Кидом не идёт.** Единственный способ сменить комнату — + `follow_guard` при переходе Кида, и первое же условие там + (`seg002:0346`) — `Guard.alive < 0 && Guard.sword == sword_2_drawn`, + то есть ЖИВОЙ и с вынутым мечом. Мёртвый уходит веткой `leave_guard`, + которая сохраняет его в **`Guard.room`** — в старую комнату. У нас + ровно это же условие, `pop_guard_cold.c` (`pop_guard_follow`); +3. **из соседней комнаты страж не рисуется.** Оригинал при + `Guard.room != drawn_room` просто ГАСИТ слот (`seg000:422`: + `Guard.direction = dir_56_none`). Механизм «видно из-за шва» + (`xpos_in_drawn_room`) работает для коллизий и для Кида, но стража из + чужой комнаты на экран не выводит. + +Итог: труп приписан комнате, где страж стоял, а его `guards_x` — за +правым краем. При возврате в ту комнату он честно восстанавливается там +же, то есть за пределами видимого поля; в соседней комнате его нет, +потому что в её данных стража и не было. + +**Живой страж в этой ситуации ведёт себя иначе** — при уходе Кида вправо +он идёт следом, если стоит достаточно близко к краю (`Guard.x >= 165`). +Это портировано и работает. + +**Чего я НЕ проверял:** живьём в SDLPoP этот сценарий не воспроизводил — +вывод сделан чтением трёх мест кода. Если понадобится подтверждение, +сценарий короткий: любой бой у правого края комнаты, вытеснить стража за +край и добить.