Merge branch 'NetHack-3.6.2'
This commit is contained in:
@@ -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
|
||||
sound if hero teleports out of vault while being confronted by guard
|
||||
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
|
||||
@@ -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
|
||||
Setting the inverse attribute for gold had the space before "$:"
|
||||
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
|
||||
|
||||
@@ -462,7 +462,7 @@ boolean FDECL((*filterfunc), (OBJ_P));
|
||||
augment_filter = (mode & SORTLOOT_PETRIFY) ? TRUE : FALSE;
|
||||
mode &= ~SORTLOOT_PETRIFY; /* remove flag, leaving mode */
|
||||
/* 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)
|
||||
/* caller may be asking us to override filterfunc (in order
|
||||
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].str = (char *) 0;
|
||||
sliarray[i].orderclass = sliarray[i].subclass = sliarray[i].disco = 0;
|
||||
++i;
|
||||
}
|
||||
n = i;
|
||||
/* add a terminator so that we don't have to pass 'n' back to caller */
|
||||
|
||||
61
src/objnam.c
61
src/objnam.c
@@ -2474,7 +2474,7 @@ boolean to_plural; /* true => makeplural, false => makesingular */
|
||||
int i, al;
|
||||
char *endstr, *spot;
|
||||
/* 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",
|
||||
"ceru", "corner", "decu", "des", "dura", "fir", "hanu", "het",
|
||||
"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",
|
||||
};
|
||||
/* 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",
|
||||
"hegu", "preno", "sonar", "speci", "dai", "exa", "fla", "sta", "teg",
|
||||
"tegu", "vela", "da", "hy", "lu", "no", "nu", "ra", "ru", "se", "vi", "ya",
|
||||
"o", "a",
|
||||
"tegu", "vela", "da", "hy", "lu", "no", "nu", "ra", "ru", "se", "vi",
|
||||
"ya", "o", "a",
|
||||
};
|
||||
|
||||
if (!basestr || strlen(basestr) < 4)
|
||||
@@ -2721,9 +2721,9 @@ char oclass;
|
||||
if (!name)
|
||||
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) {
|
||||
/* don't match extra descriptions (w/o real name) */
|
||||
@@ -2775,7 +2775,7 @@ struct obj *no_wish;
|
||||
int wetness, gsize = 0;
|
||||
struct fruit *f;
|
||||
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
|
||||
* 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
|
||||
@@ -2920,12 +2920,25 @@ struct obj *no_wish;
|
||||
} else if (!strncmpi(bp, "empty ", l = 6)) {
|
||||
contents = EMPTY;
|
||||
} 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;
|
||||
} else if (!strncmpi(bp, "medium ", l = 7)) {
|
||||
/* 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;
|
||||
} 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 */
|
||||
gsize = (very != 1) ? 3 : 4;
|
||||
} else
|
||||
@@ -2933,7 +2946,7 @@ struct obj *no_wish;
|
||||
bp += l;
|
||||
}
|
||||
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) {
|
||||
boolean keeptrailingchars = TRUE;
|
||||
|
||||
@@ -3056,15 +3069,28 @@ struct obj *no_wish;
|
||||
*
|
||||
* 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) {
|
||||
int globoffset = (*(p + 4) == 's') ? 9 : 8;
|
||||
|
||||
if ((mntmp = name_to_mon(p + globoffset)) >= PM_GRAY_OOZE
|
||||
&& mntmp <= PM_BLACK_PUDDING) {
|
||||
mntmp = NON_PM; /* lie to ourselves */
|
||||
cnt = 0; /* force only one */
|
||||
}
|
||||
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 == NON_PM)
|
||||
mntmp = rn1(PM_BLACK_PUDDING - PM_GRAY_OOZE, PM_GRAY_OOZE);
|
||||
/* construct canonical spelling in case name_to_mon() recognized a
|
||||
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 {
|
||||
/*
|
||||
* 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 */
|
||||
if (*bp) {
|
||||
char *sng = makesingular(bp);
|
||||
|
||||
if (strcmp(bp, sng)) {
|
||||
if (cnt == 1)
|
||||
cnt = 2;
|
||||
|
||||
28
src/spell.c
28
src/spell.c
@@ -886,7 +886,7 @@ int spell;
|
||||
boolean atme;
|
||||
{
|
||||
int energy, damage, chance, n, intell;
|
||||
int skill, role_skill, res = 0;
|
||||
int otyp, skill, role_skill, res = 0;
|
||||
boolean confused = (Confusion != 0);
|
||||
boolean physical_damage = FALSE;
|
||||
struct obj *pseudo;
|
||||
@@ -1029,10 +1029,11 @@ boolean atme;
|
||||
* Find the skill the hero has in a spell type category.
|
||||
* See spell_skilltype for categories.
|
||||
*/
|
||||
skill = spell_skilltype(pseudo->otyp);
|
||||
otyp = pseudo->otyp;
|
||||
skill = spell_skilltype(otyp);
|
||||
role_skill = P_SKILL(skill);
|
||||
|
||||
switch (pseudo->otyp) {
|
||||
switch (otyp) {
|
||||
/*
|
||||
* At first spells act as expected. As the hero increases in skill
|
||||
* with the appropriate spell type, some spells increase in their
|
||||
@@ -1056,9 +1057,9 @@ boolean atme;
|
||||
}
|
||||
} else {
|
||||
explode(u.dx, u.dy,
|
||||
pseudo->otyp - SPE_MAGIC_MISSILE + 10,
|
||||
otyp - SPE_MAGIC_MISSILE + 10,
|
||||
spell_damage_bonus(u.ulevel / 2 + 1), 0,
|
||||
(pseudo->otyp == SPE_CONE_OF_COLD)
|
||||
(otyp == SPE_CONE_OF_COLD)
|
||||
? EXPL_FROSTY
|
||||
: EXPL_FIERY);
|
||||
}
|
||||
@@ -1073,12 +1074,13 @@ boolean atme;
|
||||
}
|
||||
}
|
||||
break;
|
||||
} /* else fall through... */
|
||||
} /* else */
|
||||
/*FALLTHRU*/
|
||||
|
||||
/* these spells are all duplicates of wand effects */
|
||||
case SPE_FORCE_BOLT:
|
||||
physical_damage = TRUE;
|
||||
/* fall through */
|
||||
/*FALLTHRU*/
|
||||
case SPE_SLEEP:
|
||||
case SPE_MAGIC_MISSILE:
|
||||
case SPE_KNOCK:
|
||||
@@ -1096,7 +1098,13 @@ boolean atme;
|
||||
case SPE_EXTRA_HEALING:
|
||||
case SPE_DRAIN_LIFE:
|
||||
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) {
|
||||
u.dx = u.dy = u.dz = 0;
|
||||
} else if (!getdir((char *) 0)) {
|
||||
@@ -1136,7 +1144,7 @@ boolean atme;
|
||||
/* high skill yields effect equivalent to blessed scroll */
|
||||
if (role_skill >= P_SKILLED)
|
||||
pseudo->blessed = 1;
|
||||
/* fall through */
|
||||
/*FALLTHRU*/
|
||||
case SPE_CHARM_MONSTER:
|
||||
case SPE_MAGIC_MAPPING:
|
||||
case SPE_CREATE_MONSTER:
|
||||
@@ -1152,7 +1160,7 @@ boolean atme;
|
||||
/* high skill yields effect equivalent to blessed potion */
|
||||
if (role_skill >= P_SKILLED)
|
||||
pseudo->blessed = 1;
|
||||
/* fall through */
|
||||
/*FALLTHRU*/
|
||||
case SPE_INVISIBILITY:
|
||||
(void) peffects(pseudo);
|
||||
break;
|
||||
|
||||
18
src/zap.c
18
src/zap.c
@@ -138,7 +138,7 @@ struct obj *otmp;
|
||||
boolean wake = TRUE; /* Most 'zaps' should wake monster */
|
||||
boolean reveal_invis = FALSE, learn_it = FALSE;
|
||||
boolean dbldam = Role_if(PM_KNIGHT) && u.uhave.questart;
|
||||
boolean helpful_gesture = FALSE;
|
||||
boolean skilled_spell, helpful_gesture = FALSE;
|
||||
int dmg, otyp = otmp->otyp;
|
||||
const char *zap_type_text = "spell";
|
||||
struct obj *obj;
|
||||
@@ -149,10 +149,12 @@ struct obj *otmp;
|
||||
reveal_invis = FALSE;
|
||||
|
||||
notonhead = (mtmp->mx != bhitpos.x || mtmp->my != bhitpos.y);
|
||||
skilled_spell = (otmp && otmp->oclass == SPBOOK_CLASS && otmp->blessed);
|
||||
|
||||
switch (otyp) {
|
||||
case WAN_STRIKING:
|
||||
zap_type_text = "wand";
|
||||
/* fall through */
|
||||
/*FALLTHRU*/
|
||||
case SPE_FORCE_BOLT:
|
||||
reveal_invis = TRUE;
|
||||
if (disguised_mimic)
|
||||
@@ -343,10 +345,12 @@ struct obj *otmp;
|
||||
mtmp->mhp += d(6, otyp == SPE_EXTRA_HEALING ? 8 : 4);
|
||||
if (mtmp->mhp > mtmp->mhpmax)
|
||||
mtmp->mhp = mtmp->mhpmax;
|
||||
if (mtmp->mblinded) {
|
||||
mtmp->mblinded = 0;
|
||||
mtmp->mcansee = 1;
|
||||
}
|
||||
/* plain healing must be blessed to cure blindness; extra
|
||||
healing only needs to not be cursed, so spell always cures
|
||||
[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 (disguised_mimic) {
|
||||
if (is_obj_mappear(mtmp,STRANGE_OBJECT)) {
|
||||
@@ -2407,7 +2411,7 @@ boolean ordinary;
|
||||
case SPE_EXTRA_HEALING:
|
||||
learn_it = TRUE; /* (no effect for spells...) */
|
||||
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 " : "");
|
||||
break;
|
||||
case WAN_LIGHT: /* (broken wand) */
|
||||
|
||||
Reference in New Issue
Block a user