Merge branch 'NetHack-3.7' of https://rodney.nethack.org:20040/git/NHsource into NetHack-3.7

This commit is contained in:
nhmall
2020-03-07 14:36:24 -05:00
10 changed files with 139 additions and 99 deletions
+1
View File
@@ -19,6 +19,7 @@ Debug-Mode Quick Reference:
#timeout == look at timeout queue and hero's timed intrinsics #timeout == look at timeout queue and hero's timed intrinsics
#vanquished == disclose counts of dead monsters sorted in various ways #vanquished == disclose counts of dead monsters sorted in various ways
#vision == show vision array #vision == show vision array
#wizborn == show monster birth/death/geno/extinct stats
#wizintrinsic == set selected intrinsic timeouts #wizintrinsic == set selected intrinsic timeouts
#wizmakemap == recreate the current dungeon level #wizmakemap == recreate the current dungeon level
#wizrumorcheck == validate first and last rumor for true and false set #wizrumorcheck == validate first and last rumor for true and false set
+3
View File
@@ -1512,6 +1512,9 @@ Default key is \(oqw\(cq.
Wipe off your face. Wipe off your face.
Autocompletes. Autocompletes.
Default key is \(oqM-w\(cq. Default key is \(oqM-w\(cq.
.lp "#wizborn "
Show monster birth, death, genocide, and extinct statistics.
Debug mode only.
.lp "#wizbury " .lp "#wizbury "
Bury objects under and around you. Bury objects under and around you.
Autocompletes. Autocompletes.
+4
View File
@@ -1600,6 +1600,10 @@ Wield a weapon. Default key is `{\tt w}'.
\item[\tb{\#wipe}] \item[\tb{\#wipe}]
Wipe off your face. Autocompletes. Default key is `{\tt M-w}'. Wipe off your face. Autocompletes. Default key is `{\tt M-w}'.
%.lp %.lp
\item[\tb{\#wizborn}]
Show monster birth, death, genocide, and extinct statistics.
Debug mode only.
%.lp
\item[\tb{\#wizbury}] \item[\tb{\#wizbury}]
Bury objects under and around you. Bury objects under and around you.
Autocompletes. Autocompletes.
+3
View File
@@ -64,6 +64,8 @@ if eel bite attack caused hero to move (killed + rehumanized + crawled out
of water), its grab attack could succeed even if no longer adjacent of water), its grab attack could succeed even if no longer adjacent
specifying a count when picking [part of] a stack of scrolls of scare monster specifying a count when picking [part of] a stack of scrolls of scare monster
ignored that count and the whole stack was affected ignored that count and the whole stack was affected
wizmakemap didn't account for unique monsters and didn't correct monster
birth counts
Fixes to 3.7.0-x Problems that Were Exposed Via git Repository Fixes to 3.7.0-x Problems that Were Exposed Via git Repository
@@ -175,6 +177,7 @@ demon lords and princes suppress teleporting in Gehennom
for !fixinv option where inventory letters normally don't stick, try to put for !fixinv option where inventory letters normally don't stick, try to put
a throw-and-return weapon back into the same inventory slot it gets a throw-and-return weapon back into the same inventory slot it gets
thrown from; only works if it does return and is successfully caught thrown from; only works if it does return and is successfully caught
wizard mode #wizborn command
Platform- and/or Interface-Specific New Features Platform- and/or Interface-Specific New Features
+1 -6
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 decl.h $NHDT-Date: 1580600478 2020/02/01 23:41:18 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.221 $ */ /* NetHack 3.6 decl.h $NHDT-Date: 1583608809 2020/03/07 19:20:09 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.228 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Michael Allison, 2007. */ /*-Copyright (c) Michael Allison, 2007. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -928,11 +928,6 @@ struct instance_globals {
boolean vis; boolean vis;
boolean far_noise; boolean far_noise;
long noisetime; long noisetime;
struct obj *otmp;
int dieroll; /* Needed for the special case of monsters wielding vorpal
* blades (rare). If we use this a lot it should probably
* be a parameter to mdamagem() instead of a global variable.
*/
/* mhitu.c */ /* mhitu.c */
int mhitu_dieroll; int mhitu_dieroll;
+1
View File
@@ -1002,6 +1002,7 @@ E void FDECL(record_achievement, (XCHAR_P));
E boolean FDECL(remove_achievement, (XCHAR_P)); E boolean FDECL(remove_achievement, (XCHAR_P));
E int NDECL(count_achievements); E int NDECL(count_achievements);
E int NDECL(dovanquished); E int NDECL(dovanquished);
E int NDECL(doborn);
E void FDECL(list_vanquished, (CHAR_P, BOOLEAN_P)); E void FDECL(list_vanquished, (CHAR_P, BOOLEAN_P));
E int NDECL(num_genocides); E int NDECL(num_genocides);
E void FDECL(list_genocided, (CHAR_P, BOOLEAN_P)); E void FDECL(list_genocided, (CHAR_P, BOOLEAN_P));
+7 -5
View File
@@ -780,10 +780,15 @@ boolean pre, wiztower;
if (pre) { if (pre) {
rm_mapseen(ledger_no(&u.uz)); rm_mapseen(ledger_no(&u.uz));
for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
int ndx = monsndx(mtmp->data);
if (mtmp->isgd) { /* vault is going away; get rid of guard */ if (mtmp->isgd) { /* vault is going away; get rid of guard */
mtmp->isgd = 0; mtmp->isgd = 0;
mongone(mtmp); mongone(mtmp);
} }
if (mtmp->data->geno & G_UNIQ)
g.mvitals[ndx].mvflags &= ~(G_EXTINCT);
if (g.mvitals[ndx].born)
g.mvitals[ndx].born--;
if (DEADMONSTER(mtmp)) if (DEADMONSTER(mtmp))
continue; continue;
if (mtmp->isshk) if (mtmp->isshk)
@@ -802,11 +807,6 @@ boolean pre, wiztower;
g.context.achieveo.soko_prize_oid = 0; g.context.achieveo.soko_prize_oid = 0;
} }
} }
/* TODO?
* Reduce 'born' tally for each monster about to be discarded
* by savelev(), otherwise replacing heavily populated levels
* tends to make their inhabitants become extinct.
*/
} }
if (Punished) { if (Punished) {
ballrelease(FALSE); ballrelease(FALSE);
@@ -1890,6 +1890,8 @@ struct ext_func_tab extcmdlist[] = {
dowhatis, IFBURIED | GENERALCMD }, dowhatis, IFBURIED | GENERALCMD },
{ 'w', "wield", "wield (put in use) a weapon", dowield }, { 'w', "wield", "wield (put in use) a weapon", dowield },
{ M('w'), "wipe", "wipe off your face", dowipe, AUTOCOMPLETE }, { M('w'), "wipe", "wipe off your face", dowipe, AUTOCOMPLETE },
{ '\0', "wizborn", "show stats of monsters created",
doborn, IFBURIED | WIZMODECMD },
#ifdef DEBUG #ifdef DEBUG
{ '\0', "wizbury", "bury objs under and around you", { '\0', "wizbury", "bury objs under and around you",
wiz_debug_cmd_bury, IFBURIED | AUTOCOMPLETE | WIZMODECMD }, wiz_debug_cmd_bury, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
+1 -3
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 decl.c $NHDT-Date: 1580600496 2020/02/01 23:41:36 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.202 $ */ /* NetHack 3.6 decl.c $NHDT-Date: 1583608833 2020/03/07 19:20:33 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.208 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Michael Allison, 2009. */ /*-Copyright (c) Michael Allison, 2009. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -469,8 +469,6 @@ const struct instance_globals g_init = {
UNDEFINED_VALUE, /* vis */ UNDEFINED_VALUE, /* vis */
UNDEFINED_VALUE, /* far_noise */ UNDEFINED_VALUE, /* far_noise */
UNDEFINED_VALUE, /* noisetime */ UNDEFINED_VALUE, /* noisetime */
UNDEFINED_PTR, /* otmp */
UNDEFINED_VALUE, /* dieroll */
/* mhitu.c */ /* mhitu.c */
UNDEFINED_VALUE, /* mhitu_dieroll */ UNDEFINED_VALUE, /* mhitu_dieroll */
+33
View File
@@ -2062,6 +2062,39 @@ dovanquished()
return 0; return 0;
} }
/* #wizborn extended command */
int
doborn()
{
static const char fmt[] = "%4i %4i %c %-30s";
int i;
winid datawin = create_nhwindow(NHW_TEXT);
char buf[BUFSZ];
int nborn = 0, ndied = 0;
putstr(datawin, 0, "died born");
for (i = LOW_PM; i < NUMMONS; i++)
if (g.mvitals[i].born || g.mvitals[i].died
|| (g.mvitals[i].mvflags & G_GONE)) {
Sprintf(buf, fmt,
g.mvitals[i].died, g.mvitals[i].born,
((g.mvitals[i].mvflags & G_GONE) == G_EXTINCT) ? 'E' :
((g.mvitals[i].mvflags & G_GONE) == G_GENOD) ? 'G' : ' ',
mons[i].mname);
putstr(datawin, 0, buf);
nborn += g.mvitals[i].born;
ndied += g.mvitals[i].died;
}
putstr(datawin, 0, "");
Sprintf(buf, fmt, ndied, nborn, ' ', "");
display_nhwindow(datawin, FALSE);
destroy_nhwindow(datawin);
return 0;
}
/* high priests aren't unique but are flagged as such to simplify something */ /* high priests aren't unique but are flagged as such to simplify something */
#define UniqCritterIndx(mndx) ((mons[mndx].geno & G_UNIQ) \ #define UniqCritterIndx(mndx) ((mons[mndx].geno & G_UNIQ) \
&& mndx != PM_HIGH_PRIEST) && mndx != PM_HIGH_PRIEST)
+85 -85
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 mhitm.c $NHDT-Date: 1583606861 2020/03/07 18:47:41 $ $NHDT-Branch: NetHack-3.6-Mar2020 $:$NHDT-Revision: 1.119 $ */ /* NetHack 3.6 mhitm.c $NHDT-Date: 1583608838 2020/03/07 19:20:38 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.132 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2011. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -10,24 +10,18 @@ static const char brief_feeling[] =
"have a %s feeling for a moment, then it passes."; "have a %s feeling for a moment, then it passes.";
static int FDECL(hitmm, (struct monst *, struct monst *, static int FDECL(hitmm, (struct monst *, struct monst *,
struct attack *)); struct attack *, struct obj *, int));
static int FDECL(gazemm, (struct monst *, struct monst *, static int FDECL(gazemm, (struct monst *, struct monst *, struct attack *));
struct attack *)); static int FDECL(gulpmm, (struct monst *, struct monst *, struct attack *));
static int FDECL(gulpmm, (struct monst *, struct monst *, static int FDECL(explmm, (struct monst *, struct monst *, struct attack *));
struct attack *));
static int FDECL(explmm, (struct monst *, struct monst *,
struct attack *));
static int FDECL(mdamagem, (struct monst *, struct monst *, static int FDECL(mdamagem, (struct monst *, struct monst *,
struct attack *)); struct attack *, struct obj *, int));
static void FDECL(mswingsm, (struct monst *, struct monst *, static void FDECL(mswingsm, (struct monst *, struct monst *, struct obj *));
struct obj *));
static void FDECL(noises, (struct monst *, struct attack *)); static void FDECL(noises, (struct monst *, struct attack *));
static void FDECL(pre_mm_attack, (struct monst *, struct monst *)); static void FDECL(pre_mm_attack, (struct monst *, struct monst *));
static void FDECL(missmm, (struct monst *, struct monst *, static void FDECL(missmm, (struct monst *, struct monst *, struct attack *));
struct attack *));
static int FDECL(passivemm, (struct monst *, struct monst *, static int FDECL(passivemm, (struct monst *, struct monst *,
BOOLEAN_P, int)); BOOLEAN_P, int, struct obj *));
static void static void
noises(magr, mattk) noises(magr, mattk)
@@ -292,8 +286,10 @@ register struct monst *magr, *mdef;
strike = 0, /* hit this attack */ strike = 0, /* hit this attack */
attk, /* attack attempted this time */ attk, /* attack attempted this time */
struck = 0, /* hit at least once */ struck = 0, /* hit at least once */
res[NATTK]; /* results of all attacks */ res[NATTK], /* results of all attacks */
dieroll = 0;
struct attack *mattk, alt_attk; struct attack *mattk, alt_attk;
struct obj *mwep;
struct permonst *pa, *pd; struct permonst *pa, *pd;
if (!magr || !mdef) if (!magr || !mdef)
@@ -353,7 +349,7 @@ register struct monst *magr, *mdef;
for (i = 0; i < NATTK; i++) { for (i = 0; i < NATTK; i++) {
res[i] = MM_MISS; res[i] = MM_MISS;
mattk = getmattk(magr, mdef, i, res, &alt_attk); mattk = getmattk(magr, mdef, i, res, &alt_attk);
g.otmp = (struct obj *) 0; mwep = (struct obj *) 0;
attk = 1; attk = 1;
switch (mattk->aatyp) { switch (mattk->aatyp) {
case AT_WEAP: /* "hand to hand" attacks */ case AT_WEAP: /* "hand to hand" attacks */
@@ -372,12 +368,10 @@ register struct monst *magr, *mdef;
return 0; return 0;
} }
possibly_unwield(magr, FALSE); possibly_unwield(magr, FALSE);
g.otmp = MON_WEP(magr); if ((mwep = MON_WEP(magr)) != 0) {
if (g.otmp) {
if (g.vis) if (g.vis)
mswingsm(magr, mdef, g.otmp); mswingsm(magr, mdef, mwep);
tmp += hitval(g.otmp, mdef); tmp += hitval(mwep, mdef);
} }
/*FALLTHRU*/ /*FALLTHRU*/
case AT_CLAW: case AT_CLAW:
@@ -395,22 +389,22 @@ register struct monst *magr, *mdef;
* have a weapon instead. This instinct doesn't work for * have a weapon instead. This instinct doesn't work for
* players, or under conflict or confusion. * players, or under conflict or confusion.
*/ */
if (!magr->mconf && !Conflict && g.otmp && mattk->aatyp != AT_WEAP if (!magr->mconf && !Conflict && mwep && mattk->aatyp != AT_WEAP
&& touch_petrifies(mdef->data)) { && touch_petrifies(mdef->data)) {
strike = 0; strike = 0;
break; break;
} }
g.dieroll = rnd(20 + i); dieroll = rnd(20 + i);
strike = (tmp > g.dieroll); strike = (tmp > dieroll);
/* KMH -- don't accumulate to-hit bonuses */ /* KMH -- don't accumulate to-hit bonuses */
if (g.otmp) if (mwep)
tmp -= hitval(g.otmp, mdef); tmp -= hitval(mwep, mdef);
if (strike) { if (strike) {
res[i] = hitmm(magr, mdef, mattk); res[i] = hitmm(magr, mdef, mattk, mwep, dieroll);
if ((mdef->data == &mons[PM_BLACK_PUDDING] if ((mdef->data == &mons[PM_BLACK_PUDDING]
|| mdef->data == &mons[PM_BROWN_PUDDING]) || mdef->data == &mons[PM_BROWN_PUDDING])
&& (g.otmp && (objects[g.otmp->otyp].oc_material == IRON && (mwep && (objects[mwep->otyp].oc_material == IRON
|| objects[g.otmp->otyp].oc_material == METAL)) || objects[mwep->otyp].oc_material == METAL))
&& mdef->mhp > 1 && !mdef->mcan) { && mdef->mhp > 1 && !mdef->mcan) {
struct monst *mclone; struct monst *mclone;
@@ -432,7 +426,7 @@ register struct monst *magr, *mdef;
case AT_HUGS: /* automatic if prev two attacks succeed */ case AT_HUGS: /* automatic if prev two attacks succeed */
strike = (i >= 2 && res[i - 1] == MM_HIT && res[i - 2] == MM_HIT); strike = (i >= 2 && res[i - 1] == MM_HIT && res[i - 2] == MM_HIT);
if (strike) if (strike)
res[i] = hitmm(magr, mdef, mattk); res[i] = hitmm(magr, mdef, mattk, (struct obj *) 0, 0);
break; break;
@@ -516,7 +510,8 @@ register struct monst *magr, *mdef;
if (attk && !(res[i] & MM_AGR_DIED) if (attk && !(res[i] & MM_AGR_DIED)
&& distmin(magr->mx, magr->my, mdef->mx, mdef->my) <= 1) && distmin(magr->mx, magr->my, mdef->mx, mdef->my) <= 1)
res[i] = passivemm(magr, mdef, strike, res[i] & MM_DEF_DIED); res[i] = passivemm(magr, mdef, strike,
(res[i] & MM_DEF_DIED), mwep);
if (res[i] & MM_DEF_DIED) if (res[i] & MM_DEF_DIED)
return res[i]; return res[i];
@@ -534,14 +529,16 @@ register struct monst *magr, *mdef;
/* Returns the result of mdamagem(). */ /* Returns the result of mdamagem(). */
static int static int
hitmm(magr, mdef, mattk) hitmm(magr, mdef, mattk, mwep, dieroll)
register struct monst *magr, *mdef; register struct monst *magr, *mdef;
struct attack *mattk; struct attack *mattk;
struct obj *mwep;
int dieroll;
{ {
boolean weaponhit = ((mattk->aatyp == AT_WEAP boolean weaponhit = (mattk->aatyp == AT_WEAP
|| (mattk->aatyp == AT_CLAW && g.otmp))), || (mattk->aatyp == AT_CLAW && mwep)),
silverhit = (weaponhit && g.otmp silverhit = (weaponhit && mwep
&& objects[g.otmp->otyp].oc_material == SILVER); && objects[mwep->otyp].oc_material == SILVER);
pre_mm_attack(magr, mdef); pre_mm_attack(magr, mdef);
@@ -554,7 +551,7 @@ struct attack *mattk;
mdef->mcansee ? "smiles at" : "talks to"); mdef->mcansee ? "smiles at" : "talks to");
pline("%s %s %s.", buf, mon_nam(mdef), pline("%s %s %s.", buf, mon_nam(mdef),
compat == 2 ? "engagingly" : "seductively"); compat == 2 ? "engagingly" : "seductively");
} else if (shade_miss(magr, mdef, g.otmp, FALSE, TRUE)) { } else if (shade_miss(magr, mdef, mwep, FALSE, TRUE)) {
return MM_MISS; /* bypass mdamagem() */ return MM_MISS; /* bypass mdamagem() */
} else { } else {
char magr_name[BUFSZ]; char magr_name[BUFSZ];
@@ -606,13 +603,13 @@ struct attack *mattk;
} }
pline("%s %s sears %s!", magr_name, /*s_suffix(magr_name), */ pline("%s %s sears %s!", magr_name, /*s_suffix(magr_name), */
simpleonames(g.otmp), mdef_name); simpleonames(mwep), mdef_name);
} }
} }
} else } else
noises(magr, mattk); noises(magr, mattk);
return mdamagem(magr, mdef, mattk); return mdamagem(magr, mdef, mattk, mwep, dieroll);
} }
/* Returns the same values as mdamagem(). */ /* Returns the same values as mdamagem(). */
@@ -666,7 +663,7 @@ struct attack *mattk;
} }
} }
return mdamagem(magr, mdef, mattk); return mdamagem(magr, mdef, mattk, (struct obj *) 0, 0);
} }
/* return True if magr is allowed to swallow mdef, False otherwise */ /* return True if magr is allowed to swallow mdef, False otherwise */
@@ -757,7 +754,7 @@ register struct attack *mattk;
newsym(ax, ay); /* erase old position */ newsym(ax, ay); /* erase old position */
newsym(dx, dy); /* update new position */ newsym(dx, dy); /* update new position */
status = mdamagem(magr, mdef, mattk); status = mdamagem(magr, mdef, mattk, (struct obj *) 0, 0);
if ((status & (MM_AGR_DIED | MM_DEF_DIED)) if ((status & (MM_AGR_DIED | MM_DEF_DIED))
== (MM_AGR_DIED | MM_DEF_DIED)) { == (MM_AGR_DIED | MM_DEF_DIED)) {
@@ -805,7 +802,7 @@ struct attack *mattk;
else else
noises(magr, mattk); noises(magr, mattk);
result = mdamagem(magr, mdef, mattk); result = mdamagem(magr, mdef, mattk, (struct obj *) 0, 0);
/* Kill off aggressor if it didn't die. */ /* Kill off aggressor if it didn't die. */
if (!(result & MM_AGR_DIED)) { if (!(result & MM_AGR_DIED)) {
@@ -831,9 +828,11 @@ struct attack *mattk;
* See comment at top of mattackm(), for return values. * See comment at top of mattackm(), for return values.
*/ */
int int
mdamagem(magr, mdef, mattk) mdamagem(magr, mdef, mattk, mwep, dieroll)
register struct monst *magr, *mdef; struct monst *magr, *mdef;
register struct attack *mattk; struct attack *mattk;
struct obj *mwep;
int dieroll;
{ {
struct obj *obj; struct obj *obj;
char buf[BUFSZ]; char buf[BUFSZ];
@@ -850,7 +849,7 @@ register struct attack *mattk;
wornitems = magr->misc_worn_check; wornitems = magr->misc_worn_check;
/* wielded weapon gives same protection as gloves here */ /* wielded weapon gives same protection as gloves here */
if (g.otmp != 0) if (mwep)
wornitems |= W_ARMG; wornitems |= W_ARMG;
if (protector == 0L if (protector == 0L
@@ -896,7 +895,7 @@ register struct attack *mattk;
verbalize("Burrrrp!"); verbalize("Burrrrp!");
tmp = mdef->mhp; tmp = mdef->mhp;
/* Use up amulet of life saving */ /* Use up amulet of life saving */
if (!!(obj = mlifesaver(mdef))) if ((obj = mlifesaver(mdef)) != 0)
m_useup(mdef, obj); m_useup(mdef, obj);
/* Is a corpse for nutrition possible? It may kill magr */ /* Is a corpse for nutrition possible? It may kill magr */
@@ -943,35 +942,36 @@ register struct attack *mattk;
case AD_HEAL: case AD_HEAL:
case AD_PHYS: case AD_PHYS:
physical: physical:
obj = (mattk->aatyp == AT_WEAP || mattk->aatyp == AT_CLAW) ? g.otmp : 0; if (mattk->aatyp != AT_WEAP && mattk->aatyp != AT_CLAW)
if (shade_miss(magr, mdef, obj, FALSE, TRUE)) { mwep = 0;
if (shade_miss(magr, mdef, mwep, FALSE, TRUE)) {
tmp = 0; tmp = 0;
} else if (mattk->aatyp == AT_KICK && thick_skinned(pd)) { } else if (mattk->aatyp == AT_KICK && thick_skinned(pd)) {
/* [no 'kicking boots' check needed; monsters with kick attacks
can't wear boots and monsters that wear boots don't kick] */
tmp = 0; tmp = 0;
} else if (mattk->aatyp == AT_WEAP } else if (mwep) { /* non-Null 'mwep' implies AT_WEAP || AT_CLAW */
|| (mattk->aatyp == AT_CLAW && g.otmp)) { struct obj *marmg;
if (g.otmp) {
struct obj *marmg;
if (g.otmp->otyp == CORPSE if (mwep->otyp == CORPSE
&& touch_petrifies(&mons[g.otmp->corpsenm])) && touch_petrifies(&mons[mwep->corpsenm]))
goto do_stone; goto do_stone;
tmp += dmgval(g.otmp, mdef); tmp += dmgval(mwep, mdef);
if ((marmg = which_armor(magr, W_ARMG)) != 0 if ((marmg = which_armor(magr, W_ARMG)) != 0
&& marmg->otyp == GAUNTLETS_OF_POWER) && marmg->otyp == GAUNTLETS_OF_POWER)
tmp += rn1(4, 3); /* 3..6 */ tmp += rn1(4, 3); /* 3..6 */
if (tmp < 1) /* is this necessary? mhitu.c has it... */ if (tmp < 1) /* is this necessary? mhitu.c has it... */
tmp = 1; tmp = 1;
if (g.otmp->oartifact) { if (mwep->oartifact) {
(void) artifact_hit(magr, mdef, g.otmp, &tmp, g.dieroll); (void) artifact_hit(magr, mdef, mwep, &tmp, dieroll);
if (DEADMONSTER(mdef)) if (DEADMONSTER(mdef))
return (MM_DEF_DIED return (MM_DEF_DIED
| (grow_up(magr, mdef) ? 0 : MM_AGR_DIED)); | (grow_up(magr, mdef) ? 0 : MM_AGR_DIED));
}
if (tmp)
rustm(mdef, g.otmp);
} }
if (tmp)
rustm(mdef, mwep);
} else if (pa == &mons[PM_PURPLE_WORM] && pd == &mons[PM_SHRIEKER]) { } else if (pa == &mons[PM_PURPLE_WORM] && pd == &mons[PM_SHRIEKER]) {
/* hack to enhance mm_aggression(); we don't want purple /* hack to enhance mm_aggression(); we don't want purple
worm's bite attack to kill a shrieker because then it worm's bite attack to kill a shrieker because then it
@@ -1304,25 +1304,24 @@ register struct attack *mattk;
Strcpy(mdefnambuf, Strcpy(mdefnambuf,
x_monnam(mdef, ARTICLE_THE, (char *) 0, 0, FALSE)); x_monnam(mdef, ARTICLE_THE, (char *) 0, 0, FALSE));
g.otmp = obj; if (u.usteed == mdef && obj == which_armor(mdef, W_SADDLE))
if (u.usteed == mdef && g.otmp == which_armor(mdef, W_SADDLE))
/* "You can no longer ride <steed>." */ /* "You can no longer ride <steed>." */
dismount_steed(DISMOUNT_POLY); dismount_steed(DISMOUNT_POLY);
obj_extract_self(g.otmp); obj_extract_self(obj);
if (g.otmp->owornmask) { if (obj->owornmask) {
mdef->misc_worn_check &= ~g.otmp->owornmask; mdef->misc_worn_check &= ~obj->owornmask;
if (g.otmp->owornmask & W_WEP) if (obj->owornmask & W_WEP)
mwepgone(mdef); mwepgone(mdef);
g.otmp->owornmask = 0L; obj->owornmask = 0L;
update_mon_intrinsics(mdef, g.otmp, FALSE, FALSE); update_mon_intrinsics(mdef, obj, FALSE, FALSE);
/* give monster a chance to wear other equipment on its next /* give monster a chance to wear other equipment on its next
move instead of waiting until it picks something up */ move instead of waiting until it picks something up */
mdef->misc_worn_check |= I_SPECIAL; mdef->misc_worn_check |= I_SPECIAL;
} }
/* add_to_minv() might free otmp [if it merges] */ /* add_to_minv() might free 'obj' [if it merges] */
if (g.vis) if (g.vis)
Strcpy(onambuf, doname(g.otmp)); Strcpy(onambuf, doname(obj));
(void) add_to_minv(magr, g.otmp); (void) add_to_minv(magr, obj);
if (g.vis && canseemon(mdef)) { if (g.vis && canseemon(mdef)) {
Strcpy(buf, Monnam(magr)); Strcpy(buf, Monnam(magr));
pline("%s steals %s from %s!", buf, onambuf, mdefnambuf); pline("%s steals %s from %s!", buf, onambuf, mdefnambuf);
@@ -1555,10 +1554,11 @@ struct obj *otemp;
* handled above. Returns same values as mattackm. * handled above. Returns same values as mattackm.
*/ */
static int static int
passivemm(magr, mdef, mhit, mdead) passivemm(magr, mdef, mhit, mdead, mwep)
register struct monst *magr, *mdef; register struct monst *magr, *mdef;
boolean mhit; boolean mhit;
int mdead; int mdead;
struct obj *mwep;
{ {
register struct permonst *mddat = mdef->data; register struct permonst *mddat = mdef->data;
register struct permonst *madat = magr->data; register struct permonst *madat = magr->data;
@@ -1599,8 +1599,8 @@ int mdead;
acid_damage(MON_WEP(magr)); acid_damage(MON_WEP(magr));
goto assess_dmg; goto assess_dmg;
case AD_ENCH: /* KMH -- remove enchantment (disenchanter) */ case AD_ENCH: /* KMH -- remove enchantment (disenchanter) */
if (mhit && !mdef->mcan && g.otmp) { if (mhit && !mdef->mcan && mwep) {
(void) drain_item(g.otmp, FALSE); (void) drain_item(mwep, FALSE);
/* No message */ /* No message */
} }
break; break;