From 2fb9cf7a1c05de5a8db600679fba677ddb92025d Mon Sep 17 00:00:00 2001 From: HMM Date: Tue, 24 Sep 2019 18:20:49 -0400 Subject: [PATCH] Rework autopickup exceptions to override one another like menucolors --- include/extern.h | 2 +- include/flag.h | 5 ++- src/cmd.c | 3 +- src/options.c | 95 +++++++++++++++++++++--------------------------- src/pickup.c | 31 ++++++---------- 5 files changed, 60 insertions(+), 76 deletions(-) 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 3ea3ada26..4990fe691 100644 --- a/include/flag.h +++ b/include/flag.h @@ -423,9 +423,12 @@ 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]; + /* VE edit: APE overhaul */ + struct autopickup_exception *autopickup_exceptions; +/* #define AP_LEAVE 0 #define AP_GRAB 1 +*/ #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..ecacfb60e 100644 --- a/src/options.c +++ b/src/options.c @@ -573,7 +573,7 @@ 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 int NDECL(count_ape_maps); /* VE edit: APE overhaul */ STATIC_DCL boolean FDECL(is_wc_option, (const char *)); STATIC_DCL boolean FDECL(wc_supported, (const char *)); @@ -4411,10 +4411,11 @@ int nset; add_menu(win, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, MENU_UNSELECTED); } +/* VE edit: APE overhaul */ int count_apes(VOID_ARGS) { - return count_ape_maps((int *) 0, (int *) 0); + return count_ape_maps(); } enum opt_other_enums { @@ -5285,13 +5286,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, pass, 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_ape_maps(); + 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 +5308,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 +5319,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 +5891,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_ape_maps() == 1) ? ", with one exception" : ", with some exceptions") : ""); @@ -5902,6 +5903,7 @@ dotogglepickup() return 0; } +/* VE edit: APE overhaul */ int add_autopickup_exception(mapping) const char *mapping; @@ -5910,7 +5912,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,31 +5944,29 @@ 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; } +/* VE edit: APE overhaul */ STATIC_OVL void 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 +5977,31 @@ struct autopickup_exception *whichape; } } +/* VE edit: APE overhaul */ STATIC_OVL int -count_ape_maps(leave, grab) -int *leave, *grab; +count_ape_maps() { - struct autopickup_exception *ape; - int pass, totalapes, numapes[2]; + int numapes = 0; + struct autopickup_exception *ape = iflags.autopickup_exceptions; - 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]++; - } + while (ape) { + numapes++; + ape = ape->next; } - totalapes = numapes[AP_LEAVE] + numapes[AP_GRAB]; - if (leave) - *leave = numapes[AP_LEAVE]; - if (grab) - *grab = numapes[AP_GRAB]; - return totalapes; + + return numapes; } +/* VE edit: APE overhaul */ 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..647f1daa9 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; - } + do if (regex_match(objdesc, ape->regex)) return ape; + while (ape = ape->next); } - return FALSE; } 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);