autopickup exception priority in pull request 226
The pull request #226 commentary follows: One major limitation of the autopickup exception system is that you can't define an exception from an exception, despite both menucolors and msgtypes prioritizing rules based on the order they are defined in .nethackrc. This is because the "always pickup" and "never pickup" exceptions are tracked in different lists, and at runtime, when the player steps over an object, the game checks these lists seperately, with "never pickup" taking precedence. This means that if you want to pick up some but not all items matching a given expression, you may need to write a long and kludgy list of regexes to get the behavior you want. I've edited the autopickup exception code to remove this necessity: now the exceptions are stored in one list, and conflicts between them are resolved based on their relative position in that list. Whether an exception was inclusive or exclusive was already tracked individually; I don't know why they were stored separately in the first place. This edit makes the system both more convenient and more consistent with the semantics of menucolors and msgtypes. With these changes, the 33 autopickup exception rules in the wiki article linked above may be replaced with the following 7 much simpler rules for the exact same effect: AUTOPICKUP_EXCEPTION=">.* corpse.*" AUTOPICKUP_EXCEPTION="<.* newt corpse.*" AUTOPICKUP_EXCEPTION="<.* lichen corpse.*" AUTOPICKUP_EXCEPTION="<.* lizard corpse.*" AUTOPICKUP_EXCEPTION="<.* floating eye corpse.*" AUTOPICKUP_EXCEPTION="<.* wraith corpse.* AUTOPICKUP_EXCEPTION=">.*\>.*" closes #226
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -418,6 +418,7 @@ struct autopickup_exception {
|
|||||||
boolean grab;
|
boolean grab;
|
||||||
struct autopickup_exception *next;
|
struct autopickup_exception *next;
|
||||||
};
|
};
|
||||||
|
E struct autopickup_exception *apelist;
|
||||||
|
|
||||||
struct plinemsg_type {
|
struct plinemsg_type {
|
||||||
xchar msgtype; /* one of MSGTYP_foo */
|
xchar msgtype; /* one of MSGTYP_foo */
|
||||||
|
|||||||
@@ -423,7 +423,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;
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
#define MAX_ALTKEYHANDLER 25
|
#define MAX_ALTKEYHANDLER 25
|
||||||
char altkeyhandler[MAX_ALTKEYHANDLER];
|
char altkeyhandler[MAX_ALTKEYHANDLER];
|
||||||
|
|||||||
@@ -2139,7 +2139,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)
|
if (apelist)
|
||||||
Strcat(buf, ", with exceptions");
|
Strcat(buf, ", with exceptions");
|
||||||
} else
|
} else
|
||||||
Strcpy(buf, "off");
|
Strcpy(buf, "off");
|
||||||
|
|||||||
@@ -213,6 +213,8 @@ char preferred_pet; /* '\0', 'c', 'd', 'n' (none) */
|
|||||||
NEARDATA struct monst *mydogs = (struct monst *) 0;
|
NEARDATA struct monst *mydogs = (struct monst *) 0;
|
||||||
/* monsters that are moving to another dungeon level */
|
/* monsters that are moving to another dungeon level */
|
||||||
NEARDATA struct monst *migrating_mons = (struct monst *) 0;
|
NEARDATA struct monst *migrating_mons = (struct monst *) 0;
|
||||||
|
NEARDATA struct autopickup_exception *apelist =
|
||||||
|
(struct autopickup_exception *)0;
|
||||||
|
|
||||||
NEARDATA struct mvitals mvitals[NUMMONS];
|
NEARDATA struct mvitals mvitals[NUMMONS];
|
||||||
NEARDATA long domove_attempting = 0L;
|
NEARDATA long domove_attempting = 0L;
|
||||||
|
|||||||
+10
-10
@@ -4414,7 +4414,7 @@ int
|
|||||||
count_apes(VOID_ARGS)
|
count_apes(VOID_ARGS)
|
||||||
{
|
{
|
||||||
int numapes = 0;
|
int numapes = 0;
|
||||||
struct autopickup_exception *ape = iflags.autopickup_exceptions;
|
struct autopickup_exception *ape = apelist;
|
||||||
|
|
||||||
while (ape) {
|
while (ape) {
|
||||||
numapes++;
|
numapes++;
|
||||||
@@ -5327,7 +5327,7 @@ boolean setinitial, setfromfile;
|
|||||||
start_menu(tmpwin);
|
start_menu(tmpwin);
|
||||||
if (numapes) {
|
if (numapes) {
|
||||||
ape = (struct autopickup_exception *)
|
ape = (struct autopickup_exception *)
|
||||||
iflags.autopickup_exceptions;
|
apelist;
|
||||||
any = zeroany;
|
any = zeroany;
|
||||||
add_menu(tmpwin, NO_GLYPH, &any, 0, 0, iflags.menu_headings,
|
add_menu(tmpwin, NO_GLYPH, &any, 0, 0, iflags.menu_headings,
|
||||||
"Always pickup '<'; never pickup '>'",
|
"Always pickup '<'; never pickup '>'",
|
||||||
@@ -5897,7 +5897,7 @@ 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)
|
(apelist)
|
||||||
? ((count_apes() == 1)
|
? ((count_apes() == 1)
|
||||||
? ", with one exception"
|
? ", with one exception"
|
||||||
: ", with some exceptions")
|
: ", with some exceptions")
|
||||||
@@ -5952,8 +5952,8 @@ const char *mapping;
|
|||||||
|
|
||||||
ape->pattern = dupstr(text);
|
ape->pattern = dupstr(text);
|
||||||
ape->grab = grab;
|
ape->grab = grab;
|
||||||
ape->next = (struct autopickup_exception *) iflags.autopickup_exceptions;
|
ape->next = (struct autopickup_exception *) apelist;
|
||||||
iflags.autopickup_exceptions = (struct autopickup_exception *) ape;
|
apelist = (struct autopickup_exception *) ape;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5963,14 +5963,14 @@ struct autopickup_exception *whichape;
|
|||||||
{
|
{
|
||||||
struct autopickup_exception *ape, *freeape, *prev = 0;
|
struct autopickup_exception *ape, *freeape, *prev = 0;
|
||||||
|
|
||||||
for (ape = iflags.autopickup_exceptions; ape;) {
|
for (ape = 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 = ape;
|
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);
|
||||||
@@ -5984,11 +5984,11 @@ struct autopickup_exception *whichape;
|
|||||||
void
|
void
|
||||||
free_autopickup_exceptions()
|
free_autopickup_exceptions()
|
||||||
{
|
{
|
||||||
struct autopickup_exception *ape = iflags.autopickup_exceptions;
|
struct autopickup_exception *ape = apelist;
|
||||||
while ((ape = iflags.autopickup_exceptions) != 0) {
|
while ((ape = apelist) != 0) {
|
||||||
regex_free(ape->regex);
|
regex_free(ape->regex);
|
||||||
free((genericptr_t) ape->pattern);
|
free((genericptr_t) ape->pattern);
|
||||||
iflags.autopickup_exceptions = ape->next;
|
apelist = ape->next;
|
||||||
free((genericptr_t) ape);
|
free((genericptr_t) ape);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-6
@@ -718,11 +718,13 @@ struct obj *obj;
|
|||||||
/*
|
/*
|
||||||
* 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 = apelist;
|
||||||
*ape = iflags.autopickup_exceptions;
|
|
||||||
if (ape) {
|
if (ape) {
|
||||||
char *objdesc = makesingular(doname(obj));
|
char *objdesc = makesingular(doname(obj));
|
||||||
while (ape && !regex_match(objdesc, ape->regex)) ape = ape->next;
|
|
||||||
|
while (ape && !regex_match(objdesc, ape->regex))
|
||||||
|
ape = ape->next;
|
||||||
}
|
}
|
||||||
return ape;
|
return ape;
|
||||||
}
|
}
|
||||||
@@ -732,6 +734,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;
|
||||||
@@ -748,9 +751,8 @@ 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 autopickup excpetions */
|
/* check for autopickup exceptions */
|
||||||
struct autopickup_exception
|
ape = check_autopickup_exceptions(otmp);
|
||||||
*ape = check_autopickup_exceptions(otmp);
|
|
||||||
if (ape)
|
if (ape)
|
||||||
pickit = ape->grab;
|
pickit = ape->grab;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user