diff --git a/doc/fixes36.2 b/doc/fixes36.2 index fe8568a2d..beeed33a7 100644 --- a/doc/fixes36.2 +++ b/doc/fixes36.2 @@ -1,4 +1,4 @@ -$NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.219 $ $NHDT-Date: 1546212616 2018/12/30 23:30:16 $ +$NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.221 $ $NHDT-Date: 1546467443 2019/01/02 22:17:23 $ This fixes36.2 file is here to capture information about updates in the 3.6.x lineage following the release of 3.6.1 in April 2018. Please note, however, @@ -360,10 +360,12 @@ when built with STATUS_HILITES enabled (the default), gold on status line was missing '$' prefix for symset:Blank wizard mode ^G, creating a monster of class 'I' yielded impossible "mkclass found no class 35 monsters" -in some unknown circumstance, examining something on the map could match bogus - monster class #0 and trigger impossible "Alphabet soup: 'an("")'." - (fix avoids the warning but underlying cause is a mystery; noticed - with the fuzzer, which swaps symbol sets in and out at random) +wizard mode ^G, creating a monster via class name using "lo" through "long wor" + or "long worm t" through "long worm tail" yielded impossible "mkclass + found no class 59 monsters" (class '~' creates a long worm as intended) +if bouldersym bug (via 'O', above) put a ('\0') on the map, examining + that spot matched placeholder monster class #0 and triggered impossible + "Alphabet soup: 'an("")'." tty: turn off an optimization that is the suspected cause of Windows reported partial status lines following level changes tty: ensure that current status fields are always copied to prior status @@ -486,6 +488,11 @@ early level traps are sometimes covered by the remains of fake players fake player characters resist Conflict when inside a shop, far-look now includes shop prices for items marked as having been seen up close +when sortloot is enabled, gems are grouped in subsets (1) unseen gems and + glass, (2) seen but unidentified gems and glass, (3) identified gems, + (4) identified glass, (5) unseen stones (includes unseen rocks), + (6) seen but unidentified gray stones, (7) identified gray stones, + and (8) seen rocks (IDed/unIDed not applicable) NetHack Community Patches (or Variation) Included diff --git a/src/invent.c b/src/invent.c index 9a287aa24..bcb8593ff 100644 --- a/src/invent.c +++ b/src/invent.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 invent.c $NHDT-Date: 1545946249 2018/12/27 21:30:49 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.247 $ */ +/* NetHack 3.6 invent.c $NHDT-Date: 1546467443 2019/01/02 22:17:23 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.248 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -50,7 +50,7 @@ STATIC_DCL char FDECL(obj_to_let, (struct obj *)); */ static const char venom_inv[] = { VENOM_CLASS, 0 }; /* (constant) */ -/* sortloot() classification; called at most once for each object sorted */ +/* sortloot() classification; called at most once [per sort] for each object */ STATIC_OVL void loot_classify(sort_item, obj) Loot *sort_item; @@ -69,6 +69,7 @@ struct obj *obj; const char *classorder; char *p; int k, otyp = obj->otyp, oclass = obj->oclass; + boolean seen, discovered = objects[otyp].oc_name_known ? TRUE : FALSE; /* * For the value types assigned by this classification, sortloot() @@ -76,6 +77,7 @@ struct obj *obj; */ if (!Blind) obj->dknown = 1; /* xname(obj) does this; we want it sooner */ + seen = obj->dknown ? TRUE : FALSE, /* class order */ classorder = flags.sortpack ? flags.inv_order : def_srt_order; p = index(classorder, oclass); @@ -118,7 +120,7 @@ struct obj *obj; : !is_pole(obj) ? 5 : 6); break; case TOOL_CLASS: - if (obj->dknown && objects[otyp].oc_name_known + if (seen && discovered && (otyp == BAG_OF_TRICKS || otyp == HORN_OF_PLENTY)) k = 2; /* known pseudo-container */ else if (Is_container(obj)) @@ -162,6 +164,35 @@ struct obj *obj; break; } break; + case GEM_CLASS: + /* + * Normally subclass takes priority over discovery status, but + * that would give away information for gems (assuming we'll + * group them as valuable gems, next glass, then gray stones, + * and finally rocks once they're all fully identified). + * + * Order: + * 1) unseen gems and glass ("gem") + * 2) seen but undiscovered gems and glass ("blue gem"), + * 3) discovered gems ("sapphire"), + * 4) discovered glass ("worthless pieced of blue glass"), + * 5) unseen gray stones and rocks ("stone"), + * 6) seen but undiscovered gray stones ("gray stone"), + * 7) discovered gray stones ("touchstone"), + * 8) seen rocks ("rock"). + */ + switch (objects[obj->otyp].oc_material) { + case GEMSTONE: + k = !seen ? 1 : !discovered ? 2 : 3; + break; + case GLASS: + k = !seen ? 1 : !discovered ? 2 : 4; + break; + default: /* MINERAL */ + k = !seen ? 5 : (obj->otyp != ROCK) ? (!discovered ? 6 : 7) : 8; + break; + } + break; default: /* other classes don't have subclasses; we assign a nonzero value because sortloot() uses 0 to mean 'not yet classified' */ @@ -170,9 +201,9 @@ struct obj *obj; } sort_item->subclass = (xchar) k; /* discovery status */ - k = !obj->dknown ? 1 /* unseen */ - : (objects[otyp].oc_name_known || !OBJ_DESCR(objects[otyp])) ? 4 - : (objects[otyp].oc_uname)? 3 /* named (partially discovered) */ + k = !seen ? 1 /* unseen */ + : (discovered || !OBJ_DESCR(objects[otyp])) ? 4 + : (objects[otyp].oc_uname) ? 3 /* named (partially discovered) */ : 2; /* undiscovered */ sort_item->disco = (xchar) k; } diff --git a/src/mondata.c b/src/mondata.c index e99d1a4f7..963c6d865 100644 --- a/src/mondata.c +++ b/src/mondata.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 mondata.c $NHDT-Date: 1543545188 2018/11/30 02:33:08 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.69 $ */ +/* NetHack 3.6 mondata.c $NHDT-Date: 1546465283 2019/01/02 21:41:23 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.70 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ @@ -781,11 +781,12 @@ const char *in_str; } for (len = 0, i = LOW_PM; i < NUMMONS; i++) { - register int m_i_len = strlen(mons[i].mname); + register int m_i_len = (int) strlen(mons[i].mname); if (m_i_len > len && !strncmpi(mons[i].mname, str, m_i_len)) { if (m_i_len == slen) { - return i; /* exact match */ + mntmp = i; + break; /* exact match */ } else if (slen > m_i_len && (str[m_i_len] == ' ' || !strcmpi(&str[m_i_len], "s") @@ -841,7 +842,7 @@ int *mndx_p; { 0, NON_PM } }; const char *p, *x; - int i; + int i, len; if (mndx_p) *mndx_p = NON_PM; /* haven't [yet] matched a specific type */ @@ -863,6 +864,8 @@ int *mndx_p; return i; } else { /* multiple characters */ + if (!strcmpi(in_str, "long")) /* not enough to match "long worm" */ + return 0; /* avoid false whole-word match with "long worm tail" */ in_str = makesingular(in_str); /* check for special cases */ for (i = 0; falsematch[i]; i++) @@ -878,9 +881,12 @@ int *mndx_p; return mons[i].mlet; } /* check monster class descriptions */ + len = (int) strlen(in_str); for (i = 1; i < MAXMCLASSES; i++) { x = def_monsyms[i].explain; - if ((p = strstri(x, in_str)) != 0 && (p == x || *(p - 1) == ' ')) + if ((p = strstri(x, in_str)) != 0 && (p == x || *(p - 1) == ' ') + && ((int) strlen(p) >= len + && (p[len] == '\0' || p[len] == ' '))) return i; } /* check individual species names */ diff --git a/src/read.c b/src/read.c index 43a6da8b3..12f31e17d 100644 --- a/src/read.c +++ b/src/read.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 read.c $NHDT-Date: 1546053040 2018/12/29 03:10:40 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.163 $ */ +/* NetHack 3.6 read.c $NHDT-Date: 1546465285 2019/01/02 21:41:25 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.164 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2496,6 +2496,10 @@ struct _create_particular_data *d; d->which = PM_STALKER; d->monclass = MAXMCLASSES; return TRUE; + } else if (d->monclass == S_WORM_TAIL) { /* empty monster class */ + d->which = PM_LONG_WORM; + d->monclass = MAXMCLASSES; + return TRUE; } else if (d->monclass > 0) { d->which = g.urole.malenum; /* reset from NON_PM */ return TRUE; @@ -2514,7 +2518,8 @@ struct _create_particular_data *d; if (!d->randmonst) { firstchoice = d->which; - if (cant_revive(&d->which, FALSE, (struct obj *) 0)) { + if (cant_revive(&d->which, FALSE, (struct obj *) 0) + && firstchoice != PM_LONG_WORM_TAIL) { /* wizard mode can override handling of special monsters */ char buf[BUFSZ];