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

This commit is contained in:
nhmall
2020-04-11 17:55:09 -04:00
3 changed files with 91 additions and 14 deletions

View File

@@ -1,4 +1,4 @@
$NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.172 $ $NHDT-Date: 1586384219 2020/04/08 22:16:59 $
$NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.175 $ $NHDT-Date: 1586633039 2020/04/11 19:23:59 $
General Fixes and Modified Features
-----------------------------------
@@ -124,6 +124,8 @@ object taking erosion damage might give feedback message when out of view
inventory when out-of-view ice melted]
it's possible to wish for tins of the Riders in wizard mode; eating one is
fatal but if you're life-saved or decline to die, the game crashed
revival via undead turning of corpse carried by hero said "your <mon> corpse
comes alive" even when revived monster was undead
Fixes to 3.7.0-x Problems that Were Exposed Via git Repository

View File

@@ -28,6 +28,7 @@ static struct permonst *FDECL(muse_newcham_mon, (struct monst *));
static int FDECL(mloot_container, (struct monst *mon, struct obj *,
BOOLEAN_P));
static void FDECL(you_aggravate, (struct monst *));
static boolean FDECL(necrophiliac, (struct obj *, BOOLEAN_P));
static void FDECL(mon_consume_unstone, (struct monst *, struct obj *,
BOOLEAN_P, BOOLEAN_P));
static boolean FDECL(cures_stoning, (struct monst *, struct obj *,
@@ -285,7 +286,7 @@ struct obj *otmp;
#define MUSE_UNICORN_HORN 17
#define MUSE_POT_FULL_HEALING 18
#define MUSE_LIZARD_CORPSE 19
#define MUSE_WAN_UNDEAD_TURNING 20
#define MUSE_WAN_UNDEAD_TURNING 20 /* also an offensive item */
/*
#define MUSE_INNATE_TPT 9999
* We cannot use this. Since monsters get unlimited teleportation, if they
@@ -1092,6 +1093,8 @@ struct monst *mtmp;
/*#define MUSE_WAN_TELEPORTATION 15*/
#define MUSE_POT_SLEEPING 16
#define MUSE_SCR_EARTH 17
/*#define MUSE_WAN_UNDEAD_TURNING 20*/ /* also a defensive item so don't
* redefine; nonconsecutive value is ok */
/* Select an offensive item/action for a monster. Returns TRUE iff one is
* found.
@@ -1166,6 +1169,35 @@ struct monst *mtmp;
g.m.has_offense = MUSE_WAN_MAGIC_MISSILE;
}
}
nomore(MUSE_WAN_UNDEAD_TURNING);
if (obj->otyp == WAN_UNDEAD_TURNING && obj->spe > 0
/* not necrophiliac(); unlike deciding whether to pick this
type of wand up, we aren't interested in corpses within
carried containers until they're moved into open inventory;
we don't check whether hero is poly'd into an undead--the
wand's turning effect is too weak to be a useful direct
attack--only whether hero is carrying at least one corpse */
&& carrying(CORPSE)) {
/*
* Hero is carrying one or more corpses but isn't wielding
* a cockatrice corpse (unless being hit by one won't do
* the monster much harm); otherwise we'd be using this wand
* as a defensive item with higher priority.
*
* Might be cockatrice intended as a weapon (or being denied
* to glove-wearing monsters for use as a weapon) or lizard
* intended as a cure or lichen intended as veggy food or
* sacrifice fodder being lugged to an altar. Zapping with
* this will deprive hero of one from each stack although
* they might subsequently be recovered after killing again.
* In the sacrifice fodder case, it could even be to the
* player's advantage (fresher corpse if a new one gets
* dropped; player might not choose to spend a wand charge
* on that when/if hero acquires this wand).
*/
g.m.offensive = obj;
g.m.has_offense = MUSE_WAN_UNDEAD_TURNING;
}
nomore(MUSE_WAN_STRIKING);
if (obj->otyp == WAN_STRIKING && obj->spe > 0) {
g.m.offensive = obj;
@@ -1486,6 +1518,7 @@ struct monst *mtmp;
g.m_using = FALSE;
return (DEADMONSTER(mtmp)) ? 1 : 2;
case MUSE_WAN_TELEPORTATION:
case MUSE_WAN_UNDEAD_TURNING:
case MUSE_WAN_STRIKING:
g.zap_oseen = oseen;
mzapwand(mtmp, otmp, FALSE);
@@ -2222,6 +2255,23 @@ struct monst *mtmp;
return 0;
}
/* check whether hero is carrying a corpse or contained petrifier corpse */
static boolean
necrophiliac(objlist, any_corpse)
struct obj *objlist;
boolean any_corpse;
{
while (objlist) {
if (objlist->otyp == CORPSE
&& (any_corpse || touch_petrifies(&mons[objlist->corpsenm])))
return TRUE;
if (Has_contents(objlist) && necrophiliac(objlist->cobj, FALSE))
return TRUE;
objlist = objlist->nobj;
}
return FALSE;
}
boolean
searches_for_item(mon, obj)
struct monst *mon;
@@ -2258,7 +2308,8 @@ struct obj *obj;
|| typ == WAN_TELEPORTATION || typ == WAN_CREATE_MONSTER)
return TRUE;
if (typ == WAN_UNDEAD_TURNING)
return carrying(CORPSE) || (Upolyd && is_undead(g.youmonst.data));
return (necrophiliac(g.invent, TRUE)
|| (Upolyd && is_undead(g.youmonst.data)));
break;
case POTION_CLASS:
if (typ == POT_HEALING || typ == POT_EXTRA_HEALING

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 zap.c $NHDT-Date: 1580322890 2020/01/29 18:34:50 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.330 $ */
/* NetHack 3.6 zap.c $NHDT-Date: 1586633039 2020/04/11 19:23:59 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.335 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2013. */
/* NetHack may be freely redistributed. See license for details. */
@@ -852,6 +852,7 @@ boolean by_hero;
if (one_of) /* could be simplified to ''corpse->quan = 1L;'' */
corpse->quan--;
pline("%s glows iridescently.", upstart(buf));
iflags.last_msg = PLNMSG_OBJ_GLOWS; /* usually for BUC change */
} else if (shkp) {
/* need some prior description of the corpse since
stolen_value() will refer to the object as "it" */
@@ -957,11 +958,11 @@ struct monst *mon;
struct obj *otmp, *otmp2;
struct monst *mtmp2;
char owner[BUFSZ], corpse[BUFSZ];
boolean youseeit;
int res = 0;
boolean youseeit, different_type, is_u = (mon == &g.youmonst);
int corpsenm, res = 0;
youseeit = (mon == &g.youmonst) ? TRUE : canseemon(mon);
otmp2 = (mon == &g.youmonst) ? g.invent : mon->minvent;
youseeit = is_u ? TRUE : canseemon(mon);
otmp2 = is_u ? g.invent : mon->minvent;
owner[0] = corpse[0] = '\0'; /* lint suppression */
while ((otmp = otmp2) != 0) {
@@ -972,20 +973,43 @@ struct monst *mon;
continue;
/* save the name; the object is liable to go away */
if (youseeit) {
Strcpy(corpse,
corpse_xname(otmp, (const char *) 0, CXN_SINGULAR));
Shk_Your(owner, otmp); /* includes a trailing space */
Strcpy(corpse, corpse_xname(otmp, (const char *) 0, CXN_NORMAL));
/* shk_your/Shk_Your produces a value with a trailing space */
if (otmp->quan > 1L) {
Strcpy(owner, "One of ");
(void) shk_your(eos(owner), otmp);
} else
(void) Shk_Your(owner, otmp);
}
/* for a stack, only one is revived */
/* for a stack, only one is revived; if is_u, revive() calls
useup() which calls update_inventory() but not encumber_msg() */
corpsenm = otmp->corpsenm;
if ((mtmp2 = revive(otmp, !g.context.mon_moving)) != 0) {
++res;
/* might get revived as a zombie rather than corpse's monster */
different_type = (mtmp2->data != &mons[corpsenm]);
if (iflags.last_msg == PLNMSG_OBJ_GLOWS) {
/* when hero zaps undead turning at self (or breaks
non-empty wand), revive() reports "[one of] your <mon>
corpse[s] glows iridescently"; override saved corpse
and owner names to say "It comes alive" [note: we did
earlier setup because corpse gets used up but need to
do the override here after revive() sets 'last_msg'] */
Strcpy(corpse, "It");
owner[0] = '\0';
}
if (youseeit)
pline("%s%s suddenly comes alive!", owner, corpse);
pline("%s%s suddenly %s%s%s!", owner, corpse,
nonliving(mtmp2->data) ? "reanimates" : "comes alive",
different_type ? " as " : "",
different_type ? an(mtmp2->data->mname) : "");
else if (canseemon(mtmp2))
pline("%s suddenly appears!", Amonnam(mtmp2));
}
}
if (is_u && res)
(void) encumber_msg();
return res;
}