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

View File

@@ -24,7 +24,7 @@
.ds vr "NetHack 3.7
.ds f0 "\*(vr
.ds f1
.ds f2 "July 9, 2019
.ds f2 "October 1, 2019
.
.\" A note on some special characters:
.\" \(lq = left double quote
@@ -3849,11 +3849,16 @@ character in the pattern, specifically:
.CC > "never pickup an object that matches rest of pattern."
.ei
.ed
A \(lqnever pickup\(rq rule takes precedence over an \(lqalways pickup\(rq
rule if both match.
The
.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 ""
Exceptions can be set with the \(oqO\(cq command, but ones set that way will
not be preserved across saves and restores.
Exceptions can be set with the \(oqO\(cq command, but because they are not
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...
.\" use .lp "text" to make an unindented paragraph ("text" should be short)
.lp "Here are some examples:"

View File

@@ -45,7 +45,7 @@
%.au
\author{Original version - Eric S. Raymond\\
(Edited and expanded for 3.6 by Mike Stephenson and others)}
\date{July 9, 2019}
\date{October 1, 2019}
\maketitle
@@ -4289,12 +4289,14 @@ character in the pattern, specifically:
%.ei
%.ed
A ``never pickup'' rule takes precedence over an ``always pickup'' rule if
both match.
The {\it autopickup\verb+_+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 ""
Exceptions can be set with the `{\tt O}' command, but ones set that way will
not be preserved across saves and restores.
Exceptions can be set with the `{\tt O}' command, but because they are not included
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
%.lp "Here are some examples:"

View File

@@ -314,6 +314,7 @@ NetHack Community Patches (or Variation) Included
-------------------------------------------------
add a couple of engraving suggestions in pull request #79
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

View File

@@ -891,6 +891,7 @@ struct instance_globals {
char preferred_pet; /* '\0', 'c', 'd', 'n' (none) */
struct monst *mydogs; /* monsters that went down/up together with @ */
struct monst *migrating_mons; /* monsters moving to another level */
struct autopickup_exception *apelist;
struct mvitals mvitals[NUMMONS];
/* dokick.c */

View File

@@ -1892,7 +1892,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 ### */

View File

@@ -409,9 +409,6 @@ 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
#ifdef WIN32
#define MAX_ALTKEYHANDLER 25
char altkeyhandler[MAX_ALTKEYHANDLER];

View File

@@ -2134,8 +2134,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 (apelist)
Strcat(buf, ", with exceptions");
} else
Strcpy(buf, "off");

View File

@@ -376,6 +376,7 @@ const struct instance_globals g_init = {
UNDEFINED_VALUE, /* preferred_pet */
NULL, /* mydogs */
NULL, /* migrating_mons */
NULL, /* apelist */
UNDEFINED_VALUES, /* mvitals */
/* dokick.c */

View File

@@ -561,7 +561,6 @@ static boolean FDECL(special_handling, (const char *,
static const char *FDECL(get_compopt_value, (const char *, char *));
static void FDECL(remove_autopickup_exception,
(struct autopickup_exception *));
static int FDECL(count_ape_maps, (int *, int *));
static boolean FDECL(is_wc_option, (const char *));
static boolean FDECL(wc_supported, (const char *));
@@ -4352,7 +4351,15 @@ int nset;
int
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 {
@@ -5220,13 +5227,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 */
@@ -5242,7 +5249,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);
}
@@ -5253,18 +5260,18 @@ 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 = g.apelist;
any = cg.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;
@@ -5820,9 +5827,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)
(g.apelist)
? ((count_apes() == 1)
? ", with one exception"
: ", with some exceptions")
: "");
@@ -5841,7 +5847,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;
@@ -5873,13 +5879,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 = g.apelist;
g.apelist = ape;
return 1;
}
@@ -5888,16 +5892,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 = g.apelist; ape;) {
if (ape == whichape) {
freeape = ape;
ape = ape->next;
if (prev)
prev->next = ape;
else
iflags.autopickup_exceptions[chain] = ape;
g.apelist = ape;
regex_free(freeape->regex);
free((genericptr_t) freeape->pattern);
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
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);
}
while ((ape = g.apelist) != 0) {
regex_free(ape->regex);
free((genericptr_t) ape->pattern);
g.apelist = ape->next;
free((genericptr_t) ape);
}
}

View File

@@ -699,28 +699,22 @@ 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];
struct autopickup_exception *ape = g.apelist;
if (ape) {
char *objdesc = makesingular(doname(obj));
while (ape) {
if (regex_match(objdesc, ape->regex))
return TRUE;
while (ape && !regex_match(objdesc, ape->regex))
ape = ape->next;
}
}
return FALSE;
return ape;
}
boolean
@@ -728,6 +722,7 @@ autopick_testobj(otmp, calc_costly)
struct obj *otmp;
boolean calc_costly;
{
struct autopickup_exception *ape;
static boolean costly = FALSE;
const char *otypes = flags.pickup_types;
boolean pickit;
@@ -743,12 +738,12 @@ 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 exceptions */
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);