From a03d444dadcffeede4cfa9e574fae4281aa3d5f3 Mon Sep 17 00:00:00 2001 From: Peisong Xiao Date: Thu, 18 Jul 2024 22:08:20 -0400 Subject: [PATCH] added faster menu selection for base game (required) --- src/arguments.cc | 206 +++++++++++++++++++++++++++--- src/arguments.h | 2 +- src/constants.h | 20 ++- src/enemies/leprechaun.h | 2 +- src/input/console_input.cc | 14 +- src/input/file_input.cc | 23 +++- src/main.cc | 7 +- src/menu.cc | 32 ++++- src/menu.h | 2 +- src/potions/borrow_life.cc | 4 +- src/potions/echoing_resilience.cc | 3 + 11 files changed, 278 insertions(+), 37 deletions(-) diff --git a/src/arguments.cc b/src/arguments.cc index 141ec7d..73cad55 100644 --- a/src/arguments.cc +++ b/src/arguments.cc @@ -85,6 +85,14 @@ feature proc_args(int argc, char **argv, result |= FEATURE_OUT_FILE; } else if (str == "-h" || str == "--help") { return FEATURE_LIST_ARGS; + } else if (str == "--races") { + return FEATURE_LIST_RACES; + } else if (str == "--enemies") { + return FEATURE_LIST_ENEMIES; + } else if (str == "--potions") { + return FEATURE_LIST_POTIONS; + } else if (str == "--commands") { + return FEATURE_LIST_COMMANDS; } else { return FEATURE_PANIC | i; } @@ -163,20 +171,186 @@ void panic_args(feature panic) { << endl; } -void print_args_list() { - static const char *ARGS_LIST = "-n : Use ncurses for I/O\n\ --r : Randomly generate maps\n\ --c : Enemies chase the player (CAUTION: THEY CAN REALLY CHASE!!!)\n\ --d : Enemies can go through doors (CAUTION: DO NOT ENABLE WITH CHASING!)\n\ --i : Enable inventory (player can pick up potions, will turn on -o)\n\ --t : Enable throw (will turn on -i)\n\ --R : Enable revisiting levels\n\ --e : Enable extra potions and races\n\ --E : Enable extra levels\n\ --o : Allows characters to go over gold and potions\n\ --s [seed] : Sets initial seed to seed\n\ --I [file] : Reads commands from file. CANNOT BE USED WITH -n.\n\ --O [file] : Outputs to file. CANNOT BE USED WITH -n.\n\ --h/--help : Displays options list (doesn't start a game)"; - std::cout << ARGS_LIST << std::endl; +const char *ARGS_LIST = "\ +-n : Use ncurses for I/O\n \ +-r : Randomly generate maps\n\ +-c : Enemies chase the player (CAUTION: THEY CAN REALLY CHASE!!!)\n\ +-d : Enemies can go through doors (CAUTION: DO NOT ENABLE WITH CHASING!)\n\ +-i : Enable inventory (player can pick up potions, will turn on -o)\n\ +-t : Enable throw (will turn on -i)\n\ +-R : Enable revisiting levels\n\ +-e : Enable extra potions and races\n\ +-E : Enable extra levels\n\ +-o : Allows characters to go over gold and potions\n\ +-s [seed] : Sets initial seed to seed\n\ +-I [file] : Reads commands from file. CANNOT BE USED WITH -n.\n\ +-O [file] : Outputs to file. CANNOT BE USED WITH -n.\n\ +-h/--help : Displays options list (doesn't start a game)\n\ +--races : Displays playable characters list\n\ +--enemies : Displays enemies list\n\ +--potions : Displays potions list\n\ +--commands : Displays available commands\n"; + +const char *COMMANDS_LIST = "\ +Text-based commands:\n\ + Basic commands:\n\ + q : quits game (in inventory, close inventory)\n\ + r : restarts a new game\n\ + yes : confirms (in main menu) or use (in inventory)\n\ + In-menu commands:\n\ + s : starts the game as a shade\n\ + d : starts the game as a drow\n\ + v : starts the game as a vampire\n\ + g : starts the game as a goblin\n\ + t : starts the game as a troll\n\ + Directional commands:\n\ + no : north\n\ + so : south\n\ + ea : east\n\ + we : west\n\ + ne : northeast\n\ + nw : northwest\n\ + se : southeast\n\ + sw : southwest\n\ + In-game commands:\n\ + f : toggles whether or not enemies stop moving\n\ + u [direction] : try to use the potion indicated by direction\n\ + a [direction] : try to attack the enemy indicated by direction\n\ + i : toggles inventory on and off\n\ + T [direction] : (in inventory) throw the selected potion towards direction\n\n\n\ +ncurses-based commands:\n\ + Basic commands:\n\ + q : quits game (in inventory, close inventory)\n\ + r : restarts a new game\n\ + e : confirms (in main menu) or use (in inventory)\n\ + Directional commands:\n\ + k : north\n\ + j : south\n\ + l : east\n\ + h : west\n\ + u : northeast\n\ + y : northwest\n\ + n : southeast\n\ + b : southwest\n\ + In-game commands:\n\ + f : toggles whether or not enemies stop moving\n\ + u [direction] : try to use the potion indicated by direction\n\ + [direction] : also tries to attack in the indicated direction\n\ + i : toggles inventory on and off\n\ + t [direction] : (in inventory) throw the selected potion towards direction\n\ + > : go down the stairs\n\ + < : go up the stairs\n"; + +const char *RACES_LIST = "\ +Shade (125 HP, 25 Atk, 25 Def, 1/1 Hit Rate):\n\ + The most basic race.\n\ +Drow (150 HP, 25 Atk, 15 Def, 1/1 Hit Rate):\n\ + All potions have their effect magnified by 1.5.\n\ +Vampire (50 HP, 25 Atk, 25 Def, 1/1 Hit Rate):\n\ + Gains 5 HP on every successful attack;\n\ + Has no maximum HP.\n\ +Troll (120 HP, 25 Atk, 15 Def, 1/1 Hit Rate):\n\ + Gains 5 HP every turn.\n\ +Goblin (110 HP, 15 Atk, 20 Def, 1/1 Hit Rate):\n\ + Gains an additional 5 gold from every slain enemy.\n\ +T-800 (800 HP, 40 Atk, 50 Def, 2/3 Hit Rate):\n\ + All potions will give it rusty joints.\n\ +Mr. Goose (130 HP, 25 Atk, 20 Def, never misses):\n\ + All potions are know at the beginning of the game;\n\ +Monk (125 HP (starts with 100 HP), 70 Atk, 0 Def, 1/1 Hit Rate):\n\ + Gains 2 HP every turn.\n\ +Tavern Brawler (120 HP, 20 Atk, 15 Def, 3/4 Hit Rate):\n\ + Has a 1/2 chance of attacking twice and 1/2 change of attacking three times.\n\ +Assassin (100 HP, 30 Atk, 10 Def, 1/1 Hit Rate):\n\ + Upon a successful hit, has a 1/10 chance of assassinating the target.\n"; + +const char *ENEMIES_LIST = "\ +Human 'H' (140 HP, 20 Atk, 20 Def, 1/2 Hit Rate):\n\ + Upon death, drops 2 normal piles of gold.\n\ +Dwarf 'W' (100 HP, 20 Atk, 30 Def, 1/2 Hit Rate):\n\ + Vampires are allergic to them.\n\ +Elf 'E' (140 HP, 30 Atk, 10 Def, 1/2 Hit Rate):\n\ + Gets two attacks against every race except drow.\n\ +Orc 'O' (180 HP, 30 Atk, 25 Def, 1/2 Hit Rate):\n\ + Does 50% more damage to goblins.\n\ +Merchant 'M' (30 HP, 70 Atk, 5 Def, 1/2 Hit Rate):\n\ + Starts out neutral to all characters, can be angered by PC.\n\ +Dragon 'D' (150 HP, 20 Atk, 20 Def, 1/2 Hit Rate):\n\ + Always guards a treasure hoard.\n\ +Halfling 'L' (100 HP, 15 Atk, 20 Def, 1/2 Hit Rate):\n\ + Has an additional 50% chance to dodge PC's attack.\n\ +Viking 'V' (150 HP, 30 Atk, 25 Def, 1/3 Hit Rate):\n\ + Gets two attacks against every race.\n\ +Swordsman 'S' (100 HP, 25 Atk, 15 Def, 1/1 Hit Rate):\n\ + Attacks with finess.\n\ +Leprechaun 'l' (80 HP, 10 Atk, 15 Def, 1/2 Hit Rate):\n\ + Steals 3 pieces of gold from PC with every successful attack;\n\ + If PC doesn't have enough gold, hit instead with a strong attack of fixed Atk;\n\ + Upon death, drops all stolen gold plus 5 extra.\n\ +Witch 'Z' (100 HP, 20 Atk, 15 Def, 1/2 Hit Rate):\n\ + Upon a successful hit, has a 1/5 chance of applying a random potion onto PC.\n\ +Hacker 'h' (90 HP, 15 Atk, 30 Def, 1/2 Hit Rate):\n\ + He has been in grinding in MC for too long.\n\ +Baby Dragon 'B' (140 HP, 20 Atk, 40 Def, 1/3 Hit Rate):\n\ + Not fully grown, can move;\n\ + Immune to all potions.\n"; + +const char *POTIONS_LIST = "\ +Restore Health (RH):\n\ + Instantly restore 5 HP.\n\ +Boost Atk (BA):\n\ + Increase ATK by 5 until exiting the level.\n\ +Boost Def (BD):\n\ + Increase DEF by 5 until exiting the level.\n\ +Poison Health (PH):\n\ + Instantly deduct 5 HP.\n\ +Wound Atk (WA):\n\ + Decrease ATK by 5 until exiting the level.\n\ +Wound Def (BD):\n\ + Decrease DEF by 5 until exiting the level.\n\ +Continuous Restoration (CR):\n\ + Restores 3 HP every turn for 5 turns.\n\ +Savage Strike (SS):\n\ + Gets 1.25x basic ATK multiplier;\n\ + Gets 0.8x basic hit rate multiplier;\n\ + Lasts 20 turns.\n\ +Echoing Resilience (ER):\n\ + Restores 7 HP every turn;\n\ + Decrease basic ATK by 10;\n\ + Decrease basic DEF by 10;\n\ + Lasts 20 turns.\n\ +Tempest Tantrum (TT):\n\ + Instantly loses 25% of current HP;\n\ + Gets 3x final ATK multiplier;\n\ + Gets 0.5x final DEF multiplier;\n\ + Lasts 12 turns.\n\ +Bezerk Brew (BB):\n\ + Gets 2x basic ATK multiplier;\n\ + Gets 0.5x basic DEF multiplier;\n\ + Lasts 15 turns.\n\ +Borrow Life (BL):\n\ + Gains 50 HP upon use (can go over racial limit)\n\ + Loses 55 HP after 24 turns.\n\ +Fine Booze (FB):\n\ + Restores 2 HP every turn;\n\ + Gets 0.7x final hit rate multiplier;\n\ + Gives tavern brawlers the ability to never miss;\n\ + Lasts 12 turns.\n\ +Ironclad Ward (IW):\n\ + Gets 0.5x final ATK multiplier;\n\ + Gets 3x final DEF multiplier;\n\ + Gets 0.75x final hit rate multiplier;\n\ + Lasts 12 turns.\n"; + +void print_list(feature which) { + if (which & FEATURE_LIST_ARGS) + std::cout << ARGS_LIST; + else if (which & FEATURE_LIST_COMMANDS) + std::cout << COMMANDS_LIST; + else if (which & FEATURE_LIST_ENEMIES) + std::cout << ENEMIES_LIST; + else if (which & FEATURE_LIST_POTIONS) + std::cout << POTIONS_LIST; + else if (which & FEATURE_LIST_RACES) + std::cout << RACES_LIST; } diff --git a/src/arguments.h b/src/arguments.h index e1701ec..1e483d0 100644 --- a/src/arguments.h +++ b/src/arguments.h @@ -17,6 +17,6 @@ feature proc_args(int argc, char **argv, void panic_args(feature panic); -void print_args_list(); +void print_list(feature which); #endif diff --git a/src/constants.h b/src/constants.h index 683533a..be621b4 100644 --- a/src/constants.h +++ b/src/constants.h @@ -42,7 +42,9 @@ enum game_command : int {game_command_terminate = 0, enter, toggle_inventory, throw_north, throw_south, throw_east, throw_west, throw_northeast, throw_northwest, - throw_southeast, throw_southwest + throw_southeast, throw_southwest, + select_shade, select_drow, select_vampire, + select_goblin, select_troll }; // Character generation related @@ -63,17 +65,17 @@ static const char CHAR_REP[RACE_CNT] = { static const int MAX_HP[RACE_CNT] = { 125, 150, INF, 120, 110, 140, 100, 140, 180, 30, 150, 100, - 800, 130, 150, 120, 100, - 150, 100, 60, 100, 90, 140 + 600, 130, 125, 120, 100, + 150, 100, 80, 100, 90, 140 }; static const int STARTING_HP[RACE_CNT] = { 125, 150, 50, 120, 110, 140, 100, 140, 180, 30, 150, 100, - 800, 130, 100, 120, 100, - 150, 100, 60, 100, 90, 140 + 600, 130, 100, 120, 100, + 150, 100, 80, 100, 90, 140 }; static const int STARTING_ATK[RACE_CNT] = { 25, 25, 25, 25, 15, 20, 20, 30, 30, 70, 20, 15, - 40, 25, 70, 15, 30, + 40, 25, 70, 20, 30, 30, 25, 10, 20, 15, 20 }; static const int STARTING_DEF[RACE_CNT] = { @@ -84,7 +86,7 @@ static const int STARTING_DEF[RACE_CNT] = { static const fraction STARTING_HR[RACE_CNT] = { {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, - {1, 1}, {1, 1}, {100, 1}, {3, 4}, {1, 1}, + {2, 3}, {INF, 1}, {1, 1}, {3, 4}, {1, 1}, {1, 3}, {1, 1}, {1, 2}, {1, 2}, {1, 2}, {1, 3} }; @@ -146,6 +148,10 @@ static const feature FEATURE_EXTRA_STUFF = 1 << 10; static const feature FEATURE_EXTRA_LEVELS = 1 << 11; static const feature FEATURE_DOORS = 1 << 12; +static const feature FEATURE_LIST_COMMANDS = 1 << 23; +static const feature FEATURE_LIST_RACES = 1 << 24; +static const feature FEATURE_LIST_ENEMIES = 1 << 25; +static const feature FEATURE_LIST_POTIONS = 1 << 26; static const feature FEATURE_PANIC_SEED = 1 << 27; static const feature FEATURE_PANIC_FILE = 1 << 28; static const feature FEATURE_PANIC = 1 << 29; diff --git a/src/enemies/leprechaun.h b/src/enemies/leprechaun.h index e3fc694..4a8fc38 100644 --- a/src/enemies/leprechaun.h +++ b/src/enemies/leprechaun.h @@ -5,7 +5,7 @@ class leprechaun final: public enemy_base { static const int STEAL_GOLD = 3; - static const int BOOSTED_ATK = 30; + static const int BOOSTED_ATK = 50; static const int STARTING_GOLD = 5; int gold_cnt; public: diff --git a/src/input/console_input.cc b/src/input/console_input.cc index a3995be..3e58618 100644 --- a/src/input/console_input.cc +++ b/src/input/console_input.cc @@ -20,7 +20,7 @@ game_command console_input::get_command() { return the_world; else if (cmd == "r") return game_restart; - else if (cmd == "u" || cmd == "a" || cmd == "t") { + else if (cmd == "u" || cmd == "a" || cmd == "T") { auto cmdtmp = cmd; in >> cmd; @@ -42,7 +42,17 @@ game_command console_input::get_command() { return game_command::enter; } else if (cmd == "i") { return toggle_inventory; - } else { + } else if (cmd == "s") { + return select_shade; + } else if (cmd == "d") { + return select_drow; + } else if (cmd == "v") { + return select_vampire; + } else if (cmd == "g") { + return select_goblin; + } else if (cmd == "t") { + return select_troll; + } else { auto tmp = get_direction(cmd); if (tmp != game_command_panic) diff --git a/src/input/file_input.cc b/src/input/file_input.cc index 6029ee5..104498b 100644 --- a/src/input/file_input.cc +++ b/src/input/file_input.cc @@ -20,7 +20,7 @@ game_command file_input::get_command() { return the_world; else if (cmd == "r") return game_restart; - else if (cmd == "u" || cmd == "a" || cmd == "t") { + else if (cmd == "u" || cmd == "a" || cmd == "T") { auto cmdtmp = cmd; in >> cmd; @@ -30,16 +30,29 @@ game_command file_input::get_command() { auto tmp = get_direction(cmd); if (cmdtmp == "u") - return static_cast(tmp + apply_north); + return static_cast + (tmp + apply_north); else if (cmdtmp == "a") - return static_cast(tmp + attack_north); + return static_cast + (tmp + attack_north); else - return static_cast(tmp + throw_north); + return static_cast + (tmp + throw_north); } else if (cmd == "yes") { return game_command::enter; } else if (cmd == "i") { return toggle_inventory; - } else { + } else if (cmd == "s") { + return select_shade; + } else if (cmd == "d") { + return select_drow; + } else if (cmd == "v") { + return select_vampire; + } else if (cmd == "g") { + return select_goblin; + } else if (cmd == "t") { + return select_troll; + } else { auto tmp = get_direction(cmd); if (tmp != game_command_panic) diff --git a/src/main.cc b/src/main.cc index 0dff37a..c1be3c2 100644 --- a/src/main.cc +++ b/src/main.cc @@ -17,8 +17,11 @@ int main(int argc, char **argv) { FEATURE_CONFLICT | FEATURE_PANIC_SEED)) { panic_args(enabled_features); return RETURN_PANICKED; - } else if (enabled_features & FEATURE_LIST_ARGS) { - print_args_list(); + } else if (enabled_features & + (FEATURE_LIST_ARGS | FEATURE_LIST_COMMANDS | + FEATURE_LIST_ENEMIES | FEATURE_LIST_POTIONS | + FEATURE_LIST_RACES)) { + print_list(enabled_features); return RETURN_FINE; } diff --git a/src/menu.cc b/src/menu.cc index 5430d69..e1a81cc 100644 --- a/src/menu.cc +++ b/src/menu.cc @@ -4,6 +4,7 @@ const int NORMAL_CNT = 5; const int EXTRA_CNT = 10; +const int HOR_INCRM = 5; const enum race RACES[EXTRA_CNT] = { rshade, rdrow, rgoblin, rvampire, rtroll, @@ -74,7 +75,7 @@ const char *EXTRA_SCREEN = +-----------------------------------------------------------------------------+"; int menu::run(input *in) { - size_t limit = enabled_features & FEATURE_EXTRA_STUFF ? + int limit = enabled_features & FEATURE_EXTRA_STUFF ? EXTRA_CNT : NORMAL_CNT; auto cmd = in->get_command(); @@ -97,6 +98,35 @@ int menu::run(input *in) { break; } + case move_east: { + if (curr + HOR_INCRM < limit) + curr += HOR_INCRM; + + break; + } + + case move_west: { + if (curr - HOR_INCRM >= 0) + curr -= HOR_INCRM; + + break; + } + + case select_shade: + return rshade; + + case select_drow: + return rdrow; + + case select_goblin: + return rgoblin; + + case select_troll: + return rtroll; + + case select_vampire: + return rvampire; + case game_command_terminate: return -2; diff --git a/src/menu.h b/src/menu.h index dad7de1..b7aae3b 100644 --- a/src/menu.h +++ b/src/menu.h @@ -11,7 +11,7 @@ enum race : int; class menu final { private: const feature enabled_features; - size_t curr; + int curr; public: menu(const feature enabled_features); int run(input *in); diff --git a/src/potions/borrow_life.cc b/src/potions/borrow_life.cc index 81a3cb3..73fca92 100644 --- a/src/potions/borrow_life.cc +++ b/src/potions/borrow_life.cc @@ -14,8 +14,10 @@ void borrow_life::apply(const enum race &race, int &HP, int &ATK, if (remaining_duration != 0) --remaining_duration; - if (remaining_duration == 0) + if (remaining_duration == 0) { HP -= LOSE_HP * (race == rdrow ? DROW_POTION_MUL : 1); + HP = HP < 0 ? 0 : HP; + } } int borrow_life::get_priority() const { diff --git a/src/potions/echoing_resilience.cc b/src/potions/echoing_resilience.cc index 5611d01..762d0d3 100644 --- a/src/potions/echoing_resilience.cc +++ b/src/potions/echoing_resilience.cc @@ -15,6 +15,9 @@ void echoing_resilience::apply(const enum race &race, int &HP, int &ATK, ATK -= LOSE_ATK * (race == rdrow ? DROW_POTION_MUL : 1); DEF -= LOSE_DEF * (race == rdrow ? DROW_POTION_MUL : 1); + ATK = ATK < 0 ? 0 : ATK; + DEF = DEF < 0 ? 0 : DEF; + --remaining_duration; } }