Merge remote-tracking branch 'origin/NetHack-3.6.0'

This commit is contained in:
keni
2017-12-24 15:28:18 -05:00
24 changed files with 370 additions and 143 deletions

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 allmain.c $NHDT-Date: 1463217182 2016/05/14 09:13:02 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.72 $ */
/* NetHack 3.6 allmain.c $NHDT-Date: 1513130016 2017/12/13 01:53:36 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.81 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -648,6 +648,13 @@ boolean new_game; /* false => restoring an old game */
char buf[BUFSZ];
boolean currentgend = Upolyd ? u.mfemale : flags.female;
/* skip "welcome back" if restoring a doomed character */
if (!new_game && Upolyd && ugenocided()) {
/* death via self-genocide is pending */
pline("You're back, but you still feel %s inside.", udeadinside());
return;
}
/*
* The "welcome back" message always describes your innate form
* even when polymorphed or wearing a helm of opposite alignment.

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 cmd.c $NHDT-Date: 1508880573 2017/10/24 21:29:33 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.275 $ */
/* NetHack 3.6 cmd.c $NHDT-Date: 1513130017 2017/12/13 01:53:37 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.277 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -1887,8 +1887,13 @@ int final;
Strcpy(youtoo, You_);
/* not a traditional status but inherently obvious to player; more
detail given below (attributes section) for magic enlightenment */
if (Upolyd)
you_are("transformed", "");
if (Upolyd) {
Strcpy(buf, "transformed");
if (ugenocided())
Sprintf(eos(buf), " and %s %s inside",
final ? "felt" : "feel", udeadinside());
you_are(buf, "");
}
/* not a trouble, but we want to display riding status before maybe
reporting steed as trapped or hero stuck to cursed saddle */
if (Riding) {

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 do_wear.c $NHDT-Date: 1496959478 2017/06/08 22:04:38 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.98 $ */
/* NetHack 3.6 do_wear.c $NHDT-Date: 1514072526 2017/12/23 23:42:06 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.100 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -1617,6 +1617,14 @@ boolean noisy;
int err = 0;
const char *which;
/* this is the same check as for 'W' (dowear), but different message,
in case we get here via 'P' (doputon) */
if (verysmall(youmonst.data) || nohands(youmonst.data)) {
if (noisy)
You("can't wear any armor in your current form.");
return 0;
}
which = is_cloak(otmp)
? c_cloak
: is_shirt(otmp)
@@ -1964,7 +1972,7 @@ dowear()
/* cantweararm() checks for suits of armor, not what we want here;
verysmall() or nohands() checks for shields, gloves, etc... */
if ((verysmall(youmonst.data) || nohands(youmonst.data))) {
if (verysmall(youmonst.data) || nohands(youmonst.data)) {
pline("Don't even bother.");
return 0;
}

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 end.c $NHDT-Date: 1495232357 2017/05/19 22:19:17 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.131 $ */
/* NetHack 3.6 end.c $NHDT-Date: 1512803167 2017/12/09 07:06:07 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.137 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -1142,11 +1142,6 @@ int how;
else if (how == TURNED_SLIME)
u.ugrave_arise = PM_GREEN_SLIME;
/* if pets will contribute to score, populate mydogs list now
(bones creation isn't a factor, but pline() messaging is) */
if (how == ESCAPED || how == ASCENDED)
keepdogs(TRUE);
if (how == QUIT) {
killer.format = NO_KILLER_PREFIX;
if (u.uhp < 1) {
@@ -1194,6 +1189,13 @@ int how;
dump_everything(how, endtime);
}
/* if pets will contribute to score, populate mydogs list now
(bones creation isn't a factor, but pline() messaging is; used to
be done ever sooner, but we need it to come after dump_everything()
so that any accompanying pets are still on the map during dump) */
if (how == ESCAPED || how == ASCENDED)
keepdogs(TRUE);
/* finish_paybill should be called after disclosure but before bones */
if (bones_ok && taken)
finish_paybill();

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 explode.c $NHDT-Date: 1511658058 2017/11/26 01:00:58 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.54 $ */
/* NetHack 3.6 explode.c $NHDT-Date: 1513297345 2017/12/15 00:22:25 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.55 $ */
/* Copyright (C) 1990 by Ken Arromdee */
/* NetHack may be freely redistributed. See license for details. */
@@ -443,8 +443,12 @@ int expltype;
mtmp->mhp -= (idamres + idamnonres);
}
if (mtmp->mhp <= 0) {
int xkflg = ((adtyp == AD_FIRE
&& completelyburns(mtmp->data))
? XKILL_NOCORPSE : 0);
if (!context.mon_moving) {
killed(mtmp);
xkilled(mtmp, XKILL_GIVEMSG | xkflg);
} else if (mdef && mtmp == mdef) {
/* 'mdef' killed self trying to cure being turned
* into slime due to some action by the player.
@@ -456,11 +460,15 @@ int expltype;
*/
if (cansee(mtmp->mx, mtmp->my) || canspotmon(mtmp))
pline("%s is %s!", Monnam(mtmp),
nonliving(mtmp->data) ? "destroyed"
: "killed");
xkilled(mtmp, XKILL_NOMSG | XKILL_NOCONDUCT);
} else
xkflg ? "burned completely"
: nonliving(mtmp->data) ? "destroyed"
: "killed");
xkilled(mtmp, XKILL_NOMSG | XKILL_NOCONDUCT | xkflg);
} else {
if (xkflg)
adtyp = AD_RBRE; /* no corpse */
monkilled(mtmp, "", (int) adtyp);
}
} else if (!context.mon_moving) {
/* all affected monsters, even if mdef is set */
setmangry(mtmp, TRUE);

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 hack.c $NHDT-Date: 1508549436 2017/10/21 01:30:36 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.180 $ */
/* NetHack 3.6 hack.c $NHDT-Date: 1512771130 2017/12/08 22:12:10 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.181 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -1720,26 +1720,38 @@ domove()
yelp(mtmp);
}
}
/* seemimic/newsym should be done before moving hero, otherwise
the display code will draw the hero here before we possibly
cancel the swap below (we can ignore steed mx,my here) */
u.ux = u.ux0, u.uy = u.uy0;
mtmp->mundetected = 0;
if (mtmp->m_ap_type)
seemimic(mtmp);
else if (!mtmp->mtame)
newsym(mtmp->mx, mtmp->my);
u.ux = mtmp->mx, u.uy = mtmp->my; /* resume swapping positions */
if (mtmp->mtrapped && (trap = t_at(mtmp->mx, mtmp->my)) != 0
&& (trap->ttyp == PIT || trap->ttyp == SPIKED_PIT)
&& sobj_at(BOULDER, trap->tx, trap->ty)) {
/* can't swap places with pet pinned in a pit by a boulder */
u.ux = u.ux0, u.uy = u.uy0; /* didn't move after all */
if (u.usteed)
u.usteed->mx = u.ux, u.usteed->my = u.uy;
} else if (u.ux0 != x && u.uy0 != y && NODIAG(mtmp->data - mons)) {
/* can't swap places when pet can't move to your spot */
u.ux = u.ux0, u.uy = u.uy0;
if (u.usteed)
u.usteed->mx = u.ux, u.usteed->my = u.uy;
You("stop. %s can't move diagonally.", upstart(y_monnam(mtmp)));
} else if (u.ux0 != x && u.uy0 != y && bad_rock(mtmp->data, x, u.uy0)
&& bad_rock(mtmp->data, u.ux0, y)
&& (bigmonst(mtmp->data) || (curr_mon_load(mtmp) > 600))) {
/* can't swap places when pet won't fit thru the opening */
u.ux = u.ux0, u.uy = u.uy0; /* didn't move after all */
if (u.usteed)
u.usteed->mx = u.ux, u.usteed->my = u.uy;
You("stop. %s won't fit through.", upstart(y_monnam(mtmp)));
} else {
char pnambuf[BUFSZ];
@@ -1836,7 +1848,8 @@ domove()
if (Punished) /* put back ball and chain */
move_bc(0, bc_control, ballx, bally, chainx, chainy);
spoteffects(TRUE);
if (u.umoved)
spoteffects(TRUE);
/* delay next move because of ball dragging */
/* must come after we finished picking up, in spoteffects() */

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 invent.c $NHDT-Date: 1512096431 2017/12/01 02:47:11 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.222 $ */
/* NetHack 3.6 invent.c $NHDT-Date: 1512473628 2017/12/05 11:33:48 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.223 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -1472,9 +1472,6 @@ redo_menu:
else if (otmp->otyp == LOADSTONE && otmp->cursed)
/* kludge for canletgo()'s can't-drop-this message */
otmp->corpsenm = (int) cnt;
} else if (!strcmp(word, "adjust")) {
/* specifying stack's full count means something to #adjust */
otmp->nomerge = 1;
}
}
return otmp;
@@ -3539,10 +3536,18 @@ reassign()
* then a 'to' slot for its destination. Open slots and those
* filled by compatible stacks are listed as likely candidates
* but user can pick any inventory letter (including 'from').
* All compatible items found are gathered into the 'from'
* stack as it is moved. If the 'to' slot isn't empty and
* doesn't merge, then its stack is swapped to the 'from' slot.
*
* to == from, 'from' has a name
* All compatible items (same name or no name) are gathered
* into the 'from' stack. No count is allowed.
* to == from, 'from' does not have a name
* All compatible items without a name are gathered into the
* 'from' stack. No count is allowed. Compatible stacks with
* names are left as-is.
* to != from, no count
* Move 'from' to 'to'. If 'to' is not empty, merge 'from'
* into it if possible, otherwise swap it with the 'from' slot.
* to != from, count given
* If the user specifies a count when choosing the 'from' slot,
* and that count is less than the full size of the stack,
* then the stack will be split. The 'count' portion is moved
@@ -3552,10 +3557,19 @@ reassign()
* will be moved to an open slot; if there isn't any open slot
* available, the adjustment attempt fails.
*
* Splitting has one special case: if 'to' slot is non-empty
* and is compatible with 'from' in all respects except for
* user-assigned names, the 'count' portion being moved is
* effectively renamed so that it will merge with 'to' stack.
* To minimize merging for 'from == to', unnamed stacks will
* merge with named 'from' but named ones won't merge with
* unnamed 'from'. Otherwise attempting to collect all unnamed
* stacks would lump the first compatible named stack with them
* and give them its name.
*
* To maximize merging for 'from != to', compatible stacks will
* merge when either lacks a name (or they already have the same
* name). When no count is given and one stack has a name and
* the other doesn't, the merged result will have that name.
* However, when splitting results in a merger, the name of the
* destination overrides that of the source, even if destination
* is unnamed and source is named.
*/
int
doorganize() /* inventory organizer by Del Lamb */
@@ -3569,8 +3583,9 @@ doorganize() /* inventory organizer by Del Lamb */
char lets[1 + 52 + 1 + 1]; /* room for '$a-zA-Z#\0' */
char qbuf[QBUFSZ];
char allowall[4]; /* { ALLOW_COUNT, ALL_CLASSES, 0, 0 } */
char *objname, *otmpname;
const char *adj_type;
boolean ever_mind = FALSE, dont_collect = FALSE;
boolean ever_mind = FALSE, collect;
if (!invent) {
You("aren't carrying anything to adjust.");
@@ -3602,19 +3617,12 @@ doorganize() /* inventory organizer by Del Lamb */
/* figure out whether user gave a split count to getobj() */
splitting = bumped = 0;
if (obj->nomerge) {
/* player specified full count; no split occurred and we'll
avoid collecting compatible stacks when moving this one */
obj->nomerge = 0;
dont_collect = TRUE;
} else {
for (otmp = invent; otmp; otmp = otmp->nobj)
if (otmp->nobj == obj) { /* knowledge of splitobj() operation */
if (otmp->invlet == obj->invlet)
splitting = otmp;
break;
}
}
for (otmp = invent; otmp; otmp = otmp->nobj)
if (otmp->nobj == obj) { /* knowledge of splitobj() operation */
if (otmp->invlet == obj->invlet)
splitting = otmp;
break;
}
/* initialize the list with all lower and upper case letters */
lets[GOLD_INDX] = (obj->oclass == COIN_CLASS) ? GOLD_SYM : ' ';
@@ -3668,7 +3676,7 @@ doorganize() /* inventory organizer by Del Lamb */
/* adjusting to same slot is meaningful since all
compatible stacks get collected along the way,
but splitting to same slot is not */
|| ((splitting || dont_collect) && let == obj->invlet)) {
|| (splitting && let == obj->invlet)) {
noadjust:
if (splitting)
(void) merged(&splitting, &obj);
@@ -3691,8 +3699,9 @@ doorganize() /* inventory organizer by Del Lamb */
pline("Select an inventory slot letter."); /* else try again */
}
collect = (let == obj->invlet);
/* change the inventory and print the resulting item */
adj_type = !splitting ? "Moving:" : "Splitting:";
adj_type = collect ? "Collecting" : !splitting ? "Moving:" : "Splitting:";
/*
* don't use freeinv/addinv to avoid double-touching artifacts,
@@ -3701,45 +3710,52 @@ doorganize() /* inventory organizer by Del Lamb */
extract_nobj(obj, &invent);
for (otmp = invent; otmp;) {
if (!splitting && !dont_collect) {
if (merged(&otmp, &obj)) {
/* it's tempting to pull this outside the loop, but merged() could
free ONAME(obj) [via obfree()] and replace it with ONAME(otmp) */
objname = has_oname(obj) ? ONAME(obj) : (char *) 0;
if (collect) {
/* Collecting: #adjust an inventory stack into its same slot;
keep it there and merge other compatible stacks into it.
Traditional inventory behavior is to merge unnamed stacks
with compatible named ones; we only want that if it is
the 'from' stack (obj) with a name and candidate (otmp)
without one, not unnamed 'from' with named candidate. */
otmpname = has_oname(otmp) ? ONAME(otmp) : (char *) 0;
if ((!otmpname || (objname && !strcmp(objname, otmpname)))
&& merged(&otmp, &obj)) {
adj_type = "Merging:";
obj = otmp;
otmp = otmp->nobj;
extract_nobj(obj, &invent);
continue; /* otmp has already been updated */
} else if (otmp->invlet == let) {
}
} else if (otmp->invlet == let) {
/* Moving or splitting: don't merge extra compatible stacks.
Found 'otmp' in destination slot; merge if compatible,
otherwise bump whatever is there to an open slot. */
if (!splitting) {
adj_type = "Swapping:";
otmp->invlet = obj->invlet;
}
} else {
/* splitting: don't merge extra compatible stacks;
if destination is compatible, do merge with it,
otherwise bump whatever is there to an open slot */
if (otmp->invlet == let) {
int olth = 0;
if (has_oname(obj))
olth = strlen(ONAME(obj));
/* ugly hack: if these objects aren't going to merge
solely because they have conflicting user-assigned
names, strip off the name of the one being moved */
if (olth && !obj->oartifact && !mergable(otmp, obj)) {
char *holdname = ONAME(obj);
} else {
/* strip 'from' name if it has one */
if (objname && !obj->oartifact)
ONAME(obj) = (char *) 0;
/* restore name iff merging is still not possible */
if (!mergable(otmp, obj)) {
ONAME(obj) = holdname;
holdname = (char *) 0;
} else
free((genericptr_t) holdname);
if (!mergable(otmp, obj)) {
/* won't merge; put 'from' name back */
if (objname)
ONAME(obj) = objname;
} else {
/* will merge; discard 'from' name */
if (objname)
free((genericptr_t) objname), objname = 0;
}
if (merged(&otmp, &obj)) {
adj_type = "Splitting and merging:";
obj = otmp;
extract_nobj(obj, &invent);
} else if (inv_cnt(FALSE) >= 52 && !dont_collect) {
} else if (inv_cnt(FALSE) >= 52) {
(void) merged(&splitting, &obj); /* undo split */
/* "knapsack cannot accommodate any more items" */
Your("pack is too full.");
@@ -3748,9 +3764,9 @@ doorganize() /* inventory organizer by Del Lamb */
bumped = otmp;
extract_nobj(bumped, &invent);
}
break;
} /* found 'to' slot */
} /* splitting */
} /* moving vs splitting */
break; /* not collecting and found 'to' slot */
} /* collect */
otmp = otmp->nobj;
}

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 mhitm.c $NHDT-Date: 1504999944 2017/09/09 23:32:24 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.98 $ */
/* NetHack 3.6 mhitm.c $NHDT-Date: 1513297346 2017/12/15 00:22:26 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.99 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -935,10 +935,10 @@ register struct attack *mattk;
}
if (vis && canseemon(mdef))
pline("%s is %s!", Monnam(mdef), on_fire(pd, mattk));
if (pd == &mons[PM_STRAW_GOLEM] || pd == &mons[PM_PAPER_GOLEM]) {
if (completelyburns(pd)) { /* paper golem or straw golem */
if (vis && canseemon(mdef))
pline("%s burns completely!", Monnam(mdef));
mondied(mdef);
mondead(mdef); /* was mondied() but that dropped paper scrolls */
if (mdef->mhp > 0)
return 0;
else if (mdef->mtame && !vis)

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 mhitu.c $NHDT-Date: 1505001092 2017/09/09 23:51:32 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.147 $ */
/* NetHack 3.6 mhitu.c $NHDT-Date: 1513297347 2017/12/15 00:22:27 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.149 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -1030,9 +1030,8 @@ register struct attack *mattk;
hitmsg(mtmp, mattk);
if (uncancelled) {
pline("You're %s!", on_fire(youmonst.data, mattk));
if (youmonst.data == &mons[PM_STRAW_GOLEM]
|| youmonst.data == &mons[PM_PAPER_GOLEM]) {
You("roast!");
if (completelyburns(youmonst.data)) { /* paper or straw golem */
You("go up in flames!");
/* KMH -- this is okay with unchanging */
rehumanize();
break;
@@ -1629,8 +1628,11 @@ register struct attack *mattk;
dmg = 0;
break;
}
if (u.uhp < 1)
done_in_by(mtmp, DIED);
if ((Upolyd ? u.mh : u.uhp) < 1) {
/* already dead? call rehumanize() or done_in_by() as appropriate */
mdamageu(mtmp, 1);
dmg = 0;
}
/* Negative armor class reduces damage done instead of fully protecting
* against hits.

View File

@@ -1464,6 +1464,12 @@ coord *tm;
case 0:
/* elf corpses are the rarest as they're the most useful */
victim_mnum = PM_ELF;
/* elven adventurers get sleep resistance early; so don't
generate elf corpses on sleeping gas traps unless a)
we're on dlvl 2 (1 is impossible) and b) we pass a coin
flip */
if (kind == SLP_GAS_TRAP && !(lvl <= 2 && rn2(2)))
victim_mnum = PM_HUMAN;
break;
case 1: case 2:
victim_mnum = PM_DWARF;

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 mkobj.c $NHDT-Date: 1501725405 2017/08/03 01:56:45 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.124 $ */
/* NetHack 3.6 mkobj.c $NHDT-Date: 1513298759 2017/12/15 00:45:59 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.129 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -2168,7 +2168,8 @@ static const char NEARDATA /* pline formats for insane_object() */
ofmt0[] = "%s obj %s %s: %s",
ofmt3[] = "%s [not null] %s %s: %s",
/* " held by mon %p (%s)" will be appended, filled by M,mon_nam(M) */
mfmt1[] = "%s obj %s %s (%s)", mfmt2[] = "%s obj %s %s (%s) *not*";
mfmt1[] = "%s obj %s %s (%s)",
mfmt2[] = "%s obj %s %s (%s) *not*";
/* Check all object lists for consistency. */
void
@@ -2177,6 +2178,13 @@ obj_sanity_check()
int x, y;
struct obj *obj;
/*
* TODO:
* Should check whether the obj->bypass and/or obj->nomerge bits
* are set. Those are both used for temporary purposes and should
* be clear between moves.
*/
objlist_sanity(fobj, OBJ_FLOOR, "floor sanity");
/* check that the map's record of floor objects is consistent;
@@ -2186,12 +2194,12 @@ obj_sanity_check()
for (y = 0; y < ROWNO; y++)
for (obj = level.objects[x][y]; obj; obj = obj->nexthere) {
/* <ox,oy> should match <x,y>; <0,*> should always be empty */
if (obj->where != OBJ_FLOOR || x == 0 || obj->ox != x
|| obj->oy != y) {
if (obj->where != OBJ_FLOOR || x == 0
|| obj->ox != x || obj->oy != y) {
char at_fmt[BUFSZ];
Sprintf(at_fmt, "%%s obj@<%d,%d> %%s %%s: %%s@<%d,%d>", x,
y, obj->ox, obj->oy);
Sprintf(at_fmt, "%%s obj@<%d,%d> %%s %%s: %%s@<%d,%d>",
x, y, obj->ox, obj->oy);
insane_object(obj, at_fmt, "location sanity",
(struct monst *) 0);
}
@@ -2219,7 +2227,11 @@ obj_sanity_check()
if (kickedobj)
insane_object(kickedobj, ofmt3, "kickedobj sanity",
(struct monst *) 0);
/* [how about current_wand too?] */
/* current_wand isn't removed from invent while in use, but should
be Null between moves when we're called */
if (current_wand)
insane_object(current_wand, ofmt3, "current_wand sanity",
(struct monst *) 0);
}
/* sanity check for objects on specified list (fobj, &c) */

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 monmove.c $NHDT-Date: 1505265968 2017/09/13 01:26:08 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.93 $ */
/* NetHack 3.6 monmove.c $NHDT-Date: 1512808567 2017/12/09 08:36:07 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.95 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -617,7 +617,8 @@ toofar:
*/
if (!mtmp->mpeaceful || (Conflict && !resist(mtmp, RING_CLASS, 0, 0))) {
if (inrange && !noattacks(mdat) && u.uhp > 0 && !scared && tmp != 3)
if (inrange && !noattacks(mdat)
&& (Upolyd ? u.mh : u.uhp) > 0 && !scared && tmp != 3)
if (mattacku(mtmp))
return 1; /* monster died (e.g. exploded) */

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 polyself.c $NHDT-Date: 1497485548 2017/06/15 00:12:28 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.112 $ */
/* NetHack 3.6 polyself.c $NHDT-Date: 1513298347 2017/12/15 00:39:07 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.116 $ */
/* Copyright (C) 1987, 1988, 1989 by Ken Arromdee */
/* NetHack may be freely redistributed. See license for details. */
@@ -189,12 +189,7 @@ const char *fmt, *arg;
You(fmt, arg);
/* check whether player foolishly genocided self while poly'd */
if ((mvitals[urole.malenum].mvflags & G_GENOD)
|| (urole.femalenum != NON_PM
&& (mvitals[urole.femalenum].mvflags & G_GENOD))
|| (mvitals[urace.malenum].mvflags & G_GENOD)
|| (urace.femalenum != NON_PM
&& (mvitals[urace.femalenum].mvflags & G_GENOD))) {
if (ugenocided()) {
/* intervening activity might have clobbered genocide info */
struct kinfo *kptr = find_delayed_killer(POLYMORPH);
@@ -1015,10 +1010,16 @@ void
rehumanize()
{
/* You can't revert back while unchanging */
if (Unchanging && (u.mh < 1)) {
killer.format = NO_KILLER_PREFIX;
Strcpy(killer.name, "killed while stuck in creature form");
done(DIED);
if (Unchanging) {
if (u.mh < 1) {
killer.format = NO_KILLER_PREFIX;
Strcpy(killer.name, "killed while stuck in creature form");
done(DIED);
} else if (uamul && uamul->otyp == AMULET_OF_UNCHANGING) {
Your("%s %s!", simpleonames(uamul), otense(uamul, "fail"));
uamul->dknown = 1;
makeknown(AMULET_OF_UNCHANGING);
}
}
if (emits_light(youmonst.data))
@@ -1813,4 +1814,31 @@ polysense()
}
}
/* True iff hero's role or race has been genocided */
boolean
ugenocided()
{
return (boolean) ((mvitals[urole.malenum].mvflags & G_GENOD)
|| (urole.femalenum != NON_PM
&& (mvitals[urole.femalenum].mvflags & G_GENOD))
|| (mvitals[urace.malenum].mvflags & G_GENOD)
|| (urace.femalenum != NON_PM
&& (mvitals[urace.femalenum].mvflags & G_GENOD)));
}
/* how hero feels "inside" after self-genocide of role or race */
const char *
udeadinside()
{
/* self-genocide used to always say "you feel dead inside" but that
seems silly when you're polymorphed into something undead;
monkilled() distinguishes between living (killed) and non (destroyed)
for monster death message; we refine the nonliving aspect a bit */
return !nonliving(youmonst.data)
? "dead" /* living, including demons */
: !weirdnonliving(youmonst.data)
? "condemned" /* undead plus manes */
: "empty"; /* golems plus vortices */
}
/*polyself.c*/

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 read.c $NHDT-Date: 1508479721 2017/10/20 06:08:41 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.148 $ */
/* NetHack 3.6 read.c $NHDT-Date: 1513130018 2017/12/13 01:53:38 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.149 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -2088,7 +2088,7 @@ do_class_genocide()
u.uhp = -1;
if (Upolyd) {
if (!feel_dead++)
You_feel("dead inside.");
You_feel("%s inside.", udeadinside());
} else {
if (!feel_dead++)
You("die.");
@@ -2269,7 +2269,7 @@ int how;
/* KMH -- Unchanging prevents rehumanization */
if (Upolyd && ptr != youmonst.data) {
delayed_killer(POLYMORPH, killer.format, killer.name);
You_feel("dead inside.");
You_feel("%s inside.", udeadinside());
} else
done(GENOCIDED);
} else if (ptr == youmonst.data) {

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 sp_lev.c $NHDT-Date: 1508879840 2017/10/24 21:17:20 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.90 $ */
/* NetHack 3.6 sp_lev.c $NHDT-Date: 1513879435 2017/12/21 18:03:55 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.93 $ */
/* Copyright (c) 1989 by Jean-Christophe Collet */
/* NetHack may be freely redistributed. See license for details. */
@@ -4187,8 +4187,8 @@ int dx, dy;
genericptr_t arg;
{
xchar typ = *(xchar *) arg;
xchar x = dx;
xchar y = dy;
xchar x = dx, y = dy;
boolean left_or_right, up_and_down;
if (!IS_DOOR(levl[x][y].typ) && levl[x][y].typ != SDOOR)
levl[x][y].typ = (typ & D_SECRET) ? SDOOR : DOOR;
@@ -4198,12 +4198,35 @@ genericptr_t arg;
typ = D_CLOSED;
}
if (((isok(x-1,y) && IS_DOORJOIN(levl[x-1][y].typ)) || !isok(x-1,y))
|| (isok(x+1,y) && IS_DOORJOIN(levl[x+1][y].typ)) || !isok(x+1,y))
levl[x][y].horizontal = 1;
else
levl[x][y].horizontal = 0;
/* If there's a wall or door on either the left side or right
* side (or both) of this secret door, make it be horizontal.
*
* It is feasible to put SDOOR in a corner, tee, or crosswall
* position, although once the door is found and opened it won't
* make a lot sense (diagonal access required). Still, we try to
* handle that as best as possible. For top or bottom tee, using
* horizontal is the best we can do. For corner or crosswall,
* either horizontal or vertical are just as good as each other;
* we produce horizontal for corners and vertical for crosswalls.
* For left or right tee, using vertical is best.
*
* A secret door with no adjacent walls is also feasible and makes
* even less sense. It will be displayed as a vertical wall while
* hidden and become a vertical door when found.
*/
left_or_right = ((isok(x - 1, y) && (IS_WALL(levl[x - 1][y].typ)
|| IS_DOOR(levl[x - 1][y].typ)
|| levl[x - 1][y].typ == SDOOR))
|| (isok(x + 1, y) && (IS_WALL(levl[x + 1][y].typ)
|| IS_DOOR(levl[x + 1][y].typ)
|| levl[x + 1][y].typ == SDOOR)));
up_and_down = ((isok(x, y - 1) && (IS_WALL(levl[x][y - 1].typ)
|| IS_DOOR(levl[x][y - 1].typ)
|| levl[x][y - 1].typ == SDOOR))
&& (isok(x, y + 1) && (IS_WALL(levl[x][y + 1].typ)
|| IS_DOOR(levl[x][y + 1].typ)
|| levl[x][y + 1].typ == SDOOR)));
levl[x][y].horizontal = (left_or_right && !up_and_down) ? 1 : 0;
levl[x][y].doormask = typ;
SpLev_Map[x][y] = 1;
}

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 uhitm.c $NHDT-Date: 1504999056 2017/09/09 23:17:36 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.167 $ */
/* NetHack 3.6 uhitm.c $NHDT-Date: 1513297347 2017/12/15 00:22:27 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.172 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -1543,9 +1543,13 @@ register struct attack *mattk;
}
if (!Blind)
pline("%s is %s!", Monnam(mdef), on_fire(pd, mattk));
if (pd == &mons[PM_STRAW_GOLEM] || pd == &mons[PM_PAPER_GOLEM]) {
if (completelyburns(pd)) { /* paper golem or straw golem */
if (!Blind)
pline("%s burns completely!", Monnam(mdef));
else
You("smell burning%s.",
(pd == &mons[PM_PAPER_GOLEM]) ? " paper"
: (pd == &mons[PM_STRAW_GOLEM]) ? " straw" : "");
xkilled(mdef, XKILL_NOMSG | XKILL_NOCORPSE);
tmp = 0;
break;

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 zap.c $NHDT-Date: 1505475171 2017/09/15 11:32:51 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.267 $ */
/* NetHack 3.6 zap.c $NHDT-Date: 1513297348 2017/12/15 00:22:28 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.270 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -4022,10 +4022,22 @@ boolean say; /* Announce out of sight hit/miss events if true */
if (tmp == MAGIC_COOKIE) { /* disintegration */
disintegrate_mon(mon, type, fltxt);
} else if (mon->mhp < 1) {
if (type < 0)
if (type < 0) {
/* mon has just been killed by another monster */
monkilled(mon, fltxt, AD_RBRE);
else
killed(mon);
} else {
int xkflags = XKILL_GIVEMSG; /* killed(mon); */
/* killed by hero; we know 'type' isn't negative;
if it's fire, highly flammable monsters leave
no corpse; don't bother reporting that they
"burn completely" -- unnecessary verbosity */
if ((type % 10 == ZT_FIRE)
/* paper golem or straw golem */
&& completelyburns(mon->data))
xkflags |= XKILL_NOCORPSE;
xkilled(mon, xkflags);
}
} else {
if (!otmp) {
/* normal non-fatal hit */