From e4fee3d69f86395e91800e4e59c6bc7ec8a5bd52 Mon Sep 17 00:00:00 2001 From: Bardur Arantsson Date: Sat, 7 Mar 2015 16:55:41 +0100 Subject: Remove duplicate option-interaction code --- src/cmd4.cc | 263 ++++++++++++++++++++++++------------------------------------ 1 file changed, 104 insertions(+), 159 deletions(-) (limited to 'src/cmd4.cc') diff --git a/src/cmd4.cc b/src/cmd4.cc index 73af4b7d..d791ff51 100644 --- a/src/cmd4.cc +++ b/src/cmd4.cc @@ -465,63 +465,53 @@ void do_cmd_messages(void) character_icky = FALSE; } +// File-local +namespace { + /** + * Interaction mode for options + */ + enum class interaction_mode_t { + READ_ONLY = 0, + READ_WRITE = 1 + }; -/* - * Number of cheating options - */ -#define CHEAT_MAX 6 - -/* - * Cheating options - */ -static option_type cheat_info[CHEAT_MAX] = -{ - { &cheat_peek, FALSE, 0, 0, "cheat_peek", "Peek into object creation" }, - { &cheat_hear, FALSE, 0, 1, "cheat_hear", "Peek into monster creation" }, - { &cheat_room, FALSE, 0, 2, "cheat_room", "Peek into dungeon creation" }, - { &cheat_xtra, FALSE, 0, 3, "cheat_xtra", "Peek into something else" }, - { &cheat_know, FALSE, 0, 4, "cheat_know", "Know complete monster info" }, - { &cheat_live, FALSE, 0, 5, "cheat_live", "Allow player to avoid death" } -}; +} -/* - * Interact with some options for cheating +/** + * Interact with given vector of options. */ -static void do_cmd_options_cheat(cptr info) +static void interact_with_options(std::vector const &options, char const *info, interaction_mode_t interaction_mode) { - char ch; - - int i, k = 0, n = CHEAT_MAX; - - int dir; - - char buf[80]; - + size_t n = options.size(); /* Clear screen */ Term_clear(); /* Interact with the player */ + size_t k = 0; /* Currently selected option index */ while (TRUE) { /* Prompt XXX XXX XXX */ + char buf[80]; strnfmt(buf, 80, "%s (RET to advance, y/n to set, ESC to accept) ", info); prt(buf, 0, 0); /* Display the options */ - for (i = 0; i < n; i++) + for (size_t i = 0; i < n; i++) { byte a = TERM_WHITE; /* Color current option */ - if (i == k) a = TERM_L_BLUE; + if (i == k) { + a = TERM_L_BLUE; + } /* Display the option text */ strnfmt(buf, 80, "%-48s: %s (%s)", - cheat_info[i].o_desc, - (*cheat_info[i].o_var ? "yes" : "no "), - cheat_info[i].o_text); + options[i]->o_desc, + (*options[i]->o_var ? "yes" : "no "), + options[i]->o_text); c_prt(a, buf, i + 2, 0); } @@ -529,15 +519,19 @@ static void do_cmd_options_cheat(cptr info) move_cursor(k + 2, 50); /* Get a key */ - ch = inkey(); + int ch = inkey(); /* * Hack -- Try to translate the key into a direction * to allow the use of roguelike keys for navigation */ - dir = get_keymap_dir(ch); - if ((dir == 2) || (dir == 4) || (dir == 6) || (dir == 8)) ch = I2D(dir); - + { + int dir = get_keymap_dir(ch); + if ((dir == 2) || (dir == 4) || (dir == 6) || (dir == 8)) + { + ch = I2D(dir); + } + } /* Analyze */ switch (ch) @@ -550,8 +544,9 @@ static void do_cmd_options_cheat(cptr info) case '-': case '8': { + /* Adding n pre-modulo ensures that we don't + wrap around to the wrong (post-modulo) index. */ k = (n + k - 1) % n; - break; } @@ -561,7 +556,6 @@ static void do_cmd_options_cheat(cptr info) case '2': { k = (k + 1) % n; - break; } @@ -569,10 +563,12 @@ static void do_cmd_options_cheat(cptr info) case 'Y': case '6': { - noscore |= (cheat_info[k].o_page * 256 + cheat_info[k].o_bit); - (*cheat_info[k].o_var) = TRUE; + if (interaction_mode == interaction_mode_t::READ_ONLY) + { + break; + } + *(options[k]->o_var) = TRUE; k = (k + 1) % n; - break; } @@ -580,9 +576,13 @@ static void do_cmd_options_cheat(cptr info) case 'N': case '4': { - (*cheat_info[k].o_var) = FALSE; - k = (k + 1) % n; + if (interaction_mode == interaction_mode_t::READ_ONLY) + { + break; + } + *(options[k]->o_var) = FALSE; + k = (k + 1) % n; break; } @@ -594,6 +594,54 @@ static void do_cmd_options_cheat(cptr info) } } } + + +} + + + +/* + * Cheating options + */ +static option_type cheat_info[6] = +{ + { &cheat_peek, FALSE, 0, 0, "cheat_peek", "Peek into object creation" }, + { &cheat_hear, FALSE, 0, 1, "cheat_hear", "Peek into monster creation" }, + { &cheat_room, FALSE, 0, 2, "cheat_room", "Peek into dungeon creation" }, + { &cheat_xtra, FALSE, 0, 3, "cheat_xtra", "Peek into something else" }, + { &cheat_know, FALSE, 0, 4, "cheat_know", "Know complete monster info" }, + { &cheat_live, FALSE, 0, 5, "cheat_live", "Allow player to avoid death" } +}; + +/* + * Interact with some options for cheating + */ +static void do_cmd_options_cheat(cptr info) +{ + // Calculate number of cheat options + size_t n = std::distance(std::begin(cheat_info), std::end(cheat_info)); + + // Build the vector of options we're going to interact with + std::vector options; + options.reserve(n); + for (auto &option : cheat_info) + { + options.push_back(&option); + } + + // Interact + interact_with_options(options, info, interaction_mode_t::READ_WRITE); + + // If user toggled any of the options to TRUE, then we add those cheats + // to the player's "noscore" flags. Note that it doesn't matter what the + // previous value was -- we don't "unset" noscore flags anyway. + for (auto &option: options) + { + if (*option->o_var) + { + noscore |= (option->o_page * 256 + option->o_bit); + } + } } @@ -749,125 +797,22 @@ static void do_cmd_options_autosave(cptr info) */ void do_cmd_options_aux(int page, cptr info, bool_ read_only) { - char ch; - - int i, k = 0, n = 0; - - int dir; - - int opt[24]; - - char buf[80]; - - - /* Lookup the options */ - for (i = 0; i < 24; i++) opt[i] = 0; - - /* Scan the options */ - for (i = 0; option_info[i].o_desc; i++) - { - /* Notice options on this "page" */ - if (option_info[i].o_page == page) opt[n++] = i; - } - - - /* Clear screen */ - Term_clear(); - - /* Interact with the player */ - while (TRUE) + // Scrape together all the options from the relevant page. + std::vector options; + options.reserve(64); // Seems a reasonable number; anything more would be unusable anyway + for (size_t i = 0; option_info[i].o_desc; i++) { - /* Prompt XXX XXX XXX */ - strnfmt(buf, 80, "%s (RET to advance, y/n to set, ESC to accept) ", info); - prt(buf, 0, 0); - - /* Display the options */ - for (i = 0; i < n; i++) + if (option_info[i].o_page == page) { - byte a = TERM_WHITE; - - /* Color current option */ - if (i == k) a = TERM_L_BLUE; - - /* Display the option text */ - strnfmt(buf, 80, "%-48s: %s (%s)", - option_info[opt[i]].o_desc, - (*option_info[opt[i]].o_var ? "yes" : "no "), - option_info[opt[i]].o_text); - c_prt(a, buf, i + 2, 0); - } - - /* Hilite current option */ - move_cursor(k + 2, 50); - - /* Get a key */ - ch = inkey(); - - /* - * Hack -- Try to translate the key into a direction - * to allow the use of roguelike keys for navigation - */ - dir = get_keymap_dir(ch); - if ((dir == 2) || (dir == 4) || (dir == 6) || (dir == 8)) ch = I2D(dir); - - /* Analyze */ - switch (ch) - { - case ESCAPE: - { - return; - } - - case '-': - case '8': - { - k = (n + k - 1) % n; - - break; - } - - case ' ': - case '\n': - case '\r': - case '2': - { - k = (k + 1) % n; - - break; - } - - case 'y': - case 'Y': - case '6': - { - if (read_only) break; - - (*option_info[opt[k]].o_var) = TRUE; - k = (k + 1) % n; - - break; - } - - case 'n': - case 'N': - case '4': - { - if (read_only) break; - - (*option_info[opt[k]].o_var) = FALSE; - k = (k + 1) % n; - - break; - } - - default: - { - bell(); - - break; - } + options.push_back(&option_info[i]); } } + + // Interact with the options + interaction_mode_t interaction_mode = read_only + ? interaction_mode_t::READ_ONLY + : interaction_mode_t::READ_WRITE; + interact_with_options(options, info, interaction_mode); } -- cgit v1.2.3