summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBardur Arantsson <bardur@scientician.net>2015-03-07 16:55:41 +0100
committerBardur Arantsson <bardur@scientician.net>2015-03-07 16:55:41 +0100
commite4fee3d69f86395e91800e4e59c6bc7ec8a5bd52 (patch)
tree83a8d38d6515764b951033a8c2da36544cb98fda
parent72ceb4f2aba3b86be43ba9a7cb5c576b79920543 (diff)
Remove duplicate option-interaction code
-rw-r--r--src/cmd4.cc263
1 files changed, 104 insertions, 159 deletions
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<option_type *> 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<option_type *> 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<option_type *> 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);
}