From 2ee7509945382cb3468794808d34c2aaaaecaf6a Mon Sep 17 00:00:00 2001 From: PatR Date: Sun, 5 Nov 2023 02:31:26 -0800 Subject: [PATCH] replace getenv("TTYINV") with perminv_mode option Add a new option 'perminv_mode' to augment perm_invent. It handles the same choices as the temporary TTYINV method: show all items other than gold, show full inventory including gold, or only show in-use items (similar to the '*' command). For tty, both the all-except-gold and full-inventory modes can add the poorly named 'sparse' variation which populates unused slots in its fixed grid with the inventory letter that would go in each. For others, the default has been changed from full-inventory to all-except-gold. Note that gold is treated as part of 'all' or of 'in-use' if it is quivered because having the amount be shown on the status line doesn't make that redundant. Changing the default may mess up WinGUI if it assumes that perm_invent is full inventory with gold. Initially I was going to change perm_invent into a compound but this leaves it as an on/off toggle and adds perminv_mode as a separate option for how to show the inventory when the toggle is on. It may make sense to combine them since dual controls is a little confusing, but right now setting perm_invent On when perminv_mode is 'none' changes that to 'all' and changing perminv_mode away from 'none' when perm_invent is Off toggles it to On. Guidebook.mn has been updated but as usual Guidebook.tex is lagging. --- dat/opthelp | 9 ++ doc/Guidebook.mn | 34 +++++- include/flag.h | 11 +- include/optlist.h | 7 +- include/wintype.h | 24 ++++- src/invent.c | 79 +++++++------- src/options.c | 262 ++++++++++++++++++++++++++++++++++++++++++---- win/tty/wintty.c | 22 +++- 8 files changed, 369 insertions(+), 79 deletions(-) diff --git a/dat/opthelp b/dat/opthelp index 07aed9fa2..323c6f47f 100644 --- a/dat/opthelp +++ b/dat/opthelp @@ -231,6 +231,15 @@ paranoid_confirmation space separated list [paranoid_confirm:pray swim] in the object class filtering menu is selected; Remove -- always pick from inventory for 'R' and 'T' even when wearing just one applicable item to remove or take off +perminv_mode if the interface supports a persistent inventory window [a] + and the perm_invent option is true, this controls what + will be shown: + none/off -- behave as if perm_invent is false + all/on -- show inventory except for gold (default) + full -- show inventory including gold + in-use -- only show worn and wielded items + (the tty interface's optional perm_invent support includes + a couple of additional choices that vary all and full) pickup_burden when you pick up an item that exceeds this encumbrance [S] level (Unencumbered, Burdened, streSsed, straiNed, overTaxed, or overLoaded), you will be asked if you want to continue. diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index 21a56fe9e..739070bf7 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -40,7 +40,7 @@ .ds f0 "\*(vr .ds f1 .\"DO NOT REMOVE NH_DATESUB .ds f2 "DATE(%B %-d, %Y) -.ds f2 "September 8, 2023 +.ds f2 "November 4, 2023 . .\" A note on some special characters: .\" \(lq = left double quote @@ -4281,8 +4281,38 @@ and entries to be removed by \(oq\f(CR!\fP\(cq and name. The positive (no \(oq!\(cq) and negative (with \(oq!\(cq) entries can be intermixed. .lp perm_invent -If true, always display your current inventory in a window. This only +If true, always display your current inventory in a window (default false). +.lp "" +This only makes sense for windowing system interfaces that implement this feature. +For those that do, the +.op perminv_mode +option can be used to refine what gets displayed for \fIperm_invent\fP. +Setting that to a value other than \fInone\fP while \fIperm_invent\fP is +false will change it to true. +.lp perminv_mode +Augments the +.op perm_invent +option. +Value is one of +.PS "\f(CRin-use\fP" +.PL "\f(CRnone\fP" +behave as if \fIperm_invent\fP is false; +.PL "\f(CRall\fP" +show all inventory except for gold; +.PL "\f(CRfull\fP" +show full inventory including gold; +.PL "\f(CRin-use\fP" +only show items which are in use (worn, wielded, lit lamp). +.\" %if these get uncommented, change .PS argument to "\f(CRgold+grid\fP" +.\" %and the terminator for in-use to semi-colon. +.\" .PL "\f(CRon+grid\fP" +.\" special for tty only, show \fIall\fP plus unused inventory letters; +.\" .PL "\f(CRgold+grid\fP" +.\" special for tty only, show \fIfull\fP plus unused inventory letters. +.PE +Default is \fInone\fP but if \fIperm_invent\fP gets set to true while +it is \fInone\fP it will be changed to \fIall\fP. .\" petattr is a wincap option but we'll document it here... .lp "petattr " Specifies one or more text highlighting attributes to use when showing diff --git a/include/flag.h b/include/flag.h index 3da48464f..7338f027e 100644 --- a/include/flag.h +++ b/include/flag.h @@ -271,7 +271,7 @@ struct instance_flags { boolean menu_tab_sep; /* Use tabs to separate option menu fields */ boolean news; /* print news */ boolean num_pad; /* use numbers for movement commands */ - boolean perm_invent; /* keep full inventories up until dismissed */ + boolean perm_invent; /* display persistent inventory window */ boolean renameallowed; /* can change hero name during role selection */ boolean renameinprogress; /* we are changing hero name */ boolean sounds; /* master on/off switch for using soundlib */ @@ -292,7 +292,14 @@ struct instance_flags { * compression of levels when writing savefile */ schar ice_rating; /* ice_descr()'s classification of ice terrain */ schar prev_decor; /* 'mention_decor' just mentioned this */ - uchar num_pad_mode; + uchar num_pad_mode; /* for num_pad==True, controls how 5 behaves + * and/or 789456123 vs phone-style 123456789; + * for False, qwertY vs qwertZ */ + uchar perminv_mode; /* what to display in persistent invent window + * 0: nothing, 1: all inventory except gold, + * 2: full including gold, 8: in-use items only, + * 5|6: 1|2 with invent letters shown in empty + * slots (TTY only: 'sparse' modes) */ uchar bouldersym; /* symbol for boulder display */ char prevmsg_window; /* type of old message window to use */ boolean extmenu; /* extended commands use menu interface */ diff --git a/include/optlist.h b/include/optlist.h index 3f2d24cee..cbbc545c0 100644 --- a/include/optlist.h +++ b/include/optlist.h @@ -515,8 +515,11 @@ static int optfn_##a(int, int, boolean, char *, char *); Yes, Yes, Yes, Yes, "prayconfirm", "extra prompting in certain situations") NHOPTB(perm_invent, Advanced, 0, opt_in, set_in_game, - Off, Yes, No, No, NoAlias, &iflags.perm_invent, Term_False, - "show permanent inventory window") + Off, Yes, No, No, NoAlias, &iflags.perm_invent, Term_Off, + "show persistent inventory window") + NHOPTC(perminv_mode, Advanced, 20, opt_in, set_in_game, + Yes, Yes, No, Yes, NoAlias, + "what to show in persistent inventory window") NHOPTC(petattr, Advanced, 88, opt_in, set_in_game, /* curses only */ No, Yes, No, No, NoAlias, "attributes for highlighting pets") /* pettype is ignored for some roles */ diff --git a/include/wintype.h b/include/wintype.h index b498c13f3..fcb72c0b8 100644 --- a/include/wintype.h +++ b/include/wintype.h @@ -175,13 +175,31 @@ typedef struct gi { enum perm_invent_toggles {toggling_off = -1, toggling_not = 0, toggling_on = 1 }; -/* inventory modes */ -enum inv_modes { InvNormal = 0, InvShowGold = 1, InvSparse = 2, InvInUse = 4 }; +/* perm_invent modes */ +enum inv_mode_bits { + InvNormal = 1, + InvShowGold = 2, + InvSparse = 4, /* must be ORed with Normal or ShowGold to be valid */ + InvInUse = 8 +}; +enum inv_modes { /* 'perminv_mode' option settings */ + InvOptNone = 0, /* no perm_invent */ + InvOptOn = InvNormal, /* 1 */ + InvOptFull = InvShowGold, /* 2 */ +#if 1 /*#ifdef TTY_PERM_INVENT*/ + /* confusingly-named "sparse mode" shows all inventory letters, even when + their slots are empty; only meaningful for tty's perm_invent */ + InvOptOn_grid = InvNormal | InvSparse, /* 5 */ + InvOptFull_grid = InvShowGold | InvSparse, /* 6 */ +#endif + InvOptInUse = InvInUse, /* 8 */ +}; enum to_core_flags { active = 0x001, prohibited = 0x002, - no_init_done = 0x004 + no_init_done = 0x004, + too_small = 0x008, }; enum from_core_requests { diff --git a/src/invent.c b/src/invent.c index bbc4c435c..4894de253 100644 --- a/src/invent.c +++ b/src/invent.c @@ -47,7 +47,7 @@ static void mime_action(const char *); /* enum and structs are defined in wintype.h */ static win_request_info zerowri = { { 0L, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0 } }; static win_request_info wri_info; -static int done_setting_perminv_flags = 0; +static int perminv_flags = InvOptNone; static boolean in_perm_invent_toggled; /* wizards can wish for venom, which will become an invisible inventory @@ -3288,7 +3288,7 @@ display_pickinv( struct obj *otmp, wizid_fakeobj; char ilet, ret, *formattedobj; const char *invlet = flags.inv_order; - int n, classcount; + int n, classcount, inusecount = 0; winid win; /* windows being used */ anything any; menu_item *selected; @@ -3310,7 +3310,7 @@ display_pickinv( #endif if (lets || xtra_choice || wizid || want_reply #ifdef TTY_PERM_INVENT - || !gi.in_sync_perminvent + /*|| !gi.in_sync_perminvent*/ #endif || WIN_INVEN == WIN_ERR) { /* partial inventory in perm_invent setting; don't operate on @@ -3342,7 +3342,7 @@ display_pickinv( * more than 1; for the last one, we don't need a precise number. * For perm_invent update we force 'more than 1'. */ - n = (iflags.perm_invent && !lets && !want_reply) ? 2 + n = (doing_perm_invent && !lets && !want_reply) ? 2 : lets ? (int) strlen(lets) : !gi.invent ? 0 : !gi.invent->nobj ? 1 : 2; /* for xtra_choice, there's another 'item' not included in initial 'n'; @@ -3455,18 +3455,20 @@ display_pickinv( if (wizid && !not_fully_identified(otmp)) continue; if (doing_perm_invent) { - /* when showing equipment in use, gold shouldn't be excluded - just because !show_gold is set; it might be quivered; - tool_being_used() matches lit lamps/candles and active - leashes, neither of which set owornmask */ + /* don't skip gold if it is quivered, even for !show_gold */ if (inuse_only) { if (!otmp->owornmask && !tool_being_used(otmp)) { skipped_noninuse = TRUE; continue; } - } else if (otmp->invlet == GOLD_SYM && !show_gold) { - skipped_gold = TRUE; - continue; + /* for inuse-only, start with an extra header */ + if (!inusecount++) + add_menu_str(win, "In use"); + } else if (!show_gold) { + if (otmp->invlet == GOLD_SYM && !otmp->owornmask) { + skipped_gold = TRUE; + continue; + } } } any = cg.zeroany; /* all bits zero */ @@ -3519,11 +3521,10 @@ display_pickinv( /* for permanent inventory where nothing has been listed (because there isn't anything applicable to list; the n==0 case above gets skipped for perm_invent), put something into the menu */ - if (iflags.perm_invent && !lets && !gotsomething) { - add_menu_str(win, - (inuse_only && skipped_noninuse) ? not_using_anything - : (!show_gold && skipped_gold) ? only_carrying_gold - : not_carrying_anything); + if (doing_perm_invent && !lets && !gotsomething) { + add_menu_str(win, inuse_only ? not_using_anything + : (!show_gold && skipped_gold) ? only_carrying_gold + : not_carrying_anything); want_reply = FALSE; } #ifdef TTY_PERM_INVENT @@ -5608,23 +5609,15 @@ void prepare_perminvent(winid window) { win_request_info *wri; + int invmode = (int) iflags.perminv_mode; - if (!done_setting_perminv_flags) { - /*TEMPORARY*/ - char *envtmp = !gp.program_state.gameover ? nh_getenv("TTYINV") : 0; - /* default for non-tty includes gold, for tty excludes gold; - if non-tty specifies any value, gold will be excluded unless - that value includes the show-gold bit (1) */ - int invmode = envtmp ? atoi(envtmp) - : !WINDOWPORT(tty) ? InvShowGold - : InvNormal; - + if (perminv_flags != invmode) { wri_info = zerowri; wri_info.fromcore.invmode = invmode; /* relay the mode settings to the window port */ wri = ctrl_nhwindow(window, set_mode, &wri_info); + perminv_flags = invmode; nhUse(wri); - done_setting_perminv_flags = 1; } } @@ -5641,8 +5634,7 @@ sync_perminvent(void) && gp.perm_invent_toggling_direction == toggling_on)) return; } - if (!done_setting_perminv_flags && WIN_INVEN != WIN_ERR) - prepare_perminvent(WIN_INVEN); + prepare_perminvent(WIN_INVEN); if ((!iflags.perm_invent && gc.core_invent_state)) { /* Odd - but this could be end-of-game disclosure @@ -5662,33 +5654,34 @@ sync_perminvent(void) * 1. iflags.perm_invent is on * AND * gc.core_invent_state is still zero. - * * OR - * * 2. iflags.perm_invent is off, but we're in the * midst of toggling it on. + * OR + * 3. iflags.perminv_mode has been changed via 'm O'. */ if ((iflags.perm_invent && !gc.core_invent_state) - || ((!iflags.perm_invent + || (!iflags.perm_invent && (in_perm_invent_toggled - && gp.perm_invent_toggling_direction == toggling_on)))) { - + && gp.perm_invent_toggling_direction == toggling_on))) { /* Send windowport a request to return the related settings to us */ if ((iflags.perm_invent && !gc.core_invent_state) || in_perm_invent_toggled) { - if ((wri = ctrl_nhwindow(WIN_INVEN, request_settings, &wri_info)) - != 0) { - if ((wri->tocore.tocore_flags & prohibited) != 0) { + wri = ctrl_nhwindow(WIN_INVEN, request_settings, &wri_info); + if (wri != 0) { + if ((wri->tocore.tocore_flags & (too_small | prohibited)) + != 0) { /* sizes aren't good enough */ - set_option_mod_status("perm_invent", set_gameview); + if ((wri->tocore.tocore_flags & prohibited) != 0) { + set_option_mod_status("perm_invent", set_gameview); + set_option_mod_status("perminv_mode", set_gameview); + } iflags.perm_invent = FALSE; if (WIN_INVEN != WIN_ERR) destroy_nhwindow(WIN_INVEN), WIN_INVEN = WIN_ERR; - if (WINDOWPORT(tty) && iflags.perm_invent) - wport_id = "tty perm_invent"; - else - wport_id = "perm_invent"; + wport_id = WINDOWPORT(tty) ? "tty perm_invent" + : "perm_invent"; pline("%s could not be enabled.", wport_id); pline("%s needs a terminal that is at least %dx%d, yours " "is %dx%d.", @@ -5729,6 +5722,8 @@ perm_invent_toggled(boolean negated) gc.core_invent_state = 0; } else { gp.perm_invent_toggling_direction = toggling_on; + if (iflags.perminv_mode == InvOptNone) + iflags.perminv_mode = InvOptOn; /* all inventory except gold */ sync_perminvent(); } gp.perm_invent_toggling_direction = toggling_not; diff --git a/src/options.c b/src/options.c index d4f416543..7354481f3 100644 --- a/src/options.c +++ b/src/options.c @@ -234,6 +234,24 @@ static NEARDATA const char *runmodes[] = { static NEARDATA const char *sortltype[] = { "none", "loot", "full" }; +/* second column is an alias for the first; third is brief explanation; + entries 5 and 6 are 1|4 and 2|4 (tty only) */ +static NEARDATA const char *perminv_modes[][3] = { + /*0*/ { "none", "off", "no permanent inventory window" }, + /*1*/ { "all" , "on", "all inventory except for gold" }, + /*2*/ { "full", "gold", "full inventory including gold" }, + /*3*/ { NULL, NULL, NULL }, + /*4*/ { NULL, NULL, NULL }, +#ifdef TTY_PERM_INVENT + /*5*/ { "on+grid", "all+grid", "all except gold, plus unused letters" }, + /*6*/ { "gold+grid", "full+grid", "full inventory, plus unused letters" }, +#else + /*5*/ { NULL, NULL, NULL }, + /*6*/ { NULL, NULL, NULL }, +#endif + /*7*/ { NULL, NULL, NULL }, + /*8*/ { "in-use", "inuse-only", "subset: items currently in use" }, +}; /* * Default menu manipulation command accelerators. These may _not_ be: @@ -340,7 +358,7 @@ static int count_apes(void); static int count_cond(void); static void enhance_menu_text(char *, size_t, int, boolean *, struct allopt_t *); - +static boolean can_set_perm_invent(void); static int handler_align_misc(int); static int handler_autounlock(int); static int handler_disclose(void); @@ -349,6 +367,7 @@ static int handler_menustyle(void); static int handler_msg_window(void); static int handler_number_pad(void); static int handler_paranoid_confirmation(void); +static int handler_perminv_mode(void); static int handler_pickup_burden(void); static int handler_pickup_types(void); static int handler_runmode(void); @@ -2855,6 +2874,98 @@ optfn_paranoid_confirmation( return optn_ok; } +static int +optfn_perminv_mode( + int optidx, int req, boolean negated, + char *opts, char *op) +{ + boolean old_perm_invent = iflags.perm_invent; + uchar old_perminv_mode = iflags.perminv_mode; + int retval = optn_ok; + + if (req == do_init) { +#if 0 + /* old, TEMPORARY method of controlling 'perm_invent'; + note: the bits used now have been changed, hence 'n << 1' */ + char *envtmp = nh_getenv("TTYINV") : 0; + int invmode = envtmp ? (atoi(envtmp) << 1) : 0; + + iflags.perminv_mode = (uchar) invmode; + iflags.perm_invent = iflags.perminv_mode != 0; +#endif + return optn_ok; + } else if (req == do_set) { + op = string_for_opt(opts, negated); + if (op != empty_optstr && negated) { /* reject "!perminv_mode=foo" */ + bad_negation(allopt[optidx].name, TRUE); + retval = optn_silenterr; + } else if (op != empty_optstr) { /* "perminv_mode=foo" */ + const char *pi0, *pi1; + int i; + unsigned ln = (unsigned) strlen(op); /* guaranteed > 0 */ + + for (i = 0; i < SIZE(perminv_modes); ++i) { + if (!(pi0 = perminv_modes[i][0])) + continue; + pi1 = perminv_modes[i][1]; + if (!strncmpi(op, pi0, ln) || !strncmpi(op, pi1, ln) + || op[0] == i + '0') { /* also accept '0'..'8' */ +#if 1 /*#ifdef TTY_PERM_INVENT*/ + if (strstri(pi0, "+grid") && !WINDOWPORT(tty)) { + i &= ~InvSparse; + config_error_add( + "%s: unavailable perm_invent mode '%s', using '%s'", + allopt[optidx].name, pi0, + perminv_modes[i][0]); + } +#endif + iflags.perminv_mode = (uchar) i; + iflags.perm_invent = TRUE; + break; + } + } + if (i == SIZE(perminv_modes)) { + config_error_add("Unknown %s parameter '%s'", + allopt[optidx].name, op); + iflags.perminv_mode = InvOptNone; + iflags.perm_invent = FALSE; + retval = optn_silenterr; + } + } else if (negated) { /* "!perminv_mode" */ + iflags.perminv_mode = InvOptNone; + iflags.perm_invent = FALSE; + } + if (!go.opt_initial) { + if (iflags.perminv_mode != old_perminv_mode + || iflags.perm_invent != old_perm_invent) + go.opt_need_redraw = TRUE; + } + } else if (req == do_handler) { + /* use a menu to choose new value for perminv_mode */ + retval = handler_perminv_mode(); + } else if (req == get_val) { + /* value shown when examining current option settings; exclosed + within square brackets for 'O', shown as-is when setting value */ + Sprintf(opts, "%s", perminv_modes[iflags.perminv_mode][2]); + if (iflags.perminv_mode != InvOptNone && !iflags.perm_invent + /* 'op' is Null when called by handler_perminv_mode() while + setting, non-Null when 'm O' shows current option values */ + && op) { + /* perminv_mode is set but isn't useful because perm_invent is + Off; say so after squeezing out enough for it to barely fit */ + if (iflags.perminv_mode == InvOptInUse) + (void) strsubst(opts, " currently", ""); + else + (void) strsubst(opts, " inventory", " invent"); + Strcat(opts, (((iflags.perminv_mode & InvSparse) != 0) ? " (Off)" + : " ('perm_invent' is Off)")); + } + } else if (req == get_cnf_val) { + Sprintf(opts, "%s", perminv_modes[iflags.perminv_mode][0]); + } + return retval; +} + static int optfn_petattr( int optidx, int req, boolean negated, @@ -3035,7 +3146,10 @@ optfn_pickup_burden( } static int -optfn_pickup_types(int optidx, int req, boolean negated, char *opts, char *op) +optfn_pickup_types( + int optidx, int req, + boolean negated, + char *opts, char *op) { char ocl[MAXOCLASSES + 1], tbuf[MAXOCLASSES + 1], qbuf[QBUFSZ], abuf[BUFSZ]; @@ -3131,7 +3245,10 @@ optfn_pickup_types(int optidx, int req, boolean negated, char *opts, char *op) } static int -optfn_pile_limit(int optidx, int req, boolean negated, char *opts, char *op) +optfn_pile_limit( + int optidx, int req, + boolean negated, + char *opts, char *op) { if (req == do_init) { return optn_ok; @@ -4971,23 +5088,9 @@ optfn_boolean(int optidx, int req, boolean negated, char *opts, char *op) } break; case opt_perm_invent: -#ifdef TTY_PERM_INVENT - /* if attempting to enable perm_invent fails, say so and return - before "'perm_invent' option toggled on" would be given below; - perm_invent_toggled() and routines it calls don't check - iflags.perm_invent so it doesn't matter that 'SET IT HERE' - hasn't been executed yet */ - if (WINDOWPORT(tty) && !go.opt_initial && !negated) { - perm_invent_toggled(FALSE); - /* perm_invent_toggled() - -> sync_perminvent() - -> tty_create_nhwindow(NHW_PERMINVENT) - gives feedback for failure (terminal too small) */ - if (WIN_INVEN == WIN_ERR) - return optn_silenterr; - } -#endif - break; /* from opt_perm_invent */ + if (!negated && !can_set_perm_invent()) + return optn_silenterr; + break; default: break; } @@ -5172,6 +5275,40 @@ spcfn_misc_menu_cmd(int midx, int req, boolean negated, char *opts, char *op) ********************************** */ +/* test whether 'perm_invent' can be toggled On */ +static boolean +can_set_perm_invent(void) +{ + /* + * Assumption: only called when iflags.perm_invent is False + * and is about to be changed to True. + */ + uchar old_perminv_mode = iflags.perminv_mode; + + if (!(windowprocs.wincap & WC_PERM_INVENT)) + return FALSE; /* should never happen */ + + if (iflags.perminv_mode == InvOptNone) + iflags.perminv_mode = InvOptOn; + +#ifdef TTY_PERM_INVENT + if (WINDOWPORT(tty) && !go.opt_initial) { + perm_invent_toggled(FALSE); + /* perm_invent_toggled() + -> sync_perminvent() + -> tty_create_nhwindow(NHW_PERMINVENT) + gives feedback for failure (terminal too small) */ + if (WIN_INVEN == WIN_ERR) { + iflags.perminv_mode = old_perminv_mode; + return FALSE; + } + } +#else + nhUse(old_perminv_mode); +#endif + return TRUE; +} + static int handler_menustyle(void) { @@ -5599,6 +5736,80 @@ handler_paranoid_confirmation(void) return optn_ok; } +static int +handler_perminv_mode(void) +{ + winid tmpwin; + anything any; + char let, buf[BUFSZ], sepbuf[10]; + const char *pi0, *pi1; + menu_item *pi_pick = (menu_item *) 0; + boolean old_perm_invent = iflags.perm_invent; + int i, n, old_pi = (int) iflags.perminv_mode, new_pi = old_pi, + widest = !WINDOWPORT(tty) ? 8 : 11; /* "in-use__" or "full+grid__" */ + + tmpwin = create_nhwindow(NHW_MENU); + start_menu(tmpwin, MENU_BEHAVE_STANDARD); + any = cg.zeroany; + for (i = 0; i < SIZE(perminv_modes); ++i) { + if (!(pi0 = perminv_modes[i][0])) + continue; +#ifdef TTY_PERM_INVENT + if (strstri(pi0, "+grid") != 0 && !WINDOWPORT(tty)) + continue; +#endif + pi1 = perminv_modes[i][1]; + if (!iflags.menu_tab_sep) { + int numspaces = widest - (int) strlen(pi0); + + Sprintf(sepbuf, "%*s", max(numspaces, 1), " "); + } else { + Strcpy(sepbuf, "\t"); + } + Sprintf(buf, "%s%s%s", pi0, sepbuf, perminv_modes[i][2]); + let = ((i & (int) InvSparse) != 0) ? highc(pi1[0]) : pi0[0]; + any.a_int = i + 1; + add_menu(tmpwin, &nul_glyphinfo, &any, let, '0' + i, ATR_NONE, 0, + buf, (i == old_pi) ? MENU_ITEMFLAGS_SELECTED + : MENU_ITEMFLAGS_NONE); + } + end_menu(tmpwin, "Choose permanent inventory mode:"); + n = select_menu(tmpwin, PICK_ONE, &pi_pick); + destroy_nhwindow(tmpwin); + if (n > 0) { + new_pi = pi_pick[0].item.a_int - 1; + if (n > 1 && new_pi == old_pi) + new_pi = pi_pick[1].item.a_int - 1; + free((genericptr_t) pi_pick); + iflags.perminv_mode = new_pi; + } + if (n >= 0) { /* not ESC */ + buf[0] = '\0'; + (void) optfn_perminv_mode(opt_perm_invent, get_val, FALSE, buf, NULL); + pline("'perminv_mode' %s '%s' (%s).", + (new_pi != old_pi) ? "changed to" : "is still", + perminv_modes[new_pi][0], buf); + if (new_pi != InvOptNone && !old_perm_invent) + iflags.perm_invent = can_set_perm_invent(); + else if (new_pi == InvOptNone && old_perm_invent) + iflags.perm_invent = FALSE; + + if (new_pi != old_pi || iflags.perm_invent != old_perm_invent) { +#ifdef TTY_PERM_INVENT + /* FIXME: TTY_PERM_INVENT will blank WIN_INVEN when changing + perminv_mode while perm_invent is already on; to remedy that, + turn it off and then back on when already on */ + if (WINDOWPORT(tty) && iflags.perm_invent && old_perm_invent) { + perm_invent_toggled(TRUE); /*TEMP?*/ + perm_invent_toggled(FALSE); /*TEMP?*/ + } +#endif + go.opt_need_redraw = TRUE; + } + } + return optn_ok; +} + static int handler_pickup_burden(void) { @@ -8278,8 +8489,12 @@ optfn_o_menu_colors(int optidx UNUSED, int req, boolean negated UNUSED, } static int -optfn_o_message_types(int optidx UNUSED, int req, boolean negated UNUSED, - char *opts, char *op UNUSED) +optfn_o_message_types( + int optidx UNUSED, + int req, + boolean negated UNUSED, + char *opts, + char *op UNUSED) { if (req == do_init) { return optn_ok; @@ -9724,6 +9939,7 @@ static struct wc_Opt wc_options[] = { { "eight_bit_tty", WC_EIGHT_BIT_IN }, { "hilite_pet", WC_HILITE_PET }, { "perm_invent", WC_PERM_INVENT }, + { "perminv_mode", WC_PERM_INVENT }, /* shares WC_PERM_INVENT */ { "popup_dialog", WC_POPUP_DIALOG }, { "player_selection", WC_PLAYER_SELECTION }, { "preload_tiles", WC_PRELOAD_TILES }, @@ -10063,7 +10279,7 @@ enhance_menu_text( nowsz = strlen(buf) + 1; availsz = sz - nowsz; -#ifdef TTY_PERM_INVENT +#if 0 /*#ifdef TTY_PERM_INVENT*/ if (bool_p == &iflags.perm_invent && WINDOWPORT(tty)) { if (thisopt->setwhere == set_gameview) Snprintf(eos(buf), availsz, " *terminal size is too small"); diff --git a/win/tty/wintty.c b/win/tty/wintty.c index 9ad937800..76dd46824 100644 --- a/win/tty/wintty.c +++ b/win/tty/wintty.c @@ -2800,10 +2800,9 @@ win_request_info * tty_ctrl_nhwindow(winid window UNUSED, int request, win_request_info *wri) { #if !defined(TTY_PERM_INVENT) + wri = (win_request_info *) 0; nhUse(window); nhUse(request); - nhUse(wri); - return (win_request_info *) 0; #else boolean tty_ok /*, show_gold */, inuse_only; int maxslot; @@ -2831,18 +2830,24 @@ tty_ctrl_nhwindow(winid window UNUSED, int request, win_request_info *wri) wri->tocore.haverows = (int) ttyDisplay->rows; wri->tocore.havecols = (int) ttyDisplay->cols; if (!tty_ok) { - wri->tocore.tocore_flags |= prohibited; /* prohibited */ +#ifdef RESIZABLE + /* terminal isn't big enough right now but player might resize it + and then use 'm O' to try to set 'perm_invent' again */ + wri->tocore.tocore_flags |= too_small; +#else + wri->tocore.tocore_flags |= prohibited; +#endif } else { maxslot = (maxrow - 2) * (!inuse_only ? 2 : 1); wri->tocore.maxslot = maxslot; } break; default: - impossible("invalid request to tty_update_invent_slot %u", request); + impossible("invalid request to tty_ctrl_nhwindow: %d", request); break; } - return wri; #endif + return wri; } #ifdef TTY_PERM_INVENT @@ -3023,6 +3028,13 @@ ttyinv_add_menu( if (text[1] == 'h' && text[2] == 'e' && text[3] == ' ') text += 4; } + /* + * TODO? + * Replace "c - " prefix with "c: " or just "c " to have a bit more + * room for 'text' (the item description). If this prefix gets + * changed, the indentation for empty inventory in ttyinv_render() + * should be changed to match. + */ Snprintf(invbuf, sizeof invbuf, "%c - %s", ch, text); text = invbuf; row = (slot % rows_per_side) + 1; /* +1: top border */