diff --git a/include/extern.h b/include/extern.h index 7c37297b3..d4e255744 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1893,7 +1893,7 @@ E boolean NDECL(u_handsy); E int FDECL(use_container, (struct obj **, int, BOOLEAN_P)); E int FDECL(loot_mon, (struct monst *, int *, boolean *)); E int NDECL(dotip); -E boolean FDECL(is_autopickup_exception, (struct obj *, BOOLEAN_P)); +E struct autopickup_exception *FDECL(check_autopickup_exceptions, (struct obj *)); E boolean FDECL(autopick_testobj, (struct obj *, BOOLEAN_P)); /* ### pline.c ### */ diff --git a/include/flag.h b/include/flag.h index daef72bc4..090f6e1b0 100644 --- a/include/flag.h +++ b/include/flag.h @@ -423,9 +423,7 @@ struct instance_flags { int wc2_statuslines; /* default = 2, curses can handle 3 */ int wc2_windowborders; /* display borders on NetHack windows */ int wc2_petattr; /* text attributes for pet */ - struct autopickup_exception *autopickup_exceptions[2]; -#define AP_LEAVE 0 -#define AP_GRAB 1 + struct autopickup_exception *autopickup_exceptions; #ifdef WIN32 #define MAX_ALTKEYHANDLER 25 char altkeyhandler[MAX_ALTKEYHANDLER]; diff --git a/src/cmd.c b/src/cmd.c index 82a7819c7..a9b17bd86 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -2139,8 +2139,7 @@ int final; *ocl ? "'" : "", *ocl ? ocl : "all types", *ocl ? "'" : ""); if (flags.pickup_thrown && *ocl) /* *ocl: don't show if 'all types' */ Strcat(buf, " plus thrown"); - if (iflags.autopickup_exceptions[AP_GRAB] - || iflags.autopickup_exceptions[AP_LEAVE]) + if (iflags.autopickup_exceptions) Strcat(buf, ", with exceptions"); } else Strcpy(buf, "off"); diff --git a/src/options.c b/src/options.c index 50f92ca86..836e86d7a 100644 --- a/src/options.c +++ b/src/options.c @@ -573,7 +573,6 @@ STATIC_DCL boolean FDECL(special_handling, (const char *, STATIC_DCL const char *FDECL(get_compopt_value, (const char *, char *)); STATIC_DCL void FDECL(remove_autopickup_exception, (struct autopickup_exception *)); -STATIC_DCL int FDECL(count_ape_maps, (int *, int *)); STATIC_DCL boolean FDECL(is_wc_option, (const char *)); STATIC_DCL boolean FDECL(wc_supported, (const char *)); @@ -4414,7 +4413,15 @@ int nset; int count_apes(VOID_ARGS) { - return count_ape_maps((int *) 0, (int *) 0); + int numapes = 0; + struct autopickup_exception *ape = iflags.autopickup_exceptions; + + while (ape) { + numapes++; + ape = ape->next; + } + + return numapes; } enum opt_other_enums { @@ -5285,13 +5292,13 @@ boolean setinitial, setfromfile; goto menucolors_again; } } else if (!strcmp("autopickup_exception", optname)) { - int opt_idx, pass, totalapes = 0, numapes[2] = { 0, 0 }; - char apebuf[1 + BUFSZ]; /* so &apebuf[1] is BUFSZ long for getlin() */ + int opt_idx, numapes = 0; + char apebuf[2 + BUFSZ]; /* so &apebuf[1] is BUFSZ long for getlin() */ struct autopickup_exception *ape; ape_again: - totalapes = count_ape_maps(&numapes[AP_LEAVE], &numapes[AP_GRAB]); - opt_idx = handle_add_list_remove("autopickup exception", totalapes); + numapes = count_apes(); + opt_idx = handle_add_list_remove("autopickup exception", numapes); if (opt_idx == 3) { /* done */ return TRUE; } else if (opt_idx == 0) { /* add new */ @@ -5307,7 +5314,7 @@ boolean setinitial, setfromfile; /* guarantee room for \" prefix and \"\0 suffix; -2 is good enough for apebuf[] but -3 makes sure the whole thing fits within normal BUFSZ */ - apebuf[sizeof apebuf - 3] = '\0'; + apebuf[sizeof apebuf - 2] = '\0'; Strcat(apebuf, "\""); add_autopickup_exception(apebuf); } @@ -5318,18 +5325,19 @@ boolean setinitial, setfromfile; tmpwin = create_nhwindow(NHW_MENU); start_menu(tmpwin); - for (pass = AP_LEAVE; pass <= AP_GRAB; ++pass) { - if (numapes[pass] == 0) - continue; - ape = iflags.autopickup_exceptions[pass]; + if (numapes) { + ape = (struct autopickup_exception *) + iflags.autopickup_exceptions; any = zeroany; add_menu(tmpwin, NO_GLYPH, &any, 0, 0, iflags.menu_headings, - (pass == 0) ? "Never pickup" : "Always pickup", + "Always pickup '<'; never pickup '>'", MENU_UNSELECTED); - for (i = 0; i < numapes[pass] && ape; i++) { + for (i = 0; i < numapes && ape; i++) { any.a_void = (opt_idx == 1) ? 0 : ape; - /* length of pattern plus quotes is less than BUFSZ */ - Sprintf(apebuf, "\"%s\"", ape->pattern); + /* length of pattern plus quotes (plus '<'/'>') is less than + BUFSZ */ + Sprintf(apebuf, "\"%c%s\"", ape->grab ? '<' : '>', + ape->pattern); add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, apebuf, MENU_UNSELECTED); ape = ape->next; @@ -5889,9 +5897,8 @@ dotogglepickup() if (flags.pickup) { oc_to_str(flags.pickup_types, ocl); Sprintf(buf, "ON, for %s objects%s", ocl[0] ? ocl : "all", - (iflags.autopickup_exceptions[AP_LEAVE] - || iflags.autopickup_exceptions[AP_GRAB]) - ? ((count_ape_maps((int *) 0, (int *) 0) == 1) + (iflags.autopickup_exceptions) + ? ((count_apes() == 1) ? ", with one exception" : ", with some exceptions") : ""); @@ -5910,7 +5917,7 @@ const char *mapping; APE_regex_error[] = "regex error in AUTOPICKUP_EXCEPTION", APE_syntax_error[] = "syntax error in AUTOPICKUP_EXCEPTION"; - struct autopickup_exception *ape, **apehead; + struct autopickup_exception *ape; char text[256], end; int n; boolean grab = FALSE; @@ -5942,13 +5949,11 @@ const char *mapping; free((genericptr_t) ape); return 0; } - apehead = (grab) ? &iflags.autopickup_exceptions[AP_GRAB] - : &iflags.autopickup_exceptions[AP_LEAVE]; ape->pattern = dupstr(text); ape->grab = grab; - ape->next = *apehead; - *apehead = ape; + ape->next = (struct autopickup_exception *) iflags.autopickup_exceptions; + iflags.autopickup_exceptions = (struct autopickup_exception *) ape; return 1; } @@ -5957,16 +5962,15 @@ remove_autopickup_exception(whichape) struct autopickup_exception *whichape; { struct autopickup_exception *ape, *freeape, *prev = 0; - int chain = whichape->grab ? AP_GRAB : AP_LEAVE; - for (ape = iflags.autopickup_exceptions[chain]; ape;) { + for (ape = iflags.autopickup_exceptions; ape;) { if (ape == whichape) { freeape = ape; ape = ape->next; if (prev) prev->next = ape; else - iflags.autopickup_exceptions[chain] = ape; + iflags.autopickup_exceptions = ape; regex_free(freeape->regex); free((genericptr_t) freeape->pattern); free((genericptr_t) freeape); @@ -5977,42 +5981,15 @@ struct autopickup_exception *whichape; } } -STATIC_OVL int -count_ape_maps(leave, grab) -int *leave, *grab; -{ - struct autopickup_exception *ape; - int pass, totalapes, numapes[2]; - - numapes[0] = numapes[1] = 0; - for (pass = AP_LEAVE; pass <= AP_GRAB; ++pass) { - ape = iflags.autopickup_exceptions[pass]; - while (ape) { - ape = ape->next; - numapes[pass]++; - } - } - totalapes = numapes[AP_LEAVE] + numapes[AP_GRAB]; - if (leave) - *leave = numapes[AP_LEAVE]; - if (grab) - *grab = numapes[AP_GRAB]; - return totalapes; -} - void free_autopickup_exceptions() { - struct autopickup_exception *ape; - int pass; - - for (pass = AP_LEAVE; pass <= AP_GRAB; ++pass) { - while ((ape = iflags.autopickup_exceptions[pass]) != 0) { - regex_free(ape->regex); - free((genericptr_t) ape->pattern); - iflags.autopickup_exceptions[pass] = ape->next; - free((genericptr_t) ape); - } + struct autopickup_exception *ape = iflags.autopickup_exceptions; + while ((ape = iflags.autopickup_exceptions) != 0) { + regex_free(ape->regex); + free((genericptr_t) ape->pattern); + iflags.autopickup_exceptions = ape->next; + free((genericptr_t) ape); } } diff --git a/src/pickup.c b/src/pickup.c index e47d989da..c0ef2b0cf 100644 --- a/src/pickup.c +++ b/src/pickup.c @@ -711,28 +711,20 @@ int what; /* should be a long */ return (n_tried > 0); } -boolean -is_autopickup_exception(obj, grab) +struct autopickup_exception * +check_autopickup_exceptions(obj) struct obj *obj; -boolean grab; /* forced pickup, rather than forced leave behind? */ { /* * Does the text description of this match an exception? */ struct autopickup_exception - *ape = (grab) ? iflags.autopickup_exceptions[AP_GRAB] - : iflags.autopickup_exceptions[AP_LEAVE]; - + *ape = iflags.autopickup_exceptions; if (ape) { char *objdesc = makesingular(doname(obj)); - - while (ape) { - if (regex_match(objdesc, ape->regex)) - return TRUE; - ape = ape->next; - } + while (ape && !regex_match(objdesc, ape->regex)) ape = ape->next; } - return FALSE; + return ape; } boolean @@ -755,12 +747,13 @@ boolean calc_costly; /* check for pickup_types */ pickit = (!*otypes || index(otypes, otmp->oclass)); - /* check for "always pick up */ - if (!pickit) - pickit = is_autopickup_exception(otmp, TRUE); - /* then for "never pick up */ - if (pickit) - pickit = !is_autopickup_exception(otmp, FALSE); + + /* check for autopickup excpetions */ + struct autopickup_exception + *ape = check_autopickup_exceptions(otmp); + if (ape) + pickit = ape->grab; + /* pickup_thrown overrides pickup_types and exceptions */ if (!pickit) pickit = (flags.pickup_thrown && otmp->was_thrown);