diff -pruN slashem-0.0.7E7F1-official-release/dat/opthelp slashem-0.0.7E7F1-fixinv/dat/opthelp --- slashem-0.0.7E7F1-official-release/dat/opthelp 2005-07-02 09:24:44.000000000 +0200 +++ slashem-0.0.7E7F1-fixinv/dat/opthelp 2005-10-27 20:33:28.000000000 +0200 @@ -13,7 +13,6 @@ DECgraphics use DEC/VT line-drawing c disclose offer information at the end of the game [TRUE] eight_bit_tty send 8-bit characters straight to terminal [FALSE] extmenu use a menu for selecting extended commands (#) [FALSE] -fixinv try to retain the same letter for the same object [TRUE] help print all available info when using the / command [TRUE] IBMgraphics use IBM extended characters for the dungeon [FALSE] ignintr ignore interrupt signal, including breaks [FALSE] @@ -107,6 +106,13 @@ Compound options which can be set during boulder override the default boulder symbol with another default: [`] disclose the types of information you want offered at the end of the game [ni na nv ng nc] +fixinv how picking and dropping objects reorders the inventory: + None -- objects do not remember inventory letters; + Next -- put object into next free slot; + Move -- put object into the slot where it previously + was, moving any object underneath to next free slot; + boolean style negation is also usable, False is synonym for + None and True is Next [Next] fruit the name of a fruit you enjoy eating [slime mold] (basically a whimsy which NetHack uses from time to time). menustyle user interface for selection of multiple objects: diff -pruN slashem-0.0.7E7F1-official-release/include/flag.h slashem-0.0.7E7F1-fixinv/include/flag.h --- slashem-0.0.7E7F1-official-release/include/flag.h 2005-07-02 09:24:44.000000000 +0200 +++ slashem-0.0.7E7F1-fixinv/include/flag.h 2005-10-27 20:35:50.000000000 +0200 @@ -48,7 +48,7 @@ struct flag { #ifdef INSURANCE boolean ins_chkpt; /* checkpoint as appropriate */ #endif - boolean invlet_constant; /* let objects keep their inventory symbol */ + char invlet_constant; /* let objects keep their inventory symbol */ #ifdef SHOW_WEIGHT boolean invweight; /* show weight in inventory and when picking up */ #endif @@ -333,4 +333,10 @@ extern NEARDATA struct instance_flags if #define RUN_STEP 2 /* update display every single step */ #define RUN_CRAWL 3 /* walk w/ extra delay after each update */ + +/* fixinv options */ +#define FIXINV_NONE 'n' /* objects don't remember inventory letters */ +#define FIXINV_NEXT 'x' /* put object to next free slot */ +#define FIXINV_MOVE 'm' /* put object in old slot, moving any object in the slot + to next free slot */ #endif /* FLAG_H */ diff -pruN slashem-0.0.7E7F1-official-release/src/invent.c slashem-0.0.7E7F1-fixinv/src/invent.c --- slashem-0.0.7E7F1-official-release/src/invent.c 2005-07-02 09:24:44.000000000 +0200 +++ slashem-0.0.7E7F1-fixinv/src/invent.c 2005-10-27 20:33:28.000000000 +0200 @@ -55,6 +55,8 @@ register struct obj *otmp; boolean inuse[52]; register int i; register struct obj *obj; + struct obj *displaceobj = (struct obj *)0; + char ilet; #ifdef GOLDOBJ /* There is only one of these in inventory... */ @@ -69,17 +71,34 @@ register struct obj *otmp; i = obj->invlet; if('a' <= i && i <= 'z') inuse[i - 'a'] = TRUE; else if('A' <= i && i <= 'Z') inuse[i - 'A' + 26] = TRUE; - if(i == otmp->invlet) otmp->invlet = 0; + if(i == otmp->invlet) { + if (flags.invlet_constant == FIXINV_NEXT) + otmp->invlet = 0; + else displaceobj = obj; + } } - if((i = otmp->invlet) && + if((i = otmp->invlet) && flags.invlet_constant == FIXINV_NEXT && (('a' <= i && i <= 'z') || ('A' <= i && i <= 'Z'))) return; - for(i = lastinvnr+1; i != lastinvnr; i++) { + if (flags.invlet_constant == FIXINV_NEXT) { + for(i = lastinvnr+1; i != lastinvnr; i++) { if(i == 52) { i = -1; continue; } if(!inuse[i]) break; + } + } else { + for(i = 0; i <52; i++) + if(!inuse[i]) break; + } + ilet = (inuse[i] ? NOINVSYM : + (i < 26) ? ('a'+i) : ('A'+i-26)); + if (flags.invlet_constant == FIXINV_NEXT) { + otmp->invlet = ilet; + } else { + if (displaceobj) { + otmp->invlet = displaceobj->invlet; + displaceobj->invlet = ilet; + } else otmp->invlet = ilet; } - otmp->invlet = (inuse[i] ? NOINVSYM : - (i < 26) ? ('a'+i) : ('A'+i-26)); lastinvnr = i; } @@ -361,6 +380,7 @@ addinv(obj) struct obj *obj; { struct obj *otmp, *prev; + boolean fixinv = (flags.invlet_constant != FIXINV_NONE); if (obj->where != OBJ_FREE) panic("addinv: obj not free"); @@ -380,11 +400,11 @@ struct obj *obj; goto added; } /* didn't merge, so insert into chain */ - if (flags.invlet_constant || !prev) { - if (flags.invlet_constant) assigninvlet(obj); + if (fixinv || !prev) { + if (fixinv) assigninvlet(obj); obj->nobj = invent; /* insert at beginning */ invent = obj; - if (flags.invlet_constant) reorder_invent(); + if (fixinv) reorder_invent(); } else { prev->nobj = obj; /* insert at end */ obj->nobj = 0; @@ -1030,7 +1050,7 @@ register const char *let,*word; ilet = 'a'; for (otmp = invent; otmp; otmp = otmp->nobj) { - if (!flags.invlet_constant) + if (flags.invlet_constant == FIXINV_NONE) #ifdef GOLDOBJ if (otmp->invlet != GOLD_SYM) /* don't reassign this */ #endif @@ -1787,7 +1807,7 @@ register struct obj *obj; if (obj->oclass == COIN_CLASS) return GOLD_SYM; #endif - if (!flags.invlet_constant) { + if (flags.invlet_constant == FIXINV_NONE) { obj->invlet = NOINVSYM; reassign(); } @@ -1827,7 +1847,7 @@ long quan; /* if non-0, print this quan #else static char li[BUFSZ]; #endif - boolean use_invlet = flags.invlet_constant && let != CONTAINED_SYM; + boolean use_invlet = (flags.invlet_constant != FIXINV_NONE) && let != CONTAINED_SYM; long savequan = 0; if (quan && obj) { @@ -1964,7 +1984,7 @@ long* out_cnt; } /* oxymoron? temporarily assign permanent inventory letters */ - if (!flags.invlet_constant) reassign(); + if (flags.invlet_constant == FIXINV_NONE) reassign(); if (lets && strlen(lets) == 1) { /* when only one item of interest, use pline instead of menus; @@ -2136,7 +2156,7 @@ dounpaid() win = create_nhwindow(NHW_MENU); cost = totcost = 0; num_so_far = 0; /* count of # printed so far */ - if (!flags.invlet_constant) reassign(); + if (flags.invlet_constant == FIXINV_NONE) reassign(); do { classcount = 0; @@ -2311,7 +2331,7 @@ dotypeinv() this_type = oclass; } if (query_objlist((char *) 0, invent, - (flags.invlet_constant ? USE_INVLET : 0)|INVORDER_SORT, + ((flags.invlet_constant != FIXINV_NONE) ? USE_INVLET : 0)|INVORDER_SORT, &pick_list, PICK_NONE, this_type_only) > 0) free((genericptr_t)pick_list); return 0; @@ -2946,7 +2966,7 @@ doorganize() /* inventory organizer by D char allowall[2]; const char *adj_type; - if (!flags.invlet_constant) reassign(); + if (flags.invlet_constant == FIXINV_NONE) reassign(); /* get a pointer to the object the user wants to organize */ allowall[0] = ALL_CLASSES; allowall[1] = '\0'; if (!(obj = getobj(allowall,"adjust"))) return(0); diff -pruN slashem-0.0.7E7F1-official-release/src/options.c slashem-0.0.7E7F1-fixinv/src/options.c --- slashem-0.0.7E7F1-official-release/src/options.c 2005-07-02 09:24:44.000000000 +0200 +++ slashem-0.0.7E7F1-fixinv/src/options.c 2005-10-27 20:34:50.000000000 +0200 @@ -98,7 +98,6 @@ static struct Bool_Opt {"fast_map", (boolean *)0, TRUE, SET_IN_FILE}, #endif {"female", &flags.female, FALSE, DISP_IN_GAME}, - {"fixinv", &flags.invlet_constant, TRUE, SET_IN_GAME}, #ifdef AMIFLUSH {"flush", &flags.amiflush, FALSE, SET_IN_GAME}, #else @@ -280,6 +279,8 @@ static struct Comp_Opt MAXDCHARS+1, SET_IN_FILE }, { "effects", "the symbols to use in drawing special effects", MAXECHARS+1, SET_IN_FILE }, + { "fixinv", "how objects reorder inventory", + sizeof "none", SET_IN_GAME}, { "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", @@ -578,6 +579,7 @@ initoptions() flags.end_top = 3; flags.end_around = 2; iflags.runmode = RUN_LEAP; + flags.invlet_constant = FIXINV_NEXT; iflags.msg_history = 20; #ifdef TTY_GRAPHICS iflags.prevmsg_window = 's'; @@ -1417,6 +1419,27 @@ boolean tinitial, tfrom_file; return; } + fullname="fixinv"; + /* fixinv:none, next or move */ + if (match_optname(opts, fullname, 6, TRUE)) { + if (!(op = string_for_opt(opts, TRUE))) { + flags.invlet_constant = negated ? FIXINV_NONE : FIXINV_NEXT; + } else { + if (negated) { + bad_negation(fullname, TRUE); + return; + } + if (!strncmpi(op, "next", strlen(op))) + flags.invlet_constant = FIXINV_NEXT; + else if (!strncmpi(op, "move", strlen(op))) + flags.invlet_constant = FIXINV_MOVE; + else if (!strncmpi(op, "none", strlen(op))) + flags.invlet_constant = FIXINV_NONE; + else badoption(opts); + } + return; + } + fullname="msg_window"; /* msg_window:single, combo, full or reversed */ if (match_optname(opts, fullname, 4, TRUE)) { @@ -2519,10 +2542,6 @@ goodfruit: #endif ) bot_reconfig(); - - else if ((boolopt[i].addr) == &flags.invlet_constant) { - if (flags.invlet_constant) reassign(); - } #ifdef LAN_MAIL else if ((boolopt[i].addr) == &flags.biff) { if (flags.biff) lan_mail_init(); @@ -3030,12 +3049,33 @@ boolean setinitial,setfromfile; boolean retval = FALSE; /* Special handling of menustyle, pickup_burden, pickup_types, - * disclose, runmode, msg_window, menu_headings, and number_pad options. + * fixinv disclose, runmode, msg_window, menu_headings, + * and number_pad options. #ifdef AUTOPICKUP_EXCEPTIONS * Also takes care of interactive autopickup_exception_handling changes. #endif */ - if (!strcmp("menustyle", optname)) { + if (!strcmp("fixinv", optname)) { + menu_item *window_pick = (menu_item *)0; + tmpwin = create_nhwindow(NHW_MENU); + start_menu(tmpwin); + any.a_char = FIXINV_NONE; + add_menu(tmpwin, NO_GLYPH, &any, FIXINV_NONE, 0, + ATR_NONE, "none", MENU_UNSELECTED); + any.a_char = FIXINV_NEXT; + add_menu(tmpwin, NO_GLYPH, &any, FIXINV_NEXT, 0, + ATR_NONE, "next", MENU_UNSELECTED); + any.a_char = FIXINV_MOVE; + add_menu(tmpwin, NO_GLYPH, &any, FIXINV_MOVE, 0, + ATR_NONE, "move", MENU_UNSELECTED); + end_menu(tmpwin, "Select inventory letter persistance type:"); + if (select_menu(tmpwin, PICK_ONE, &window_pick) > 0) { + flags.invlet_constant = window_pick->item.a_char; + free((genericptr_t)window_pick); + } + destroy_nhwindow(tmpwin); + retval = TRUE; + } else if (!strcmp("menustyle", optname)) { const char *style_name; menu_item *style_pick = (menu_item *)0; tmpwin = create_nhwindow(NHW_MENU); @@ -3428,6 +3468,10 @@ char *buf; Sprintf(buf, "%s", to_be_done); else if (!strcmp(optname, "effects")) Sprintf(buf, "%s", to_be_done); + else if (!strcmp(optname, "fixinv")) + Sprintf(buf, "%s", + (flags.invlet_constant == FIXINV_MOVE) ? "move" : + (flags.invlet_constant == FIXINV_NEXT) ? "next" : "none" ); else if (!strcmp(optname, "font_map")) Sprintf(buf, "%s", iflags.wc_font_map ? iflags.wc_font_map : defopt); else if (!strcmp(optname, "font_message"))