Merge branch 'NetHack-3.6'

This commit is contained in:
nhmall
2019-10-01 20:44:57 -04:00
10 changed files with 68 additions and 90 deletions
+10 -5
View File
@@ -24,7 +24,7 @@
.ds vr "NetHack 3.7 .ds vr "NetHack 3.7
.ds f0 "\*(vr .ds f0 "\*(vr
.ds f1 .ds f1
.ds f2 "July 9, 2019 .ds f2 "October 1, 2019
. .
.\" A note on some special characters: .\" A note on some special characters:
.\" \(lq = left double quote .\" \(lq = left double quote
@@ -3849,11 +3849,16 @@ character in the pattern, specifically:
.CC > "never pickup an object that matches rest of pattern." .CC > "never pickup an object that matches rest of pattern."
.ei .ei
.ed .ed
A \(lqnever pickup\(rq rule takes precedence over an \(lqalways pickup\(rq The
rule if both match. .op autopickup_exception
rules are processed in the order in which they appear in your config file,
thus allowing a later rule to override an earlier rule.
.lp "" .lp ""
Exceptions can be set with the \(oqO\(cq command, but ones set that way will Exceptions can be set with the \(oqO\(cq command, but because they are not
not be preserved across saves and restores. included in your config file, they won't be in effect if you save and then
restore your game.
.op autopickup_exception
rules and not saved with the game.
.\" end of ``.lp autopickup_exception'' entry; continue enclosing page... .\" end of ``.lp autopickup_exception'' entry; continue enclosing page...
.\" use .lp "text" to make an unindented paragraph ("text" should be short) .\" use .lp "text" to make an unindented paragraph ("text" should be short)
.lp "Here are some examples:" .lp "Here are some examples:"
+7 -5
View File
@@ -45,7 +45,7 @@
%.au %.au
\author{Original version - Eric S. Raymond\\ \author{Original version - Eric S. Raymond\\
(Edited and expanded for 3.6 by Mike Stephenson and others)} (Edited and expanded for 3.6 by Mike Stephenson and others)}
\date{July 9, 2019} \date{October 1, 2019}
\maketitle \maketitle
@@ -4289,12 +4289,14 @@ character in the pattern, specifically:
%.ei %.ei
%.ed %.ed
A ``never pickup'' rule takes precedence over an ``always pickup'' rule if The {\it autopickup\verb+_+exception\/} rules are processed in the order
both match. in which they appear in your config file, thus allowing a later rule to override
an earlier rule.
%.lp "" %.lp ""
Exceptions can be set with the `{\tt O}' command, but ones set that way will Exceptions can be set with the `{\tt O}' command, but because they are not included
not be preserved across saves and restores. in your config file, they won't be in effect if you save and then restore your game.
{\it autopickup\verb+_+exception\/} rules are not saved with the game.
\elist \elist
%.lp "Here are some examples:" %.lp "Here are some examples:"
+1
View File
@@ -314,6 +314,7 @@ NetHack Community Patches (or Variation) Included
------------------------------------------------- -------------------------------------------------
add a couple of engraving suggestions in pull request #79 add a couple of engraving suggestions in pull request #79
chasonr's faster method to write characters to msdos VGA in pull request #220 chasonr's faster method to write characters to msdos VGA in pull request #220
autopickup exception priority change in pull request #226
Code Cleanup and Reorganization Code Cleanup and Reorganization
+1
View File
@@ -891,6 +891,7 @@ struct instance_globals {
char preferred_pet; /* '\0', 'c', 'd', 'n' (none) */ char preferred_pet; /* '\0', 'c', 'd', 'n' (none) */
struct monst *mydogs; /* monsters that went down/up together with @ */ struct monst *mydogs; /* monsters that went down/up together with @ */
struct monst *migrating_mons; /* monsters moving to another level */ struct monst *migrating_mons; /* monsters moving to another level */
struct autopickup_exception *apelist;
struct mvitals mvitals[NUMMONS]; struct mvitals mvitals[NUMMONS];
/* dokick.c */ /* dokick.c */
+1 -1
View File
@@ -1892,7 +1892,7 @@ E boolean NDECL(u_handsy);
E int FDECL(use_container, (struct obj **, int, BOOLEAN_P)); E int FDECL(use_container, (struct obj **, int, BOOLEAN_P));
E int FDECL(loot_mon, (struct monst *, int *, boolean *)); E int FDECL(loot_mon, (struct monst *, int *, boolean *));
E int NDECL(dotip); 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)); E boolean FDECL(autopick_testobj, (struct obj *, BOOLEAN_P));
/* ### pline.c ### */ /* ### pline.c ### */
-3
View File
@@ -409,9 +409,6 @@ struct instance_flags {
int wc2_statuslines; /* default = 2, curses can handle 3 */ int wc2_statuslines; /* default = 2, curses can handle 3 */
int wc2_windowborders; /* display borders on NetHack windows */ int wc2_windowborders; /* display borders on NetHack windows */
int wc2_petattr; /* text attributes for pet */ int wc2_petattr; /* text attributes for pet */
struct autopickup_exception *autopickup_exceptions[2];
#define AP_LEAVE 0
#define AP_GRAB 1
#ifdef WIN32 #ifdef WIN32
#define MAX_ALTKEYHANDLER 25 #define MAX_ALTKEYHANDLER 25
char altkeyhandler[MAX_ALTKEYHANDLER]; char altkeyhandler[MAX_ALTKEYHANDLER];
+1 -2
View File
@@ -2134,8 +2134,7 @@ int final;
*ocl ? "'" : "", *ocl ? ocl : "all types", *ocl ? "'" : ""); *ocl ? "'" : "", *ocl ? ocl : "all types", *ocl ? "'" : "");
if (flags.pickup_thrown && *ocl) /* *ocl: don't show if 'all types' */ if (flags.pickup_thrown && *ocl) /* *ocl: don't show if 'all types' */
Strcat(buf, " plus thrown"); Strcat(buf, " plus thrown");
if (iflags.autopickup_exceptions[AP_GRAB] if (apelist)
|| iflags.autopickup_exceptions[AP_LEAVE])
Strcat(buf, ", with exceptions"); Strcat(buf, ", with exceptions");
} else } else
Strcpy(buf, "off"); Strcpy(buf, "off");
+1
View File
@@ -376,6 +376,7 @@ const struct instance_globals g_init = {
UNDEFINED_VALUE, /* preferred_pet */ UNDEFINED_VALUE, /* preferred_pet */
NULL, /* mydogs */ NULL, /* mydogs */
NULL, /* migrating_mons */ NULL, /* migrating_mons */
NULL, /* apelist */
UNDEFINED_VALUES, /* mvitals */ UNDEFINED_VALUES, /* mvitals */
/* dokick.c */ /* dokick.c */
+34 -57
View File
@@ -561,7 +561,6 @@ static boolean FDECL(special_handling, (const char *,
static const char *FDECL(get_compopt_value, (const char *, char *)); static const char *FDECL(get_compopt_value, (const char *, char *));
static void FDECL(remove_autopickup_exception, static void FDECL(remove_autopickup_exception,
(struct autopickup_exception *)); (struct autopickup_exception *));
static int FDECL(count_ape_maps, (int *, int *));
static boolean FDECL(is_wc_option, (const char *)); static boolean FDECL(is_wc_option, (const char *));
static boolean FDECL(wc_supported, (const char *)); static boolean FDECL(wc_supported, (const char *));
@@ -4352,7 +4351,15 @@ int nset;
int int
count_apes(VOID_ARGS) count_apes(VOID_ARGS)
{ {
return count_ape_maps((int *) 0, (int *) 0); int numapes = 0;
struct autopickup_exception *ape = g.apelist;
while (ape) {
numapes++;
ape = ape->next;
}
return numapes;
} }
enum opt_other_enums { enum opt_other_enums {
@@ -5220,13 +5227,13 @@ boolean setinitial, setfromfile;
goto menucolors_again; goto menucolors_again;
} }
} else if (!strcmp("autopickup_exception", optname)) { } else if (!strcmp("autopickup_exception", optname)) {
int opt_idx, pass, totalapes = 0, numapes[2] = { 0, 0 }; int opt_idx, numapes = 0;
char apebuf[1 + BUFSZ]; /* so &apebuf[1] is BUFSZ long for getlin() */ char apebuf[2 + BUFSZ]; /* so &apebuf[1] is BUFSZ long for getlin() */
struct autopickup_exception *ape; struct autopickup_exception *ape;
ape_again: ape_again:
totalapes = count_ape_maps(&numapes[AP_LEAVE], &numapes[AP_GRAB]); numapes = count_apes();
opt_idx = handle_add_list_remove("autopickup exception", totalapes); opt_idx = handle_add_list_remove("autopickup exception", numapes);
if (opt_idx == 3) { /* done */ if (opt_idx == 3) { /* done */
return TRUE; return TRUE;
} else if (opt_idx == 0) { /* add new */ } else if (opt_idx == 0) { /* add new */
@@ -5242,7 +5249,7 @@ boolean setinitial, setfromfile;
/* guarantee room for \" prefix and \"\0 suffix; /* guarantee room for \" prefix and \"\0 suffix;
-2 is good enough for apebuf[] but -3 makes -2 is good enough for apebuf[] but -3 makes
sure the whole thing fits within normal BUFSZ */ sure the whole thing fits within normal BUFSZ */
apebuf[sizeof apebuf - 3] = '\0'; apebuf[sizeof apebuf - 2] = '\0';
Strcat(apebuf, "\""); Strcat(apebuf, "\"");
add_autopickup_exception(apebuf); add_autopickup_exception(apebuf);
} }
@@ -5253,18 +5260,18 @@ boolean setinitial, setfromfile;
tmpwin = create_nhwindow(NHW_MENU); tmpwin = create_nhwindow(NHW_MENU);
start_menu(tmpwin); start_menu(tmpwin);
for (pass = AP_LEAVE; pass <= AP_GRAB; ++pass) { if (numapes) {
if (numapes[pass] == 0) ape = g.apelist;
continue;
ape = iflags.autopickup_exceptions[pass];
any = cg.zeroany; any = cg.zeroany;
add_menu(tmpwin, NO_GLYPH, &any, 0, 0, iflags.menu_headings, add_menu(tmpwin, NO_GLYPH, &any, 0, 0, iflags.menu_headings,
(pass == 0) ? "Never pickup" : "Always pickup", "Always pickup '<'; never pickup '>'",
MENU_UNSELECTED); 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; any.a_void = (opt_idx == 1) ? 0 : ape;
/* length of pattern plus quotes is less than BUFSZ */ /* length of pattern plus quotes (plus '<'/'>') is less than
Sprintf(apebuf, "\"%s\"", ape->pattern); BUFSZ */
Sprintf(apebuf, "\"%c%s\"", ape->grab ? '<' : '>',
ape->pattern);
add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, apebuf, add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, apebuf,
MENU_UNSELECTED); MENU_UNSELECTED);
ape = ape->next; ape = ape->next;
@@ -5820,9 +5827,8 @@ dotogglepickup()
if (flags.pickup) { if (flags.pickup) {
oc_to_str(flags.pickup_types, ocl); oc_to_str(flags.pickup_types, ocl);
Sprintf(buf, "ON, for %s objects%s", ocl[0] ? ocl : "all", Sprintf(buf, "ON, for %s objects%s", ocl[0] ? ocl : "all",
(iflags.autopickup_exceptions[AP_LEAVE] (g.apelist)
|| iflags.autopickup_exceptions[AP_GRAB]) ? ((count_apes() == 1)
? ((count_ape_maps((int *) 0, (int *) 0) == 1)
? ", with one exception" ? ", with one exception"
: ", with some exceptions") : ", with some exceptions")
: ""); : "");
@@ -5841,7 +5847,7 @@ const char *mapping;
APE_regex_error[] = "regex error in AUTOPICKUP_EXCEPTION", APE_regex_error[] = "regex error in AUTOPICKUP_EXCEPTION",
APE_syntax_error[] = "syntax 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; char text[256], end;
int n; int n;
boolean grab = FALSE; boolean grab = FALSE;
@@ -5873,13 +5879,11 @@ const char *mapping;
free((genericptr_t) ape); free((genericptr_t) ape);
return 0; return 0;
} }
apehead = (grab) ? &iflags.autopickup_exceptions[AP_GRAB]
: &iflags.autopickup_exceptions[AP_LEAVE];
ape->pattern = dupstr(text); ape->pattern = dupstr(text);
ape->grab = grab; ape->grab = grab;
ape->next = *apehead; ape->next = g.apelist;
*apehead = ape; g.apelist = ape;
return 1; return 1;
} }
@@ -5888,16 +5892,15 @@ remove_autopickup_exception(whichape)
struct autopickup_exception *whichape; struct autopickup_exception *whichape;
{ {
struct autopickup_exception *ape, *freeape, *prev = 0; struct autopickup_exception *ape, *freeape, *prev = 0;
int chain = whichape->grab ? AP_GRAB : AP_LEAVE;
for (ape = iflags.autopickup_exceptions[chain]; ape;) { for (ape = g.apelist; ape;) {
if (ape == whichape) { if (ape == whichape) {
freeape = ape; freeape = ape;
ape = ape->next; ape = ape->next;
if (prev) if (prev)
prev->next = ape; prev->next = ape;
else else
iflags.autopickup_exceptions[chain] = ape; g.apelist = ape;
regex_free(freeape->regex); regex_free(freeape->regex);
free((genericptr_t) freeape->pattern); free((genericptr_t) freeape->pattern);
free((genericptr_t) freeape); free((genericptr_t) freeape);
@@ -5908,42 +5911,16 @@ struct autopickup_exception *whichape;
} }
} }
static 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 void
free_autopickup_exceptions() free_autopickup_exceptions()
{ {
struct autopickup_exception *ape; struct autopickup_exception *ape;
int pass;
for (pass = AP_LEAVE; pass <= AP_GRAB; ++pass) { while ((ape = g.apelist) != 0) {
while ((ape = iflags.autopickup_exceptions[pass]) != 0) { regex_free(ape->regex);
regex_free(ape->regex); free((genericptr_t) ape->pattern);
free((genericptr_t) ape->pattern); g.apelist = ape->next;
iflags.autopickup_exceptions[pass] = ape->next; free((genericptr_t) ape);
free((genericptr_t) ape);
}
} }
} }
+12 -17
View File
@@ -699,28 +699,22 @@ int what; /* should be a long */
return (n_tried > 0); return (n_tried > 0);
} }
boolean struct autopickup_exception *
is_autopickup_exception(obj, grab) check_autopickup_exceptions(obj)
struct obj *obj; struct obj *obj;
boolean grab; /* forced pickup, rather than forced leave behind? */
{ {
/* /*
* Does the text description of this match an exception? * Does the text description of this match an exception?
*/ */
struct autopickup_exception struct autopickup_exception *ape = g.apelist;
*ape = (grab) ? iflags.autopickup_exceptions[AP_GRAB]
: iflags.autopickup_exceptions[AP_LEAVE];
if (ape) { if (ape) {
char *objdesc = makesingular(doname(obj)); char *objdesc = makesingular(doname(obj));
while (ape) { while (ape && !regex_match(objdesc, ape->regex))
if (regex_match(objdesc, ape->regex))
return TRUE;
ape = ape->next; ape = ape->next;
}
} }
return FALSE; return ape;
} }
boolean boolean
@@ -728,6 +722,7 @@ autopick_testobj(otmp, calc_costly)
struct obj *otmp; struct obj *otmp;
boolean calc_costly; boolean calc_costly;
{ {
struct autopickup_exception *ape;
static boolean costly = FALSE; static boolean costly = FALSE;
const char *otypes = flags.pickup_types; const char *otypes = flags.pickup_types;
boolean pickit; boolean pickit;
@@ -743,12 +738,12 @@ boolean calc_costly;
/* check for pickup_types */ /* check for pickup_types */
pickit = (!*otypes || index(otypes, otmp->oclass)); pickit = (!*otypes || index(otypes, otmp->oclass));
/* check for "always pick up */
if (!pickit) /* check for autopickup exceptions */
pickit = is_autopickup_exception(otmp, TRUE); ape = check_autopickup_exceptions(otmp);
/* then for "never pick up */ if (ape)
if (pickit) pickit = ape->grab;
pickit = !is_autopickup_exception(otmp, FALSE);
/* pickup_thrown overrides pickup_types and exceptions */ /* pickup_thrown overrides pickup_types and exceptions */
if (!pickit) if (!pickit)
pickit = (flags.pickup_thrown && otmp->was_thrown); pickit = (flags.pickup_thrown && otmp->was_thrown);