PoP roomtest: ИИ стража — подход к Киду и боевые ветки диспетчера
Пункт 2 плана закрыт: страж не только замечает Кида, но и идёт к нему и дерётся. Порт по SDLPoP, диспетчер общий — ИИ выставляет те же control_*, что и клавиатура игрока. guards.c (банк 1), порт seg002: - autocontrol_guard_active (737) + kid_in_sight (0A93) + kid_armed (0AC1) + kid_far (09CB); - guard_advance / guard_block / guard_strike с таблицами вероятностей по 12 градациям мастерства (seg002:26..38), бросок prob > prandom(255); - move_2_backward / move_3_up / move_6_shift / move_down_back; - таймеры justblocked / kid_sword_strike / guard_refrac убывают раз в кадр в autocontrol_opponent, как в оригинале. pop_ctrl.c, порт seg005: control_with_sword (964), swordfight (0CDB), sword_strike, parry, forward_with_sword, back_with_sword. Ветвление у Кида и у соперника разное — соперник блокирует только на кадре 152, Кид ещё и по 153 (и тогда последовательность прокручивается сразу). pop_guard.c: guard_skill из данных уровня (12 градаций, вне диапазона -> 3), HP по get_guard_hp (extrastrength[skill] + tbl_guard_hp[уровень]), собственный сид бросков pop_fight_seed — иначе перерисовка стены сбивала бы решения стража. char_opp_dist переехал из банка в pop_kid.c: он нужен по ОБЕ стороны банковой границы — и ИИ, и диспетчеру боёвки. Проверено в MAME (комната 3): страж проходит комнату, встаёт в дистанцию и машет мечом, позы меняются. Урона пока нет — HP-учёт и check_hurt следующим шагом, без них бой не заканчивается. Бюджет В БОЮ (175 кадров): 412 224 – 421 068 = 0.958–0.979 кадра. В покое было 400 800. Запас в худшем кадре ~9 000 — тесно, но в один кадр укладываемся; оптимизация отложена сознательно. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -17,6 +17,13 @@ uint8_t guardhp_curr, guardhp_max;
|
||||
int8_t guardhp_delta;
|
||||
int8_t can_guard_see_kid;
|
||||
int8_t is_guard_notice;
|
||||
uint8_t guard_skill;
|
||||
int8_t guard_refrac, justblocked, kid_sword_strike;
|
||||
|
||||
/* Сид бросков боёвки. В оригинале генератор один на всё, у нас
|
||||
* последовательности разведены по доменам (кладка / анимация тайлов / бой),
|
||||
* см. pop_geom.h — иначе перерисовка стены сбивала бы броски стража. */
|
||||
pop_rnd_t pop_fight_seed;
|
||||
|
||||
/* Кадр стража (порт cur_frame для Char). Глобальный, а не статик: его
|
||||
* заполняет логика (W1/W2), а читает отрисовка из резидента W3. */
|
||||
@@ -36,6 +43,7 @@ void pop_guard_reset(void)
|
||||
guardhp_delta = 0;
|
||||
can_guard_see_kid = 0;
|
||||
is_guard_notice = 0;
|
||||
guard_refrac = justblocked = kid_sword_strike = 0;
|
||||
}
|
||||
|
||||
/* kill guard cheat (seg000:786):
|
||||
@@ -84,7 +92,12 @@ void pop_guard_enter(uint8_t room)
|
||||
Guard.alive = -1;
|
||||
Guard.action = 1; /* actions_1_run_jump */
|
||||
Guard.fall_x = Guard.fall_y = 0;
|
||||
guardhp_max = guardhp_curr = 3; /* get_guard_hp: skill 0, уровень 1 */
|
||||
/* enter_guard (seg002:214): мастерство из данных уровня, 12 градаций;
|
||||
* всё, что вне диапазона, оригинал сводит к 3. */
|
||||
guard_skill = (uint8_t)(skill < NUM_GUARD_SKILLS ? skill : 3);
|
||||
/* get_guard_hp (seg002:54): extrastrength[skill] + tbl_guard_hp[уровень].
|
||||
* Уровень 1 -> 3; extrastrength ненулевой только у skill 4. */
|
||||
guardhp_max = guardhp_curr = (uint8_t)(3 + (guard_skill == 4 ? 1 : 0));
|
||||
guardhp_delta = 0;
|
||||
/* enter_guard (seg002:0208): seqtbl_offset_char(seq_77_guard_stand_inactive).
|
||||
* Последовательность крутит общий интерпретатор (pop_guard_play), а
|
||||
|
||||
Reference in New Issue
Block a user