Skip to content

Commit

Permalink
Use a PromptMenu for various selections in wizard mode.
Browse files Browse the repository at this point in the history
Various wizmode functions functions printed a menu in the message
window, but didn't check if it would fit, and thereby hid some of the
options.

Make some use PromptMenu instead (which displays the menu in a separate
popup if it's larger than the message window).
  • Loading branch information
Aliscans committed Dec 15, 2023
1 parent aa9e43c commit 9b12bb3
Show file tree
Hide file tree
Showing 5 changed files with 255 additions and 286 deletions.
189 changes: 63 additions & 126 deletions crawl-ref/source/wiz-item.cc
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
#include "terrain.h"
#include "unicode.h"
#include "view.h"
#include "wizard.h"

#ifdef WIZARD
static void _make_all_books()
Expand Down Expand Up @@ -95,33 +96,18 @@ void wizard_create_spec_object_by_name()

void wizard_create_spec_object()
{
char specs[80];
char32_t keyin;
object_class_type class_wanted;

do
string title = "Which item class (ESC to exit)?";
vector<WizardEntry> options =
{
mprf(MSGCH_PROMPT, ") - weapons ( - missiles [ - armour / - wands ? - scrolls");
mprf(MSGCH_PROMPT, "= - jewellery ! - potions : - books | - staves } - miscellany");
mprf(MSGCH_PROMPT, "%% - talismans X - corpses $ - gold 0 - the Orb");
mprf(MSGCH_PROMPT, "ESC - exit");

msgwin_prompt("What class of item? ");

keyin = towupper(get_ch());

class_wanted = item_class_by_sym(keyin);
if (key_is_escape(keyin) || keyin == ' '
|| keyin == '\r' || keyin == '\n')
{
msgwin_reply("");
canned_msg(MSG_OK);
return;
}
} while (class_wanted == NUM_OBJECT_CLASSES);

// XXX: hope item_class_by_sym never returns a real class for non-ascii.
msgwin_reply(string(1, (char) keyin));
{')', "weapons"}, {'(', "missiles"}, {'[', "armour"}, {'/', "wands"},
{'?', "scrolls"}, {'=', "jewellery"}, {'!', "potions"}, {':', "books"},
{'|', "staves"}, {'}', "miscellany"}, {'X', "corpses"}, {'$', "gold"},
{'0', "the Orb"}
};
auto menu = WizardMenu(title, options);
object_class_type class_wanted = item_class_by_sym(menu.run());
if (NUM_OBJECT_CLASSES == class_wanted)
return;

// Allocate an item to play with.
int thing_created = get_mitm_slot();
Expand Down Expand Up @@ -194,7 +180,9 @@ void wizard_create_spec_object()
}
else
{
string prompt = "What type of item? ";
char specs[80];
string prompt = make_stringf("What type of %s? ",
base_type_string(class_wanted));
if (class_wanted == OBJ_BOOKS)
prompt += "(\"all\" for all) ";
msgwin_get_line_autohist(prompt, specs, sizeof(specs));
Expand Down Expand Up @@ -258,68 +246,30 @@ static void _tweak_randart(item_def &item)

string prompt = "";

vector<unsigned int> choice_to_prop;
for (unsigned int i = 0, choice_num = 0; i < ARTP_NUM_PROPERTIES; ++i)
vector<WizardEntry> choices;
for (unsigned int i = 0, choice = 'a'; i < ARTP_NUM_PROPERTIES; ++i)
{
#if TAG_MAJOR_VERSION == 34
if (i == ARTP_METABOLISM || i == ARTP_ACCURACY || i == ARTP_TWISTER)
continue;
#endif
choice_to_prop.push_back(i);
if (choice_num % 8 == 0 && choice_num != 0)
prompt.back() = '\n'; // Replace the space

char choice;
char buf[80];

if (choice_num < 26)
choice = 'a' + choice_num;
else if (choice_num < 52)
choice = 'A' + choice_num - 26;
else if (choice_num < 'A' - '0' + 52)
{
// 0-9 then :;<=>?@ . Any higher would collide with letters.
choice = '0' + choice_num - 52;
}
auto prop = (artefact_prop_type)i;
choices.emplace_back(WizardEntry(choice, artp_name(prop), i));

if (choice == 'z')
choice = 'A';
else if (choice == 'Z')
choice = '0';
else if (choice == '@' || !choice)
choice = 0;
else
choice = '-'; // Too many choices!

snprintf(buf, sizeof(buf), "%s) %s%-6s%s ",
choice == '<' ? "<<" : string(1, choice).c_str(),
props[i] ? "<w>" : "",
artp_name((artefact_prop_type)choice_to_prop[choice_num]),
props[i] ? "</w>" : "");

prompt += buf;

choice_num++;
++choice;
}
mprf_nocap(MSGCH_PROMPT, "%s", prompt.c_str());

mprf(MSGCH_PROMPT, "Change which field? ");

int keyin = get_ch();
unsigned int choice;

if (isaalpha(keyin) && islower(keyin))
choice = keyin - 'a';
else if (isaalpha(keyin) && isupper(keyin))
choice = keyin - 'A' + 26;
else if (keyin >= '0' && keyin < 'A')
choice = keyin - '0' + 52;
else
{
canned_msg(MSG_OK);
auto menu = WizardMenu("Change which field (ESC to exit)?", choices);
if (!menu.run(true))
return;
}
auto prop = static_cast<artefact_prop_type>(menu.result());

if (choice >= choice_to_prop.size())
{
canned_msg(MSG_HUH);
return;
}

const artefact_prop_type prop = (artefact_prop_type)choice_to_prop[choice];
switch (artp_potential_value_types(prop))
{
case ARTP_VAL_BOOL:
Expand Down Expand Up @@ -407,39 +357,29 @@ void wizard_tweak_object()
while (true)
{
int64_t old_val = 0; // flags are uint64_t, but they don't care

while (true)
string c_prop = is_art ? "art props" : "special";
vector<WizardEntry> options =
{
mprf_nocap("%s", you.inv[item].name(DESC_INVENTORY_EQUIP).c_str());

mprf_nocap(MSGCH_PROMPT, "a - plus b - plus2 c - %s "
"d - quantity e - flags ESC - exit",
is_art ? "art props" : "special");

mprf(MSGCH_PROMPT, "Which field? ");

keyin = toalower(get_ch());

if (keyin == 'a')
old_val = you.inv[item].plus;
else if (keyin == 'b')
old_val = you.inv[item].plus2;
else if (keyin == 'c')
old_val = you.inv[item].special;
else if (keyin == 'd')
old_val = you.inv[item].quantity;
else if (keyin == 'e')
old_val = you.inv[item].flags;
else if (key_is_escape(keyin) || keyin == ' '
|| keyin == '\r' || keyin == '\n')
{
canned_msg(MSG_OK);
return;
}
{'a', "plus"}, {'b', "plus2"}, {'c', c_prop}, {'d', "quantity"},
{'e', "flags"}
};
mprf_nocap("%s", you.inv[item].name(DESC_INVENTORY_EQUIP).c_str());
auto menu = WizardMenu("Which field (Esc to exit)?", options);
keyin = menu.run();

if (keyin == 'a')
old_val = you.inv[item].plus;
else if (keyin == 'b')
old_val = you.inv[item].plus2;
else if (keyin == 'c')
old_val = you.inv[item].special;
else if (keyin == 'd')
old_val = you.inv[item].quantity;
else if (keyin == 'e')
old_val = you.inv[item].flags;
else if (!menu.success())
return;

if (keyin >= 'a' && keyin <= 'e')
break;
}

if (is_art && keyin == 'c')
{
Expand Down Expand Up @@ -834,24 +774,21 @@ static void _debug_acquirement_stats(FILE *ostat)
env.item[p].base_type = OBJ_UNASSIGNED;

clear_messages();
mpr("[a] Weapons [b] Armours [c] Jewellery [d] Books");
mpr("[e] Staves [f] Evocables");
mprf(MSGCH_PROMPT, "What kind of item would you like to get acquirement stats on? ");

object_class_type type;
const int keyin = toalower(get_ch());
switch (keyin)
vector<WizardEntry> choices;
object_class_type list[] =
{
case 'a': type = OBJ_WEAPONS; break;
case 'b': type = OBJ_ARMOUR; break;
case 'c': type = OBJ_JEWELLERY; break;
case 'd': type = OBJ_BOOKS; break;
case 'e': type = OBJ_STAVES; break;
case 'f': type = OBJ_MISCELLANY; break;
default:
canned_msg(MSG_OK);
OBJ_WEAPONS, OBJ_ARMOUR, OBJ_JEWELLERY, OBJ_BOOKS, OBJ_STAVES,
OBJ_MISCELLANY
};
char c = 'a';
for (auto typ : list)
choices.emplace_back(WizardEntry(c++, item_class_name(typ), typ));
auto menu = WizardMenu("What kind of item would you like to get acquirement"
" stats on (ESC to exit)?", choices, OBJ_UNASSIGNED);
if (!menu.run(true))
return;
}
auto type = static_cast<object_class_type>(menu.result());

const int num_itrs = prompt_for_int("How many iterations? ", true);

Expand Down
72 changes: 27 additions & 45 deletions crawl-ref/source/wiz-mon.cc
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
#include "terrain.h"
#include "view.h"
#include "viewmap.h"
#include "wizard.h"

#ifdef WIZARD

Expand Down Expand Up @@ -784,60 +785,41 @@ void wizard_make_monster_summoned(monster* mon)
return;
}

mprf(MSGCH_PROMPT, "[a] clone [b] animated [c] chaos [d] miscast [e] zot");
mprf(MSGCH_PROMPT, "[f] wrath [h] aid [m] misc [s] spell");

mprf(MSGCH_PROMPT, "Which summon type? ");

char choice = toalower(getchm());

if (!(choice >= 'a' && choice <= 'h') && choice != 'm' && choice != 's')
vector<WizardEntry> choices =
{
canned_msg(MSG_OK);
{'a', "clone", MON_SUMM_CLONE}, {'b', "animated", MON_SUMM_ANIMATE},
{'c', "chaos", MON_SUMM_CHAOS}, {'d', "miscast", MON_SUMM_MISCAST},
{'e', "zot", MON_SUMM_ZOT}, {'f', "wrath", MON_SUMM_WRATH},
{'h', "aid", MON_SUMM_AID}, {'m', "misc", 0},
{'s', "spell", 's'},
};

auto menu = WizardMenu("Which summon type (ESC to exit)?", choices);
if (!menu.run(true))
return;
}

int type = 0;

switch (choice)
int type = menu.result();
if ('s' == type)
{
case 'a': type = MON_SUMM_CLONE; break;
case 'b': type = MON_SUMM_ANIMATE; break;
case 'c': type = MON_SUMM_CHAOS; break;
case 'd': type = MON_SUMM_MISCAST; break;
case 'e': type = MON_SUMM_ZOT; break;
case 'f': type = MON_SUMM_WRATH; break;
case 'h': type = MON_SUMM_AID; break;
case 'm': type = 0; break;

case 's':
{
char specs[80];
char specs[80];

msgwin_get_line("Cast which spell by name? ",
specs, sizeof(specs));
msgwin_get_line("Cast which spell by name? ",
specs, sizeof(specs));

if (specs[0] == '\0')
{
canned_msg(MSG_OK);
return;
}

spell_type spell = spell_by_name(specs, true);
if (spell == SPELL_NO_SPELL)
{
mprf(MSGCH_PROMPT, "No such spell.");
return;
}
type = (int) spell;
break;
if (specs[0] == '\0')
{
canned_msg(MSG_OK);
return;
}

default:
die("Invalid summon type choice.");
break;
spell_type spell = spell_by_name(specs, true);
if (spell == SPELL_NO_SPELL)
{
mprf(MSGCH_PROMPT, "No such spell.");
return;
}
type = (int) spell;
}

mon->mark_summoned(dur, true, type);
mpr("Monster is now summoned.");
}
Expand Down
Loading

0 comments on commit 9b12bb3

Please sign in to comment.