Merge branch 'NetHack-3.6.2-beta01' into NetHack-3.6.2

This commit is contained in:
nhmall
2018-06-22 08:31:02 -04:00
5 changed files with 83 additions and 35 deletions
+8
View File
@@ -39,6 +39,13 @@ internals for 'sortloot' option have been changed to not reorder the actual
give vault guards a cursed tin whistle since there is a shrill whistling give vault guards a cursed tin whistle since there is a shrill whistling
sound if hero teleports out of vault while being confronted by guard sound if hero teleports out of vault while being confronted by guard
polymorphing worn amulet triggers panic if it turns into amulet of change polymorphing worn amulet triggers panic if it turns into amulet of change
wishing for small mimic corpse or large mimic corpse failed with 'nothing
matching that exists'; wishing for large {dog,cat,kobold} corpse
yielded normal size one (size prefix was being stripped off for globs)
wishing for "glob of grey ooze" failed even though grey ooze is recognized
as a variant spelling for gray ooze
spells of healing and extra healing cast at monsters handled monster blindness
inconsistently compared to other healing
Fixes to Post-3.6.1 Problems that Were Exposed Via git Repository Fixes to Post-3.6.1 Problems that Were Exposed Via git Repository
@@ -46,6 +53,7 @@ Fixes to Post-3.6.1 Problems that Were Exposed Via git Repository
fix access violation when --debug:xxxx has no other args after it fix access violation when --debug:xxxx has no other args after it
Setting the inverse attribute for gold had the space before "$:" Setting the inverse attribute for gold had the space before "$:"
getting highlighted along with the gold field getting highlighted along with the gold field
sortloot segfaulted when filtering a subset of items (seen with 'A' command)
Platform- and/or Interface-Specific Fixes Platform- and/or Interface-Specific Fixes
+2 -1
View File
@@ -462,7 +462,7 @@ boolean FDECL((*filterfunc), (OBJ_P));
augment_filter = (mode & SORTLOOT_PETRIFY) ? TRUE : FALSE; augment_filter = (mode & SORTLOOT_PETRIFY) ? TRUE : FALSE;
mode &= ~SORTLOOT_PETRIFY; /* remove flag, leaving mode */ mode &= ~SORTLOOT_PETRIFY; /* remove flag, leaving mode */
/* populate aliarray[0..n-1] */ /* populate aliarray[0..n-1] */
for (i = 0, o = *olist; o; ++i, o = by_nexthere ? o->nexthere : o->nobj) { for (i = 0, o = *olist; o; o = by_nexthere ? o->nexthere : o->nobj) {
if (filterfunc && !(*filterfunc)(o) if (filterfunc && !(*filterfunc)(o)
/* caller may be asking us to override filterfunc (in order /* caller may be asking us to override filterfunc (in order
to do a cockatrice corpse touch check during pickup even to do a cockatrice corpse touch check during pickup even
@@ -473,6 +473,7 @@ boolean FDECL((*filterfunc), (OBJ_P));
sliarray[i].obj = o, sliarray[i].indx = (int) i; sliarray[i].obj = o, sliarray[i].indx = (int) i;
sliarray[i].str = (char *) 0; sliarray[i].str = (char *) 0;
sliarray[i].orderclass = sliarray[i].subclass = sliarray[i].disco = 0; sliarray[i].orderclass = sliarray[i].subclass = sliarray[i].disco = 0;
++i;
} }
n = i; n = i;
/* add a terminator so that we don't have to pass 'n' back to caller */ /* add a terminator so that we don't have to pass 'n' back to caller */
+44 -17
View File
@@ -2474,7 +2474,7 @@ boolean to_plural; /* true => makeplural, false => makesingular */
int i, al; int i, al;
char *endstr, *spot; char *endstr, *spot;
/* these are all the prefixes for *man that don't have a *men plural */ /* these are all the prefixes for *man that don't have a *men plural */
const char *no_men[] = { static const char *no_men[] = {
"albu", "antihu", "anti", "ata", "auto", "bildungsro", "cai", "cay", "albu", "antihu", "anti", "ata", "auto", "bildungsro", "cai", "cay",
"ceru", "corner", "decu", "des", "dura", "fir", "hanu", "het", "ceru", "corner", "decu", "des", "dura", "fir", "hanu", "het",
"infrahu", "inhu", "nonhu", "otto", "out", "prehu", "protohu", "infrahu", "inhu", "nonhu", "otto", "out", "prehu", "protohu",
@@ -2482,11 +2482,11 @@ boolean to_plural; /* true => makeplural, false => makesingular */
"hu", "un", "le", "re", "so", "to", "at", "a", "hu", "un", "le", "re", "so", "to", "at", "a",
}; };
/* these are all the prefixes for *men that don't have a *man singular */ /* these are all the prefixes for *men that don't have a *man singular */
const char *no_man[] = { static const char *no_man[] = {
"abdo", "acu", "agno", "ceru", "cogno", "cycla", "fleh", "grava", "abdo", "acu", "agno", "ceru", "cogno", "cycla", "fleh", "grava",
"hegu", "preno", "sonar", "speci", "dai", "exa", "fla", "sta", "teg", "hegu", "preno", "sonar", "speci", "dai", "exa", "fla", "sta", "teg",
"tegu", "vela", "da", "hy", "lu", "no", "nu", "ra", "ru", "se", "vi", "ya", "tegu", "vela", "da", "hy", "lu", "no", "nu", "ra", "ru", "se", "vi",
"o", "a", "ya", "o", "a",
}; };
if (!basestr || strlen(basestr) < 4) if (!basestr || strlen(basestr) < 4)
@@ -2721,9 +2721,9 @@ char oclass;
if (!name) if (!name)
return STRANGE_OBJECT; return STRANGE_OBJECT;
memset((genericptr_t) validobjs, 0, sizeof(validobjs)); memset((genericptr_t) validobjs, 0, sizeof validobjs);
for (i = oclass ? bases[(int)oclass] : STRANGE_OBJECT + 1; for (i = oclass ? bases[(int) oclass] : STRANGE_OBJECT + 1;
i < NUM_OBJECTS && (!oclass || objects[i].oc_class == oclass); i < NUM_OBJECTS && (!oclass || objects[i].oc_class == oclass);
++i) { ++i) {
/* don't match extra descriptions (w/o real name) */ /* don't match extra descriptions (w/o real name) */
@@ -2775,7 +2775,7 @@ struct obj *no_wish;
int wetness, gsize = 0; int wetness, gsize = 0;
struct fruit *f; struct fruit *f;
int ftype = context.current_fruit; int ftype = context.current_fruit;
char fruitbuf[BUFSZ]; char fruitbuf[BUFSZ], globbuf[BUFSZ];
/* Fruits may not mess up the ability to wish for real objects (since /* Fruits may not mess up the ability to wish for real objects (since
* you can leave a fruit in a bones file and it will be added to * you can leave a fruit in a bones file and it will be added to
* another person's game), so they must be checked for last, after * another person's game), so they must be checked for last, after
@@ -2920,12 +2920,25 @@ struct obj *no_wish;
} else if (!strncmpi(bp, "empty ", l = 6)) { } else if (!strncmpi(bp, "empty ", l = 6)) {
contents = EMPTY; contents = EMPTY;
} else if (!strncmpi(bp, "small ", l = 6)) { /* glob sizes */ } else if (!strncmpi(bp, "small ", l = 6)) { /* glob sizes */
/* "small" might be part of monster name (mimic, if wishing
for its corpse) rather than prefix for glob size; when
used for globs, it might be either "small glob of <foo>" or
"small <foo> glob" and user might add 's' even though plural
doesn't accomplish anything because globs don't stack */
if (strncmpi(bp + l, "glob", 4) && !strstri(bp + l, " glob"))
break;
gsize = 1; gsize = 1;
} else if (!strncmpi(bp, "medium ", l = 7)) { } else if (!strncmpi(bp, "medium ", l = 7)) {
/* xname() doesn't display "medium" but without this /* xname() doesn't display "medium" but without this
there'd be no way to ask for the intermediate size */ there'd be no way to ask for the intermediate size
("glob" without size prefix yields smallest one) */
gsize = 2; gsize = 2;
} else if (!strncmpi(bp, "large ", l = 6)) { } else if (!strncmpi(bp, "large ", l = 6)) {
/* "large" might be part of monster name (dog, cat, koboold,
mimic) or object name (box, round shield) rather than
prefix for glob size */
if (strncmpi(bp + l, "glob", 4) && !strstri(bp + l, " glob"))
break;
/* "very large " had "very " peeled off on previous iteration */ /* "very large " had "very " peeled off on previous iteration */
gsize = (very != 1) ? 3 : 4; gsize = (very != 1) ? 3 : 4;
} else } else
@@ -2933,7 +2946,7 @@ struct obj *no_wish;
bp += l; bp += l;
} }
if (!cnt) if (!cnt)
cnt = 1; /* %% what with "gems" etc. ? */ cnt = 1; /* will be changed to 2 if makesingular() changes string */
if (strlen(bp) > 1 && (p = rindex(bp, '(')) != 0) { if (strlen(bp) > 1 && (p = rindex(bp, '(')) != 0) {
boolean keeptrailingchars = TRUE; boolean keeptrailingchars = TRUE;
@@ -3056,15 +3069,28 @@ struct obj *no_wish;
* *
* also don't let player wish for multiple globs. * also don't let player wish for multiple globs.
*/ */
if ((p = strstri(bp, "glob of ")) != 0 i = (int) strlen(bp);
p = (char *) 0;
/* check for "glob", "<foo> glob", and "glob of <foo>" */
if (!strcmpi(bp, "glob") || !BSTRCMPI(bp, bp + i - 5, " glob")
|| !strcmpi(bp, "globs") || !BSTRCMPI(bp, bp + i - 6, " globs")
|| (p = strstri(bp, "glob of ")) != 0
|| (p = strstri(bp, "globs of ")) != 0) { || (p = strstri(bp, "globs of ")) != 0) {
int globoffset = (*(p + 4) == 's') ? 9 : 8; mntmp = name_to_mon(!p ? bp : (strstri(p, " of ") + 4));
/* if we didn't recognize monster type, pick a valid one at random */
if ((mntmp = name_to_mon(p + globoffset)) >= PM_GRAY_OOZE if (mntmp == NON_PM)
&& mntmp <= PM_BLACK_PUDDING) { mntmp = rn1(PM_BLACK_PUDDING - PM_GRAY_OOZE, PM_GRAY_OOZE);
mntmp = NON_PM; /* lie to ourselves */ /* construct canonical spelling in case name_to_mon() recognized a
cnt = 0; /* force only one */ variant (grey ooze) or player used inverted syntax (<foo> glob);
} if player has given a valid monster type but not valid glob type,
object name lookup won't find it and wish attempt will fail */
Sprintf(globbuf, "glob of %s", mons[mntmp].mname);
bp = globbuf;
mntmp = NON_PM; /* not useful for "glob of <foo>" object lookup */
cnt = 0; /* globs don't stack */
oclass = FOOD_CLASS;
actualn = bp, dn = 0;
goto srch;
} else { } else {
/* /*
* Find corpse type using "of" (figurine of an orc, tin of orc meat) * Find corpse type using "of" (figurine of an orc, tin of orc meat)
@@ -3120,6 +3146,7 @@ struct obj *no_wish;
/* first change to singular if necessary */ /* first change to singular if necessary */
if (*bp) { if (*bp) {
char *sng = makesingular(bp); char *sng = makesingular(bp);
if (strcmp(bp, sng)) { if (strcmp(bp, sng)) {
if (cnt == 1) if (cnt == 1)
cnt = 2; cnt = 2;
+18 -10
View File
@@ -886,7 +886,7 @@ int spell;
boolean atme; boolean atme;
{ {
int energy, damage, chance, n, intell; int energy, damage, chance, n, intell;
int skill, role_skill, res = 0; int otyp, skill, role_skill, res = 0;
boolean confused = (Confusion != 0); boolean confused = (Confusion != 0);
boolean physical_damage = FALSE; boolean physical_damage = FALSE;
struct obj *pseudo; struct obj *pseudo;
@@ -1029,10 +1029,11 @@ boolean atme;
* Find the skill the hero has in a spell type category. * Find the skill the hero has in a spell type category.
* See spell_skilltype for categories. * See spell_skilltype for categories.
*/ */
skill = spell_skilltype(pseudo->otyp); otyp = pseudo->otyp;
skill = spell_skilltype(otyp);
role_skill = P_SKILL(skill); role_skill = P_SKILL(skill);
switch (pseudo->otyp) { switch (otyp) {
/* /*
* At first spells act as expected. As the hero increases in skill * At first spells act as expected. As the hero increases in skill
* with the appropriate spell type, some spells increase in their * with the appropriate spell type, some spells increase in their
@@ -1056,9 +1057,9 @@ boolean atme;
} }
} else { } else {
explode(u.dx, u.dy, explode(u.dx, u.dy,
pseudo->otyp - SPE_MAGIC_MISSILE + 10, otyp - SPE_MAGIC_MISSILE + 10,
spell_damage_bonus(u.ulevel / 2 + 1), 0, spell_damage_bonus(u.ulevel / 2 + 1), 0,
(pseudo->otyp == SPE_CONE_OF_COLD) (otyp == SPE_CONE_OF_COLD)
? EXPL_FROSTY ? EXPL_FROSTY
: EXPL_FIERY); : EXPL_FIERY);
} }
@@ -1073,12 +1074,13 @@ boolean atme;
} }
} }
break; break;
} /* else fall through... */ } /* else */
/*FALLTHRU*/
/* these spells are all duplicates of wand effects */ /* these spells are all duplicates of wand effects */
case SPE_FORCE_BOLT: case SPE_FORCE_BOLT:
physical_damage = TRUE; physical_damage = TRUE;
/* fall through */ /*FALLTHRU*/
case SPE_SLEEP: case SPE_SLEEP:
case SPE_MAGIC_MISSILE: case SPE_MAGIC_MISSILE:
case SPE_KNOCK: case SPE_KNOCK:
@@ -1096,7 +1098,13 @@ boolean atme;
case SPE_EXTRA_HEALING: case SPE_EXTRA_HEALING:
case SPE_DRAIN_LIFE: case SPE_DRAIN_LIFE:
case SPE_STONE_TO_FLESH: case SPE_STONE_TO_FLESH:
if (!(objects[pseudo->otyp].oc_dir == NODIR)) { if (objects[otyp].oc_dir != NODIR) {
if (otyp == SPE_HEALING || otyp == SPE_EXTRA_HEALING) {
/* healing and extra healing are actually potion effects,
but they've been extended to take a direction like wands */
if (role_skill >= P_SKILLED)
pseudo->blessed = 1;
}
if (atme) { if (atme) {
u.dx = u.dy = u.dz = 0; u.dx = u.dy = u.dz = 0;
} else if (!getdir((char *) 0)) { } else if (!getdir((char *) 0)) {
@@ -1136,7 +1144,7 @@ boolean atme;
/* high skill yields effect equivalent to blessed scroll */ /* high skill yields effect equivalent to blessed scroll */
if (role_skill >= P_SKILLED) if (role_skill >= P_SKILLED)
pseudo->blessed = 1; pseudo->blessed = 1;
/* fall through */ /*FALLTHRU*/
case SPE_CHARM_MONSTER: case SPE_CHARM_MONSTER:
case SPE_MAGIC_MAPPING: case SPE_MAGIC_MAPPING:
case SPE_CREATE_MONSTER: case SPE_CREATE_MONSTER:
@@ -1152,7 +1160,7 @@ boolean atme;
/* high skill yields effect equivalent to blessed potion */ /* high skill yields effect equivalent to blessed potion */
if (role_skill >= P_SKILLED) if (role_skill >= P_SKILLED)
pseudo->blessed = 1; pseudo->blessed = 1;
/* fall through */ /*FALLTHRU*/
case SPE_INVISIBILITY: case SPE_INVISIBILITY:
(void) peffects(pseudo); (void) peffects(pseudo);
break; break;
+11 -7
View File
@@ -138,7 +138,7 @@ struct obj *otmp;
boolean wake = TRUE; /* Most 'zaps' should wake monster */ boolean wake = TRUE; /* Most 'zaps' should wake monster */
boolean reveal_invis = FALSE, learn_it = FALSE; boolean reveal_invis = FALSE, learn_it = FALSE;
boolean dbldam = Role_if(PM_KNIGHT) && u.uhave.questart; boolean dbldam = Role_if(PM_KNIGHT) && u.uhave.questart;
boolean helpful_gesture = FALSE; boolean skilled_spell, helpful_gesture = FALSE;
int dmg, otyp = otmp->otyp; int dmg, otyp = otmp->otyp;
const char *zap_type_text = "spell"; const char *zap_type_text = "spell";
struct obj *obj; struct obj *obj;
@@ -149,10 +149,12 @@ struct obj *otmp;
reveal_invis = FALSE; reveal_invis = FALSE;
notonhead = (mtmp->mx != bhitpos.x || mtmp->my != bhitpos.y); notonhead = (mtmp->mx != bhitpos.x || mtmp->my != bhitpos.y);
skilled_spell = (otmp && otmp->oclass == SPBOOK_CLASS && otmp->blessed);
switch (otyp) { switch (otyp) {
case WAN_STRIKING: case WAN_STRIKING:
zap_type_text = "wand"; zap_type_text = "wand";
/* fall through */ /*FALLTHRU*/
case SPE_FORCE_BOLT: case SPE_FORCE_BOLT:
reveal_invis = TRUE; reveal_invis = TRUE;
if (disguised_mimic) if (disguised_mimic)
@@ -343,10 +345,12 @@ struct obj *otmp;
mtmp->mhp += d(6, otyp == SPE_EXTRA_HEALING ? 8 : 4); mtmp->mhp += d(6, otyp == SPE_EXTRA_HEALING ? 8 : 4);
if (mtmp->mhp > mtmp->mhpmax) if (mtmp->mhp > mtmp->mhpmax)
mtmp->mhp = mtmp->mhpmax; mtmp->mhp = mtmp->mhpmax;
if (mtmp->mblinded) { /* plain healing must be blessed to cure blindness; extra
mtmp->mblinded = 0; healing only needs to not be cursed, so spell always cures
mtmp->mcansee = 1; [potions quaffed by monsters behave slightly differently;
} we use the rules for the hero here...] */
if (skilled_spell || otyp == SPE_EXTRA_HEALING)
mcureblindness(mtmp, canseemon(mtmp));
if (canseemon(mtmp)) { if (canseemon(mtmp)) {
if (disguised_mimic) { if (disguised_mimic) {
if (is_obj_mappear(mtmp,STRANGE_OBJECT)) { if (is_obj_mappear(mtmp,STRANGE_OBJECT)) {
@@ -2407,7 +2411,7 @@ boolean ordinary;
case SPE_EXTRA_HEALING: case SPE_EXTRA_HEALING:
learn_it = TRUE; /* (no effect for spells...) */ learn_it = TRUE; /* (no effect for spells...) */
healup(d(6, obj->otyp == SPE_EXTRA_HEALING ? 8 : 4), 0, FALSE, healup(d(6, obj->otyp == SPE_EXTRA_HEALING ? 8 : 4), 0, FALSE,
(obj->otyp == SPE_EXTRA_HEALING)); (obj->blessed || obj->otyp == SPE_EXTRA_HEALING));
You_feel("%sbetter.", obj->otyp == SPE_EXTRA_HEALING ? "much " : ""); You_feel("%sbetter.", obj->otyp == SPE_EXTRA_HEALING ? "much " : "");
break; break;
case WAN_LIGHT: /* (broken wand) */ case WAN_LIGHT: /* (broken wand) */