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

This commit is contained in:
keni
2018-02-20 10:09:57 -05:00
23 changed files with 341 additions and 215 deletions
+8 -5
View File
@@ -1,10 +1,10 @@
___ _ ___ _
| \ _____ _____| |___ _ __ ___ _ _ | \ _____ _____| |___ _ __ ___ _ _
| |) / -_) V / -_) / _ \ '_ \/ -_) '_| | |) / -_) V / -_) / _ \ '_ \/ -_) '_|
|___/\___|\_/\___|_\___/ .__/\___|_| |___/\___|\_/\___|_\___/ .__/\___|_|
|_| |_|
$NHDT-Date: 1512426817 2017/12/04 22:33:37 $ $NHDT-Date: 1518800857 2018/02/16 17:07:37 $
Welcome to the NetHack Infrastructure Developer's Guide. Welcome to the NetHack Infrastructure Developer's Guide.
@@ -45,12 +45,15 @@ us an email if that's more appropriate).
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
4. git configuration 4. git configuration
NOTE: These instructions assume you are on the default branch ("master"); NOTE: These instructions assume you are on the default branch; this _is_
this _is_ where you want to be for setting things up. This may or may where you want to be for setting things up. This may or may not be
not be the branch you want to use for your changes; see the appropriate the branch you want to use for your changes; see the appropriate
project private documentation for more information (if you are working project private documentation for more information (if you are working
alone we suggest using branch names starting with "LOCAL-"). alone we suggest using branch names starting with "LOCAL-").
NOTE: The following instructions require perl. If you do not have perl on
your system, please install it before proceeding.
A. If you have never set up git on this machine before: A. If you have never set up git on this machine before:
(This assumes you will only be using git for NetHack. If you are going to (This assumes you will only be using git for NetHack. If you are going to
use it for other projects as well, think before you type.) use it for other projects as well, think before you type.)
+4 -1
View File
@@ -1,6 +1,6 @@
#!/usr/bin/perl #!/usr/bin/perl
# nhsub # nhsub
# $NHDT-Date: 1515274284 2018/01/06 21:31:24 $ # $NHDT-Date: 1518800857 2018/02/16 17:07:37 $
# Note: was originally called nhdate; the rename is not reflected in the code. # Note: was originally called nhdate; the rename is not reflected in the code.
@@ -245,6 +245,7 @@ my $count = s/\$$PREFIX-(([A-Za-z][A-Za-z0-9_]*)(: ([^\x24]+))?)\$/&handlevar($2
# XXX had o modifier, why? # XXX had o modifier, why?
return unless($count>0); return unless($count>0);
return if($opt{n}); return if($opt{n});
my $mode = 0777 & (stat($file))[2];
my $ofile = $file . ".nht"; my $ofile = $file . ".nht";
open(TOUT, ">", $ofile) or die "Can't open $ofile"; open(TOUT, ">", $ofile) or die "Can't open $ofile";
@@ -263,6 +264,8 @@ my $count = s/\$$PREFIX-(([A-Za-z][A-Za-z0-9_]*)(: ([^\x24]+))?)\$/&handlevar($2
} }
close TOUT or die "Can't close $ofile"; close TOUT or die "Can't close $ofile";
# Do the right thing for *nix and hope for the best elsewhere:
chmod($mode, $ofile)==1 or warn "Can't set filemode on $ofile";
rename $ofile, $file or die "Can't rename $ofile to $file"; rename $ofile, $file or die "Can't rename $ofile to $file";
} }
+14 -1
View File
@@ -277,7 +277,7 @@ when getpos was picking a location, typing '^' to move to the next known trap
skipped some detected traps if their location was unseen skipped some detected traps if their location was unseen
describe detected door traps and chest traps as trapped door and trapped chest describe detected door traps and chest traps as trapped door and trapped chest
instead of bear trap; bear trap tile is still used on map though instead of bear trap; bear trap tile is still used on map though
thrown potion that killed peaceful monster would cause "the <mon> gets argry" thrown potion that killed peaceful monster would cause "the <mon> gets angry"
after the message about it being killed after the message about it being killed
when poly'd into a hider and engulfed, attempt to hide via #monster was blocked when poly'd into a hider and engulfed, attempt to hide via #monster was blocked
but feedback said "can't hide while held" rather than "while engulfed" but feedback said "can't hide while held" rather than "while engulfed"
@@ -503,6 +503,14 @@ a shop object stolen from outside the shop (via grappling hook) would be left
"unpaid_cost: object wasn't on any bill" when looking at inventory "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 a shop object stolen from outside the shop could trigger a crash if that shop
had never been entered by the hero had never been entered by the hero
shopkeepers in their own shop and priests in their own temple are no longer
frightened by hero standing on scroll of scare monster
the Wizard, Angels and lawful minions, the Riders, shopkeep/priest in own room
are never frightened by tooled horns
'Iu' would reveal unknown container contents if carrying one unpaid item inside
a hero-owned container whose contents weren't known
docall wasn't taking the space allocation needed for the object name + "Call :"
into account in the prompt string
Fixes to Post-3.6.0 Problems that Were Exposed Via git Repository Fixes to Post-3.6.0 Problems that Were Exposed Via git Repository
@@ -571,6 +579,11 @@ the fix for secret doors on special levels always having vertical orientation
the fix intended for "a shop object stolen from outside the shop (via the fix intended for "a shop object stolen from outside the shop (via
grappling hook) would be left marked as 'unpaid'" broke normal pickup, grappling hook) would be left marked as 'unpaid'" broke normal pickup,
preventing any picked up item from merging with compatible stack preventing any picked up item from merging with compatible stack
unix: freeing mailbox data at game end crashed if MAIL came from environment
unix: fix for freeing MAIL introduced a one-byte buffer overrun which could
interfere with malloc/free operation
unix: fix for freeing MAIL also introduced a memory leak whenever new mail
is detected and MAIL comes from the environment
Platform- and/or Interface-Specific Fixes Platform- and/or Interface-Specific Fixes
+1 -1
View File
@@ -11,7 +11,7 @@
* For "UNIX" select BSD, ULTRIX, SYSV, or HPUX in unixconf.h. * For "UNIX" select BSD, ULTRIX, SYSV, or HPUX in unixconf.h.
* A "VMS" option is not needed since the VMS C-compilers * A "VMS" option is not needed since the VMS C-compilers
* provide it (no need to change sec#1, vmsconf.h handles it). * provide it (no need to change sec#1, vmsconf.h handles it).
* MacOSX uses the UNIX configruation, not the old MAC one. * MacOSX uses the UNIX configuration, not the old MAC one.
*/ */
#define UNIX /* delete if no fork(), exec() available */ #define UNIX /* delete if no fork(), exec() available */
+6 -4
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 extern.h $NHDT-Date: 1514769568 2018/01/01 01:19:28 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.622 $ */ /* NetHack 3.6 extern.h $NHDT-Date: 1518053385 2018/02/08 01:29:45 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.625 $ */
/* Copyright (c) Steve Creps, 1988. */ /* Copyright (c) Steve Creps, 1988. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -1287,6 +1287,7 @@ E struct obj *FDECL(splitobj, (struct obj *, long));
E struct obj *FDECL(unsplitobj, (struct obj *)); E struct obj *FDECL(unsplitobj, (struct obj *));
E void NDECL(clear_splitobjs); E void NDECL(clear_splitobjs);
E void FDECL(replace_object, (struct obj *, struct obj *)); E void FDECL(replace_object, (struct obj *, struct obj *));
E struct obj *FDECL(unknwn_contnr_contents, (struct obj *));
E void FDECL(bill_dummy_object, (struct obj *)); E void FDECL(bill_dummy_object, (struct obj *));
E void FDECL(costly_alteration, (struct obj *, int)); E void FDECL(costly_alteration, (struct obj *, int));
E struct obj *FDECL(mksobj, (int, BOOLEAN_P, BOOLEAN_P)); E struct obj *FDECL(mksobj, (int, BOOLEAN_P, BOOLEAN_P));
@@ -2476,13 +2477,14 @@ E void NDECL(u_init);
E void FDECL(erode_armor, (struct monst *, int)); E void FDECL(erode_armor, (struct monst *, int));
E boolean FDECL(attack_checks, (struct monst *, struct obj *)); E boolean FDECL(attack_checks, (struct monst *, struct obj *));
E void FDECL(check_caitiff, (struct monst *)); E void FDECL(check_caitiff, (struct monst *));
E int FDECL(find_roll_to_hit, E int FDECL(find_roll_to_hit, (struct monst *, UCHAR_P, struct obj *,
(struct monst *, UCHAR_P, struct obj *, int *, int *)); int *, int *));
E boolean FDECL(attack, (struct monst *)); E boolean FDECL(attack, (struct monst *));
E boolean FDECL(hmon, (struct monst *, struct obj *, int, int)); E boolean FDECL(hmon, (struct monst *, struct obj *, int, int));
E int FDECL(damageum, (struct monst *, struct attack *)); E int FDECL(damageum, (struct monst *, struct attack *));
E void FDECL(missum, (struct monst *, struct attack *, BOOLEAN_P)); E void FDECL(missum, (struct monst *, struct attack *, BOOLEAN_P));
E int FDECL(passive, (struct monst *, BOOLEAN_P, int, UCHAR_P, BOOLEAN_P)); E int FDECL(passive, (struct monst *, struct obj *, BOOLEAN_P, int,
UCHAR_P, BOOLEAN_P));
E void FDECL(passive_obj, (struct monst *, struct obj *, struct attack *)); E void FDECL(passive_obj, (struct monst *, struct obj *, struct attack *));
E void FDECL(stumble_onto_mimic, (struct monst *)); E void FDECL(stumble_onto_mimic, (struct monst *));
E int FDECL(flash_hits_mon, (struct monst *, struct obj *)); E int FDECL(flash_hits_mon, (struct monst *, struct obj *));
+3 -3
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. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -2767,7 +2767,7 @@ int final;
if (!u.uconduct.food) if (!u.uconduct.food)
enl_msg(You_, "have gone", "went", " without food", ""); enl_msg(You_, "have gone", "went", " without food", "");
/* But beverages are okay */ /* but beverages are okay */
else if (!u.uconduct.unvegan) else if (!u.uconduct.unvegan)
you_have_X("followed a strict vegan diet"); you_have_X("followed a strict vegan diet");
else if (!u.uconduct.unvegetarian) else if (!u.uconduct.unvegetarian)
@@ -4246,7 +4246,7 @@ register char *cmd;
} else if (*cmd == ' ' && !flags.rest_on_space) { } else if (*cmd == ' ' && !flags.rest_on_space) {
bad_command = TRUE; /* skip cmdlist[] loop */ bad_command = TRUE; /* skip cmdlist[] loop */
/* handle all other commands */ /* handle all other commands */
} else { } else {
register const struct ext_func_tab *tlist; register const struct ext_func_tab *tlist;
int res, NDECL((*func)); int res, NDECL((*func));
+19 -13
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. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -708,8 +708,8 @@ int ttyp;
} }
if (mtmp->isshk) if (mtmp->isshk)
make_angry_shk(mtmp, 0, 0); make_angry_shk(mtmp, 0, 0);
migrate_to_level(mtmp, ledger_no(&tolevel), MIGR_RANDOM, migrate_to_level(mtmp, ledger_no(&tolevel),
(coord *) 0); MIGR_RANDOM, (coord *) 0);
} }
} }
} }
@@ -842,7 +842,7 @@ coord *cc;
"As you dig, the hole fills with %s!"); "As you dig, the hole fills with %s!");
return TRUE; 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)) { } else if (IS_THRONE(lev->typ)) {
pline_The("throne is too hard to break apart."); pline_The("throne is too hard to break apart.");
@@ -914,9 +914,8 @@ coord *cc;
case 0: case 0:
case 1: case 1:
You("unearth a corpse."); 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 */ otmp->age -= 100; /* this is an *OLD* corpse */
;
break; break;
case 2: case 2:
if (!Blind) if (!Blind)
@@ -1069,13 +1068,14 @@ struct obj *obj;
} else if (lev->typ == IRONBARS) { } else if (lev->typ == IRONBARS) {
pline("Clang!"); pline("Clang!");
wake_nearby(); wake_nearby();
} else if (IS_TREE(lev->typ)) } else if (IS_TREE(lev->typ)) {
You("need an axe to cut down a tree."); 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."); You("need a pick to dig rock.");
else if (!ispick && (sobj_at(STATUE, rx, ry) } else if (!ispick && (sobj_at(STATUE, rx, ry)
|| sobj_at(BOULDER, rx, ry))) { || sobj_at(BOULDER, rx, ry))) {
boolean vibrate = !rn2(3); boolean vibrate = !rn2(3);
pline("Sparks fly as you whack the %s.%s", pline("Sparks fly as you whack the %s.%s",
sobj_at(STATUE, rx, ry) ? "statue" : "boulder", sobj_at(STATUE, rx, ry) ? "statue" : "boulder",
vibrate ? " The axe-handle vibrates violently!" : ""); vibrate ? " The axe-handle vibrates violently!" : "");
@@ -1087,6 +1087,7 @@ struct obj *obj;
&& (trap->ttyp == PIT || trap->ttyp == SPIKED_PIT) && (trap->ttyp == PIT || trap->ttyp == SPIKED_PIT)
&& !conjoined_pits(trap, trap_with_u, FALSE)) { && !conjoined_pits(trap, trap_with_u, FALSE)) {
int idx; int idx;
for (idx = 0; idx < 8; idx++) { for (idx = 0; idx < 8; idx++) {
if (xdir[idx] == u.dx && ydir[idx] == u.dy) if (xdir[idx] == u.dx && ydir[idx] == u.dy)
break; break;
@@ -1094,6 +1095,7 @@ struct obj *obj;
/* idx is valid if < 8 */ /* idx is valid if < 8 */
if (idx < 8) { if (idx < 8) {
int adjidx = (idx + 4) % 8; int adjidx = (idx + 4) % 8;
trap_with_u->conjoined |= (1 << idx); trap_with_u->conjoined |= (1 << idx);
trap->conjoined |= (1 << adjidx); trap->conjoined |= (1 << adjidx);
pline("You clear some debris from between the pits."); 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))) { && (trap_with_u = t_at(u.ux, u.uy))) {
You("swing %s, but the rubble has no place to go.", You("swing %s, but the rubble has no place to go.",
yobjnam(obj, (char *) 0)); yobjnam(obj, (char *) 0));
} else } else {
You("swing %s through thin air.", yobjnam(obj, (char *) 0)); You("swing %s through thin air.", yobjnam(obj, (char *) 0));
}
} else { } else {
static const char *const d_action[6] = { "swinging", "digging", static const char *const d_action[6] = { "swinging", "digging",
"chipping the statue", "chipping the statue",
"hitting the boulder", "hitting the boulder",
"chopping at the door", "chopping at the door",
"cutting the tree" }; "cutting the tree" };
did_dig_msg = FALSE; did_dig_msg = FALSE;
context.digging.quiet = FALSE; context.digging.quiet = FALSE;
if (context.digging.pos.x != rx || context.digging.pos.y != ry if (context.digging.pos.x != rx || context.digging.pos.y != ry
|| !on_level(&context.digging.level, &u.uz) || !on_level(&context.digging.level, &u.uz)
|| context.digging.down) { || context.digging.down) {
if (flags.autodig && dig_target == DIGTYP_ROCK 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 && context.digging.pos.y == u.uy
&& (moves <= context.digging.lastdigtime + 2 && (moves <= context.digging.lastdigtime + 2
&& moves >= context.digging.lastdigtime)) { && moves >= context.digging.lastdigtime)) {
@@ -1271,8 +1276,9 @@ register struct monst *mtmp;
newsym(mtmp->mx, mtmp->my); newsym(mtmp->mx, mtmp->my);
draft_message(FALSE); /* "You feel a draft." */ draft_message(FALSE); /* "You feel a draft." */
return FALSE; 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; return FALSE;
}
/* Only rock, trees, and walls fall through to this point. */ /* Only rock, trees, and walls fall through to this point. */
if ((here->wall_info & W_NONDIGGABLE) != 0) { if ((here->wall_info & W_NONDIGGABLE) != 0) {
+11 -4
View File
@@ -1415,12 +1415,19 @@ register struct obj *obj;
otemp.quan = 1L; otemp.quan = 1L;
otemp.oextra = (struct oextra *) 0; 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 */ /* kludge, meaning it's sink water */
Sprintf(qbuf, "Call a stream of %s fluid:", Sprintf(qbuf, "Call a stream of %s fluid:",
OBJ_DESCR(objects[otemp.otyp])); OBJ_DESCR(objects[otemp.otyp]));
else } else {
Sprintf(qbuf, "Call %s:", an(xname(&otemp))); 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); getlin(qbuf, buf);
if (!*buf || *buf == '\033') if (!*buf || *buf == '\033')
return; return;
+9 -9
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. */ /* Copyright (c) Izchak Miller, Mike Stephenson, Steve Linhart, 1989. */
/* NetHack may be freely redistributed. See license for details. */ /* 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) if (mon->mhp <= 0 && !trapkilled)
killed(mon); killed(mon);
@@ -162,7 +162,7 @@ xchar x, y;
&& !is_flyer(mon->data)) { && !is_flyer(mon->data)) {
pline("Floating in the air, you miss wildly!"); pline("Floating in the air, you miss wildly!");
exercise(A_DEX, FALSE); exercise(A_DEX, FALSE);
(void) passive(mon, FALSE, 1, AT_KICK, FALSE); (void) passive(mon, uarmf, FALSE, 1, AT_KICK, FALSE);
return; return;
} }
@@ -213,13 +213,13 @@ xchar x, y;
} else if (tmp > (kickdieroll = rnd(20))) { } else if (tmp > (kickdieroll = rnd(20))) {
You("kick %s.", mon_nam(mon)); You("kick %s.", mon_nam(mon));
sum = damageum(mon, uattk); sum = damageum(mon, uattk);
(void) passive(mon, (boolean) (sum > 0), (sum != 2), AT_KICK, (void) passive(mon, uarmf, (boolean) (sum > 0),
FALSE); (sum != 2), AT_KICK, FALSE);
if (sum == 2) if (sum == 2)
break; /* Defender died */ break; /* Defender died */
} else { } else {
missum(mon, uattk, (tmp + armorpenalty > kickdieroll)); missum(mon, uattk, (tmp + armorpenalty > kickdieroll));
(void) passive(mon, FALSE, 1, AT_KICK, FALSE); (void) passive(mon, uarmf, FALSE, 1, AT_KICK, FALSE);
} }
} }
return; return;
@@ -233,7 +233,7 @@ xchar x, y;
if (martial() && !rn2(2)) if (martial() && !rn2(2))
goto doit; goto doit;
Your("clumsy kick does no damage."); Your("clumsy kick does no damage.");
(void) passive(mon, FALSE, 1, AT_KICK, FALSE); (void) passive(mon, uarmf, FALSE, 1, AT_KICK, FALSE);
return; return;
} }
if (i < j / 10) if (i < j / 10)
@@ -257,7 +257,7 @@ doit:
if (!nohands(mon->data) && !rn2(martial() ? 5 : 3)) { if (!nohands(mon->data) && !rn2(martial() ? 5 : 3)) {
pline("%s blocks your %skick.", Monnam(mon), pline("%s blocks your %skick.", Monnam(mon),
clumsy ? "clumsy " : ""); clumsy ? "clumsy " : "");
(void) passive(mon, FALSE, 1, AT_KICK, FALSE); (void) passive(mon, uarmf, FALSE, 1, AT_KICK, FALSE);
return; return;
} else { } else {
maybe_mnexto(mon); maybe_mnexto(mon);
@@ -274,7 +274,7 @@ doit:
? "slides" ? "slides"
: "jumps", : "jumps",
clumsy ? "easily" : "nimbly", clumsy ? "clumsy " : ""); clumsy ? "easily" : "nimbly", clumsy ? "clumsy " : "");
(void) passive(mon, FALSE, 1, AT_KICK, FALSE); (void) passive(mon, uarmf, FALSE, 1, AT_KICK, FALSE);
return; return;
} }
} }
+9 -9
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. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -1220,16 +1220,16 @@ int upflag;
destination instead of its enclosing region. destination instead of its enclosing region.
Note: up vs down doesn't matter in this case Note: up vs down doesn't matter in this case
because both specify the same exclusion area. */ because both specify the same exclusion area. */
place_lregion(dndest.nlx, dndest.nly, dndest.nhx, dndest.nhy, 0, 0, 0, place_lregion(dndest.nlx, dndest.nly, dndest.nhx, dndest.nhy,
0, LR_DOWNTELE, (d_level *) 0); 0, 0, 0, 0, LR_DOWNTELE, (d_level *) 0);
else if (up) else if (up)
place_lregion(updest.lx, updest.ly, updest.hx, updest.hy, updest.nlx, place_lregion(updest.lx, updest.ly, updest.hx, updest.hy,
updest.nly, updest.nhx, updest.nhy, LR_UPTELE, updest.nlx, updest.nly, updest.nhx, updest.nhy,
(d_level *) 0); LR_UPTELE, (d_level *) 0);
else else
place_lregion(dndest.lx, dndest.ly, dndest.hx, dndest.hy, dndest.nlx, place_lregion(dndest.lx, dndest.ly, dndest.hx, dndest.hy,
dndest.nly, dndest.nhx, dndest.nhy, LR_DOWNTELE, dndest.nlx, dndest.nly, dndest.nhx, dndest.nhy,
(d_level *) 0); LR_DOWNTELE, (d_level *) 0);
} }
/* place you on the special staircase */ /* place you on the special staircase */
+10 -11
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. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -1614,9 +1614,9 @@ domove()
newsym(x, y); newsym(x, y);
glyph = glyph_at(x, y); /* might have just changed */ glyph = glyph_at(x, y); /* might have just changed */
if (boulder) if (boulder) {
Strcpy(buf, ansimpleoname(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 /* Underwater, targetting non-water; the map just shows blank
because you don't see remembered terrain while underwater; because you don't see remembered terrain while underwater;
although the hero can attack an adjacent monster this way, 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) Sprintf(buf, (Is_waterlevel(&u.uz) && levl[x][y].typ == AIR)
? "an air bubble" ? "an air bubble"
: "nothing"); : "nothing");
else if (solid) } else if (solid) {
/* glyph might indicate unseen terrain if hero is blind; /* glyph might indicate unseen terrain if hero is blind;
unlike searching, this won't reveal what that terrain is unlike searching, this won't reveal what that terrain is
(except for solid rock, where the glyph would otherwise (except for solid rock, where the glyph would otherwise
yield ludicrous "dark part of a room") */ yield ludicrous "dark part of a room") */
Strcpy(buf, Strcpy(buf, (levl[x][y].typ == STONE) ? "solid rock"
(levl[x][y].typ == STONE) : glyph_is_cmap(glyph)
? "solid rock"
: glyph_is_cmap(glyph)
? the(defsyms[glyph_to_cmap(glyph)].explanation) ? the(defsyms[glyph_to_cmap(glyph)].explanation)
: (const char *) "an unknown obstacle"); : (const char *) "an unknown obstacle");
/* note: 'solid' is misleadingly named and catches pools /* note: 'solid' is misleadingly named and catches pools
of water and lava as well as rock and walls */ of water and lava as well as rock and walls */
else } else {
Strcpy(buf, "thin air"); Strcpy(buf, "thin air");
}
You("%s%s %s.", You("%s%s %s.",
!(boulder || solid) ? "" : !explo ? "harmlessly " : "futilely ", !(boulder || solid) ? "" : !explo ? "harmlessly " : "futilely ",
explo ? "explode at" : "attack", buf); explo ? "explode at" : "attack", buf);
+2 -2
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) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* Copyright (c) Robert Patrick Rankin, 1991 */ /* Copyright (c) Robert Patrick Rankin, 1991 */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -451,7 +451,7 @@ const char *stuff_to_strip, *orig;
char *s = bp; char *s = bp;
if (s) { if (s) {
while (s && *orig && i < (BUFSZ - 1)) { while (*orig && i < (BUFSZ - 1)) {
if (!index(stuff_to_strip, *orig)) { if (!index(stuff_to_strip, *orig)) {
*s++ = *orig; *s++ = *orig;
i++; i++;
+9 -5
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. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -2541,22 +2541,26 @@ STATIC_OVL void
dounpaid() dounpaid()
{ {
winid win; winid win;
struct obj *otmp, *marker; struct obj *otmp, *marker, *contnr;
register char ilet; register char ilet;
char *invlet = flags.inv_order; char *invlet = flags.inv_order;
int classcount, count, num_so_far; int classcount, count, num_so_far;
long cost, totcost; long cost, totcost;
count = count_unpaid(invent); count = count_unpaid(invent);
otmp = marker = contnr = (struct obj *) 0;
if (count == 1) { if (count == 1) {
marker = (struct obj *) 0;
otmp = find_unpaid(invent, &marker); 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); cost = unpaid_cost(otmp, FALSE);
iflags.suppress_price++; /* suppress "(unpaid)" suffix */ iflags.suppress_price++; /* suppress "(unpaid)" suffix */
pline1(xprname(otmp, distant_name(otmp, doname), pline1(xprname(otmp, distant_name(otmp, doname),
carried(otmp) ? otmp->invlet : CONTAINED_SYM, TRUE, carried(otmp) ? otmp->invlet : CONTAINED_SYM,
cost, 0L)); TRUE, cost, 0L));
iflags.suppress_price--; iflags.suppress_price--;
return; return;
} }
+25 -19
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. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -90,38 +90,44 @@ free_maildata()
void void
getmailstatus() getmailstatus()
{ {
char *emailbox; if (mailbox) {
if ((emailbox = nh_getenv("MAIL")) != 0) { ; /* no need to repeat the setup */
mailbox = (char *) alloc((unsigned) strlen(emailbox)); } else if ((mailbox = nh_getenv("MAIL")) != 0) {
Strcpy(mailbox, emailbox); mailbox = dupstr(mailbox);
}
if (!mailbox) {
#ifdef MAILPATH #ifdef MAILPATH
} else {
#ifdef AMS #ifdef AMS
struct passwd ppasswd; struct passwd ppasswd;
(void) memcpy(&ppasswd, getpwuid(getuid()), sizeof(struct passwd)); (void) memcpy(&ppasswd, getpwuid(getuid()), sizeof (struct passwd));
if (ppasswd.pw_dir) { if (ppasswd.pw_dir) {
mailbox = (char *) alloc((unsigned) strlen(ppasswd.pw_dir) /* note: 'sizeof "LITERAL"' includes +1 for terminating '\0' */
+ sizeof(AMS_MAILBOX)); mailbox = (char *) alloc((unsigned) (strlen(ppasswd.pw_dir)
+ sizeof AMS_MAILBOX));
Strcpy(mailbox, ppasswd.pw_dir); Strcpy(mailbox, ppasswd.pw_dir);
Strcat(mailbox, AMS_MAILBOX); Strcat(mailbox, AMS_MAILBOX);
} else }
return;
#else #else
const char *pw_name = getpwuid(getuid())->pw_name; 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); Strcpy(mailbox, MAILPATH);
Strcat(mailbox, pw_name); Strcat(mailbox, pw_name);
#endif /* AMS */ #endif /* AMS */
#else #endif /* MAILPATH */
return;
#endif
} }
if (stat(mailbox, &omstat)) {
debugpline3("mailbox=%c%s%c",
mailbox ? '\"' : '<',
mailbox ? mailbox : "null",
mailbox ? '\"' : '>');
if (mailbox && stat(mailbox, &omstat)) {
#ifdef PERMANENT_MAILBOX #ifdef PERMANENT_MAILBOX
pline("Cannot get status of MAIL=\"%s\".", mailbox); pline("Cannot get status of MAIL=\"%s\".", mailbox);
mailbox = 0; free_maildata(); /* set 'mailbox' to Null */
#else #else
omstat.st_mtime = 0; omstat.st_mtime = 0;
#endif #endif
@@ -495,7 +501,7 @@ ckmailstatus()
if (stat(mailbox, &nmstat)) { if (stat(mailbox, &nmstat)) {
#ifdef PERMANENT_MAILBOX #ifdef PERMANENT_MAILBOX
pline("Cannot get status of MAIL=\"%s\" anymore.", mailbox); pline("Cannot get status of MAIL=\"%s\" anymore.", mailbox);
mailbox = 0; free_maildata();
#else #else
nmstat.st_mtime = 0; nmstat.st_mtime = 0;
#endif #endif
+4 -6
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. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -296,9 +296,9 @@ d_level *lev;
return; return;
} }
lx = 1; lx = 1; /* column 0 is not used */
hx = COLNO - 1; hx = COLNO - 1;
ly = 1; ly = 0; /* 3.6.0 and earlier erroneously had 1 here */
hy = ROWNO - 1; hy = ROWNO - 1;
} }
@@ -314,11 +314,9 @@ d_level *lev;
/* then a deterministic one */ /* then a deterministic one */
oneshot = TRUE;
for (x = lx; x <= hx; x++) for (x = lx; x <= hx; x++)
for (y = ly; y <= hy; y++) for (y = ly; y <= hy; y++)
if (put_lregion_here(x, y, nlx, nly, nhx, nhy, rtype, oneshot, if (put_lregion_here(x, y, nlx, nly, nhx, nhy, rtype, TRUE, lev))
lev))
return; return;
impossible("Couldn't place lregion type %d!", rtype); impossible("Couldn't place lregion type %d!", rtype);
+18 -1
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. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */ /* 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 * 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 * only in the billobjs chain. This function is used when a shop object
+14 -5
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. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -135,11 +135,19 @@ int x, y;
struct monst *mtmp; struct monst *mtmp;
{ {
/* creatures who are directly resistant to magical scaring: /* 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] 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; 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? */ /* should this still be true for defiled/molochian altars? */
if (IS_ALTAR(levl[x][y].typ) if (IS_ALTAR(levl[x][y].typ)
&& (mtmp->data->mlet == S_VAMPIRE || is_vampshifter(mtmp))) && (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: * Creatures who don't (or can't) fear a written Elbereth:
* all the above plus shopkeepers, guards, blind or * all the above plus shopkeepers (even if poly'd into non-human),
* peaceful monsters, humans, and minotaurs. * 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 * 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. * isn't displaced to the square, no protection is being granted.
+4 -2
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 */ /* Copyright (c) 1989 by Jean-Christophe Collet */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -76,7 +76,9 @@ int distance;
&& (mtmp->mstrategy & STRAT_WAITMASK) != 0) && (mtmp->mstrategy & STRAT_WAITMASK) != 0)
mtmp->mstrategy &= ~STRAT_WAITMASK; mtmp->mstrategy &= ~STRAT_WAITMASK;
else if (distm < distance / 3 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); monflee(mtmp, 0, FALSE, TRUE);
} }
} }
+65 -40
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. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -392,11 +392,10 @@ register struct monst *mtmp;
unweapon = FALSE; unweapon = FALSE;
if (flags.verbose) { if (flags.verbose) {
if (uwep) if (uwep)
You("begin bashing monsters with %s.", You("begin bashing monsters with %s.", yname(uwep));
yobjnam(uwep, (char *) 0));
else if (!cantwield(youmonst.data)) else if (!cantwield(youmonst.data))
You("begin %sing monsters with your %s %s.", You("begin %s monsters with your %s %s.",
Role_if(PM_MONK) ? "strik" : "bash", ing_suffix(Role_if(PM_MONK) ? "strike" : "bash"),
uarmg ? "gloved" : "bare", /* Del Lamb */ uarmg ? "gloved" : "bare", /* Del Lamb */
makeplural(body_part(HAND))); makeplural(body_part(HAND)));
} }
@@ -541,7 +540,7 @@ struct attack *uattk;
mhit = (tmp > dieroll); mhit = (tmp > dieroll);
result = known_hitum(mtmp, uwep, &mhit, tmp, armorpenalty, result = known_hitum(mtmp, uwep, &mhit, tmp, armorpenalty,
uattk, dieroll); uattk, dieroll);
(void) passive(mtmp, mhit, DEADMONSTER(mtmp), AT_WEAP, !uwep); (void) passive(mtmp, uwep, mhit, DEADMONSTER(mtmp), AT_WEAP, !uwep);
if (mon == mtmp) if (mon == mtmp)
malive = result; malive = result;
} }
@@ -570,6 +569,10 @@ struct attack *uattk;
if (tmp > dieroll) if (tmp > dieroll)
exercise(A_DEX, TRUE); exercise(A_DEX, TRUE);
malive = known_hitum(mon, uwep, &mhit, tmp, armorpenalty, uattk, dieroll); 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 /* second attack for two-weapon combat; won't occur if Stormbringer
overrode confirmation (assumes Stormbringer is primary weapon) overrode confirmation (assumes Stormbringer is primary weapon)
or if the monster was killed or knocked to different location */ or if the monster was killed or knocked to different location */
@@ -580,10 +583,10 @@ struct attack *uattk;
mhit = (tmp > dieroll || u.uswallow); mhit = (tmp > dieroll || u.uswallow);
malive = known_hitum(mon, uswapwep, &mhit, tmp, armorpenalty, uattk, malive = known_hitum(mon, uswapwep, &mhit, tmp, armorpenalty, uattk,
dieroll); 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; return malive;
} }
@@ -1157,8 +1160,9 @@ int dieroll;
if ((mdat == &mons[PM_BLACK_PUDDING] || mdat == &mons[PM_BROWN_PUDDING]) if ((mdat == &mons[PM_BLACK_PUDDING] || mdat == &mons[PM_BROWN_PUDDING])
/* pudding is alive and healthy enough to split */ /* pudding is alive and healthy enough to split */
&& mon->mhp > 1 && !mon->mcan && mon->mhp > 1 && !mon->mcan
/* iron weapon using melee or polearm hit [3.6.1: metal weapon too] */ /* iron weapon using melee or polearm hit [3.6.1: metal weapon too;
&& obj && obj == uwep also allow either or both weapons to cause split when twoweap] */
&& obj && (obj == uwep || (u.twoweap && obj == uswapwep))
&& ((objects[obj->otyp].oc_material == IRON && ((objects[obj->otyp].oc_material == IRON
/* allow scalpel and tsurugi to split puddings */ /* allow scalpel and tsurugi to split puddings */
|| objects[obj->otyp].oc_material == METAL) || objects[obj->otyp].oc_material == METAL)
@@ -1166,7 +1170,12 @@ int dieroll;
&& !(is_ammo(obj) || is_missile(obj))) && !(is_ammo(obj) || is_missile(obj)))
&& hand_to_hand) { && hand_to_hand) {
if (clone_mon(mon, 0, 0)) { 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; hittxt = TRUE;
} }
} }
@@ -2186,7 +2195,7 @@ hmonas(mon)
register struct monst *mon; register struct monst *mon;
{ {
struct attack *mattk, alt_attk; struct attack *mattk, alt_attk;
struct obj *weapon; struct obj *weapon, **originalweapon;
boolean altwep = FALSE, weapon_used = FALSE; boolean altwep = FALSE, weapon_used = FALSE;
int i, tmp, armorpenalty, sum[NATTK], nsum = 0, dhit = 0, attknum = 0; int i, tmp, armorpenalty, sum[NATTK], nsum = 0, dhit = 0, attknum = 0;
int dieroll; int dieroll;
@@ -2194,6 +2203,7 @@ register struct monst *mon;
for (i = 0; i < NATTK; i++) { for (i = 0; i < NATTK; i++) {
sum[i] = 0; sum[i] = 0;
mattk = getmattk(&youmonst, mon, i, sum, &alt_attk); mattk = getmattk(&youmonst, mon, i, sum, &alt_attk);
weapon = 0;
switch (mattk->aatyp) { switch (mattk->aatyp) {
case AT_WEAP: case AT_WEAP:
use_weapon: use_weapon:
@@ -2208,20 +2218,36 @@ register struct monst *mon;
* we currently allow the player to get each of these as a weapon * we currently allow the player to get each of these as a weapon
* attack. Is this really desirable? * attack. Is this really desirable?
*/ */
/* approximate two-weapon mode */ /* approximate two-weapon mode; known_hitum() -> hmon() -> &c
weapon = (altwep && uswapwep) ? uswapwep : uwep; might destroy the weapon argument, but it might also already
altwep = !altwep; /* toggle for next attack */ 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, tmp = find_roll_to_hit(mon, AT_WEAP, weapon, &attknum,
&armorpenalty); &armorpenalty);
dieroll = rnd(20); dieroll = rnd(20);
dhit = (tmp > dieroll || u.uswallow); dhit = (tmp > dieroll || u.uswallow);
/* Enemy dead, before any special abilities used */ /* Enemy dead, before any special abilities used */
if (!known_hitum(mon, weapon, &dhit, tmp, armorpenalty, mattk, if (!known_hitum(mon, weapon, &dhit, tmp,
dieroll)) { armorpenalty, mattk, dieroll)) {
sum[i] = 2; sum[i] = 2;
break; break;
} else } else
sum[i] = dhit; 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 */ /* might be a worm that gets cut in half */
if (m_at(u.ux + u.dx, u.uy + u.dy) != mon) if (m_at(u.ux + u.dx, u.uy + u.dy) != mon)
return (boolean) (nsum != 0); return (boolean) (nsum != 0);
@@ -2366,11 +2392,11 @@ register struct monst *mon;
u.mh = -1; /* dead in the current form */ u.mh = -1; /* dead in the current form */
rehumanize(); rehumanize();
} }
if (sum[i] == 2) if (sum[i] == 2) {
return (boolean) passive(mon, 1, 0, mattk->aatyp, FALSE); /* defender dead */
/* defender dead */ return (boolean) passive(mon, weapon, 1, 0, mattk->aatyp, FALSE);
else { } else {
(void) passive(mon, sum[i], 1, mattk->aatyp, FALSE); (void) passive(mon, weapon, sum[i], 1, mattk->aatyp, FALSE);
nsum |= sum[i]; nsum |= sum[i];
} }
if (!Upolyd) if (!Upolyd)
@@ -2384,10 +2410,11 @@ register struct monst *mon;
/* Special (passive) attacks on you by monsters done here. /* Special (passive) attacks on you by monsters done here.
*/ */
int int
passive(mon, mhit, malive, aatyp, wep_was_destroyed) passive(mon, weapon, mhit, malive, aatyp, wep_was_destroyed)
register struct monst *mon; struct monst *mon;
register boolean mhit; struct obj *weapon; /* uwep or uswapwep or uarmg or uarmf or Null */
register int malive; boolean mhit;
int malive;
uchar aatyp; uchar aatyp;
boolean wep_was_destroyed; boolean wep_was_destroyed;
{ {
@@ -2412,14 +2439,14 @@ boolean wep_was_destroyed;
*/ */
switch (ptr->mattk[i].adtyp) { switch (ptr->mattk[i].adtyp) {
case AD_FIRE: case AD_FIRE:
if (mhit && !mon->mcan) { if (mhit && !mon->mcan && weapon) {
if (aatyp == AT_KICK) { if (aatyp == AT_KICK) {
if (uarmf && !rn2(6)) if (uarmf && !rn2(6))
(void) erode_obj(uarmf, xname(uarmf), ERODE_BURN, (void) erode_obj(uarmf, xname(uarmf), ERODE_BURN,
EF_GREASE | EF_VERBOSE); EF_GREASE | EF_VERBOSE);
} else if (aatyp == AT_WEAP || aatyp == AT_CLAW } else if (aatyp == AT_WEAP || aatyp == AT_CLAW
|| aatyp == AT_MAGC || aatyp == AT_TUCH) || aatyp == AT_MAGC || aatyp == AT_TUCH)
passive_obj(mon, (struct obj *) 0, &(ptr->mattk[i])); passive_obj(mon, weapon, &(ptr->mattk[i]));
} }
break; break;
case AD_ACID: case AD_ACID:
@@ -2435,14 +2462,14 @@ boolean wep_was_destroyed;
if (!rn2(30)) if (!rn2(30))
erode_armor(&youmonst, ERODE_CORRODE); erode_armor(&youmonst, ERODE_CORRODE);
} }
if (mhit) { if (mhit && weapon) {
if (aatyp == AT_KICK) { if (aatyp == AT_KICK) {
if (uarmf && !rn2(6)) if (uarmf && !rn2(6))
(void) erode_obj(uarmf, xname(uarmf), ERODE_CORRODE, (void) erode_obj(uarmf, xname(uarmf), ERODE_CORRODE,
EF_GREASE | EF_VERBOSE); EF_GREASE | EF_VERBOSE);
} else if (aatyp == AT_WEAP || aatyp == AT_CLAW } else if (aatyp == AT_WEAP || aatyp == AT_CLAW
|| aatyp == AT_MAGC || aatyp == AT_TUCH) || 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); exercise(A_STR, FALSE);
break; break;
@@ -2471,25 +2498,25 @@ boolean wep_was_destroyed;
} }
break; break;
case AD_RUST: case AD_RUST:
if (mhit && !mon->mcan) { if (mhit && !mon->mcan && weapon) {
if (aatyp == AT_KICK) { if (aatyp == AT_KICK) {
if (uarmf) if (uarmf)
(void) erode_obj(uarmf, xname(uarmf), ERODE_RUST, (void) erode_obj(uarmf, xname(uarmf), ERODE_RUST,
EF_GREASE | EF_VERBOSE); EF_GREASE | EF_VERBOSE);
} else if (aatyp == AT_WEAP || aatyp == AT_CLAW } else if (aatyp == AT_WEAP || aatyp == AT_CLAW
|| aatyp == AT_MAGC || aatyp == AT_TUCH) || aatyp == AT_MAGC || aatyp == AT_TUCH)
passive_obj(mon, (struct obj *) 0, &(ptr->mattk[i])); passive_obj(mon, weapon, &(ptr->mattk[i]));
} }
break; break;
case AD_CORR: case AD_CORR:
if (mhit && !mon->mcan) { if (mhit && !mon->mcan && weapon) {
if (aatyp == AT_KICK) { if (aatyp == AT_KICK) {
if (uarmf) if (uarmf)
(void) erode_obj(uarmf, xname(uarmf), ERODE_CORRODE, (void) erode_obj(uarmf, xname(uarmf), ERODE_CORRODE,
EF_GREASE | EF_VERBOSE); EF_GREASE | EF_VERBOSE);
} else if (aatyp == AT_WEAP || aatyp == AT_CLAW } else if (aatyp == AT_WEAP || aatyp == AT_CLAW
|| aatyp == AT_MAGC || aatyp == AT_TUCH) || aatyp == AT_MAGC || aatyp == AT_TUCH)
passive_obj(mon, (struct obj *) 0, &(ptr->mattk[i])); passive_obj(mon, weapon, &(ptr->mattk[i]));
} }
break; break;
case AD_MAGM: case AD_MAGM:
@@ -2504,17 +2531,14 @@ boolean wep_was_destroyed;
break; break;
case AD_ENCH: /* KMH -- remove enchantment (disenchanter) */ case AD_ENCH: /* KMH -- remove enchantment (disenchanter) */
if (mhit) { if (mhit) {
struct obj *obj = (struct obj *) 0;
if (aatyp == AT_KICK) { if (aatyp == AT_KICK) {
obj = uarmf; if (!weapon)
if (!obj)
break; break;
} else if (aatyp == AT_BITE || aatyp == AT_BUTT } else if (aatyp == AT_BITE || aatyp == AT_BUTT
|| (aatyp >= AT_STNG && aatyp < AT_WEAP)) { || (aatyp >= AT_STNG && aatyp < AT_WEAP)) {
break; /* no object involved */ break; /* no object involved */
} }
passive_obj(mon, obj, &(ptr->mattk[i])); passive_obj(mon, weapon, &(ptr->mattk[i]));
} }
break; break;
default: default:
@@ -2628,6 +2652,7 @@ struct attack *mattk; /* null means we find one internally */
struct permonst *ptr = mon->data; struct permonst *ptr = mon->data;
int i; 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 caller hasn't specified an object, use uwep, uswapwep or uarmg */
if (!obj) { if (!obj) {
obj = (u.twoweap && uswapwep && !rn2(2)) ? uswapwep : uwep; obj = (u.twoweap && uswapwep && !rn2(2)) ? uswapwep : uwep;
Regular → Executable
+1 -1
View File
@@ -1,5 +1,5 @@
#!/bin/sh #!/bin/sh
# NetHack 3.6 macosx.sh $NHDT-Date: 1515549543 2018/01/10 01:59:03 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.18 $ # NetHack 3.6 macosx.sh $NHDT-Date: 1518800856 2018/02/16 17:07:36 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.19 $
# Copyright (c) Kenneth Lorber, Kensington, Maryland, 2007. # Copyright (c) Kenneth Lorber, Kensington, Maryland, 2007.
# NetHack may be freely redistributed. See license for details. # NetHack may be freely redistributed. See license for details.
# #
+2 -2
View File
@@ -1,6 +1,6 @@
$ ! vms/vmsbuild.com -- compile and link NetHack 3.6.* [pr] $ ! vms/vmsbuild.com -- compile and link NetHack 3.6.* [pr]
$ version_number = "3.6.1" $ version_number = "3.6.1"
$ ! $NHDT-Date: 1465133393 2016/06/05 13:29:53 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.15 $ $ ! $NHDT-Date: 1518661015 2018/02/15 02:16:55 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.16 $
$ ! $ !
$ ! usage: $ ! usage:
$ ! $ set default [.src] !or [-.-.src] if starting from [.sys.vms] $ ! $ set default [.src] !or [-.-.src] if starting from [.sys.vms]
@@ -175,7 +175,7 @@ $ ! final setup
$ nethacklib = "[-.src]nethack.olb" $ nethacklib = "[-.src]nethack.olb"
$ create nethack.opt $ create nethack.opt
! nethack.opt ! nethack.opt
nethack.olb/Library/Include=(vmsmain) nethack.olb/Include=(vmsmain)/Library
sys$library:starlet.olb/Include=(lib$initialize) sys$library:starlet.olb/Include=(lib$initialize)
psect_attr=lib$initialize, Con,Usr,noPic,Rel,Gbl,noShr,noExe,Rd,noWrt,Long psect_attr=lib$initialize, Con,Usr,noPic,Rel,Gbl,noShr,noExe,Rd,noWrt,Long
iosegment=128 iosegment=128
+96 -65
View File
@@ -1,5 +1,5 @@
# NetHack 3.6 Makefile.msc $NHDT-Date: 1451610993 2016/01/01 01:16:33 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.101 $ */ # NetHack 3.6 Makefile.msc $NHDT-Date: 1518220654 2018/02/09 23:57:34 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.105 $ */
# Copyright (c) NetHack PC Development Team 1993-2017 # Copyright (c) NetHack PC Development Team 1993-2018
# #
#============================================================================== #==============================================================================
# Build Tools Environment # Build Tools Environment
@@ -29,70 +29,38 @@
# #
# If you have any questions read the sys/winnt/Install.nt file included # If you have any questions read the sys/winnt/Install.nt file included
# with the distribution. # with the distribution.
#============================================================================== #========================================================================================
# Before we get started, this section is used to determine the version of
# Visual Studio we are using. We set VSVER to 0000 to flag any version that
# is too old or untested.
#
!IF "$(_NMAKE_VER)" == "14.11.25547.0"
VSVER=2017
!ELSEIF "$(_NMAKE_VER)" == "14.00.22310.1"
VSVER=2015
!ELSEIF "$(_NMAKE_VER)" == "12.00.21005.1"
VSVER=2013
!ELSEIF "$(_NMAKE_VER)" == "11.00.50727.1"
VSVER=2012
!ELSEIF "$(_NMAKE_VER)" == "10.00.40219.01"
VSVER=2010
!ELSE
VSVER=0000 #untested version
!ENDIF
#==============================================================================
# BUILD DECISIONS SECTION # BUILD DECISIONS SECTION
# #
# There are currently only 3 decisions that you have to make. # There are currently only 3 decisions that you can choose to make, and none are
# 1. 32-bit or 64-bit? # required:
# 2. Where do you want your build to end up? # 1. Where do you want your build to end up?
# 3. Do you want debug information in the executable? # 2. Do you want debug information in the executable?
# 3. Do you want to explicitly override auto-detection of a 32-bit or 64-bit target?
# #
#-----------------------------------------------------------------------------------------
#=========================================================================================
#--------------------------------------------------------------- #---------------------------------------------------------------
#============================================================================== # 1. Where do you want the game to be built (which folder)?
# 1. 32-bit or 64-bit? (comment/uncomment appropriate TARGET_CPU line)
#
!IF ($(VSVER) >= 2012) GAMEDIR = ..\binary # Default game build directory
#
# 64 bit
#TARGET_CPU=x64
#
# 32 bit
TARGET_CPU=x86
!ELSE
!IF ($(VSVER) == 0000)
!ERROR Unsupported and untested version of Visual Studio
!ELSE
# For VS2010 use "setenv /x86" or "setenv /x64" before invoking make process
# DO NOT DELETE THE FOLLOWING LINE
!include <win32.mak>
!ENDIF
!ENDIF
#
#--------------------------------------------------------------- #---------------------------------------------------------------
# 2. Where do you want the game to be built (which folder)? # 2. Do you want debug information available to the executable?
#
GAMEDIR = ..\binary # Game directory
#
#---------------------------------------------------------------
# 3. Do you want debug information in the executable?
#
DEBUGINFO = Y DEBUGINFO = Y
#---------------------------------------------------------------
# 3. This Makefile will attempt to auto-detect your selected target architecture
# based on Visual Studio command prompt configuration settins etc.
# However, if you want to manually override generation of a
# 32-bit or 64-bit build target, you can uncomment the apppropriate
# TARGET_CPU line below.
#
#TARGET_CPU=x64
#TARGET_CPU=x86
#============================================================================== #==============================================================================
# This marks the end of the BUILD DECISIONS section. # This marks the end of the BUILD DECISIONS section.
#============================================================================== #==============================================================================
@@ -181,6 +149,76 @@ DLBFLG =
#========================================== #==========================================
#========================================== #==========================================
# Before we get started, this section is used to determine the version of
# Visual Studio we are using. We set VSVER to 0000 to flag any version that
# is too old or untested.
#
#!MESSAGE $(MAKEFLAGS)
#!MESSAGE $(MAKEDIR)
#!MESSAGE $(MAKE)
MAKEVERSION=$(_NMAKE_VER:.= )
MAKEVERSION=$(MAKEVERSION: =)
#!MESSAGE $(_NMAKE_VER)
#!MESSAGE $(MAKEVERSION)
VSNEWEST=2017
!IF ($(MAKEVERSION) < 1000000000)
VSVER=0000 #untested ancient version
!ELSEIF ($(MAKEVERSION) > 1000000000) && ($(MAKEVERSION) < 1100000000)
VSVER=2010
!ELSEIF ($(MAKEVERSION) > 1100000000) && ($(MAKEVERSION) < 1200000000)
VSVER=2012
!ELSEIF ($(MAKEVERSION) > 1200000000) && ($(MAKEVERSION) < 1400000000)
VSVER=2013
!ELSEIF ($(MAKEVERSION) > 1400000000) && ($(MAKEVERSION) < 1411000000)
VSVER=2015
!ELSEIF ($(MAKEVERSION) > 1411000000) && ($(MAKEVERSION) < 1412258351)
VSVER=$(VSNEWEST)
!ELSEIF ($(MAKEVERSION) > 1412258350)
VSVER=2999 #untested future version
!ENDIF
!IF ($(VSVER) >= 2012)
!MESSAGE Autodetected Visual Studio $(VSVER)
!ELSEIF ($(VSVER) == 2999
!MESSAGE The version of Visual Studio is newer than the most recent at
!MESSAGE the time this Makefile was crafted (Visual Studio $(VSNEWEST)).
!MESSAGE Because it is newer we'll proceed expecting that the
!MESSAGE VS$(VSNEWEST) processing will still work.
!ELSEIF ($(VSVER) == 0000)
!MESSAGE The version of Visual Studio appears to be quite old, older
!MESSAGE than VS2010 which is the oldest supported version by this
!MESSAGE Makefile, so we'll stop now.
!ERROR Untested old Visual Studio version with NMAKE $(_NMAKE_VER).
!ENDIF
!IF ($(VSVER) == 2010)
# For VS2010 use "setenv /x86" or "setenv /x64" before invoking make process
# DO NOT DELETE THE FOLLOWING LINE
!include <win32.mak>
! ENDIF
#----------------------------------------------------------------
#These will be in the environment variables with one of the VS2017
#developer command prompts.
#VSCMD_ARG_HOST_ARCH=x64
#VSCMD_ARG_TGT_ARCH=x86
!IFDEF VSCMD_ARG_HOST_ARCH
!MESSAGE Host architecture is $(VSCMD_ARG_HOST_ARCH)
!MESSAGE Target architecture is $(VSCMD_ARG_TGT_ARCH)
! IFNDEF TARGET_CPU
! IF "$(VSCMD_ARG_TGT_ARCH)"=="x64"
TARGET_CPU=x64
! ELSE
TARGET_CPU=x86
! ENDIF
! ENDIF
!ENDIF
!IF "$(TARGET_CPU)" == "" !IF "$(TARGET_CPU)" == ""
TARGET_CPU=x86 TARGET_CPU=x86
!ENDIF !ENDIF
@@ -937,22 +975,15 @@ $(O)obj.tag:
#========================================== #==========================================
envchk: envchk:
! IF ($(VSVER) < 2010)
@echo Your Visual Studio version is too old or untested ($(_NMAKE_VER))
!ERROR Your Visual Studio version is too old or untested ($(_NMAKE_VER))
! ENDIF
! IF "$(TARGET_CPU)"=="x64" ! IF "$(TARGET_CPU)"=="x64"
@echo Windows x64 64-bit build @echo Windows x64 64-bit target build
! ELSE ! ELSE
@echo Windows x86 32-bit build @echo Windows x86 32-bit target build
! ENDIF ! ENDIF
! IF "$(CL)"!="" ! IF "$(CL)"!=""
# @echo Warning, the CL Environment variable is defined: # @echo Warning, the CL Environment variable is defined:
# @echo CL=$(CL) # @echo CL=$(CL)
! ENDIF ! ENDIF
@echo ----
@echo NOTE: This build will include tile support.
@echo ----
#========================================== #==========================================
#=========== SECONDARY TARGETS ============ #=========== SECONDARY TARGETS ============
+3 -2
View File
@@ -256,11 +256,12 @@ main(argc, argv)
int argc; int argc;
char *argv[]; char *argv[];
{ {
if ((argc != 2) if ((argc == 1) ||
((argc != 2)
#ifdef FILE_PREFIX #ifdef FILE_PREFIX
&& (argc != 3) && (argc != 3)
#endif #endif
&& !(argv[1][0] == '-' && argv[1][1] == '-')) { && !(argv[1][0] == '-' && argv[1][1] == '-'))) {
Fprintf(stderr, "Bad arg count (%d).\n", argc - 1); Fprintf(stderr, "Bad arg count (%d).\n", argc - 1);
(void) fflush(stderr); (void) fflush(stderr);
return 1; return 1;