Бессмертие: два уровня вместо тумблера
1 — только бой: удары мечом не отнимают HP (ветка в hurt_by_sword).
2 — плюс мелкий урон: не проходят «минус деление» от падения с двух
этажей и от падающей плиты (pop_take_hp гасит count < 100).
Мгновенная смерть остаётся на обоих: пики, чомпер, падение с трёх этажей
и удар вне боевой стойки приходят с count = 100. В коде ровно два
значения урона, 1 и 100, поэтому граница точная, а не эвристическая.
Заодно ушёл костыль «снять бессмертие на время вызова take_hp(100)» в
hurt_by_sword — он был нужен только потому, что прежний чит глушил и
смертельный урон.
Клавиша I идёт по кругу 0 -> 1 -> 2 -> 0; в отладочной метке число
красных палочек = уровень.
This commit is contained in:
@@ -973,14 +973,15 @@ static void hurt_by_sword(void)
|
|||||||
* нет ни одной — управление зависало намертво: Кид стоял в боевой
|
* нет ни одной — управление зависало намертво: Кид стоял в боевой
|
||||||
* стойке без меча и не разворачивался к сопернику (BUG-CHEAT-IMM-1).
|
* стойке без меча и не разворачивался к сопернику (BUG-CHEAT-IMM-1).
|
||||||
*
|
*
|
||||||
* Ветку глушим на время вызова, а не правим pop_take_hp: тот общий
|
* Костыля «снять бессмертие на время вызова» здесь БОЛЬШЕ НЕТ:
|
||||||
* с физикой (падения/пики/чомперы), и там бессмертие обязано
|
* pop_take_hp гасит только урон меньше 100, а тут ровно 100. */
|
||||||
* работать при любом положении меча. */
|
|
||||||
uint8_t imm = pop_immortal;
|
|
||||||
pop_immortal = 0;
|
|
||||||
pop_take_hp(100);
|
pop_take_hp(100);
|
||||||
pop_immortal = imm;
|
|
||||||
pop_char_set_seq(SEQ_85_STABBED_TO_DEATH);
|
pop_char_set_seq(SEQ_85_STABBED_TO_DEATH);
|
||||||
|
} else if (Char.charid == CHARID_0_KID && pop_immortal) {
|
||||||
|
/* ЧИТ, уровень 1 и выше: в боевой стойке удары не отнимают HP.
|
||||||
|
* Кадр «получил удар» оставляем — иначе бой перестаёт читаться,
|
||||||
|
* да и оригинал на выживший удар ставит ровно его. */
|
||||||
|
pop_char_set_seq(SEQ_74_HIT_BY_SWORD);
|
||||||
} else if (Char.charid != CHARID_4_SKELETON && pop_take_hp(1)) {
|
} else if (Char.charid != CHARID_4_SKELETON && pop_take_hp(1)) {
|
||||||
pop_char_set_seq(SEQ_85_STABBED_TO_DEATH); /* HP кончились */
|
pop_char_set_seq(SEQ_85_STABBED_TO_DEATH); /* HP кончились */
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -19,7 +19,9 @@
|
|||||||
extern uint8_t pop_cheats; /* 0 = выключены, иначе включены */
|
extern uint8_t pop_cheats; /* 0 = выключены, иначе включены */
|
||||||
|
|
||||||
#define KBD_CHEAT_KILL 0x42 /* K (PS/2 set 2) — kill guard */
|
#define KBD_CHEAT_KILL 0x42 /* K (PS/2 set 2) — kill guard */
|
||||||
#define KBD_CHEAT_IMMO 0x43 /* I (PS/2 set 2) — бессмертие Кида (toggle) */
|
#define KBD_CHEAT_IMMO 0x43 /* I (PS/2 set 2) — бессмертие Кида по кругу
|
||||||
|
* 0 -> 1 (только бой) -> 2 (и мелкий урон) -> 0;
|
||||||
|
* уровни расписаны в pop_state.h */
|
||||||
#define KBD_CHEAT_SWORD 0x1B /* S (PS/2 set 2) — выдать Киду меч */
|
#define KBD_CHEAT_SWORD 0x1B /* S (PS/2 set 2) — выдать Киду меч */
|
||||||
#define KBD_CHEAT_NEXTLVL 0x4B /* Shift+L (PS/2 set 2) — следующий уровень */
|
#define KBD_CHEAT_NEXTLVL 0x4B /* Shift+L (PS/2 set 2) — следующий уровень */
|
||||||
#define KBD_CHEAT_XDEC 0x54 /* [ (PS/2 set 2) — сдвинуть Кида на 1 px влево */
|
#define KBD_CHEAT_XDEC 0x54 /* [ (PS/2 set 2) — сдвинуть Кида на 1 px влево */
|
||||||
|
|||||||
@@ -85,7 +85,14 @@ void pop_guard_kill(void)
|
|||||||
uint8_t pop_take_hp(uint8_t count)
|
uint8_t pop_take_hp(uint8_t count)
|
||||||
{
|
{
|
||||||
if (Char.charid == CHARID_0_KID) {
|
if (Char.charid == CHARID_0_KID) {
|
||||||
if (pop_immortal) return 0;
|
/* ЧИТ БЕССМЕРТИЯ, уровень 2 (pop_state.h): гасим ТОЛЬКО мелкий урон
|
||||||
|
* — падение с двух этажей, придавливание плитой. Мгновенная смерть
|
||||||
|
* (пики, чомпер, падение с трёх этажей, удар вне боевой стойки)
|
||||||
|
* приходит с count = 100 и проходит всегда: у читa нет задачи
|
||||||
|
* отменять смерть, у него задача отменить «минус одно деление».
|
||||||
|
* Уровень 1 сюда не вмешивается вовсе — он живёт в hurt_by_sword и
|
||||||
|
* гасит только удары мечом. */
|
||||||
|
if (pop_immortal >= 2 && count < 100) return 0;
|
||||||
if (count >= hitp_curr) { hitp_delta = (int8_t)-hitp_curr; return 1; }
|
if (count >= hitp_curr) { hitp_delta = (int8_t)-hitp_curr; return 1; }
|
||||||
hitp_delta = (int8_t)-(int8_t)count;
|
hitp_delta = (int8_t)-(int8_t)count;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -45,6 +45,15 @@ extern uint8_t pop_nav_hold;
|
|||||||
|
|
||||||
/* Чит «бессмертие» (I): Кида бьют, но HP не убавляется. Читают пути урона
|
/* Чит «бессмертие» (I): Кида бьют, но HP не убавляется. Читают пути урона
|
||||||
* (боёвка в банке, пики в pop_map), переключает главный цикл. */
|
* (боёвка в банке, пики в pop_map), переключает главный цикл. */
|
||||||
|
/* ЧИТ БЕССМЕРТИЯ, три состояния (клавиша I по кругу):
|
||||||
|
* 0 — выключено;
|
||||||
|
* 1 — только БОЙ: удары мечом не отнимают HP (pop_take_hp тут ни при
|
||||||
|
* чём, ветка живёт в hurt_by_sword, guards.c);
|
||||||
|
* 2 — бой И мелкий урон: не проходят «минус одно деление» от падения с
|
||||||
|
* двух этажей и от падающей плиты (pop_take_hp гасит count < 100).
|
||||||
|
* МГНОВЕННАЯ СМЕРТЬ остаётся на любом уровне: пики, чомпер, падение с
|
||||||
|
* трёх этажей, удар мечом вне боевой стойки — все они приходят с
|
||||||
|
* count = 100. Чит отменяет потерю HP, а не смерть. */
|
||||||
extern uint8_t pop_immortal;
|
extern uint8_t pop_immortal;
|
||||||
|
|
||||||
/* Габариты ПОСЛЕДНЕЙ нарисованной двери уровня — порт глобалов
|
/* Габариты ПОСЛЕДНЕЙ нарисованной двери уровня — порт глобалов
|
||||||
|
|||||||
@@ -312,7 +312,10 @@ int main(void)
|
|||||||
uint8_t xd = kbd_raw_down(KBD_CHEAT_XDEC);
|
uint8_t xd = kbd_raw_down(KBD_CHEAT_XDEC);
|
||||||
uint8_t xi = kbd_raw_down(KBD_CHEAT_XINC);
|
uint8_t xi = kbd_raw_down(KBD_CHEAT_XINC);
|
||||||
if (pop_cheats && k && !cheat_prev) pop_guard_kill();
|
if (pop_cheats && k && !cheat_prev) pop_guard_kill();
|
||||||
if (pop_cheats && i && !immo_prev) pop_immortal = !pop_immortal;
|
/* Бессмертие по кругу: 0 выкл -> 1 «только бой» -> 2 «бой и
|
||||||
|
* мелкий урон» -> 0. Что означают уровни — pop_state.h. */
|
||||||
|
if (pop_cheats && i && !immo_prev)
|
||||||
|
pop_immortal = (uint8_t)(pop_immortal >= 2 ? 0 : pop_immortal + 1);
|
||||||
if (pop_cheats && s && !sword_prev) pop_have_sword = 1;
|
if (pop_cheats && s && !sword_prev) pop_have_sword = 1;
|
||||||
if (pop_cheats && nl && !nlvl_prev && pop_current_level < POP_LAST_LEVEL)
|
if (pop_cheats && nl && !nlvl_prev && pop_current_level < POP_LAST_LEVEL)
|
||||||
pop_next_level = (uint8_t)(pop_current_level + 1);
|
pop_next_level = (uint8_t)(pop_current_level + 1);
|
||||||
|
|||||||
@@ -302,7 +302,7 @@ uint8_t pop_dbg_roomnav(uint8_t dir) __banked
|
|||||||
* жёлтый x 10.. 85 уровень (1..15)
|
* жёлтый x 10.. 85 уровень (1..15)
|
||||||
* белый x 100..175 комната (1..24)
|
* белый x 100..175 комната (1..24)
|
||||||
* голубой x 190..205 скорость (1 палочка NORMAL, 2 FAST, 3 FASTEST)
|
* голубой x 190..205 скорость (1 палочка NORMAL, 2 FAST, 3 FASTEST)
|
||||||
* красный x 220..225 бессмертие (палочка есть = включено)
|
* красный x 220..230 бессмертие (1 палочка = только бой, 2 = и мелкий урон)
|
||||||
*
|
*
|
||||||
* ЦВЕТА — индексы ИГРОВОЙ палитры, и выбраны они не по вкусу, а по двум
|
* ЦВЕТА — индексы ИГРОВОЙ палитры, и выбраны они не по вкусу, а по двум
|
||||||
* ограничениям.
|
* ограничениям.
|
||||||
@@ -370,7 +370,7 @@ void pop_dbg_room_label(uint8_t room) __banked
|
|||||||
|
|
||||||
if (imm) { /* бессмертие — красный */
|
if (imm) { /* бессмертие — красный */
|
||||||
setfillstyle(SOLID_FILL, 0x3C);
|
setfillstyle(SOLID_FILL, 0x3C);
|
||||||
label_bars(220, 1);
|
label_bars(220, imm); /* палочек = уровень (1 или 2) */
|
||||||
}
|
}
|
||||||
room_label_redraw--;
|
room_label_redraw--;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user