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

This commit is contained in:
Alex Smith
2018-01-06 00:39:17 +00:00
12 changed files with 243 additions and 102 deletions

View File

@@ -490,6 +490,19 @@ if a fiery monster, wand of fire, or fiery explosion burned up a paper golem,
it could still leave blank scrolls
hero poly'd into paper or straw golem reverts to human if burned up even when
Unchanging without any explanation given
hero polymorphed into form which can't wear armor via 'W' (eliciting "don't
even bother") could wear it via 'P'
make multi-shot missiles fired by monsters be less verbose when they miss
can no longer play controlled notes on musical instrument if impaired
if a special level specified the appearance of a mimic and mimics had been
genocided prior to creating the level, whatever random monster took
the mimic's place got its intended appearance
redundant "hit by gush of water" message if poly'd into iron golem or gremlin
a shop object stolen from outside the shop (via grappling hook) would be left
marked as 'unpaid' after the shop robbery took place, resulting in
"unpaid_cost: object wasn't on any bill" when looking at inventory
a shop object stolen from outside the shop could trigger a crash if that shop
had never been entered by the hero
Fixes to Post-3.6.0 Problems that Were Exposed Via git Repository
@@ -735,11 +748,14 @@ Master Key of Thievery always finds door and chest traps if used to lock or
blessed (for non-rogues); player is offered the opportunity to disarm
"Elbereth" must now be the only engraved text on a square to function
"Elbereth" now erodes based on attacks by the player, not monsters scared
option herecmd_menu to make a mouse click on your character pop up
add option herecmd_menu to make a mouse click on your character pop up
a context menu, and extended command #herecmdmenu to do the same
change #adjust's behavior when collecting compatible stacks; that used to
occur for any #adjust which lacked a split count, now it only happens
when 'adjusting' into a stack's own inventory slot
a prayer result which results in uncursing some or all of the hero's items
won't uncurse a worn helm of opposite alignment since that would
facilitate the hero switching to another god by taking it off
Platform- and/or Interface-Specific New Features

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 extern.h $NHDT-Date: 1513130012 2017/12/13 01:53:32 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.621 $ */
/* NetHack 3.6 extern.h $NHDT-Date: 1514769568 2018/01/01 01:19:28 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.622 $ */
/* Copyright (c) Steve Creps, 1988. */
/* NetHack may be freely redistributed. See license for details. */
@@ -1397,6 +1397,7 @@ E void FDECL(restore_cham, (struct monst *));
E boolean FDECL(hideunder, (struct monst *));
E void FDECL(hide_monst, (struct monst *));
E void FDECL(mon_animal_list, (BOOLEAN_P));
E boolean FDECL(validvamp, (struct monst *, int *, int));
E int FDECL(select_newcham_form, (struct monst *));
E void FDECL(mgender_from_permonst, (struct monst *, struct permonst *));
E int FDECL(newcham,

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 flag.h $NHDT-Date: 1508827590 2017/10/24 06:46:30 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.129 $ */
/* NetHack 3.6 flag.h $NHDT-Date: 1514071158 2017/12/23 23:19:18 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.132 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -48,7 +48,42 @@ struct flag {
boolean showexp; /* show experience points */
boolean showscore; /* show score */
boolean silent; /* whether the bell rings or not */
/* The story so far:
* 'sortloot' originally took a True/False value but was changed
* to use a letter instead. 3.6.0 was released without changing its
* type from 'boolean' to 'char'. A compiler was smart enough to
* complain that assigning any of the relevant letters was not 0 or 1
* so not appropriate for boolean (by a configuration which used
* SKIP_BOOLEAN to bypass nethack's 'boolean' and use a C++-compatible
* one). So the type was changed to 'xchar', which is guaranteed to
* match the size of 'boolean' (this guarantee only applies for the
* !SKIP_BOOLEAN config, unfortunately). Since xchar does not match
* actual use, the type was later changed to 'char'. But that would
* break 3.6.0 savefile compatibility for configurations which typedef
* 'schar' to 'short int' instead of to 'char'. (Needed by pre-ANSI
* systems that use unsigned characters without a way to force them
* to be signed.) So, the type has been changed back to 'xchar' for
* 3.6.1.
*
* TODO: change to 'char' (and move out of this block of booleans,
* and get rid of these comments...) once 3.6.0 savefile compatibility
* eventually ends.
*/
#ifndef SKIP_BOOLEAN
/* this is the normal configuration; assigning a character constant
for a normal letter to an 'xchar' variable should always work even
if 'char' is unsigned since character constants are actually 'int'
and letters are within the range where signedness shouldn't matter */
xchar sortloot; /* 'n'=none, 'l'=loot (pickup), 'f'=full ('l'+invent) */
#else
/* with SKIP_BOOLEAN, we have no idea what underlying type is being
used, other than it isn't 'xchar' (although its size might match
that) or a bitfield (because it must be directly addressable);
it's probably either 'char' for compactness or 'int' for access,
but we don't know which and it might be something else anyway;
flip a coin here and guess 'char' for compactness */
char sortloot; /* 'n'=none, 'l'=loot (pickup), 'f'=full ('l'+invent) */
#endif
boolean sortpack; /* sorted inventory */
boolean sparkle; /* show "resisting" special FX (Scott Bigham) */
boolean standout; /* use standout for --More-- */

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 mon.c $NHDT-Date: 1505266804 2017/09/13 01:40:04 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.244 $ */
/* NetHack 3.6 mon.c $NHDT-Date: 1514769571 2018/01/01 01:19:31 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.246 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -23,7 +23,6 @@ STATIC_DCL void FDECL(kill_eggs, (struct obj *));
STATIC_DCL int FDECL(pickvampshape, (struct monst *));
STATIC_DCL boolean FDECL(isspecmon, (struct monst *));
STATIC_DCL boolean FDECL(validspecmon, (struct monst *, int));
STATIC_DCL boolean FDECL(validvamp, (struct monst *, int *, int));
STATIC_DCL struct permonst *FDECL(accept_newcham_form, (int));
STATIC_DCL struct obj *FDECL(make_corpse, (struct monst *, unsigned));
STATIC_DCL void FDECL(m_detach, (struct monst *, struct permonst *));
@@ -3162,7 +3161,7 @@ int mndx;
}
/* prevent wizard mode user from specifying invalid vampshifter shape */
STATIC_OVL boolean
boolean
validvamp(mon, mndx_p, monclass)
struct monst *mon;
int *mndx_p, monclass;

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 mthrowu.c $NHDT-Date: 1446887531 2015/11/07 09:12:11 $ $NHDT-Branch: master $:$NHDT-Revision: 1.63 $ */
/* NetHack 3.6 mthrowu.c $NHDT-Date: 1514152830 2017/12/24 22:00:30 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.73 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -26,6 +26,7 @@ STATIC_OVL NEARDATA const char *breathwep[] = {
};
extern boolean notonhead; /* for long worms */
STATIC_VAR int mesg_given; /* for m_throw()/thitu() 'miss' message */
/* hero is hit by something other than a monster */
int
@@ -37,7 +38,7 @@ const char *name; /* if null, then format `*objp' */
struct obj *obj = objp ? *objp : 0;
const char *onm, *knm;
boolean is_acid;
int kprefix = KILLED_BY_AN;
int kprefix = KILLED_BY_AN, dieroll;
char onmbuf[BUFSZ], knmbuf[BUFSZ];
if (!name) {
@@ -59,10 +60,15 @@ const char *name; /* if null, then format `*objp' */
: an(name);
is_acid = (obj && obj->otyp == ACID_VENOM);
if (u.uac + tlev <= rnd(20)) {
if (Blind || !flags.verbose)
if (u.uac + tlev <= (dieroll = rnd(20))) {
++mesg_given;
if (Blind || !flags.verbose) {
pline("It misses.");
else
} else if (u.uac + tlev <= dieroll - 2) {
if (onm != onmbuf)
Strcpy(onmbuf, onm); /* [modifiable buffer for upstart()] */
pline("%s %s you.", upstart(onmbuf), vtense(onmbuf, "miss"));
} else
You("are almost hit by %s.", onm);
return 0;
} else {
@@ -518,6 +524,7 @@ struct obj *obj; /* missile (or stack providing it) */
(void) drop_throw(singleobj, 0, bhitpos.x, bhitpos.y);
return;
}
mesg_given = 0; /* a 'missile misses' message has not yet been shown */
/* Note: drop_throw may destroy singleobj. Since obj must be destroyed
* early to avoid the dagger bug, anyone who modifies this code should
@@ -646,8 +653,10 @@ struct obj *obj; /* missile (or stack providing it) */
if (!range /* reached end of path */
|| MT_FLIGHTCHECK(FALSE)) {
if (singleobj) { /* hits_bars might have destroyed it */
if (m_shot.n > 1 && (cansee(bhitpos.x, bhitpos.y)
|| (archer && canseemon(archer))))
if (m_shot.n > 1
&& (!mesg_given || bhitpos.x != u.ux || bhitpos.y != u.uy)
&& (cansee(bhitpos.x, bhitpos.y)
|| (archer && canseemon(archer))))
pline("%s misses.", The(mshot_xname(singleobj)));
(void) drop_throw(singleobj, 0, bhitpos.x, bhitpos.y);
}
@@ -659,6 +668,7 @@ struct obj *obj; /* missile (or stack providing it) */
tmp_at(bhitpos.x, bhitpos.y);
delay_output();
tmp_at(DISP_END, 0);
mesg_given = 0; /* reset */
if (blindinc) {
u.ucreamed += blindinc;

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 music.c $NHDT-Date: 1452660194 2016/01/13 04:43:14 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.42 $ */
/* NetHack 3.6 music.c $NHDT-Date: 1514504228 2017/12/28 23:37:08 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.46 $ */
/* Copyright (c) 1989 by Jean-Christophe Collet */
/* NetHack may be freely redistributed. See license for details. */
@@ -6,7 +6,7 @@
* This file contains the different functions designed to manipulate the
* musical instruments and their various effects.
*
* Actually the list of instruments / effects is :
* The list of instruments / effects is :
*
* (wooden) flute may calm snakes if player has enough dexterity
* magic flute may put monsters to sleep: area of effect depends
@@ -450,8 +450,7 @@ STATIC_OVL int
do_improvisation(instr)
struct obj *instr;
{
int damage, do_spec = !Confusion;
#if defined(MAC) || defined(AMIGA) || defined(VPIX_MUSIC) || defined(PCMUSIC)
int damage, mode, do_spec = !(Stunned || Confusion);
struct obj itmp;
itmp = *instr;
@@ -476,23 +475,55 @@ struct obj *instr;
#ifdef PCMUSIC
pc_speaker(&itmp, "C");
#endif
#endif /* MAC || AMIGA || VPIX_MUSIC || PCMUSIC */
if (!do_spec)
#define PLAY_NORMAL 0
#define PLAY_STUNNED 1
#define PLAY_CONFUSED 2
#define PLAY_HALLU 4
mode = PLAY_NORMAL;
if (Stunned)
mode |= PLAY_STUNNED;
if (Confusion)
mode |= PLAY_CONFUSED;
if (Hallucination)
mode |= PLAY_HALLU;
switch (mode) {
case PLAY_NORMAL:
You("start playing %s.", yname(instr));
break;
case PLAY_STUNNED:
You("produce an obnoxious droning sound.");
break;
case PLAY_CONFUSED:
You("produce a raucous noise.");
break;
case PLAY_HALLU:
You("produce a kaleidoscopic display of floating butterfiles.");
break;
/* TODO? give some or all of these combinations their own feedback;
hallucination ones should reference senses other than hearing... */
case PLAY_STUNNED | PLAY_CONFUSED:
case PLAY_STUNNED | PLAY_HALLU:
case PLAY_CONFUSED | PLAY_HALLU:
case PLAY_STUNNED | PLAY_CONFUSED | PLAY_HALLU:
default:
pline("What you produce is quite far from music...");
else
You("start playing %s.", the(xname(instr)));
break;
}
#undef PLAY_NORMAL
#undef PLAY_STUNNED
#undef PLAY_CONFUSED
#undef PLAY_HALLU
switch (instr->otyp) {
switch (itmp.otyp) { /* note: itmp.otyp might differ from instr->otyp */
case MAGIC_FLUTE: /* Make monster fall asleep */
if (do_spec && instr->spe > 0) {
consume_obj_charge(instr, TRUE);
consume_obj_charge(instr, TRUE);
You("produce %s music.", Hallucination ? "piped" : "soft");
put_monsters_to_sleep(u.ulevel * 5);
exercise(A_DEX, TRUE);
break;
} /* else FALLTHRU */
You("produce %s music.", Hallucination ? "piped" : "soft");
put_monsters_to_sleep(u.ulevel * 5);
exercise(A_DEX, TRUE);
break;
case WOODEN_FLUTE: /* May charm snakes */
do_spec &= (rn2(ACURR(A_DEX)) + u.ulevel > 25);
pline("%s.", Tobjnam(instr, do_spec ? "trill" : "toot"));
@@ -502,66 +533,59 @@ struct obj *instr;
break;
case FIRE_HORN: /* Idem wand of fire */
case FROST_HORN: /* Idem wand of cold */
if (do_spec && instr->spe > 0) {
consume_obj_charge(instr, TRUE);
consume_obj_charge(instr, TRUE);
if (!getdir((char *) 0)) {
pline("%s.", Tobjnam(instr, "vibrate"));
break;
} else if (!u.dx && !u.dy && !u.dz) {
if ((damage = zapyourself(instr, TRUE)) != 0) {
char buf[BUFSZ];
Sprintf(buf, "using a magical horn on %sself", uhim());
losehp(damage, buf, KILLED_BY); /* fire or frost damage */
}
} else {
buzz((instr->otyp == FROST_HORN) ? AD_COLD - 1 : AD_FIRE - 1,
rn1(6, 6), u.ux, u.uy, u.dx, u.dy);
}
makeknown(instr->otyp);
if (!getdir((char *) 0)) {
pline("%s.", Tobjnam(instr, "vibrate"));
break;
} /* else FALLTHRU */
} else if (!u.dx && !u.dy && !u.dz) {
if ((damage = zapyourself(instr, TRUE)) != 0) {
char buf[BUFSZ];
Sprintf(buf, "using a magical horn on %sself", uhim());
losehp(damage, buf, KILLED_BY); /* fire or frost damage */
}
} else {
buzz((instr->otyp == FROST_HORN) ? AD_COLD - 1 : AD_FIRE - 1,
rn1(6, 6), u.ux, u.uy, u.dx, u.dy);
}
makeknown(instr->otyp);
break;
case TOOLED_HORN: /* Awaken or scare monsters */
You("produce a frightful, grave sound.");
awaken_monsters(u.ulevel * 30);
exercise(A_WIS, FALSE);
break;
case BUGLE: /* Awaken & attract soldiers */
You("extract a loud noise from %s.", the(xname(instr)));
You("extract a loud noise from %s.", yname(instr));
awaken_soldiers(&youmonst);
exercise(A_WIS, FALSE);
break;
case MAGIC_HARP: /* Charm monsters */
if (do_spec && instr->spe > 0) {
consume_obj_charge(instr, TRUE);
consume_obj_charge(instr, TRUE);
pline("%s very attractive music.", Tobjnam(instr, "produce"));
charm_monsters((u.ulevel - 1) / 3 + 1);
exercise(A_DEX, TRUE);
break;
} /* else FALLTHRU */
pline("%s very attractive music.", Tobjnam(instr, "produce"));
charm_monsters((u.ulevel - 1) / 3 + 1);
exercise(A_DEX, TRUE);
break;
case WOODEN_HARP: /* May calm Nymph */
do_spec &= (rn2(ACURR(A_DEX)) + u.ulevel > 25);
pline("%s %s.", The(xname(instr)),
pline("%s %s.", Yname2(instr),
do_spec ? "produces a lilting melody" : "twangs");
if (do_spec)
calm_nymphs(u.ulevel * 3);
exercise(A_DEX, TRUE);
break;
case DRUM_OF_EARTHQUAKE: /* create several pits */
if (do_spec && instr->spe > 0) {
consume_obj_charge(instr, TRUE);
consume_obj_charge(instr, TRUE);
You("produce a heavy, thunderous rolling!");
pline_The("entire %s is shaking around you!",
generic_lvl_desc());
do_earthquake((u.ulevel - 1) / 3 + 1);
/* shake up monsters in a much larger radius... */
awaken_monsters(ROWNO * COLNO);
makeknown(DRUM_OF_EARTHQUAKE);
break;
} /* else FALLTHRU */
You("produce a heavy, thunderous rolling!");
pline_The("entire %s is shaking around you!", generic_lvl_desc());
do_earthquake((u.ulevel - 1) / 3 + 1);
/* shake up monsters in a much larger radius... */
awaken_monsters(ROWNO * COLNO);
makeknown(DRUM_OF_EARTHQUAKE);
break;
case LEATHER_DRUM: /* Awaken monsters */
You("beat a deafening row!");
awaken_monsters(u.ulevel * 40);
@@ -571,7 +595,7 @@ struct obj *instr;
break;
default:
impossible("What a weird instrument (%d)!", instr->otyp);
break;
return 0;
}
return 2; /* That takes time */
}
@@ -598,11 +622,13 @@ struct obj *instr;
You("are incapable of playing %s.", the(distant_name(instr, xname)));
return 0;
}
if (instr->otyp != LEATHER_DRUM && instr->otyp != DRUM_OF_EARTHQUAKE) {
if (instr->otyp != LEATHER_DRUM && instr->otyp != DRUM_OF_EARTHQUAKE
&& !(Stunned || Confusion || Hallucination)) {
c = ynq("Improvise?");
if (c == 'q')
goto nevermind;
}
if (c == 'n') {
if (u.uevent.uheard_tune == 2)
c = ynq("Play the passtune?");

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 pickup.c $NHDT-Date: 1508549438 2017/10/21 01:30:38 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.192 $ */
/* NetHack 3.6 pickup.c $NHDT-Date: 1515144225 2018/01/05 09:23:45 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.193 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -1495,15 +1495,30 @@ struct obj *
pick_obj(otmp)
struct obj *otmp;
{
struct obj *result;
int ox = otmp->ox, oy = otmp->oy;
boolean robshop = (!u.uswallow && otmp != uball && costly_spot(ox, oy));
obj_extract_self(otmp);
if (!u.uswallow && otmp != uball && costly_spot(otmp->ox, otmp->oy)) {
otmp->nomerge = 1;
result = addinv(otmp);
otmp->nomerge = 0;
newsym(ox, oy);
/* this used to be done before addinv(), but remote_burglary()
calls rob_shop() which calls setpaid() after moving costs of
unpaid items to shop debt; setpaid() calls clear_unpaid() for
lots of object chains, but 'otmp' wasn't on any of those so
remained flagged as an unpaid item in inventory, triggering
impossible() every time inventory was examined... */
if (robshop) {
char saveushops[5], fakeshop[2];
/* addtobill cares about your location rather than the object's;
usually they'll be the same, but not when using telekinesis
(if ever implemented) or a grappling hook */
Strcpy(saveushops, u.ushops);
fakeshop[0] = *in_rooms(otmp->ox, otmp->oy, SHOPBASE);
fakeshop[0] = *in_rooms(ox, oy, SHOPBASE);
fakeshop[1] = '\0';
Strcpy(u.ushops, fakeshop);
/* sets obj->unpaid if necessary */
@@ -1511,10 +1526,9 @@ struct obj *otmp;
Strcpy(u.ushops, saveushops);
/* if you're outside the shop, make shk notice */
if (!index(u.ushops, *fakeshop))
remote_burglary(otmp->ox, otmp->oy);
remote_burglary(ox, oy);
}
newsym(otmp->ox, otmp->oy);
return addinv(otmp); /* might merge it with other objects */
return result;
}
/*

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 pray.c $NHDT-Date: 1450577672 2015/12/20 02:14:32 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.89 $ */
/* NetHack 3.6 pray.c $NHDT-Date: 1514593198 2017/12/30 00:19:58 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.95 $ */
/* Copyright (c) Benson I. Margulies, Mike Stephenson, Steve Linhart, 1989. */
/* NetHack may be freely redistributed. See license for details. */
@@ -265,18 +265,21 @@ worst_cursed_item()
with taking off a ring or putting on a shield */
if (welded(uwep) && (uright || bimanual(uwep))) { /* weapon */
otmp = uwep;
/* gloves come next, due to rings */
/* gloves come next, due to rings */
} else if (uarmg && uarmg->cursed) { /* gloves */
otmp = uarmg;
/* then shield due to two handed weapons and spells */
/* then shield due to two handed weapons and spells */
} else if (uarms && uarms->cursed) { /* shield */
otmp = uarms;
/* then cloak due to body armor */
/* then cloak due to body armor */
} else if (uarmc && uarmc->cursed) { /* cloak */
otmp = uarmc;
} else if (uarm && uarm->cursed) { /* suit */
otmp = uarm;
} else if (uarmh && uarmh->cursed) { /* helmet */
/* if worn helmet of opposite alignment is making you an adherent
of the current god, he/she/it won't uncurse that for you */
} else if (uarmh && uarmh->cursed /* helmet */
&& uarmh->otyp != HELM_OF_OPPOSITE_ALIGNMENT) {
otmp = uarmh;
} else if (uarmf && uarmf->cursed) { /* boots */
otmp = uarmf;
@@ -290,13 +293,13 @@ worst_cursed_item()
otmp = uright;
} else if (ublindf && ublindf->cursed) { /* eyewear */
otmp = ublindf; /* must be non-blinding lenses */
/* if weapon wasn't handled above, do it now */
/* if weapon wasn't handled above, do it now */
} else if (welded(uwep)) { /* weapon */
otmp = uwep;
/* active secondary weapon even though it isn't welded */
/* active secondary weapon even though it isn't welded */
} else if (uswapwep && uswapwep->cursed && u.twoweap) {
otmp = uswapwep;
/* all worn items ought to be handled by now */
/* all worn items ought to be handled by now */
} else {
for (otmp = invent; otmp; otmp = otmp->nobj) {
if (!otmp->cursed)
@@ -336,9 +339,7 @@ int trouble;
break;
case TROUBLE_LAVA:
You("are back on solid ground.");
/* teleport should always succeed, but if not,
* just untrap them.
*/
/* teleport should always succeed, but if not, just untrap them */
if (!safe_teleds(FALSE))
u.utrap = 0;
break;
@@ -386,8 +387,7 @@ int trouble;
if ((otmp = stuck_ring(uleft, RIN_SUSTAIN_ABILITY)) != 0) {
if (otmp == uleft)
what = leftglow;
} else if ((otmp = stuck_ring(uright, RIN_SUSTAIN_ABILITY))
!= 0) {
} else if ((otmp = stuck_ring(uright, RIN_SUSTAIN_ABILITY)) != 0) {
if (otmp == uright)
what = rightglow;
}
@@ -1070,7 +1070,9 @@ aligntyp g_align;
else
You("are surrounded by %s aura.", an(hcolor(NH_LIGHT_BLUE)));
for (otmp = invent; otmp; otmp = otmp->nobj) {
if (otmp->cursed) {
if (otmp->cursed
&& (otmp != uarmh /* [see worst_cursed_item()] */
|| uarmh->otyp != HELM_OF_OPPOSITE_ALIGNMENT)) {
if (!Blind) {
pline("%s %s.", Yobjnam2(otmp, "softly glow"),
hcolor(NH_AMBER));

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 shk.c $NHDT-Date: 1464138042 2016/05/25 01:00:42 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.132 $ */
/* NetHack 3.6 shk.c $NHDT-Date: 1515144230 2018/01/05 09:23:50 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.136 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -2354,6 +2354,12 @@ struct monst *shkp;
return;
}
/* normally bill_p gets set up whenever you enter the shop, but obj
might be going onto the bill because hero just snagged it with
a grappling hook from outside without ever having been inside */
if (!eshkp->bill_p)
eshkp->bill_p = &(eshkp->bill[0]);
bct = eshkp->billct;
bp = &(eshkp->bill_p[bct]);
bp->bo_id = obj->o_id;

View File

@@ -1,4 +1,4 @@
/* 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 $ */
/* NetHack 3.6 sp_lev.c $NHDT-Date: 1514769572 2018/01/01 01:19:32 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.95 $ */
/* Copyright (c) 1989 by Jean-Christophe Collet */
/* NetHack may be freely redistributed. See license for details. */
@@ -1589,11 +1589,14 @@ struct mkroom *croom;
mtmp = christen_monst(mtmp, m->name.str);
/*
* This is currently hardwired for mimics only. It should
* eventually be expanded.
* This doesn't complain if an attempt is made to give a
* non-mimic/non-shapechanger an appearance or to give a
* shapechanger a non-monster shape, it just refuses to comply.
*/
if (m->appear_as.str
&& ((mtmp->data->mlet == S_MIMIC) || mtmp->cham)
&& ((mtmp->data->mlet == S_MIMIC)
/* shapechanger (chameleons, et al, and vampires) */
|| (mtmp->cham >= LOW_PM && m->appear == M_AP_MONSTER))
&& !Protection_from_shape_changers) {
int i;
@@ -1658,7 +1661,29 @@ struct mkroom *croom;
mndx = select_newcham_form(mtmp);
else
mndx = name_to_mon(m->appear_as.str);
if ((mndx != NON_PM) && (&mons[mndx] != mtmp->data)) {
if (mndx == NON_PM || (is_vampshifter(mtmp)
&& !validvamp(mtmp, &mndx, S_HUMAN))) {
impossible("create_monster: invalid %s (\"%s\")",
(mtmp->data->mlet == S_MIMIC)
? "mimic appearance"
: (mtmp->data == &mons[PM_WIZARD_OF_YENDOR])
? "Wizard appearance"
: is_vampshifter(mtmp)
? "vampire shape"
: "chameleon shape",
m->appear_as.str);
} else if (&mons[mndx] == mtmp->data) {
/* explicitly forcing a mimic to appear as itself */
mtmp->m_ap_type = M_AP_NOTHING;
mtmp->mappearance = 0;
} else if (mtmp->data->mlet == S_MIMIC
|| mtmp->data == &mons[PM_WIZARD_OF_YENDOR]) {
/* this is ordinarily only used for Wizard clones
and hasn't been exhaustively tested for mimics */
mtmp->m_ap_type = M_AP_MONSTER;
mtmp->mappearance = mndx;
} else { /* chameleon or vampire */
struct permonst *mdat = &mons[mndx];
struct permonst *olddata = mtmp->data;

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 trap.c $NHDT-Date: 1494107206 2017/05/06 21:46:46 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.278 $ */
/* NetHack 3.6 trap.c $NHDT-Date: 1514855666 2018/01/02 01:14:26 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.284 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -1103,7 +1103,7 @@ unsigned trflags;
if (uarmc)
(void) water_damage(uarmc, cloak_simple_name(uarmc), TRUE);
else if (uarm)
(void) water_damage(uarm, "armor", TRUE);
(void) water_damage(uarm, suit_simple_name(uarm), TRUE);
else if (uarmu)
(void) water_damage(uarmu, "shirt", TRUE);
}
@@ -1112,11 +1112,9 @@ unsigned trflags;
if (u.umonnum == PM_IRON_GOLEM) {
int dam = u.mhmax;
pline("%s you!", A_gush_of_water_hits);
You("are covered with rust!");
losehp(Maybe_Half_Phys(dam), "rusting away", KILLED_BY);
} else if (u.umonnum == PM_GREMLIN && rn2(3)) {
pline("%s you!", A_gush_of_water_hits);
(void) split_mon(&youmonst, (struct monst *) 0);
}
@@ -2292,7 +2290,8 @@ register struct monst *mtmp;
(void) water_damage(target, cloak_simple_name(target),
TRUE);
else if ((target = which_armor(mtmp, W_ARM)) != 0)
(void) water_damage(target, "armor", TRUE);
(void) water_damage(target, suit_simple_name(target),
TRUE);
else if ((target = which_armor(mtmp, W_ARMU)) != 0)
(void) water_damage(target, "shirt", TRUE);
}