Merge branch 'NetHack-3.6.0' into NetHack-3.6.0

This commit is contained in:
Alex Smith
2018-02-20 21:55:31 +00:00
25 changed files with 371 additions and 231 deletions

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 cmd.c $NHDT-Date: 1513130017 2017/12/13 01:53:37 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.277 $ */
/* NetHack 3.6 cmd.c $NHDT-Date: 1518861485 2018/02/17 09:58:05 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.278 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -2767,7 +2767,7 @@ int final;
if (!u.uconduct.food)
enl_msg(You_, "have gone", "went", " without food", "");
/* But beverages are okay */
/* but beverages are okay */
else if (!u.uconduct.unvegan)
you_have_X("followed a strict vegan diet");
else if (!u.uconduct.unvegetarian)
@@ -4246,7 +4246,7 @@ register char *cmd;
} else if (*cmd == ' ' && !flags.rest_on_space) {
bad_command = TRUE; /* skip cmdlist[] loop */
/* handle all other commands */
/* handle all other commands */
} else {
register const struct ext_func_tab *tlist;
int res, NDECL((*func));

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 dig.c $NHDT-Date: 1449269915 2015/12/04 22:58:35 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.103 $ */
/* NetHack 3.6 dig.c $NHDT-Date: 1517913682 2018/02/06 10:41:22 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.108 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -708,8 +708,8 @@ int ttyp;
}
if (mtmp->isshk)
make_angry_shk(mtmp, 0, 0);
migrate_to_level(mtmp, ledger_no(&tolevel), MIGR_RANDOM,
(coord *) 0);
migrate_to_level(mtmp, ledger_no(&tolevel),
MIGR_RANDOM, (coord *) 0);
}
}
}
@@ -842,7 +842,7 @@ coord *cc;
"As you dig, the hole fills with %s!");
return TRUE;
/* the following two are here for the wand of digging */
/* the following two are here for the wand of digging */
} else if (IS_THRONE(lev->typ)) {
pline_The("throne is too hard to break apart.");
@@ -914,9 +914,8 @@ coord *cc;
case 0:
case 1:
You("unearth a corpse.");
if (!!(otmp = mk_tt_object(CORPSE, dig_x, dig_y)))
if ((otmp = mk_tt_object(CORPSE, dig_x, dig_y)) != 0)
otmp->age -= 100; /* this is an *OLD* corpse */
;
break;
case 2:
if (!Blind)
@@ -1069,13 +1068,14 @@ struct obj *obj;
} else if (lev->typ == IRONBARS) {
pline("Clang!");
wake_nearby();
} else if (IS_TREE(lev->typ))
} else if (IS_TREE(lev->typ)) {
You("need an axe to cut down a tree.");
else if (IS_ROCK(lev->typ))
} else if (IS_ROCK(lev->typ)) {
You("need a pick to dig rock.");
else if (!ispick && (sobj_at(STATUE, rx, ry)
|| sobj_at(BOULDER, rx, ry))) {
} else if (!ispick && (sobj_at(STATUE, rx, ry)
|| sobj_at(BOULDER, rx, ry))) {
boolean vibrate = !rn2(3);
pline("Sparks fly as you whack the %s.%s",
sobj_at(STATUE, rx, ry) ? "statue" : "boulder",
vibrate ? " The axe-handle vibrates violently!" : "");
@@ -1087,6 +1087,7 @@ struct obj *obj;
&& (trap->ttyp == PIT || trap->ttyp == SPIKED_PIT)
&& !conjoined_pits(trap, trap_with_u, FALSE)) {
int idx;
for (idx = 0; idx < 8; idx++) {
if (xdir[idx] == u.dx && ydir[idx] == u.dy)
break;
@@ -1094,6 +1095,7 @@ struct obj *obj;
/* idx is valid if < 8 */
if (idx < 8) {
int adjidx = (idx + 4) % 8;
trap_with_u->conjoined |= (1 << idx);
trap->conjoined |= (1 << adjidx);
pline("You clear some debris from between the pits.");
@@ -1102,21 +1104,24 @@ struct obj *obj;
&& (trap_with_u = t_at(u.ux, u.uy))) {
You("swing %s, but the rubble has no place to go.",
yobjnam(obj, (char *) 0));
} else
} else {
You("swing %s through thin air.", yobjnam(obj, (char *) 0));
}
} else {
static const char *const d_action[6] = { "swinging", "digging",
"chipping the statue",
"hitting the boulder",
"chopping at the door",
"cutting the tree" };
did_dig_msg = FALSE;
context.digging.quiet = FALSE;
if (context.digging.pos.x != rx || context.digging.pos.y != ry
|| !on_level(&context.digging.level, &u.uz)
|| context.digging.down) {
if (flags.autodig && dig_target == DIGTYP_ROCK
&& !context.digging.down && context.digging.pos.x == u.ux
&& !context.digging.down
&& context.digging.pos.x == u.ux
&& context.digging.pos.y == u.uy
&& (moves <= context.digging.lastdigtime + 2
&& moves >= context.digging.lastdigtime)) {
@@ -1271,8 +1276,9 @@ register struct monst *mtmp;
newsym(mtmp->mx, mtmp->my);
draft_message(FALSE); /* "You feel a draft." */
return FALSE;
} else if (!IS_ROCK(here->typ) && !IS_TREE(here->typ)) /* no dig */
} else if (!IS_ROCK(here->typ) && !IS_TREE(here->typ)) { /* no dig */
return FALSE;
}
/* Only rock, trees, and walls fall through to this point. */
if ((here->wall_info & W_NONDIGGABLE) != 0) {

View File

@@ -1415,12 +1415,19 @@ register struct obj *obj;
otemp.quan = 1L;
otemp.oextra = (struct oextra *) 0;
if (objects[otemp.otyp].oc_class == POTION_CLASS && otemp.fromsink)
if (objects[otemp.otyp].oc_class == POTION_CLASS && otemp.fromsink) {
/* kludge, meaning it's sink water */
Sprintf(qbuf, "Call a stream of %s fluid:",
OBJ_DESCR(objects[otemp.otyp]));
else
Sprintf(qbuf, "Call %s:", an(xname(&otemp)));
OBJ_DESCR(objects[otemp.otyp]));
} else {
char tmpbuf[BUFSZ], *tmpname = an(xname(&otemp));
if (strlen(tmpname) < (BUFSZ - 1)) {
Strcpy(tmpbuf, tmpname);
tmpbuf[QBUFSZ - 7] = '\0'; /* need room for "Call :"*/
Sprintf(qbuf, "Call %s:", tmpbuf);
}
}
getlin(qbuf, buf);
if (!*buf || *buf == '\033')
return;

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 dokick.c $NHDT-Date: 1446955295 2015/11/08 04:01:35 $ $NHDT-Branch: master $:$NHDT-Revision: 1.104 $ */
/* NetHack 3.6 dokick.c $NHDT-Date: 1517128663 2018/01/28 08:37:43 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.113 $ */
/* Copyright (c) Izchak Miller, Mike Stephenson, Steve Linhart, 1989. */
/* NetHack may be freely redistributed. See license for details. */
@@ -116,7 +116,7 @@ register boolean clumsy;
}
}
(void) passive(mon, TRUE, mon->mhp > 0, AT_KICK, FALSE);
(void) passive(mon, uarmf, TRUE, mon->mhp > 0, AT_KICK, FALSE);
if (mon->mhp <= 0 && !trapkilled)
killed(mon);
@@ -162,7 +162,7 @@ xchar x, y;
&& !is_flyer(mon->data)) {
pline("Floating in the air, you miss wildly!");
exercise(A_DEX, FALSE);
(void) passive(mon, FALSE, 1, AT_KICK, FALSE);
(void) passive(mon, uarmf, FALSE, 1, AT_KICK, FALSE);
return;
}
@@ -213,13 +213,13 @@ xchar x, y;
} else if (tmp > (kickdieroll = rnd(20))) {
You("kick %s.", mon_nam(mon));
sum = damageum(mon, uattk);
(void) passive(mon, (boolean) (sum > 0), (sum != 2), AT_KICK,
FALSE);
(void) passive(mon, uarmf, (boolean) (sum > 0),
(sum != 2), AT_KICK, FALSE);
if (sum == 2)
break; /* Defender died */
} else {
missum(mon, uattk, (tmp + armorpenalty > kickdieroll));
(void) passive(mon, FALSE, 1, AT_KICK, FALSE);
(void) passive(mon, uarmf, FALSE, 1, AT_KICK, FALSE);
}
}
return;
@@ -233,7 +233,7 @@ xchar x, y;
if (martial() && !rn2(2))
goto doit;
Your("clumsy kick does no damage.");
(void) passive(mon, FALSE, 1, AT_KICK, FALSE);
(void) passive(mon, uarmf, FALSE, 1, AT_KICK, FALSE);
return;
}
if (i < j / 10)
@@ -257,7 +257,7 @@ doit:
if (!nohands(mon->data) && !rn2(martial() ? 5 : 3)) {
pline("%s blocks your %skick.", Monnam(mon),
clumsy ? "clumsy " : "");
(void) passive(mon, FALSE, 1, AT_KICK, FALSE);
(void) passive(mon, uarmf, FALSE, 1, AT_KICK, FALSE);
return;
} else {
maybe_mnexto(mon);
@@ -274,7 +274,7 @@ doit:
? "slides"
: "jumps",
clumsy ? "easily" : "nimbly", clumsy ? "clumsy " : "");
(void) passive(mon, FALSE, 1, AT_KICK, FALSE);
(void) passive(mon, uarmf, FALSE, 1, AT_KICK, FALSE);
return;
}
}

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 dungeon.c $NHDT-Date: 1491958681 2017/04/12 00:58:01 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.79 $ */
/* NetHack 3.6 dungeon.c $NHDT-Date: 1517912411 2018/02/06 10:20:11 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.83 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -1220,16 +1220,16 @@ int upflag;
destination instead of its enclosing region.
Note: up vs down doesn't matter in this case
because both specify the same exclusion area. */
place_lregion(dndest.nlx, dndest.nly, dndest.nhx, dndest.nhy, 0, 0, 0,
0, LR_DOWNTELE, (d_level *) 0);
place_lregion(dndest.nlx, dndest.nly, dndest.nhx, dndest.nhy,
0, 0, 0, 0, LR_DOWNTELE, (d_level *) 0);
else if (up)
place_lregion(updest.lx, updest.ly, updest.hx, updest.hy, updest.nlx,
updest.nly, updest.nhx, updest.nhy, LR_UPTELE,
(d_level *) 0);
place_lregion(updest.lx, updest.ly, updest.hx, updest.hy,
updest.nlx, updest.nly, updest.nhx, updest.nhy,
LR_UPTELE, (d_level *) 0);
else
place_lregion(dndest.lx, dndest.ly, dndest.hx, dndest.hy, dndest.nlx,
dndest.nly, dndest.nhx, dndest.nhy, LR_DOWNTELE,
(d_level *) 0);
place_lregion(dndest.lx, dndest.ly, dndest.hx, dndest.hy,
dndest.nlx, dndest.nly, dndest.nhx, dndest.nhy,
LR_DOWNTELE, (d_level *) 0);
}
/* place you on the special staircase */

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 hack.c $NHDT-Date: 1512771130 2017/12/08 22:12:10 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.181 $ */
/* NetHack 3.6 hack.c $NHDT-Date: 1518861490 2018/02/17 09:58:10 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.182 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -1614,9 +1614,9 @@ domove()
newsym(x, y);
glyph = glyph_at(x, y); /* might have just changed */
if (boulder)
if (boulder) {
Strcpy(buf, ansimpleoname(boulder));
else if (Underwater && !is_pool(x, y))
} else if (Underwater && !is_pool(x, y)) {
/* Underwater, targetting non-water; the map just shows blank
because you don't see remembered terrain while underwater;
although the hero can attack an adjacent monster this way,
@@ -1624,21 +1624,20 @@ domove()
Sprintf(buf, (Is_waterlevel(&u.uz) && levl[x][y].typ == AIR)
? "an air bubble"
: "nothing");
else if (solid)
} else if (solid) {
/* glyph might indicate unseen terrain if hero is blind;
unlike searching, this won't reveal what that terrain is
(except for solid rock, where the glyph would otherwise
yield ludicrous "dark part of a room") */
Strcpy(buf,
(levl[x][y].typ == STONE)
? "solid rock"
: glyph_is_cmap(glyph)
Strcpy(buf, (levl[x][y].typ == STONE) ? "solid rock"
: glyph_is_cmap(glyph)
? the(defsyms[glyph_to_cmap(glyph)].explanation)
: (const char *) "an unknown obstacle");
/* note: 'solid' is misleadingly named and catches pools
of water and lava as well as rock and walls */
else
/* note: 'solid' is misleadingly named and catches pools
of water and lava as well as rock and walls */
} else {
Strcpy(buf, "thin air");
}
You("%s%s %s.",
!(boulder || solid) ? "" : !explo ? "harmlessly " : "futilely ",
explo ? "explode at" : "attack", buf);

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 hacklib.c $NHDT-Date: 1496860756 2017/06/07 18:39:16 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.50 $ */
/* NetHack 3.6 hacklib.c $NHDT-Date: 1518922474 2018/02/18 02:54:34 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.54 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* Copyright (c) Robert Patrick Rankin, 1991 */
/* NetHack may be freely redistributed. See license for details. */
@@ -451,7 +451,7 @@ const char *stuff_to_strip, *orig;
char *s = bp;
if (s) {
while (s && *orig && i < (BUFSZ - 1)) {
while (*orig && i < (BUFSZ - 1)) {
if (!index(stuff_to_strip, *orig)) {
*s++ = *orig;
i++;

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 invent.c $NHDT-Date: 1512473628 2017/12/05 11:33:48 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.223 $ */
/* NetHack 3.6 invent.c $NHDT-Date: 1518053384 2018/02/08 01:29:44 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.224 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -2541,22 +2541,26 @@ STATIC_OVL void
dounpaid()
{
winid win;
struct obj *otmp, *marker;
struct obj *otmp, *marker, *contnr;
register char ilet;
char *invlet = flags.inv_order;
int classcount, count, num_so_far;
long cost, totcost;
count = count_unpaid(invent);
otmp = marker = contnr = (struct obj *) 0;
if (count == 1) {
marker = (struct obj *) 0;
otmp = find_unpaid(invent, &marker);
contnr = unknwn_contnr_contents(otmp);
}
if (otmp && !contnr) {
/* 1 item; use pline instead of popup menu */
cost = unpaid_cost(otmp, FALSE);
iflags.suppress_price++; /* suppress "(unpaid)" suffix */
pline1(xprname(otmp, distant_name(otmp, doname),
carried(otmp) ? otmp->invlet : CONTAINED_SYM, TRUE,
cost, 0L));
carried(otmp) ? otmp->invlet : CONTAINED_SYM,
TRUE, cost, 0L));
iflags.suppress_price--;
return;
}

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 mail.c $NHDT-Date: 1464222344 2016/05/26 00:25:44 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.27 $ */
/* NetHack 3.6 mail.c $NHDT-Date: 1519070343 2018/02/19 19:59:03 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.31 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -90,38 +90,44 @@ free_maildata()
void
getmailstatus()
{
char *emailbox;
if ((emailbox = nh_getenv("MAIL")) != 0) {
mailbox = (char *) alloc((unsigned) strlen(emailbox));
Strcpy(mailbox, emailbox);
}
if (!mailbox) {
if (mailbox) {
; /* no need to repeat the setup */
} else if ((mailbox = nh_getenv("MAIL")) != 0) {
mailbox = dupstr(mailbox);
#ifdef MAILPATH
} else {
#ifdef AMS
struct passwd ppasswd;
(void) memcpy(&ppasswd, getpwuid(getuid()), sizeof(struct passwd));
(void) memcpy(&ppasswd, getpwuid(getuid()), sizeof (struct passwd));
if (ppasswd.pw_dir) {
mailbox = (char *) alloc((unsigned) strlen(ppasswd.pw_dir)
+ sizeof(AMS_MAILBOX));
/* note: 'sizeof "LITERAL"' includes +1 for terminating '\0' */
mailbox = (char *) alloc((unsigned) (strlen(ppasswd.pw_dir)
+ sizeof AMS_MAILBOX));
Strcpy(mailbox, ppasswd.pw_dir);
Strcat(mailbox, AMS_MAILBOX);
} else
return;
}
#else
const char *pw_name = getpwuid(getuid())->pw_name;
mailbox = (char *) alloc(sizeof(MAILPATH) + strlen(pw_name));
/* note: 'sizeof "LITERAL"' includes +1 for terminating '\0' */
mailbox = (char *) alloc((unsigned) (strlen(pw_name)
+ sizeof MAILPATH));
Strcpy(mailbox, MAILPATH);
Strcat(mailbox, pw_name);
#endif /* AMS */
#else
return;
#endif
#endif /* MAILPATH */
}
if (stat(mailbox, &omstat)) {
debugpline3("mailbox=%c%s%c",
mailbox ? '\"' : '<',
mailbox ? mailbox : "null",
mailbox ? '\"' : '>');
if (mailbox && stat(mailbox, &omstat)) {
#ifdef PERMANENT_MAILBOX
pline("Cannot get status of MAIL=\"%s\".", mailbox);
mailbox = 0;
free_maildata(); /* set 'mailbox' to Null */
#else
omstat.st_mtime = 0;
#endif
@@ -495,7 +501,7 @@ ckmailstatus()
if (stat(mailbox, &nmstat)) {
#ifdef PERMANENT_MAILBOX
pline("Cannot get status of MAIL=\"%s\" anymore.", mailbox);
mailbox = 0;
free_maildata();
#else
nmstat.st_mtime = 0;
#endif

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 mkmaze.c $NHDT-Date: 1469930897 2016/07/31 02:08:17 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.50 $ */
/* NetHack 3.6 mkmaze.c $NHDT-Date: 1518718417 2018/02/15 18:13:37 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.55 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -287,9 +287,9 @@ d_level *lev;
return;
}
lx = 1;
lx = 1; /* column 0 is not used */
hx = COLNO - 1;
ly = 1;
ly = 0; /* 3.6.0 and earlier erroneously had 1 here */
hy = ROWNO - 1;
}
@@ -305,11 +305,9 @@ d_level *lev;
/* then a deterministic one */
oneshot = TRUE;
for (x = lx; x <= hx; x++)
for (y = ly; y <= hy; y++)
if (put_lregion_here(x, y, nlx, nly, nhx, nhy, rtype, oneshot,
lev))
if (put_lregion_here(x, y, nlx, nly, nhx, nhy, rtype, TRUE, lev))
return;
impossible("Couldn't place lregion type %d!", rtype);

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 mkobj.c $NHDT-Date: 1513298759 2017/12/15 00:45:59 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.129 $ */
/* NetHack 3.6 mkobj.c $NHDT-Date: 1518053380 2018/02/08 01:29:40 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.130 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -579,6 +579,23 @@ struct obj *otmp;
}
}
/* is 'obj' inside a container whose contents aren't known?
if so, return the outermost container meeting that criterium */
struct obj *
unknwn_contnr_contents(obj)
struct obj *obj;
{
struct obj *result = 0, *parent;
while (obj->where == OBJ_CONTAINED) {
parent = obj->ocontainer;
if (!parent->cknown)
result = parent;
obj = parent;
}
return result;
}
/*
* Create a dummy duplicate to put on shop bill. The duplicate exists
* only in the billobjs chain. This function is used when a shop object

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 monmove.c $NHDT-Date: 1512808567 2017/12/09 08:36:07 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.95 $ */
/* NetHack 3.6 monmove.c $NHDT-Date: 1517877380 2018/02/06 00:36:20 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.96 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -135,11 +135,19 @@ int x, y;
struct monst *mtmp;
{
/* creatures who are directly resistant to magical scaring:
* Rodney, lawful minions, angels, the Riders */
* Rodney, lawful minions, Angels, the Riders, shopkeepers
* inside their own shop, priests inside their own temple */
if (mtmp->iswiz || is_lminion(mtmp) || mtmp->data == &mons[PM_ANGEL]
|| is_rider(mtmp->data))
|| is_rider(mtmp->data)
|| (mtmp->isshk && inhishop(mtmp))
|| (mtmp->ispriest && inhistemple(mtmp)))
return FALSE;
/* <0,0> is used by musical scaring to check for the above;
* it doesn't care about scrolls or engravings or dungeon branch */
if (x == 0 && y == 0)
return TRUE;
/* should this still be true for defiled/molochian altars? */
if (IS_ALTAR(levl[x][y].typ)
&& (mtmp->data->mlet == S_VAMPIRE || is_vampshifter(mtmp)))
@@ -152,8 +160,9 @@ struct monst *mtmp;
/*
* Creatures who don't (or can't) fear a written Elbereth:
* all the above plus shopkeepers, guards, blind or
* peaceful monsters, humans, and minotaurs.
* all the above plus shopkeepers (even if poly'd into non-human),
* vault guards (also even if poly'd), blind or peaceful monsters,
* humans and elves, and minotaurs.
*
* If the player isn't actually on the square OR the player's image
* isn't displaced to the square, no protection is being granted.

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 music.c $NHDT-Date: 1514504228 2017/12/28 23:37:08 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.46 $ */
/* NetHack 3.6 music.c $NHDT-Date: 1517877381 2018/02/06 00:36:21 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.47 $ */
/* Copyright (c) 1989 by Jean-Christophe Collet */
/* NetHack may be freely redistributed. See license for details. */
@@ -76,7 +76,9 @@ int distance;
&& (mtmp->mstrategy & STRAT_WAITMASK) != 0)
mtmp->mstrategy &= ~STRAT_WAITMASK;
else if (distm < distance / 3
&& !resist(mtmp, TOOL_CLASS, 0, NOTELL))
&& !resist(mtmp, TOOL_CLASS, 0, NOTELL)
/* some monsters are immune */
&& onscary(0, 0, mtmp))
monflee(mtmp, 0, FALSE, TRUE);
}
}

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 uhitm.c $NHDT-Date: 1513297347 2017/12/15 00:22:27 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.172 $ */
/* NetHack 3.6 uhitm.c $NHDT-Date: 1517128664 2018/01/28 08:37:44 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.173 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -392,11 +392,10 @@ register struct monst *mtmp;
unweapon = FALSE;
if (flags.verbose) {
if (uwep)
You("begin bashing monsters with %s.",
yobjnam(uwep, (char *) 0));
You("begin bashing monsters with %s.", yname(uwep));
else if (!cantwield(youmonst.data))
You("begin %sing monsters with your %s %s.",
Role_if(PM_MONK) ? "strik" : "bash",
You("begin %s monsters with your %s %s.",
ing_suffix(Role_if(PM_MONK) ? "strike" : "bash"),
uarmg ? "gloved" : "bare", /* Del Lamb */
makeplural(body_part(HAND)));
}
@@ -541,7 +540,7 @@ struct attack *uattk;
mhit = (tmp > dieroll);
result = known_hitum(mtmp, uwep, &mhit, tmp, armorpenalty,
uattk, dieroll);
(void) passive(mtmp, mhit, DEADMONSTER(mtmp), AT_WEAP, !uwep);
(void) passive(mtmp, uwep, mhit, DEADMONSTER(mtmp), AT_WEAP, !uwep);
if (mon == mtmp)
malive = result;
}
@@ -570,6 +569,10 @@ struct attack *uattk;
if (tmp > dieroll)
exercise(A_DEX, TRUE);
malive = known_hitum(mon, uwep, &mhit, tmp, armorpenalty, uattk, dieroll);
if (wepbefore && !uwep)
wep_was_destroyed = TRUE;
(void) passive(mon, uwep, mhit, malive, AT_WEAP, wep_was_destroyed);
/* second attack for two-weapon combat; won't occur if Stormbringer
overrode confirmation (assumes Stormbringer is primary weapon)
or if the monster was killed or knocked to different location */
@@ -580,10 +583,10 @@ struct attack *uattk;
mhit = (tmp > dieroll || u.uswallow);
malive = known_hitum(mon, uswapwep, &mhit, tmp, armorpenalty, uattk,
dieroll);
/* second passive counter-attack only occurs if second attack hits */
if (mhit)
(void) passive(mon, uswapwep, mhit, malive, AT_WEAP, !uswapwep);
}
if (wepbefore && !uwep)
wep_was_destroyed = TRUE;
(void) passive(mon, mhit, malive, AT_WEAP, wep_was_destroyed);
return malive;
}
@@ -1157,8 +1160,9 @@ int dieroll;
if ((mdat == &mons[PM_BLACK_PUDDING] || mdat == &mons[PM_BROWN_PUDDING])
/* pudding is alive and healthy enough to split */
&& mon->mhp > 1 && !mon->mcan
/* iron weapon using melee or polearm hit [3.6.1: metal weapon too] */
&& obj && obj == uwep
/* iron weapon using melee or polearm hit [3.6.1: metal weapon too;
also allow either or both weapons to cause split when twoweap] */
&& obj && (obj == uwep || (u.twoweap && obj == uswapwep))
&& ((objects[obj->otyp].oc_material == IRON
/* allow scalpel and tsurugi to split puddings */
|| objects[obj->otyp].oc_material == METAL)
@@ -1166,7 +1170,12 @@ int dieroll;
&& !(is_ammo(obj) || is_missile(obj)))
&& hand_to_hand) {
if (clone_mon(mon, 0, 0)) {
pline("%s divides as you hit it!", Monnam(mon));
char withwhat[BUFSZ];
withwhat[0] = '\0';
if (u.twoweap && flags.verbose)
Sprintf(withwhat, " with %s", yname(obj));
pline("%s divides as you hit it%s!", Monnam(mon), withwhat);
hittxt = TRUE;
}
}
@@ -2186,7 +2195,7 @@ hmonas(mon)
register struct monst *mon;
{
struct attack *mattk, alt_attk;
struct obj *weapon;
struct obj *weapon, **originalweapon;
boolean altwep = FALSE, weapon_used = FALSE;
int i, tmp, armorpenalty, sum[NATTK], nsum = 0, dhit = 0, attknum = 0;
int dieroll;
@@ -2194,6 +2203,7 @@ register struct monst *mon;
for (i = 0; i < NATTK; i++) {
sum[i] = 0;
mattk = getmattk(&youmonst, mon, i, sum, &alt_attk);
weapon = 0;
switch (mattk->aatyp) {
case AT_WEAP:
use_weapon:
@@ -2208,20 +2218,36 @@ register struct monst *mon;
* we currently allow the player to get each of these as a weapon
* attack. Is this really desirable?
*/
/* approximate two-weapon mode */
weapon = (altwep && uswapwep) ? uswapwep : uwep;
altwep = !altwep; /* toggle for next attack */
/* approximate two-weapon mode; known_hitum() -> hmon() -> &c
might destroy the weapon argument, but it might also already
be Null, and we want to track that for passive() */
originalweapon = (altwep && uswapwep) ? &uswapwep : &uwep;
if (uswapwep /* set up 'altwep' flag for next iteration */
/* only switch to uswapwep if it's a weapon */
&& (uswapwep->oclass == WEAPON_CLASS || is_weptool(uswapwep))
/* only switch if uswapwep is not bow, arrows, or darts */
&& !(is_launcher(uswapwep) || is_ammo(uswapwep)
|| is_missile(uswapwep))) /* dart, shuriken, boomerang */
altwep = !altwep; /* toggle for next attack */
weapon = *originalweapon;
if (!weapon) /* no need to go beyond no-gloves to rings; not ...*/
originalweapon = &uarmg; /*... subject to erosion damage */
tmp = find_roll_to_hit(mon, AT_WEAP, weapon, &attknum,
&armorpenalty);
dieroll = rnd(20);
dhit = (tmp > dieroll || u.uswallow);
/* Enemy dead, before any special abilities used */
if (!known_hitum(mon, weapon, &dhit, tmp, armorpenalty, mattk,
dieroll)) {
if (!known_hitum(mon, weapon, &dhit, tmp,
armorpenalty, mattk, dieroll)) {
sum[i] = 2;
break;
} else
sum[i] = dhit;
/* originalweapon points to an equipment slot which might
now be empty if the weapon was destroyed during the hit;
passive(,weapon,...) won't call passive_obj() in that case */
weapon = *originalweapon; /* might receive passive erosion */
/* might be a worm that gets cut in half */
if (m_at(u.ux + u.dx, u.uy + u.dy) != mon)
return (boolean) (nsum != 0);
@@ -2366,11 +2392,11 @@ register struct monst *mon;
u.mh = -1; /* dead in the current form */
rehumanize();
}
if (sum[i] == 2)
return (boolean) passive(mon, 1, 0, mattk->aatyp, FALSE);
/* defender dead */
else {
(void) passive(mon, sum[i], 1, mattk->aatyp, FALSE);
if (sum[i] == 2) {
/* defender dead */
return (boolean) passive(mon, weapon, 1, 0, mattk->aatyp, FALSE);
} else {
(void) passive(mon, weapon, sum[i], 1, mattk->aatyp, FALSE);
nsum |= sum[i];
}
if (!Upolyd)
@@ -2384,10 +2410,11 @@ register struct monst *mon;
/* Special (passive) attacks on you by monsters done here.
*/
int
passive(mon, mhit, malive, aatyp, wep_was_destroyed)
register struct monst *mon;
register boolean mhit;
register int malive;
passive(mon, weapon, mhit, malive, aatyp, wep_was_destroyed)
struct monst *mon;
struct obj *weapon; /* uwep or uswapwep or uarmg or uarmf or Null */
boolean mhit;
int malive;
uchar aatyp;
boolean wep_was_destroyed;
{
@@ -2412,14 +2439,14 @@ boolean wep_was_destroyed;
*/
switch (ptr->mattk[i].adtyp) {
case AD_FIRE:
if (mhit && !mon->mcan) {
if (mhit && !mon->mcan && weapon) {
if (aatyp == AT_KICK) {
if (uarmf && !rn2(6))
(void) erode_obj(uarmf, xname(uarmf), ERODE_BURN,
EF_GREASE | EF_VERBOSE);
} else if (aatyp == AT_WEAP || aatyp == AT_CLAW
|| aatyp == AT_MAGC || aatyp == AT_TUCH)
passive_obj(mon, (struct obj *) 0, &(ptr->mattk[i]));
passive_obj(mon, weapon, &(ptr->mattk[i]));
}
break;
case AD_ACID:
@@ -2435,14 +2462,14 @@ boolean wep_was_destroyed;
if (!rn2(30))
erode_armor(&youmonst, ERODE_CORRODE);
}
if (mhit) {
if (mhit && weapon) {
if (aatyp == AT_KICK) {
if (uarmf && !rn2(6))
(void) erode_obj(uarmf, xname(uarmf), ERODE_CORRODE,
EF_GREASE | EF_VERBOSE);
} else if (aatyp == AT_WEAP || aatyp == AT_CLAW
|| aatyp == AT_MAGC || aatyp == AT_TUCH)
passive_obj(mon, (struct obj *) 0, &(ptr->mattk[i]));
passive_obj(mon, weapon, &(ptr->mattk[i]));
}
exercise(A_STR, FALSE);
break;
@@ -2471,25 +2498,25 @@ boolean wep_was_destroyed;
}
break;
case AD_RUST:
if (mhit && !mon->mcan) {
if (mhit && !mon->mcan && weapon) {
if (aatyp == AT_KICK) {
if (uarmf)
(void) erode_obj(uarmf, xname(uarmf), ERODE_RUST,
EF_GREASE | EF_VERBOSE);
} else if (aatyp == AT_WEAP || aatyp == AT_CLAW
|| aatyp == AT_MAGC || aatyp == AT_TUCH)
passive_obj(mon, (struct obj *) 0, &(ptr->mattk[i]));
passive_obj(mon, weapon, &(ptr->mattk[i]));
}
break;
case AD_CORR:
if (mhit && !mon->mcan) {
if (mhit && !mon->mcan && weapon) {
if (aatyp == AT_KICK) {
if (uarmf)
(void) erode_obj(uarmf, xname(uarmf), ERODE_CORRODE,
EF_GREASE | EF_VERBOSE);
} else if (aatyp == AT_WEAP || aatyp == AT_CLAW
|| aatyp == AT_MAGC || aatyp == AT_TUCH)
passive_obj(mon, (struct obj *) 0, &(ptr->mattk[i]));
passive_obj(mon, weapon, &(ptr->mattk[i]));
}
break;
case AD_MAGM:
@@ -2504,17 +2531,14 @@ boolean wep_was_destroyed;
break;
case AD_ENCH: /* KMH -- remove enchantment (disenchanter) */
if (mhit) {
struct obj *obj = (struct obj *) 0;
if (aatyp == AT_KICK) {
obj = uarmf;
if (!obj)
if (!weapon)
break;
} else if (aatyp == AT_BITE || aatyp == AT_BUTT
|| (aatyp >= AT_STNG && aatyp < AT_WEAP)) {
break; /* no object involved */
}
passive_obj(mon, obj, &(ptr->mattk[i]));
passive_obj(mon, weapon, &(ptr->mattk[i]));
}
break;
default:
@@ -2628,6 +2652,7 @@ struct attack *mattk; /* null means we find one internally */
struct permonst *ptr = mon->data;
int i;
/* [this first bit is obsolete; we're not called with Null anymore] */
/* if caller hasn't specified an object, use uwep, uswapwep or uarmg */
if (!obj) {
obj = (u.twoweap && uswapwep && !rn2(2)) ? uswapwep : uwep;

View File

@@ -15,8 +15,6 @@
#include "patchlevel.h"
#endif
#define BETA_INFO ""
STATIC_DCL void FDECL(insert_rtoption, (char *));
/* fill buffer with short version (so caller can avoid including date.h) */
@@ -32,13 +30,26 @@ char *
getversionstring(buf)
char *buf;
{
int details = 0;
Strcpy(buf, VERSION_ID);
#if defined(BETA) && defined(BETA_INFO)
Sprintf(eos(buf), " %s", BETA_INFO);
#endif
#if defined(RUNTIME_PORT_ID)
append_port_id(buf);
details++;
#endif
if (details) {
int c = 0;
char tmpbuf[BUFSZ];
char *tmp = (char *)0;
Sprintf(eos(buf), " (");
#if defined(RUNTIME_PORT_ID)
tmp = get_port_id(tmpbuf);
if (tmp)
Sprintf(eos(buf), "%s%s", c++ ? "," : "", tmp);
#endif
Sprintf(eos(buf), ")");
}
return buf;
}