/*
 * pop_guard.h — СОСТОЯНИЕ стража и точки входа в его логику.
 *
 * Разделение по окнам (docs/layout_plan_v2.md §4, подтверждено пробником
 * tests/w3bankgfx):
 *   - СОСТОЯНИЕ живёт здесь, в W1/W2.  Писучие статики __banked-модуля
 *     линкуются В СТРАНИЦУ БАНКА и снаружи не читаются, поэтому банк —
 *     только код;
 *   - ЛОГИКА (ИИ, боёвка) — в guards.c, собираемом как --bank 1=guards.c;
 *   - ОТРИСОВКА стража — в pop_gdraw.c, РЕЗИДЕНТЕ W3 (--w3): её зовёт
 *     только главный цикл, а из банка резидент недостижим.  Так код
 *     отрисовки не занимает дефицитные W1/W2 (куча).
 *
 * Поля char_type — как в оригинале (types.h:302), чтобы порт seg005/seg006
 * ложился один в один.
 */
#ifndef POP_GUARD_H
#define POP_GUARD_H

#include <stdint.h>
#include "kid_data.h"          /* kframe */
#include "pop_char.h"
#include "pop_geom.h"    /* pop_rnd_t — сид бросков боёвки */

/* seqids (types.h:1052+) — последовательности боя и стойки. */
#define SEQ_55_DRAW_SWORD           55
#define SEQ_56_GUARD_FORWARD        56   /* шаг вперёд с мечом (страж)   */
#define SEQ_57_BACK_WITH_SWORD      57
#define SEQ_58_GUARD_STRIKE         58
#define SEQ_60_TURN_WITH_SWORD      60
#define SEQ_61_PARRY_AFTER_STRIKE   61
#define SEQ_62_PARRY                62
#define SEQ_66_STRIKE_AFTER_PARRY   66
#define SEQ_71_DYING                71
#define SEQ_75_STRIKE               75   /* удар (Кид)                   */
#define SEQ_77_GUARD_STAND_INACTIVE 77
#define SEQ_80_STAND_FLIPPED        80
#define SEQ_86_FORWARD_WITH_SWORD   86   /* шаг вперёд с мечом (Кид)     */
#define SEQ_87_GUARD_BECOME_INACT   87
#define SEQ_90_EN_GARDE             90
#define SEQ_92_PUT_SWORD_AWAY       92
#define SEQ_93_PUT_SWORD_AWAY_FAST  93

/* frameids (types.h:911+) и состояния меча (types.h:332). */
#define FRAME_150_PARRY            150
#define FRAME_151_STRIKE_1         151
#define FRAME_152_STRIKE_2         152
#define FRAME_153_STRIKE_3         153
#define FRAME_157_WALK_WITH_SWORD  157
#define FRAME_158_STAND_WITH_SWORD 158
#define FRAME_161_PARRY            161
#define FRAME_162_BLOCK_TO_STRIKE  162
#define FRAME_165_WALK_WITH_SWORD  165
#define FRAME_166_STAND_INACTIVE   166
#define FRAME_167_BLOCKED          167
#define FRAME_168_BACK             168
#define FRAME_169_BEGIN_BLOCK      169
#define FRAME_170_STAND_WITH_SWORD 170
#define FRAME_171_STAND_WITH_SWORD 171
#define SWORD_0_SHEATHED             0
#define SWORD_2_DRAWN                2

/* charids (types.h:320) — нужны хотя бы для «скелет не убивается читом». */
#define CHARID_0_KID       0
#define CHARID_1_SHADOW    1
#define CHARID_2_GUARD     2
#define CHARID_4_SKELETON  4
#define CHARID_5_PRINCESS  5

/* Градаций мастерства стража (seg002: таблицы вероятностей по 12 записей). */
#define NUM_GUARD_SKILLS  12

/* Тип персонажа — в pop_char.h (общий с Кидом и Char). */

extern pop_char_t Guard;            /* страж ТЕКУЩЕЙ комнаты (как в оригинале) */
extern uint8_t  guardhp_curr, guardhp_max;
extern int8_t   guardhp_delta;      /* <0 = в этом кадре отняли HP */

/* Видит ли страж Кида (порт can_guard_see_kid, seg003:688):
 *   0 — не видит, 1 — видит, но не пойдёт (между ними loose/чомпер/дыра),
 *   2 — видит и пойдёт.  Считает pop_check_can_guard_see_kid (банк) раз в
 * кадр ДО логики персонажей; читают ИИ (autocontrol_*) и боёвка. */
extern int8_t can_guard_see_kid;

/* Кид «нашумел» (порт is_guard_notice, seg000:364): заставляет неактивного
 * стража обернуться, даже если Кид у него за спиной.  Ставит источник шума,
 * снимает сам ИИ. */
extern int8_t is_guard_notice;

/* Боевые таймеры/уровень мастерства (seg000:295..311).  Все убывают раз в
 * кадр в autocontrol_opponent — как в оригинале.
 *   guard_skill      — 0..11, из данных уровня; индекс в таблицы вероятностей;
 *   guard_refrac     — «отдышка» стража: пока >0, он не атакует и не наступает;
 *   justblocked      — Кид только что парировал (влияет на вероятность блока);
 *   kid_sword_strike — Кид только что бил (стража это придерживает). */
extern uint8_t guard_skill;
extern int8_t  guard_refrac, justblocked, kid_sword_strike;

/* Состояние меча КИДА (seg005/seg006):
 *   offguard      — меч убран НАМЕРЕННО (вниз в бою): пока стоит, Кид не
 *                   достаёт клинок автоматически, даже видя стража;
 *   holding_sword — клинок в руке (для индикатора HP стража). */
extern int8_t  offguard, holding_sword;

/* Сид бросков боёвки (свой домен последовательности, см. pop_geom.h). */
extern pop_rnd_t pop_fight_seed;

/* Луч видимости стража — раз в кадр, ДО тиков персонажей (в оригинале
 * check_can_guard_see_kid стоит в play_frame перед play_kid_frame). */
void pop_check_can_guard_see_kid(void) __banked;

/* Боёвка: пометить попадания (обе стороны) и применить их.  Порядок в
 * кадре как в play_frame: hurting -> hurt -> do_delta_hp. */
void pop_check_sword_hurting(void) __banked;
void pop_check_sword_hurt(void) __banked;

/* Текущий кадр стража (порт cur_frame для Char): заполняет логика в W1/W2,
 * читает отрисовка в резиденте W3.  image == 255 — рисовать нечего. */
extern kframe pop_gframe;
void pop_guard_load_frame(void);

/* Есть ли живой страж в отрисованной комнате (для главного цикла). */
uint8_t pop_guard_present(void);

/* Атласы стража (GUARD\\g0..g4.atl) — грузить ДО initgraph, как Kid.
 * 0 — OK, -1 — ошибка (тогда страж просто не рисуется). */
int  pop_guard_load(void) __banked;
void pop_guard_free(void) __banked;

/* Вход в комнату: поднять стража из данных уровня (порт enter_guard,
 * seg002:0112) либо убрать его, если в комнате стража нет. */
void pop_guard_enter(uint8_t room);

/* Запомнить стража УХОДЯЩЕЙ комнаты (порт leave_guard).  Звать в начале
 * enter_room, пока Guard ещё держит прежнего. */
void pop_guard_leave(void);

/* Нарисовать текущий кадр стража на back-странице (банк GFX_BANK_SPRITE,
 * как kid_draw) и стереть прошлый (heal).  Реализация — pop_gdraw.c
 * (резидент W3), поэтому звать ТОЛЬКО из главного цикла, не из банка. */
/* Полоса HP (Кид слева, страж справа) в статус-полосе.  Рисует главный цикл
 * ПОСЛЕ персонажей — она ничего не перекрывает. */
void pop_hp_draw(void) __banked;
/* Полоса стёрта перерисовкой фона (вход в комнату) — обновить обе страницы. */
void pop_hp_invalidate(void) __banked;

void pop_guard_heal(void) __banked;
void pop_guard_draw(void) __banked;

/* Ширина спрайта последнего нарисованного кадра стража (char_width_half
 * в set_char_collision).  Нужна для его ТАЙЛА ОБЪЕКТА — от него зависит
 * порядок отрисовки относительно Кида. */
uint16_t pop_guard_fp_width(void) __banked;

/* Убрать стража со сцены (смена комнаты / инициализация). */
void pop_guard_reset(void);

/* Чит «убить стража» (seg000:786, K): скелета не берёт.  Вызывать только
 * при включённых читах — проверку делает вызывающий. */
void pop_guard_kill(void);

/* do_delta_hp (seg003): применить дельту HP, накопленную за кадр.  Звать
 * раз в кадр ПОСЛЕ тиков персонажей (в оригинале — в play_frame). */
void pop_do_delta_hp(void);

/* Тик логики стража — В БАНКЕ (guards.c).  Состояние берёт отсюда. */
void pop_guard_tick(void) __banked;

#endif
