PoP roomtest: убитый страж остаётся мёртвым; меч только по подбору или читу S
Смерть стража теперь персистентна между входами в комнату — по механизму оригинала, а не отдельной таблицей «убит/не убит». В SDLPoP массивы level.guards_* лежат в ОЗУ и движок их ПЕРЕПИСЫВАЕТ: leave_guard (seg002:02F5) кладёт туда позицию/направление/мастерство, а у МЁРТВОГО ещё и curr_seq; enter_guard, увидев непустой seq_hi, поднимает стража прямо в этой последовательности и по кадру смерти (185/177/178) ставит alive = 1. У нас уровень лежит в EMM-странице только на чтение, поэтому в W2 добавлена живая копия — 6 байт на комнату (tile/dir/x/skill/seq_lo/seq_hi): - pop_guard_leave() в начале enter_room запоминает уходящего стража; - pop_guard_enter поднимает труп сохранённой последовательностью И сохранённой X (pos_guards пересчитывает её из колонки только при загрузке уровня, дальше ею владеет leave_guard — иначе тело прыгает в центр тайла). ГРАБЛИ: guards_seq_lo/hi в ФАЙЛЕ уровня не используются, там 0xFF во всех комнатах (оригинал чистит их в reset_level_unused_fields). Прочитав их как есть, я скормил интерпретатору curr_seq = 0xFFFF, и приложение зависало — бордюр оставался синим, цикл не доходил до vsync. Живая копия стартует нулями: 0 = «поднимать стандартной стойкой». Меч Киду больше не выдаётся автоматически: DEBUG_SWORD_ROOM убран, вместо него чит S (выдать меч). Штатный путь — подобрать с пола. Проверено в MAME: чит K убивает стража, уход из комнаты 3 и возврат — тело на месте, страж не воскресает. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -73,11 +73,6 @@ uint8_t pop_cheats;
|
||||
* Убирается закомментированием ОДНОЙ строки ниже. */
|
||||
#define ROOMNAV 1
|
||||
|
||||
/* ОТЛАДКА БОЁВКИ: выдавать Киду меч сразу при входе в комнату с этим
|
||||
* номером (в комнате 3 стоит страж уровня 1). Иначе каждый прогон надо
|
||||
* бежать за мечом в комнату 15. Убрать, когда боёвку можно будет
|
||||
* проверять штатным путём. */
|
||||
#define DEBUG_SWORD_ROOM 3
|
||||
|
||||
/* Рабочая копия ТЕКУЩЕЙ комнаты (W2, мутабельная: loose→empty) + срезы
|
||||
* соседей для кромок. Заполняются pop_room_load из уровня. File-scope,
|
||||
@@ -170,6 +165,7 @@ static void apply_overrides(uint8_t room, uint8_t *tiles, uint8_t base, uint8_t
|
||||
static void enter_room(uint8_t room)
|
||||
{
|
||||
uint8_t pg;
|
||||
pop_guard_leave(); /* запомнить стража уходящей комнаты */
|
||||
uint8_t *room_mod;
|
||||
pop_room_load(room, room_fg, room_bg, lcol_fg, lcol_bg, rcol_fg, rcol_bg, below_fg);
|
||||
apply_overrides(room, room_fg, 0, 30); /* щебень/пустота от упавших плит */
|
||||
@@ -202,9 +198,6 @@ static void enter_room(uint8_t room)
|
||||
* Kid.room == Guard.room нужно уже сейчас: без него луч видимости
|
||||
* стража никогда не срабатывает. */
|
||||
Kid.room = room;
|
||||
#ifdef DEBUG_SWORD_ROOM
|
||||
if (room == DEBUG_SWORD_ROOM) pop_have_sword = 1;
|
||||
#endif
|
||||
pop_loose_reset(); /* loose-состояние не тянем из старой комнаты */
|
||||
pop_trob_room_changed(); /* отложенные перерисовки пик — не из старой комнаты */
|
||||
pop_trob_anim_room(room); /* факелы/зелья: стартовая фаза + trob */
|
||||
@@ -247,7 +240,7 @@ int main(void)
|
||||
#ifdef ROOMNAV
|
||||
uint8_t nav_prev = 0;
|
||||
#endif
|
||||
uint8_t cheat_prev = 0, immo_prev = 0;
|
||||
uint8_t cheat_prev = 0, immo_prev = 0, sword_prev = 0;
|
||||
|
||||
if (pop_bg_load() != 0) { /* атласы — ДО initgraph (снимает DSS-страницу W0) */
|
||||
puts("pop_bg_load failed");
|
||||
@@ -328,13 +321,18 @@ int main(void)
|
||||
* ФРОНТУ нажатия, иначе срабатывали бы каждый кадр.
|
||||
* K — убить стража;
|
||||
* I — бессмертие Кида (наш отладочный, в оригинале его нет:
|
||||
* иначе боёвку проверять получается ровно три раза). */
|
||||
* иначе боёвку проверять получается ровно три раза);
|
||||
* S — выдать меч, не бегая за ним в комнату 15. Штатно меч
|
||||
* берётся с пола (pop_have_sword ставит подбор). */
|
||||
uint8_t k = kbd_raw_down(KBD_CHEAT_KILL);
|
||||
uint8_t i = kbd_raw_down(KBD_CHEAT_IMMO);
|
||||
uint8_t s = kbd_raw_down(KBD_CHEAT_SWORD);
|
||||
if (pop_cheats && k && !cheat_prev) pop_guard_kill();
|
||||
if (pop_cheats && i && !immo_prev) pop_immortal = !pop_immortal;
|
||||
if (pop_cheats && s && !sword_prev) pop_have_sword = 1;
|
||||
cheat_prev = k;
|
||||
immo_prev = i;
|
||||
sword_prev = s;
|
||||
}
|
||||
if (frozen) {
|
||||
PROF(0); /* чёрный: ждём vsync */
|
||||
|
||||
Reference in New Issue
Block a user