diff --git a/include/decl.h b/include/decl.h index 717a23fdd..dcec14aa9 100644 --- a/include/decl.h +++ b/include/decl.h @@ -370,6 +370,28 @@ E char *fqn_prefix[PREFIX_COUNT]; E char *fqn_prefix_names[PREFIX_COUNT]; #endif +/* + * Feature toggles + * + * The following provide a way to offer two different + * behaviours for a game interface feature, and allow + * the player to toggle the alternate behaviour on. + * The feature_name fields stored in the feature_toggles[] + * array can be specified in an OPTIONS=feature_toggle:value1 value2 + * statement in the config file. + */ + +E unsigned long toggled_features; + +E struct features_that_toggle { + char *feature_name; + unsigned long feature_bit; +} feature_toggles[]; + +#define TOGGLE_INVALID 0 +#define TOGGLE_LOOT_MENU_SELECTORS 1 /* index in feature_toogle_list[] */ +#define LAST_FEATURE_TOGGLE 1 + #undef E #endif /* DECL_H */ diff --git a/include/extern.h b/include/extern.h index 7bfb13e48..8ea329124 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1353,6 +1353,7 @@ E char *FDECL(nh_getenv, (const char *)); E void FDECL(set_duplicate_opt_detection, (int)); E void FDECL(set_wc_option_mod_status, (unsigned long, int)); E void FDECL(set_option_mod_status, (char *, int)); +E boolean FDECL(feature_toggle, (int)); /* ### pager.c ### */ diff --git a/src/decl.c b/src/decl.c index a82e493b7..a8f5e719c 100644 --- a/src/decl.c +++ b/src/decl.c @@ -268,6 +268,21 @@ char *fqn_prefix_names[PREFIX_COUNT] = { "hackdir", "leveldir", "savedir", "bonesdir", "datadir", "scoredir", "lockdir", "configdir" }; #endif + +/* + * The following provide a way to offer two different + * behaviours for a game interface feature, and allow + * the player to toggle the alternate behaviour on. + * The strings in the feature_toggles[] array can be + * specified in an OPTIONS=feature_toggle:value1 value2 + * statement in the config file. + */ +unsigned long toggled_features = 0L; + +struct features_that_toggle feature_toggles[] = { + {(char *)0, 0x00000000L}, /* 0 = TOGGLE_INVALID */ + {"loot_menu_selectors", 0x00000001L}, /* 1 = TOGGLE_LOOT_MENU_SELECTORS */ +}; /* dummy routine used to force linkage */ void diff --git a/src/options.c b/src/options.c index a63de72d5..4568766d7 100644 --- a/src/options.c +++ b/src/options.c @@ -219,6 +219,7 @@ static struct Comp_Opt MAXDCHARS+1, SET_IN_FILE }, { "effects", "the symbols to use in drawing special effects", MAXECHARS+1, SET_IN_FILE }, + { "feature_toggle", "alternate feature behaviour", 79, SET_IN_FILE }, { "font_map", "the font to use in the map window", 40, DISP_IN_GAME }, /*WC*/ { "font_menu", "the font to use in menus", 40, DISP_IN_GAME }, /*WC*/ { "font_message", "the font to use in the message window", @@ -1041,6 +1042,43 @@ boolean tinitial, tfrom_file; return; } + fullname = "feature_toggle"; + if (match_optname(opts, fullname, 11, TRUE)) { + char buf[BUFSZ]; + char *feature; + boolean matched = FALSE; + if (!(op = string_for_opt(opts, FALSE))) + return; + if (!negated) { + boolean has_badfield = FALSE; + char badfields[BUFSZ]; + buf[BUFSZ-1] = '\0'; + + Strcpy(badfields, "feature_toggle:"); + (void)strncpy(buf, op, BUFSZ - 1); + (void)mungspaces(buf); + feature = strtok(buf, " \n"); + while(feature && *feature && *feature != ' ') { + matched = FALSE; + for (num = 1; num <= LAST_FEATURE_TOGGLE; num++) { + if (!strcmpi(feature, feature_toggles[num].feature_name)) { + toggled_features |= feature_toggles[num].feature_bit; + matched = TRUE; + } + } + if (!matched) { + if (has_badfield) Strcat(badfields, " "); + Strcat(badfields, feature); + has_badfield = TRUE; + } + feature = strtok((char *)0, " \n"); + } + if (has_badfield) badoption(badfields); + } else + bad_negation(fullname, FALSE); + return; + } + fullname = "horsename"; if (match_optname(opts, fullname, 5, TRUE)) { if (negated) bad_negation(fullname, FALSE); @@ -3249,6 +3287,16 @@ char *op; return 1; } +boolean +feature_toggle(ftidx) +int ftidx; +{ + if (ftidx > 0 && ftidx <= LAST_FEATURE_TOGGLE) { + if (toggled_features & feature_toggles[ftidx].feature_bit) + return TRUE; + } + return FALSE; +} #endif /* OPTION_LISTS_ONLY */ /*options.c*/ diff --git a/src/pickup.c b/src/pickup.c index 19a8bf5ea..0cadd6382 100644 --- a/src/pickup.c +++ b/src/pickup.c @@ -2197,18 +2197,21 @@ struct obj *obj; menu_item *pick_list; char buf[BUFSZ]; int n; + char oldmenu[3] = {'a', 'b', 'c'}, newmenu[3] = {'o', 'i', 'b'}; + char *menuselector = newmenu; + if (feature_toggle(TOGGLE_LOOT_MENU_SELECTORS)) menuselector = oldmenu; any.a_void = 0; win = create_nhwindow(NHW_MENU); start_menu(win); any.a_int = 1; Sprintf(buf,"Take %s out of %s", something, the(xname(obj))); - add_menu(win, NO_GLYPH, &any, 'o', 0, ATR_NONE, buf, MENU_UNSELECTED); + add_menu(win, NO_GLYPH, &any, *menuselector++, 0, ATR_NONE, buf, MENU_UNSELECTED); any.a_int = 2; Sprintf(buf,"Put %s into %s", something, the(xname(obj))); - add_menu(win, NO_GLYPH, &any, 'i', 0, ATR_NONE, buf, MENU_UNSELECTED); + add_menu(win, NO_GLYPH, &any, *menuselector++, 0, ATR_NONE, buf, MENU_UNSELECTED); any.a_int = 3; - add_menu(win, NO_GLYPH, &any, 'b', 0, ATR_NONE, + add_menu(win, NO_GLYPH, &any, *menuselector, 0, ATR_NONE, "Both of the above", MENU_UNSELECTED); end_menu(win, prompt); n = select_menu(win, PICK_ONE, &pick_list);