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

This commit is contained in:
keni
2017-06-13 08:55:47 -04:00
25 changed files with 515 additions and 205 deletions
+28
View File
@@ -378,6 +378,27 @@ levitation vs encumbrance message sequencing issues: putting on boots of
levitation reported reduction of encumbrance before finish-wearing levitation reported reduction of encumbrance before finish-wearing
and float-up messages, taking off such boots didn't report increase and float-up messages, taking off such boots didn't report increase
of encumbrance until player took another action of encumbrance until player took another action
removing a blindfold with 'A' took two turns, with 'R' (and 'T') only one,
and could result in a crash if the blindfold was stolen during removal
removing a blindfold and wielded weapon with 'A' could result in crash if the
weapon was destroyed by various methods
cmdassist help for movement prefix followed by invalid direction was strange
when the direction was up, down, or self disallowed for that prefix
poor message when shape-shifted vampire reverts to vampire if it has a name:
The Dracula suddenly transforms and rises as Dracula.
poor message when shape-shifted vampire reverts if cause of 'death' was
disintegration or digestion and shifted form wasn't amorphous:
The vampire bat is disintegrated. The vampire bat suddenly transforms
and rises as a vampire. (fix: switch to existing alternate phrasing
used for amorphous form, "reconstitute" rather than "transform")
poor message when named vampire shifts shape within view:
You observe a Dracula where a Dracula was.
vampire shifting into fog cloud to pass under door "oozed" rather than "flowed"
adult green dragons and the Chromatic Dragon were blinded by gas clouds
named floating eye (when hit by another monster with reflection) or named
silver weapon (when hero hits silver-hating monster) could disrupt
message formatting and conceivably trigger crash if name had '%' in it
crashes for 'A' above were downgraded to impossible "cursed without otmp"
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
@@ -418,6 +439,13 @@ humanoid pet could become hostile but still remain tame if it observed hero
attacking a peaceful creature attacking a peaceful creature
minor ^X/enlightenment bugs: grammar when poly'd into '1 hit dice' critter, minor ^X/enlightenment bugs: grammar when poly'd into '1 hit dice' critter,
missing punctuation for "You entered the dungeon N turns ago" missing punctuation for "You entered the dungeon N turns ago"
when configured with DUMPLOG enabled, artifacts were counted twice towards
final score
once Moloch's Sanctum (or Astral Plane via wizard mode level teleport direct
to end-game) was entered, end of game disclosure would reveal that
high priests had been incorrectly flagged as extinct
attempting to name an item as an artifact and failing via hand slip violates
illiterate conduct
Platform- and/or Interface-Specific Fixes Platform- and/or Interface-Specific Fixes
+2 -1
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 decl.h $NHDT-Date: 1432512782 2015/05/25 00:13:02 $ $NHDT-Branch: master $:$NHDT-Revision: 1.76 $ */ /* NetHack 3.6 decl.h $NHDT-Date: 1496531104 2017/06/03 23:05:04 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.82 $ */
/* 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. */
@@ -317,6 +317,7 @@ E const char *materialnm[];
#define SUPPRESS_HALLUCINATION 0x04 #define SUPPRESS_HALLUCINATION 0x04
#define SUPPRESS_SADDLE 0x08 #define SUPPRESS_SADDLE 0x08
#define EXACT_NAME 0x0F #define EXACT_NAME 0x0F
#define SUPPRESS_NAME 0x10
/* Vision */ /* Vision */
E NEARDATA boolean vision_full_recalc; /* TRUE if need vision recalc */ E NEARDATA boolean vision_full_recalc; /* TRUE if need vision recalc */
+6 -1
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 extern.h $NHDT-Date: 1494107197 2017/05/06 21:46:37 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.587 $ */ /* NetHack 3.6 extern.h $NHDT-Date: 1496959470 2017/06/08 22:04:30 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.591 $ */
/* 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. */
@@ -270,7 +270,9 @@ E void NDECL(warnreveal);
E int FDECL(dosearch0, (int)); E int FDECL(dosearch0, (int));
E int NDECL(dosearch); E int NDECL(dosearch);
E void NDECL(sokoban_detect); E void NDECL(sokoban_detect);
#ifdef DUMPLOG
E void NDECL(dump_map); E void NDECL(dump_map);
#endif
E void FDECL(reveal_terrain, (int, int)); E void FDECL(reveal_terrain, (int, int));
/* ### dig.c ### */ /* ### dig.c ### */
@@ -402,6 +404,7 @@ E char *FDECL(mon_nam, (struct monst *));
E char *FDECL(noit_mon_nam, (struct monst *)); E char *FDECL(noit_mon_nam, (struct monst *));
E char *FDECL(Monnam, (struct monst *)); E char *FDECL(Monnam, (struct monst *));
E char *FDECL(noit_Monnam, (struct monst *)); E char *FDECL(noit_Monnam, (struct monst *));
E char *FDECL(noname_monnam, (struct monst *, int));
E char *FDECL(m_monnam, (struct monst *)); E char *FDECL(m_monnam, (struct monst *));
E char *FDECL(y_monnam, (struct monst *)); E char *FDECL(y_monnam, (struct monst *));
E char *FDECL(Adjmonnam, (struct monst *, const char *)); E char *FDECL(Adjmonnam, (struct monst *, const char *));
@@ -433,6 +436,7 @@ E void FDECL(off_msg, (struct obj *));
E void FDECL(set_wear, (struct obj *)); E void FDECL(set_wear, (struct obj *));
E boolean FDECL(donning, (struct obj *)); E boolean FDECL(donning, (struct obj *));
E boolean FDECL(doffing, (struct obj *)); E boolean FDECL(doffing, (struct obj *));
E void FDECL(cancel_doff, (struct obj *, long));
E void NDECL(cancel_don); E void NDECL(cancel_don);
E int FDECL(stop_donning, (struct obj *)); E int FDECL(stop_donning, (struct obj *));
E int NDECL(Armor_off); E int NDECL(Armor_off);
@@ -873,6 +877,7 @@ E boolean FDECL(onlyspace, (const char *));
E char *FDECL(tabexpand, (char *)); E char *FDECL(tabexpand, (char *));
E char *FDECL(visctrl, (CHAR_P)); E char *FDECL(visctrl, (CHAR_P));
E char *FDECL(strsubst, (char *, const char *, const char *)); E char *FDECL(strsubst, (char *, const char *, const char *));
E int FDECL(strNsubst, (char *, const char *, const char *, int));
E const char *FDECL(ordin, (int)); E const char *FDECL(ordin, (int));
E char *FDECL(sitoa, (int)); E char *FDECL(sitoa, (int));
E int FDECL(sgn, (int)); E int FDECL(sgn, (int));
+2 -1
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 apply.c $NHDT-Date: 1457397477 2016/03/08 00:37:57 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.224 $ */ /* NetHack 3.6 apply.c $NHDT-Date: 1496619131 2017/06/04 23:32:11 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.232 $ */
/* 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. */
@@ -2060,6 +2060,7 @@ long timeout;
char and_vanish[BUFSZ]; char and_vanish[BUFSZ];
struct obj *mshelter = level.objects[mtmp->mx][mtmp->my]; struct obj *mshelter = level.objects[mtmp->mx][mtmp->my];
/* [m_monnam() yields accurate mon type, overriding hallucination] */
Sprintf(monnambuf, "%s", an(m_monnam(mtmp))); Sprintf(monnambuf, "%s", an(m_monnam(mtmp)));
and_vanish[0] = '\0'; and_vanish[0] = '\0';
if ((mtmp->minvis && !See_invisible) if ((mtmp->minvis && !See_invisible)
+142 -43
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 cmd.c $NHDT-Date: 1494034344 2017/05/06 01:32:24 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.256 $ */ /* NetHack 3.6 cmd.c $NHDT-Date: 1494985492 2017/05/17 01:44:52 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.258 $ */
/* 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. */
@@ -184,8 +184,8 @@ static const char *readchar_queue = "";
static coord clicklook_cc; static coord clicklook_cc;
STATIC_DCL char *NDECL(parse); STATIC_DCL char *NDECL(parse);
STATIC_DCL void FDECL(show_direction_keys, (winid, BOOLEAN_P)); STATIC_DCL void FDECL(show_direction_keys, (winid, CHAR_P, BOOLEAN_P));
STATIC_DCL boolean FDECL(help_dir, (CHAR_P, const char *)); STATIC_DCL boolean FDECL(help_dir, (CHAR_P, int, const char *));
STATIC_PTR int STATIC_PTR int
doprev_message(VOID_ARGS) doprev_message(VOID_ARGS)
@@ -3073,7 +3073,11 @@ dokeylist(VOID_ARGS)
boolean keys_used[256] = {0}; boolean keys_used[256] = {0};
winid datawin; winid datawin;
int i; int i;
const struct { static const char
run_desc[] = "Prefix: run until something very interesting is seen",
forcefight_desc[] =
"Prefix: force fight even if you don't see a monster";
static const struct {
int nhkf; int nhkf;
const char *desc; const char *desc;
boolean numpad; boolean numpad;
@@ -3081,22 +3085,18 @@ dokeylist(VOID_ARGS)
{ NHKF_ESC, "escape from the current query/action", FALSE }, { NHKF_ESC, "escape from the current query/action", FALSE },
{ NHKF_RUSH, { NHKF_RUSH,
"Prefix: rush until something interesting is seen", FALSE }, "Prefix: rush until something interesting is seen", FALSE },
{ NHKF_RUN, { NHKF_RUN, run_desc, FALSE },
"Prefix: run until something extremely interesting is seen", FALSE }, { NHKF_RUN2, run_desc, TRUE },
{ NHKF_RUN2, { NHKF_FIGHT, forcefight_desc, FALSE },
"Prefix: run until something extremely interesting is seen", TRUE }, { NHKF_FIGHT2, forcefight_desc, TRUE } ,
{ NHKF_FIGHT,
"Prefix: force fight even if you don't see a monster", FALSE },
{ NHKF_FIGHT2,
"Prefix: force fight even if you don't see a monster", TRUE },
{ NHKF_NOPICKUP, { NHKF_NOPICKUP,
"Prefix: move without picking up objects/fighting", FALSE }, "Prefix: move without picking up objects/fighting", FALSE },
{ NHKF_RUN_NOPICKUP, { NHKF_RUN_NOPICKUP,
"Prefix: run without picking up objects/fighting", FALSE }, "Prefix: run without picking up objects/fighting", FALSE },
{ NHKF_DOINV, "inventory (same as #inventory)", TRUE }, { NHKF_DOINV, "view inventory", TRUE },
{ NHKF_REQMENU, "Prefix: request a menu", FALSE }, { NHKF_REQMENU, "Prefix: request a menu", FALSE },
#ifdef REDO #ifdef REDO
{ NHKF_DOAGAIN , "redo the previous command", FALSE }, { NHKF_DOAGAIN , "re-do: perform the previous command again", FALSE },
#endif #endif
{ 0, (const char *) 0, FALSE } { 0, (const char *) 0, FALSE }
}; };
@@ -3108,7 +3108,7 @@ dokeylist(VOID_ARGS)
/* directional keys */ /* directional keys */
putstr(datawin, 0, ""); putstr(datawin, 0, "");
putstr(datawin, 0, "Directional keys:"); putstr(datawin, 0, "Directional keys:");
show_direction_keys(datawin, FALSE); show_direction_keys(datawin, '.', FALSE); /* '.'==self in direction grid */
keys_used[(uchar) Cmd.move_NW] = keys_used[(uchar) Cmd.move_N] keys_used[(uchar) Cmd.move_NW] = keys_used[(uchar) Cmd.move_N]
= keys_used[(uchar) Cmd.move_NE] = keys_used[(uchar) Cmd.move_W] = keys_used[(uchar) Cmd.move_NE] = keys_used[(uchar) Cmd.move_W]
@@ -3942,11 +3942,12 @@ int NDECL((*cmd_func));
} }
int int
ch2spkeys(c, start,end) ch2spkeys(c, start, end)
char c; char c;
int start,end; int start,end;
{ {
int i; int i;
for (i = start; i <= end; i++) for (i = start; i <= end; i++)
if (Cmd.spkeys[i] == c) if (Cmd.spkeys[i] == c)
return i; return i;
@@ -3957,6 +3958,7 @@ void
rhack(cmd) rhack(cmd)
register char *cmd; register char *cmd;
{ {
int spkey;
boolean do_walk, do_rush, prefix_seen, bad_command, boolean do_walk, do_rush, prefix_seen, bad_command,
firsttime = (cmd == 0); firsttime = (cmd == 0);
@@ -3990,7 +3992,9 @@ register char *cmd;
/* handle most movement commands */ /* handle most movement commands */
do_walk = do_rush = prefix_seen = FALSE; do_walk = do_rush = prefix_seen = FALSE;
context.travel = context.travel1 = 0; context.travel = context.travel1 = 0;
switch (ch2spkeys(*cmd, NHKF_RUN,NHKF_CLICKLOOK)) { spkey = ch2spkeys(*cmd, NHKF_RUN, NHKF_CLICKLOOK);
switch (spkey) {
case NHKF_RUSH: case NHKF_RUSH:
if (movecmd(cmd[1])) { if (movecmd(cmd[1])) {
context.run = 2; context.run = 2;
@@ -4161,14 +4165,13 @@ register char *cmd;
if (bad_command) { if (bad_command) {
char expcmd[20]; /* we expect 'cmd' to point to 1 or 2 chars */ char expcmd[20]; /* we expect 'cmd' to point to 1 or 2 chars */
register char c; char c, c1 = cmd[1];
expcmd[0] = '\0'; expcmd[0] = '\0';
while ((c = *cmd++) != '\0') while ((c = *cmd++) != '\0')
Strcat(expcmd, visctrl(c)); /* add 1..4 chars plus terminator */ Strcat(expcmd, visctrl(c)); /* add 1..4 chars plus terminator */
if (!prefix_seen || !iflags.cmdassist if (!prefix_seen || !help_dir(c1, spkey, "Invalid direction key!"))
|| !help_dir(0, "Invalid direction key!"))
Norep("Unknown command '%s'.", expcmd); Norep("Unknown command '%s'.", expcmd);
} }
/* didn't move */ /* didn't move */
@@ -4319,7 +4322,8 @@ retry:
if (!index(quitchars, dirsym)) { if (!index(quitchars, dirsym)) {
help_requested = (dirsym == Cmd.spkeys[NHKF_GETDIR_HELP]); help_requested = (dirsym == Cmd.spkeys[NHKF_GETDIR_HELP]);
if (help_requested || iflags.cmdassist) { if (help_requested || iflags.cmdassist) {
did_help = help_dir((s && *s == '^') ? dirsym : 0, did_help = help_dir((s && *s == '^') ? dirsym : '\0',
NHKF_ESC,
help_requested ? (const char *) 0 help_requested ? (const char *) 0
: "Invalid direction key!"); : "Invalid direction key!");
if (help_requested) if (help_requested)
@@ -4339,61 +4343,144 @@ retry:
} }
STATIC_OVL void STATIC_OVL void
show_direction_keys(win, nodiag) show_direction_keys(win, centerchar, nodiag)
winid win; winid win; /* should specify a window which is using a fixed-width font... */
char centerchar; /* '.' or '@' or ' ' */
boolean nodiag; boolean nodiag;
{ {
char buf[BUFSZ]; char buf[BUFSZ];
if (!centerchar)
centerchar = ' ';
if (nodiag) { if (nodiag) {
Sprintf(buf, " %c ", Cmd.move_N); Sprintf(buf, " %c ", Cmd.move_N);
putstr(win, 0, buf); putstr(win, 0, buf);
putstr(win, 0, " | "); putstr(win, 0, " | ");
Sprintf(buf, " %c- . -%c", Cmd.move_W, Cmd.move_E); Sprintf(buf, " %c- %c -%c",
Cmd.move_W, centerchar, Cmd.move_E);
putstr(win, 0, buf); putstr(win, 0, buf);
putstr(win, 0, " | "); putstr(win, 0, " | ");
Sprintf(buf, " %c ", Cmd.move_S); Sprintf(buf, " %c ", Cmd.move_S);
putstr(win, 0, buf); putstr(win, 0, buf);
} else { } else {
Sprintf(buf, " %c %c %c", Cmd.move_NW, Cmd.move_N, Sprintf(buf, " %c %c %c",
Cmd.move_NE); Cmd.move_NW, Cmd.move_N, Cmd.move_NE);
putstr(win, 0, buf); putstr(win, 0, buf);
putstr(win, 0, " \\ | / "); putstr(win, 0, " \\ | / ");
Sprintf(buf, " %c- . -%c", Cmd.move_W, Cmd.move_E); Sprintf(buf, " %c- %c -%c",
Cmd.move_W, centerchar, Cmd.move_E);
putstr(win, 0, buf); putstr(win, 0, buf);
putstr(win, 0, " / | \\ "); putstr(win, 0, " / | \\ ");
Sprintf(buf, " %c %c %c", Cmd.move_SW, Cmd.move_S, Sprintf(buf, " %c %c %c",
Cmd.move_SE); Cmd.move_SW, Cmd.move_S, Cmd.move_SE);
putstr(win, 0, buf); putstr(win, 0, buf);
}; };
} }
/* explain choices if player has asked for getdir() help or has given
an invalid direction after a prefix key ('F', 'g', 'm', &c), which
might be bogus but could be up, down, or self when not applicable */
STATIC_OVL boolean STATIC_OVL boolean
help_dir(sym, msg) help_dir(sym, spkey, msg)
char sym; char sym;
int spkey; /* NHKF_ code for prefix key, if one was used, or for ESC */
const char *msg; const char *msg;
{ {
static const char wiz_only_list[] = "EFGIVW"; static const char wiz_only_list[] = "EFGIVW";
char ctrl; char ctrl;
winid win; winid win;
char buf[BUFSZ], buf2[BUFSZ], *explain; char buf[BUFSZ], buf2[BUFSZ], *explain;
const char *dothat, *how;
boolean prefixhandling, viawindow;
/* NHKF_ESC indicates that player asked for help at getdir prompt */
viawindow = (spkey == NHKF_ESC || iflags.cmdassist);
prefixhandling = (spkey != NHKF_ESC);
/*
* Handling for prefix keys that don't want special directions.
* Delivered via pline if 'cmdassist' is off, or instead of the
* general message if it's on.
*/
dothat = "do that";
how = " at"; /* for "<action> at yourself"; not used for up/down */
switch (spkey) {
case NHKF_NOPICKUP:
dothat = "move";
break;
case NHKF_RUSH:
dothat = "rush";
break;
case NHKF_RUN2:
if (!Cmd.num_pad)
break; /* else FALLTHRU */
case NHKF_RUN:
case NHKF_RUN_NOPICKUP:
dothat = "run";
break;
case NHKF_FIGHT2:
if (!Cmd.num_pad)
break; /* else FALLTHRU */
case NHKF_FIGHT:
dothat = "fight";
how = ""; /* avoid "fight at yourself" */
break;
default:
prefixhandling = FALSE;
break;
}
buf[0] = '\0';
/* for movement prefix followed by '.' or (numpad && 's') to mean 'self';
note: '-' for hands (inventory form of 'self') is not handled here */
if (prefixhandling
&& (sym == Cmd.spkeys[NHKF_GETDIR_SELF]
|| (Cmd.num_pad && sym == Cmd.spkeys[NHKF_GETDIR_SELF2]))) {
Sprintf(buf, "You can't %s%s yourself.", dothat, how);
/* for movement prefix followed by up or down */
} else if (prefixhandling && (sym == '<' || sym == '>')) {
Sprintf(buf, "You can't %s %s.", dothat,
/* was "upwards" and "downwards", but they're considered
to be variants of canonical "upward" and "downward" */
(sym == '<') ? "upward" : "downward");
}
/* if '!cmdassist', display via pline() and we're done (note: asking
for help at getdir() prompt forces cmdassist for this operation) */
if (!viawindow) {
if (prefixhandling) {
if (!*buf)
Sprintf(buf, "Invalid direction for '%s' prefix.",
visctrl(Cmd.spkeys[spkey]));
pline("%s", buf);
return TRUE;
}
/* when 'cmdassist' is off and caller doesn't insist, do nothing */
return FALSE;
}
win = create_nhwindow(NHW_TEXT); win = create_nhwindow(NHW_TEXT);
if (!win) if (!win)
return FALSE; return FALSE;
if (msg) {
if (*buf) {
/* show bad-prefix message instead of general invalid-direction one */
putstr(win, 0, buf);
putstr(win, 0, "");
} else if (msg) {
Sprintf(buf, "cmdassist: %s", msg); Sprintf(buf, "cmdassist: %s", msg);
putstr(win, 0, buf); putstr(win, 0, buf);
putstr(win, 0, ""); putstr(win, 0, "");
} }
if (letter(sym) || sym == '[') { /* 'dat/cmdhelp' shows ESC as ^[ */
if (!prefixhandling && (letter(sym) || sym == '[')) {
/* '[': old 'cmdhelp' showed ESC as ^[ */
sym = highc(sym); /* @A-Z[ (note: letter() accepts '@') */ sym = highc(sym); /* @A-Z[ (note: letter() accepts '@') */
ctrl = (sym - 'A') + 1; /* 0-27 (note: 28-31 aren't applicable) */ ctrl = (sym - 'A') + 1; /* 0-27 (note: 28-31 aren't applicable) */
if ((explain = dowhatdoes_core(ctrl, buf2)) != 0 if ((explain = dowhatdoes_core(ctrl, buf2)) != 0
&& (!index(wiz_only_list, sym) || wizard)) { && (!index(wiz_only_list, sym) || wizard)) {
Sprintf(buf, "Are you trying to use ^%c%s?", sym, Sprintf(buf, "Are you trying to use ^%c%s?", sym,
index(wiz_only_list, sym) index(wiz_only_list, sym) ? ""
? ""
: " as specified in the Guidebook"); : " as specified in the Guidebook");
putstr(win, 0, buf); putstr(win, 0, buf);
putstr(win, 0, ""); putstr(win, 0, "");
@@ -4407,17 +4494,29 @@ const char *msg;
} }
} }
Sprintf(buf, "Valid direction keys %sare:", Sprintf(buf, "Valid direction keys%s%s%s are:",
NODIAG(u.umonnum) ? "in your current form " : ""); prefixhandling ? " to " : "", prefixhandling ? dothat : "",
NODIAG(u.umonnum) ? " in your current form" : "");
putstr(win, 0, buf); putstr(win, 0, buf);
show_direction_keys(win, NODIAG(u.umonnum)); show_direction_keys(win, !prefixhandling ? '.' : ' ', NODIAG(u.umonnum));
if (!prefixhandling || spkey == NHKF_NOPICKUP) {
/* NOPICKUP: unlike the other prefix keys, 'm' allows up/down for
stair traversal; we won't get here when "m<" or "m>" has been
given but we include up and down for 'm'+invalid_direction;
self is excluded as a viable direction for every prefix */
putstr(win, 0, "");
putstr(win, 0, " < up");
putstr(win, 0, " > down");
if (!prefixhandling) {
int selfi = Cmd.num_pad ? NHKF_GETDIR_SELF2 : NHKF_GETDIR_SELF;
Sprintf(buf, " %4s direct at yourself",
visctrl(Cmd.spkeys[selfi]));
putstr(win, 0, buf);
}
}
putstr(win, 0, "");
putstr(win, 0, " < up");
putstr(win, 0, " > down");
Sprintf(buf, " %4s direct at yourself",
visctrl(Cmd.spkeys[NHKF_GETDIR_SELF]));
putstr(win, 0, buf);
if (msg) { if (msg) {
/* non-null msg means that this wasn't an explicit user request */ /* non-null msg means that this wasn't an explicit user request */
putstr(win, 0, ""); putstr(win, 0, "");
+33 -5
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 detect.c $NHDT-Date: 1491705573 2017/04/09 02:39:33 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.76 $ */ /* NetHack 3.6 detect.c $NHDT-Date: 1495346103 2017/05/21 05:55:03 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.77 $ */
/* 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. */
@@ -1799,15 +1799,28 @@ int default_glyph, which_subset;
return glyph; return glyph;
} }
#ifdef DUMPLOG
void void
dump_map() dump_map()
{ {
int x, y, glyph; int x, y, glyph, skippedrows;
int subset = TER_MAP | TER_TRP | TER_OBJ | TER_MON; int subset = TER_MAP | TER_TRP | TER_OBJ | TER_MON;
int default_glyph = cmap_to_glyph(level.flags.arboreal ? S_tree : S_stone); int default_glyph = cmap_to_glyph(level.flags.arboreal ? S_tree : S_stone);
char buf[BUFSZ]; char buf[BUFSZ];
boolean blankrow, toprow;
/*
* Squeeze out excess vertial space when dumping the map.
* If there are any blank map rows at the top, suppress them
* (our caller has already printed a separator). If there is
* more than one blank map row at the bottom, keep just one.
* Any blank rows within the middle of the map are kept.
* Note: putstr() with winid==0 is for dumplog.
*/
skippedrows = 0;
toprow = TRUE;
for (y = 0; y < ROWNO; y++) { for (y = 0; y < ROWNO; y++) {
blankrow = TRUE; /* assume blank until we discover otherwise */
for (x = 1; x < COLNO; x++) { for (x = 1; x < COLNO; x++) {
int ch, color; int ch, color;
unsigned special; unsigned special;
@@ -1815,12 +1828,27 @@ dump_map()
glyph = reveal_terrain_getglyph(x,y, FALSE, u.uswallow, glyph = reveal_terrain_getglyph(x,y, FALSE, u.uswallow,
default_glyph, subset); default_glyph, subset);
(void) mapglyph(glyph, &ch, &color, &special, x, y); (void) mapglyph(glyph, &ch, &color, &special, x, y);
buf[x-1] = ch; buf[x - 1] = ch;
if (ch != ' ')
blankrow = FALSE;
}
if (!blankrow) {
buf[x - 2] = '\0';
if (toprow) {
skippedrows = 0;
toprow = FALSE;
}
for (x = 0; x < skippedrows; x++)
putstr(0, 0, "");
putstr(0, 0, buf); /* map row #y */
} else {
++skippedrows;
} }
buf[x-2] = '\0';
putstr(0,0, buf);
} }
if (skippedrows)
putstr(0, 0, "");
} }
#endif /* DUMPLOG */
/* idea from crawl; show known portion of map without any monsters, /* idea from crawl; show known portion of map without any monsters,
objects, or traps occluding the view of the underlying terrain */ objects, or traps occluding the view of the underlying terrain */
+14 -9
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 display.c $NHDT-Date: 1463614572 2016/05/18 23:36:12 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.86 $ */ /* NetHack 3.6 display.c $NHDT-Date: 1496101037 2017/05/29 23:37:17 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.87 $ */
/* Copyright (c) Dean Luick, with acknowledgements to Kevin Darcy */ /* Copyright (c) Dean Luick, with acknowledgements to Kevin Darcy */
/* and Dave Cohrs, 1990. */ /* and Dave Cohrs, 1990. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -424,24 +424,29 @@ xchar worm_tail; /* mon is actually a worm tail */
} }
} }
/* If the mimic is unsuccessfully mimicing something, display the monster /* If the mimic is unsuccessfully mimicing something, display the monster.
*/ */
if (!mon_mimic || sensed) { if (!mon_mimic || sensed) {
int num; int num;
/* [ALI] Only use detected glyphs when monster wouldn't be /* [ALI] Only use detected glyphs when monster wouldn't be
* visible by any other means. * visible by any other means.
*
* There are no glyphs for "detected pets" so we have to
* decide whether to display such things as detected or as tame.
* If both are being highlighted in the same way, it doesn't
* matter, but if not, showing them as pets is preferrable.
*/ */
if (sightflags == DETECTED && !mon->mtame) { if (mon->mtame && !Hallucination) {
if (worm_tail)
num = detected_monnum_to_glyph(what_mon(PM_LONG_WORM_TAIL));
else
num = detected_mon_to_glyph(mon);
} else if (mon->mtame && !Hallucination) {
if (worm_tail) if (worm_tail)
num = petnum_to_glyph(PM_LONG_WORM_TAIL); num = petnum_to_glyph(PM_LONG_WORM_TAIL);
else else
num = pet_to_glyph(mon); num = pet_to_glyph(mon);
} else if (sightflags == DETECTED) {
if (worm_tail)
num = detected_monnum_to_glyph(what_mon(PM_LONG_WORM_TAIL));
else
num = detected_mon_to_glyph(mon);
} else { } else {
if (worm_tail) if (worm_tail)
num = monnum_to_glyph(what_mon(PM_LONG_WORM_TAIL)); num = monnum_to_glyph(what_mon(PM_LONG_WORM_TAIL));
@@ -666,7 +671,7 @@ xchar x, y;
show_glyph(x, y, lev->glyph = cmap_to_glyph(S_corr)); show_glyph(x, y, lev->glyph = cmap_to_glyph(S_corr));
} }
/* draw monster on top if we can sense it */ /* draw monster on top if we can sense it */
if ((x != u.ux || y != u.uy) && (mon = m_at(x, y)) && sensemon(mon)) if ((x != u.ux || y != u.uy) && (mon = m_at(x, y)) != 0 && sensemon(mon))
display_monster(x, y, mon, display_monster(x, y, mon,
(tp_sensemon(mon) || MATCH_WARN_OF_MON(mon)) (tp_sensemon(mon) || MATCH_WARN_OF_MON(mon))
? PHYSICALLY_SEEN ? PHYSICALLY_SEEN
+22 -5
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 do_name.c $NHDT-Date: 1489494376 2017/03/14 12:26:16 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.116 $ */ /* NetHack 3.6 do_name.c $NHDT-Date: 1496531112 2017/06/03 23:05:12 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.119 $ */
/* 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. */
@@ -1081,6 +1081,9 @@ register struct obj *obj;
pline("While engraving, your %s slips.", body_part(HAND)); pline("While engraving, your %s slips.", body_part(HAND));
display_nhwindow(WIN_MESSAGE, FALSE); display_nhwindow(WIN_MESSAGE, FALSE);
You("engrave: \"%s\".", buf); You("engrave: \"%s\".", buf);
/* violate illiteracy conduct since hero attempted to write
a valid artifact name */
u.uconduct.literate++;
} }
++via_naming; /* This ought to be an argument rather than a static... */ ++via_naming; /* This ought to be an argument rather than a static... */
obj = oname(obj, buf); obj = oname(obj, buf);
@@ -1389,6 +1392,8 @@ rndghostname()
* a_monnam: a newt it an invisible orc Fido * a_monnam: a newt it an invisible orc Fido
* m_monnam: newt xan orc Fido * m_monnam: newt xan orc Fido
* y_monnam: your newt your xan your invisible orc Fido * y_monnam: your newt your xan your invisible orc Fido
* noname_monnam(mon,article):
* article newt art xan art invisible orc art dog
*/ */
/* Bug: if the monster is a priest or shopkeeper, not every one of these /* Bug: if the monster is a priest or shopkeeper, not every one of these
@@ -1409,13 +1414,14 @@ const char *adjective;
int suppress; int suppress;
/* SUPPRESS_IT, SUPPRESS_INVISIBLE, SUPPRESS_HALLUCINATION, SUPPRESS_SADDLE. /* SUPPRESS_IT, SUPPRESS_INVISIBLE, SUPPRESS_HALLUCINATION, SUPPRESS_SADDLE.
* EXACT_NAME: combination of all the above * EXACT_NAME: combination of all the above
* SUPPRESS_NAME: omit monster's assigned name (unless uniq w/ pname).
*/ */
boolean called; boolean called;
{ {
char *buf = nextmbuf(); char *buf = nextmbuf();
struct permonst *mdat = mtmp->data; struct permonst *mdat = mtmp->data;
const char *pm_name = mdat->mname; const char *pm_name = mdat->mname;
boolean do_hallu, do_invis, do_it, do_saddle; boolean do_hallu, do_invis, do_it, do_saddle, do_name;
boolean name_at_start, has_adjectives; boolean name_at_start, has_adjectives;
char *bp; char *bp;
@@ -1430,6 +1436,7 @@ boolean called;
&& !program_state.gameover && mtmp != u.usteed && !program_state.gameover && mtmp != u.usteed
&& !(u.uswallow && mtmp == u.ustuck) && !(suppress & SUPPRESS_IT); && !(u.uswallow && mtmp == u.ustuck) && !(suppress & SUPPRESS_IT);
do_saddle = !(suppress & SUPPRESS_SADDLE); do_saddle = !(suppress & SUPPRESS_SADDLE);
do_name = !(suppress & SUPPRESS_NAME) || type_is_pname(mdat);
buf[0] = '\0'; buf[0] = '\0';
@@ -1510,7 +1517,7 @@ boolean called;
Strcat(buf, rname); Strcat(buf, rname);
name_at_start = bogon_is_pname(rnamecode); name_at_start = bogon_is_pname(rnamecode);
} else if (has_mname(mtmp)) { } else if (do_name && has_mname(mtmp)) {
char *name = MNAME(mtmp); char *name = MNAME(mtmp);
if (mdat == &mons[PM_GHOST]) { if (mdat == &mons[PM_GHOST]) {
@@ -1605,7 +1612,7 @@ struct monst *mtmp;
{ {
return x_monnam(mtmp, ARTICLE_THE, (char *) 0, return x_monnam(mtmp, ARTICLE_THE, (char *) 0,
(has_mname(mtmp)) ? (SUPPRESS_SADDLE | SUPPRESS_IT) (has_mname(mtmp)) ? (SUPPRESS_SADDLE | SUPPRESS_IT)
: SUPPRESS_IT, : SUPPRESS_IT,
FALSE); FALSE);
} }
@@ -1629,7 +1636,17 @@ struct monst *mtmp;
return bp; return bp;
} }
/* monster's own name */ /* return "a dog" rather than "Fido", honoring hallucination and visibility */
char *
noname_monnam(mtmp, article)
struct monst *mtmp;
int article;
{
return x_monnam(mtmp, article, (char *) 0, SUPPRESS_NAME, FALSE);
}
/* monster's own name -- overrides hallucination and [in]visibility
so shouldn't be used in ordinary messages (mainly for disclosure) */
char * char *
m_monnam(mtmp) m_monnam(mtmp)
struct monst *mtmp; struct monst *mtmp;
+61 -27
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 do_wear.c $NHDT-Date: 1494107204 2017/05/06 21:46:44 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.94 $ */ /* 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 $ */
/* 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. */
@@ -1200,37 +1200,30 @@ struct obj *obj; /* if null, do all worn items; otherwise just obj itself */
} }
/* check whether the target object is currently being put on (or taken off-- /* check whether the target object is currently being put on (or taken off--
also checks for doffing) */ also checks for doffing--[why?]) */
boolean boolean
donning(otmp) donning(otmp)
struct obj *otmp; struct obj *otmp;
{ {
/* long what = (occupation == take_off) ? context.takeoff.what : 0L; */
long what = context.takeoff.what; /* if nonzero, occupation is implied */
boolean result = FALSE; boolean result = FALSE;
/* 'W' and 'T' set afternmv, 'A' sets context.takeoff.what */ /* 'W' (or 'P' used for armor) sets afternmv */
if (otmp == uarm) if (doffing(otmp))
result = (afternmv == Armor_on || afternmv == Armor_off result = TRUE;
|| what == WORN_ARMOR); else if (otmp == uarm)
result = (afternmv == Armor_on);
else if (otmp == uarmu) else if (otmp == uarmu)
result = (afternmv == Shirt_on || afternmv == Shirt_off result = (afternmv == Shirt_on);
|| what == WORN_SHIRT);
else if (otmp == uarmc) else if (otmp == uarmc)
result = (afternmv == Cloak_on || afternmv == Cloak_off result = (afternmv == Cloak_on);
|| what == WORN_CLOAK);
else if (otmp == uarmf) else if (otmp == uarmf)
result = (afternmv == Boots_on || afternmv == Boots_off result = (afternmv == Boots_on);
|| what == WORN_BOOTS);
else if (otmp == uarmh) else if (otmp == uarmh)
result = (afternmv == Helmet_on || afternmv == Helmet_off result = (afternmv == Helmet_on);
|| what == WORN_HELMET);
else if (otmp == uarmg) else if (otmp == uarmg)
result = (afternmv == Gloves_on || afternmv == Gloves_off result = (afternmv == Gloves_on);
|| what == WORN_GLOVES);
else if (otmp == uarms) else if (otmp == uarms)
result = (afternmv == Shield_on || afternmv == Shield_off result = (afternmv == Shield_on);
|| what == WORN_SHIELD);
return result; return result;
} }
@@ -1244,7 +1237,7 @@ struct obj *otmp;
long what = context.takeoff.what; long what = context.takeoff.what;
boolean result = FALSE; boolean result = FALSE;
/* 'T' (also 'W') sets afternmv, 'A' sets context.takeoff.what */ /* 'T' (or 'R' used for armor) sets afternmv, 'A' sets takeoff.what */
if (otmp == uarm) if (otmp == uarm)
result = (afternmv == Armor_off || what == WORN_ARMOR); result = (afternmv == Armor_off || what == WORN_ARMOR);
else if (otmp == uarmu) else if (otmp == uarmu)
@@ -1259,10 +1252,48 @@ struct obj *otmp;
result = (afternmv == Gloves_off || what == WORN_GLOVES); result = (afternmv == Gloves_off || what == WORN_GLOVES);
else if (otmp == uarms) else if (otmp == uarms)
result = (afternmv == Shield_off || what == WORN_SHIELD); result = (afternmv == Shield_off || what == WORN_SHIELD);
/* these 1-turn items don't need 'afternmv' checks */
else if (otmp == uamul)
result = (what == WORN_AMUL);
else if (otmp == uleft)
result = (what == LEFT_RING);
else if (otmp == uright)
result = (what == RIGHT_RING);
else if (otmp == ublindf)
result = (what == WORN_BLINDF);
else if (otmp == uwep)
result = (what == W_WEP);
else if (otmp == uswapwep)
result = (what == W_SWAPWEP);
else if (otmp == uquiver)
result = (what == W_QUIVER);
return result; return result;
} }
/* despite their names, cancel_don() and cancel_doff() both apply to both
donning and doffing... */
void
cancel_doff(obj, slotmask)
struct obj *obj;
long slotmask;
{
/* Called by setworn() for old item in specified slot or by setnotworn()
* for specified item. We don't want to call cancel_don() if we got
* here via <X>_off() -> setworn((struct obj *)0) -> cancel_doff()
* because that would stop the 'A' command from continuing with next
* selected item. So do_takeoff() sets a flag in takeoff.mask for us.
* [For taking off an individual item with 'T'/'R'/'w-', it doesn't
* matter whether cancel_don() gets called here--the item has already
* been removed by now.]
*/
if (!(context.takeoff.mask & I_SPECIAL) && donning(obj))
cancel_don(); /* applies to doffing too */
context.takeoff.mask &= ~slotmask;
}
/* despite their names, cancel_don() and cancel_doff() both apply to both
donning and doffing... */
void void
cancel_don() cancel_don()
{ {
@@ -1299,11 +1330,11 @@ struct obj *stolenobj; /* no message if stolenobj is already being doffing */
/* donning() returns True when doffing too; doffing() is more specific */ /* donning() returns True when doffing too; doffing() is more specific */
putting_on = !doffing(otmp); putting_on = !doffing(otmp);
/* cancel_don() looks at afternmv; it also serves as cancel_doff() */ /* cancel_don() looks at afternmv; it can also cancel doffing */
cancel_don(); cancel_don();
/* don't want <armor>_on() or <armor>_off() being called /* don't want <armor>_on() or <armor>_off() being called
by unmul() since the on or off action isn't completing */ by unmul() since the on or off action isn't completing */
afternmv = 0; afternmv = (int NDECL((*))) 0;
if (putting_on || otmp != stolenobj) { if (putting_on || otmp != stolenobj) {
Sprintf(buf, "You stop %s %s.", Sprintf(buf, "You stop %s %s.",
putting_on ? "putting on" : "taking off", putting_on ? "putting on" : "taking off",
@@ -2293,6 +2324,7 @@ do_takeoff()
struct obj *otmp = (struct obj *) 0; struct obj *otmp = (struct obj *) 0;
struct takeoff_info *doff = &context.takeoff; struct takeoff_info *doff = &context.takeoff;
context.takeoff.mask |= I_SPECIAL; /* set flag for cancel_doff() */
if (doff->what == W_WEP) { if (doff->what == W_WEP) {
if (!cursed(uwep)) { if (!cursed(uwep)) {
setuwep((struct obj *) 0); setuwep((struct obj *) 0);
@@ -2352,6 +2384,7 @@ do_takeoff()
} else { } else {
impossible("do_takeoff: taking off %lx", doff->what); impossible("do_takeoff: taking off %lx", doff->what);
} }
context.takeoff.mask &= ~I_SPECIAL; /* clear cancel_doff() flag */
return otmp; return otmp;
} }
@@ -2369,10 +2402,9 @@ take_off(VOID_ARGS)
if (doff->delay > 0) { if (doff->delay > 0) {
doff->delay--; doff->delay--;
return 1; /* still busy */ return 1; /* still busy */
} else {
if ((otmp = do_takeoff()))
off_msg(otmp);
} }
if ((otmp = do_takeoff()) != 0)
off_msg(otmp);
doff->mask &= ~doff->what; doff->mask &= ~doff->what;
doff->what = 0L; doff->what = 0L;
} }
@@ -2427,7 +2459,9 @@ take_off(VOID_ARGS)
} else if (doff->what == RIGHT_RING) { } else if (doff->what == RIGHT_RING) {
doff->delay = 1; doff->delay = 1;
} else if (doff->what == WORN_BLINDF) { } else if (doff->what == WORN_BLINDF) {
doff->delay = 2; /* [this used to be 2, but 'R' (and 'T') only require 1 turn to
remove a blindfold, so 'A' shouldn't have been requiring 2] */
doff->delay = 1;
} else { } else {
impossible("take_off: taking off %lx", doff->what); impossible("take_off: taking off %lx", doff->what);
return 0; /* force done */ return 0; /* force done */
+48 -31
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 end.c $NHDT-Date: 1489192539 2017/03/11 00:35:39 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.130 $ */ /* NetHack 3.6 end.c $NHDT-Date: 1495232357 2017/05/19 22:19:17 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.131 $ */
/* 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. */
@@ -59,7 +59,7 @@ STATIC_DCL boolean FDECL(should_query_disclose_option, (int, char *));
#ifdef DUMPLOG #ifdef DUMPLOG
STATIC_DCL void NDECL(dump_plines); STATIC_DCL void NDECL(dump_plines);
#endif #endif
STATIC_DCL void FDECL(dump_everything, (int)); STATIC_DCL void FDECL(dump_everything, (int, time_t));
STATIC_DCL int NDECL(num_extinct); STATIC_DCL int NDECL(num_extinct);
#if defined(__BEOS__) || defined(MICRO) || defined(WIN32) || defined(OS2) #if defined(__BEOS__) || defined(MICRO) || defined(WIN32) || defined(OS2)
@@ -680,8 +680,7 @@ dump_plines()
extern char *saved_plines[]; extern char *saved_plines[];
extern unsigned saved_pline_index; extern unsigned saved_pline_index;
Strcpy(buf, " "); Strcpy(buf, " "); /* one space for indentation */
putstr(0, 0, "");
putstr(0, 0, "Latest messages:"); putstr(0, 0, "Latest messages:");
for (i = 0, j = (int) saved_pline_index; i < DUMPLOG_MSG_COUNT; for (i = 0, j = (int) saved_pline_index; i < DUMPLOG_MSG_COUNT;
++i, j = (j + 1) % DUMPLOG_MSG_COUNT) { ++i, j = (j + 1) % DUMPLOG_MSG_COUNT) {
@@ -697,27 +696,41 @@ dump_plines()
} }
#endif #endif
/*ARGSUSED*/
STATIC_OVL void STATIC_OVL void
dump_everything(how) dump_everything(how, when)
int how; int how;
time_t when; /* date+time at end of game */
{ {
#ifdef DUMPLOG #ifdef DUMPLOG
struct obj *obj; char pbuf[BUFSZ], datetimebuf[24]; /* [24]: room for 64-bit bogus value */
char pbuf[BUFSZ];
dump_redirect(TRUE); dump_redirect(TRUE);
if (!iflags.in_dumplog) if (!iflags.in_dumplog)
return; return;
init_symbols(); init_symbols(); /* revert to default symbol set */
for (obj = invent; obj; obj = obj->nobj) { /* one line version ID, which includes build date+time;
makeknown(obj->otyp); it's conceivable that the game started with a different
obj->known = obj->bknown = obj->dknown = obj->rknown = 1; build date+time or even with an older nethack version,
if (Is_container(obj) || obj->otyp == STATUE) but we only have access to the one it finished under */
obj->cknown = obj->lknown = 1; putstr(0, 0, getversionstring(pbuf));
} putstr(0, 0, "");
/* game start and end date+time to disambiguate version date+time */
Strcpy(datetimebuf, yyyymmddhhmmss(ubirthday));
Sprintf(pbuf, "Game began %4.4s-%2.2s-%2.2s %2.2s:%2.2s:%2.2s",
&datetimebuf[0], &datetimebuf[4], &datetimebuf[6],
&datetimebuf[8], &datetimebuf[10], &datetimebuf[12]);
Strcpy(datetimebuf, yyyymmddhhmmss(when));
Sprintf(eos(pbuf), ", ended %4.4s-%2.2s-%2.2s %2.2s:%2.2s:%2.2s.",
&datetimebuf[0], &datetimebuf[4], &datetimebuf[6],
&datetimebuf[8], &datetimebuf[10], &datetimebuf[12]);
putstr(0, 0, pbuf);
putstr(0, 0, "");
/* character name and basic role info */
Sprintf(pbuf, "%s, %s %s %s %s", plname, Sprintf(pbuf, "%s, %s %s %s %s", plname,
aligns[1 - u.ualign.type].adj, aligns[1 - u.ualign.type].adj,
genders[flags.female].adj, genders[flags.female].adj,
@@ -772,14 +785,7 @@ boolean taken;
ask = should_query_disclose_option('i', &defquery); ask = should_query_disclose_option('i', &defquery);
c = ask ? yn_function(qbuf, ynqchars, defquery) : defquery; c = ask ? yn_function(qbuf, ynqchars, defquery) : defquery;
if (c == 'y') { if (c == 'y') {
struct obj *obj; /* caller has already ID'd everything */
for (obj = invent; obj; obj = obj->nobj) {
makeknown(obj->otyp);
obj->known = obj->bknown = obj->dknown = obj->rknown = 1;
if (Is_container(obj) || obj->otyp == STATUE)
obj->cknown = obj->lknown = 1;
}
(void) display_inventory((char *) 0, TRUE); (void) display_inventory((char *) 0, TRUE);
container_contents(invent, TRUE, TRUE, FALSE); container_contents(invent, TRUE, TRUE, FALSE);
} }
@@ -1166,10 +1172,26 @@ int how;
if (have_windows) if (have_windows)
display_nhwindow(WIN_MESSAGE, FALSE); display_nhwindow(WIN_MESSAGE, FALSE);
if (strcmp(flags.end_disclose, "none") && how != PANICKED) if (how != PANICKED) {
disclose(how, taken); struct obj *obj;
dump_everything(how); /*
* This is needed for both inventory disclosure and dumplog.
* Both are optional, so do it once here instead of duplicating
* it in both of those places.
*/
for (obj = invent; obj; obj = obj->nobj) {
makeknown(obj->otyp);
obj->known = obj->bknown = obj->dknown = obj->rknown = 1;
if (Is_container(obj) || obj->otyp == STATUE)
obj->cknown = obj->lknown = 1;
}
if (strcmp(flags.end_disclose, "none"))
disclose(how, taken);
dump_everything(how, endtime);
}
/* finish_paybill should be called after disclosure but before bones */ /* finish_paybill should be called after disclosure but before bones */
if (bones_ok && taken) if (bones_ok && taken)
@@ -1319,11 +1341,6 @@ int how;
/* count the points for artifacts */ /* count the points for artifacts */
artifact_score(invent, TRUE, endwin); artifact_score(invent, TRUE, endwin);
#ifdef DUMPLOG
dump_redirect(TRUE);
artifact_score(invent, TRUE, endwin);
dump_redirect(FALSE);
#endif
viz_array[0][0] |= IN_SIGHT; /* need visibility for naming */ viz_array[0][0] |= IN_SIGHT; /* need visibility for naming */
mtmp = mydogs; mtmp = mydogs;
@@ -1418,7 +1435,7 @@ int how;
plur(umoney), moves, plur(moves)); plur(umoney), moves, plur(moves));
dump_forward_putstr(endwin, 0, pbuf, done_stopprint); dump_forward_putstr(endwin, 0, pbuf, done_stopprint);
Sprintf(pbuf, Sprintf(pbuf,
"You were level %d with a maximum of %d hit point%s when you %s.", "You were level %d with a maximum of %d hit point%s when you %s.",
u.ulevel, u.uhpmax, plur(u.uhpmax), ends[how]); u.ulevel, u.uhpmax, plur(u.uhpmax), ends[how]);
dump_forward_putstr(endwin, 0, pbuf, done_stopprint); dump_forward_putstr(endwin, 0, pbuf, done_stopprint);
dump_forward_putstr(endwin, 0, "", done_stopprint); dump_forward_putstr(endwin, 0, "", done_stopprint);
+7 -10
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 explode.c $NHDT-Date: 1450915435 2015/12/24 00:03:55 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.45 $ */ /* NetHack 3.6 explode.c $NHDT-Date: 1496103440 2017/05/30 00:17:20 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.49 $ */
/* Copyright (C) 1990 by Ken Arromdee */ /* Copyright (C) 1990 by Ken Arromdee */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -174,7 +174,7 @@ int expltype;
break; break;
} }
} }
/* can be both you and mtmp if you're swallowed */ /* can be both you and mtmp if you're swallowed or riding */
mtmp = m_at(i + x - 1, j + y - 1); mtmp = m_at(i + x - 1, j + y - 1);
if (!mtmp && i + x - 1 == u.ux && j + y - 1 == u.uy) if (!mtmp && i + x - 1 == u.ux && j + y - 1 == u.uy)
mtmp = u.usteed; mtmp = u.usteed;
@@ -392,8 +392,7 @@ int expltype;
} else { } else {
/* call resist with 0 and do damage manually so 1) we can /* call resist with 0 and do damage manually so 1) we can
* get out the message before doing the damage, and 2) we * get out the message before doing the damage, and 2) we
* can * can call mondied, not killed, if it's not your blast
* call mondied, not killed, if it's not your blast
*/ */
int mdam = dam; int mdam = dam;
@@ -512,12 +511,10 @@ int expltype;
} }
if (shopdamage) { if (shopdamage) {
pay_for_damage(adtyp == AD_FIRE pay_for_damage((adtyp == AD_FIRE) ? "burn away"
? "burn away" : (adtyp == AD_COLD) ? "shatter"
: adtyp == AD_COLD : (adtyp == AD_DISN) ? "disintegrate"
? "shatter" : "destroy",
: adtyp == AD_DISN ? "disintegrate"
: "destroy",
FALSE); FALSE);
} }
+2 -1
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 hack.c $NHDT-Date: 1494107206 2017/05/06 21:46:46 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.174 $ */ /* NetHack 3.6 hack.c $NHDT-Date: 1496619131 2017/06/04 23:32:11 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.175 $ */
/* 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. */
@@ -1526,6 +1526,7 @@ domove()
&& !sensemon(mtmp)) && !sensemon(mtmp))
stumble_onto_mimic(mtmp); stumble_onto_mimic(mtmp);
else if (mtmp->mpeaceful && !Hallucination) else if (mtmp->mpeaceful && !Hallucination)
/* m_monnam(): "dog" or "Fido", no "invisible dog" or "it" */
pline("Pardon me, %s.", m_monnam(mtmp)); pline("Pardon me, %s.", m_monnam(mtmp));
else else
You("move right into %s.", mon_nam(mtmp)); You("move right into %s.", mon_nam(mtmp));
+50 -2
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 hacklib.c $NHDT-Date: 1472006251 2016/08/24 02:37:31 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.48 $ */ /* NetHack 3.6 hacklib.c $NHDT-Date: 1496860756 2017/06/07 18:39:16 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.50 $ */
/* 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. */
@@ -33,6 +33,7 @@
char * tabexpand (char *) char * tabexpand (char *)
char * visctrl (char) char * visctrl (char)
char * strsubst (char *, const char *, const char *) char * strsubst (char *, const char *, const char *)
int strNsubst (char *,const char *,const char *,int)
const char * ordin (int) const char * ordin (int)
char * sitoa (int) char * sitoa (int)
int sgn (int) int sgn (int)
@@ -45,7 +46,7 @@
boolean pmatchz (const char *, const char *) boolean pmatchz (const char *, const char *)
int strncmpi (const char *, const char *, int) int strncmpi (const char *, const char *, int)
char * strstri (const char *, const char *) char * strstri (const char *, const char *)
boolean fuzzymatch (const char *,const char *, boolean fuzzymatch (const char *, const char *,
const char *, boolean) const char *, boolean)
void setrandom (void) void setrandom (void)
time_t getnow (void) time_t getnow (void)
@@ -442,6 +443,7 @@ const char *orig, *replacement;
char *found, buf[BUFSZ]; char *found, buf[BUFSZ];
if (bp) { if (bp) {
/* [this could be replaced by strNsubst(bp, orig, replacement, 1)] */
found = strstr(bp, orig); found = strstr(bp, orig);
if (found) { if (found) {
Strcpy(buf, found + strlen(orig)); Strcpy(buf, found + strlen(orig));
@@ -452,6 +454,52 @@ const char *orig, *replacement;
return bp; return bp;
} }
/* substitute the Nth occurrence of a substring within a string (in place);
if N is 0, substitute all occurrences; returns the number of subsitutions;
maximum output length is BUFSZ (BUFSZ-1 chars + terminating '\0') */
int
strNsubst(inoutbuf, orig, replacement, n)
char *inoutbuf; /* current string, and result buffer */
const char *orig, /* old substring; if "" then insert in front of Nth char */
*replacement; /* new substring; if "" then delete old substring */
int n; /* which occurrence to replace; 0 => all */
{
char *bp, *op, workbuf[BUFSZ];
const char *rp;
unsigned len = (unsigned) strlen(orig);
int ocount = 0, /* number of times 'orig' has been matched */
rcount = 0; /* number of subsitutions made */
for (bp = inoutbuf, op = workbuf; *bp && op < &workbuf[BUFSZ - 1]; ) {
if ((!len || !strncmp(bp, orig, len)) && (++ocount == n || n == 0)) {
/* Nth match found */
for (rp = replacement; *rp && op < &workbuf[BUFSZ - 1]; )
*op++ = *rp++;
++rcount;
if (len) {
bp += len; /* skip 'orig' */
continue;
}
}
/* no match (or len==0) so retain current character */
*op++ = *bp++;
}
if (!len && n == ocount + 1) {
/* special case: orig=="" (!len) and n==strlen(inoutbuf)+1,
insert in front of terminator (in other words, append);
[when orig=="", ocount will have been incremented once for
each input char] */
for (rp = replacement; *rp && op < &workbuf[BUFSZ - 1]; )
*op++ = *rp++;
++rcount;
}
if (rcount) {
*op = '\0';
Strcpy(inoutbuf, workbuf);
}
return rcount;
}
/* return the ordinal suffix of a number */ /* return the ordinal suffix of a number */
const char * const char *
ordin(n) ordin(n)
+2 -2
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 makemon.c $NHDT-Date: 1450451931 2015/12/18 15:18:51 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.106 $ */ /* NetHack 3.6 makemon.c $NHDT-Date: 1495237801 2017/05/19 23:50:01 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.116 $ */
/* 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. */
@@ -903,7 +903,7 @@ boolean ghostly;
result = (((int) mvitals[mndx].born < lim) && !gone) ? TRUE : FALSE; result = (((int) mvitals[mndx].born < lim) && !gone) ? TRUE : FALSE;
/* if it's unique, don't ever make it again */ /* if it's unique, don't ever make it again */
if (mons[mndx].geno & G_UNIQ) if ((mons[mndx].geno & G_UNIQ) && mndx != PM_HIGH_PRIEST)
mvitals[mndx].mvflags |= G_EXTINCT; mvitals[mndx].mvflags |= G_EXTINCT;
if (mvitals[mndx].born < 255 && tally if (mvitals[mndx].born < 255 && tally
+15 -8
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 mhitm.c $NHDT-Date: 1470819842 2016/08/10 09:04:02 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.92 $ */ /* NetHack 3.6 mhitm.c $NHDT-Date: 1496860757 2017/06/07 18:39:17 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.97 $ */
/* 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. */
@@ -322,11 +322,16 @@ register struct monst *magr, *mdef;
mdef->mundetected = 0; mdef->mundetected = 0;
newsym(mdef->mx, mdef->my); newsym(mdef->mx, mdef->my);
if (canseemon(mdef) && !sensemon(mdef)) { if (canseemon(mdef) && !sensemon(mdef)) {
if (Unaware) if (Unaware) {
You("dream of %s.", (mdef->data->geno & G_UNIQ) boolean justone = (mdef->data->geno & G_UNIQ) != 0L;
? a_monnam(mdef) const char *montype;
: makeplural(m_monnam(mdef)));
else montype = noname_monnam(mdef, justone ? ARTICLE_THE
: ARTICLE_NONE);
if (!justone)
montype = makeplural(montype);
You("dream of %s.", montype);
} else
pline("Suddenly, you notice %s.", a_monnam(mdef)); pline("Suddenly, you notice %s.", a_monnam(mdef));
} }
} }
@@ -1551,8 +1556,10 @@ int mdead;
tmp = 127; tmp = 127;
if (magr->mcansee && haseyes(madat) && mdef->mcansee if (magr->mcansee && haseyes(madat) && mdef->mcansee
&& (perceives(madat) || !mdef->minvis)) { && (perceives(madat) || !mdef->minvis)) {
Sprintf(buf, "%s gaze is reflected by %%s %%s.", /* construct format string; guard against '%' in Monnam */
s_suffix(Monnam(mdef))); Strcpy(buf, s_suffix(Monnam(mdef)));
(void) strNsubst(buf, "%", "%%", 0);
Strcat(buf, " gaze is reflected by %s %s.");
if (mon_reflects(magr, if (mon_reflects(magr,
canseemon(magr) ? buf : (char *) 0)) canseemon(magr) ? buf : (char *) 0))
return (mdead | mhit); return (mdead | mhit);
+5 -3
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 mhitu.c $NHDT-Date: 1470819843 2016/08/10 09:04:03 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.144 $ */ /* NetHack 3.6 mhitu.c $NHDT-Date: 1496619132 2017/06/04 23:32:12 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.146 $ */
/* 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. */
@@ -486,6 +486,8 @@ register struct monst *mtmp;
if (obj->otyp == EGG) if (obj->otyp == EGG)
obj->spe = 0; obj->spe = 0;
} }
/* note that m_monnam() overrides hallucination, which is
what we want when message is from mtmp's perspective */
if (youmonst.data->mlet == S_EEL if (youmonst.data->mlet == S_EEL
|| u.umonnum == PM_TRAPPER) || u.umonnum == PM_TRAPPER)
pline( pline(
@@ -515,7 +517,7 @@ register struct monst *mtmp;
map_invisible(mtmp->mx, mtmp->my); map_invisible(mtmp->mx, mtmp->my);
if (sticky && !youseeit) if (sticky && !youseeit)
pline("It gets stuck on you."); pline("It gets stuck on you.");
else else /* see note about m_monnam() above */
pline("Wait, %s! That's a %s named %s!", m_monnam(mtmp), pline("Wait, %s! That's a %s named %s!", m_monnam(mtmp),
youmonst.data->mname, plname); youmonst.data->mname, plname);
if (sticky) if (sticky)
@@ -536,7 +538,7 @@ register struct monst *mtmp;
&& youmonst.mappearance == GOLD_PIECE) && youmonst.mappearance == GOLD_PIECE)
? "tries to pick you up" ? "tries to pick you up"
: "disturbs you"); : "disturbs you");
else else /* see note about m_monnam() above */
pline("Wait, %s! That %s is really %s named %s!", m_monnam(mtmp), pline("Wait, %s! That %s is really %s named %s!", m_monnam(mtmp),
mimic_obj_name(&youmonst), an(mons[u.umonnum].mname), mimic_obj_name(&youmonst), an(mons[u.umonnum].mname),
plname); plname);
+24 -28
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 mon.c $NHDT-Date: 1492733171 2017/04/21 00:06:11 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.237 $ */ /* NetHack 3.6 mon.c $NHDT-Date: 1496531114 2017/06/03 23:05:14 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.240 $ */
/* 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. */
@@ -11,7 +11,7 @@
#include "mfndpos.h" #include "mfndpos.h"
#include <ctype.h> #include <ctype.h>
STATIC_VAR boolean vamp_rise_msg; STATIC_VAR boolean vamp_rise_msg, disintegested;
STATIC_DCL void FDECL(sanity_check_single_mon, (struct monst *, BOOLEAN_P, STATIC_DCL void FDECL(sanity_check_single_mon, (struct monst *, BOOLEAN_P,
const char *)); const char *));
@@ -1826,16 +1826,20 @@ register struct monst *mtmp;
/* alternate message phrasing for some monster types */ /* alternate message phrasing for some monster types */
spec_mon = (nonliving(mtmp->data) spec_mon = (nonliving(mtmp->data)
|| noncorporeal(mtmp->data) || noncorporeal(mtmp->data)
|| amorphous(mtmp->data)); || amorphous(mtmp->data)),
spec_death = (disintegested /* disintegrated or digested */
|| noncorporeal(mtmp->data)
|| amorphous(mtmp->data));
/* construct a format string before transformation */ /* construct a format string before transformation;
Sprintf(buf, "The %s%s suddenly %s and rises as %%s!", will be capitalized when used, expects one %s arg */
spec_mon ? "" : "seemingly dead ", Sprintf(buf, "%s suddenly %s and rises as %%s!",
x_monnam(mtmp, ARTICLE_NONE, (char *) 0, x_monnam(mtmp, ARTICLE_THE,
spec_mon ? (char *) 0 : "seemingly dead",
SUPPRESS_SADDLE | SUPPRESS_HALLUCINATION SUPPRESS_SADDLE | SUPPRESS_HALLUCINATION
| SUPPRESS_INVISIBLE | SUPPRESS_IT, | SUPPRESS_INVISIBLE | SUPPRESS_IT,
FALSE), FALSE),
spec_mon ? "reconstitutes" : "transforms"); spec_death ? "reconstitutes" : "transforms");
mtmp->mcanmove = 1; mtmp->mcanmove = 1;
mtmp->mfrozen = 0; mtmp->mfrozen = 0;
if (mtmp->mhpmax <= 0) if (mtmp->mhpmax <= 0)
@@ -1857,7 +1861,9 @@ register struct monst *mtmp;
else else
mtmp->cham = mndx; mtmp->cham = mndx;
if (canspotmon(mtmp)) { if (canspotmon(mtmp)) {
pline(buf, a_monnam(mtmp)); /* was using a_monnam(mtmp) but that's weird if mtmp is named:
"Dracula suddenly transforms and rises as Dracula" */
pline(upstart(buf), an(mtmp->data->mname));
vamp_rise_msg = TRUE; vamp_rise_msg = TRUE;
} }
newsym(x, y); newsym(x, y);
@@ -1887,9 +1893,7 @@ register struct monst *mtmp;
else if (mtmp->data == &mons[PM_WERERAT]) else if (mtmp->data == &mons[PM_WERERAT])
set_mon_data(mtmp, &mons[PM_HUMAN_WERERAT], -1); set_mon_data(mtmp, &mons[PM_HUMAN_WERERAT], -1);
/* if MAXMONNO monsters of a given type have died, and it /*
* can be done, extinguish that monster.
*
* mvitals[].died does double duty as total number of dead monsters * mvitals[].died does double duty as total number of dead monsters
* and as experience factor for the player killing more monsters. * and as experience factor for the player killing more monsters.
* this means that a dragon dying by other means reduces the * this means that a dragon dying by other means reduces the
@@ -2145,7 +2149,8 @@ int how;
be_sad = (mdef->mtame != 0); be_sad = (mdef->mtame != 0);
/* no corpses if digested or disintegrated */ /* no corpses if digested or disintegrated */
if (how == AD_DGST || how == -AD_RBRE) disintegested = (how == AD_DGST || how == -AD_RBRE);
if (disintegested)
mondead(mdef); mondead(mdef);
else else
mondied(mdef); mondied(mdef);
@@ -2241,16 +2246,18 @@ int xkill_flags; /* 1: suppress message, 2: suppress corpse, 4: pacifist */
thrownobj = 0; thrownobj = 0;
} }
vamp_rise_msg = FALSE; /* might get set in mondead() */ vamp_rise_msg = FALSE; /* might get set in mondead(); only checked below */
disintegested = nocorpse; /* alternate vamp_rise message needed if true */
/* dispose of monster and make cadaver */ /* dispose of monster and make cadaver */
if (stoned) if (stoned)
monstone(mtmp); monstone(mtmp);
else else
mondead(mtmp); mondead(mtmp);
disintegested = FALSE; /* reset */
if (mtmp->mhp > 0) { /* monster lifesaved */ if (mtmp->mhp > 0) { /* monster lifesaved */
/* Cannot put the non-visible lifesaving message in /* Cannot put the non-visible lifesaving message in
* lifesaved_monster() since the message appears only when you * lifesaved_monster() since the message appears only when _you_
* kill it (as opposed to visible lifesaving which always appears). * kill it (as opposed to visible lifesaving which always appears).
*/ */
stoned = FALSE; stoned = FALSE;
@@ -3451,7 +3458,7 @@ boolean msg; /* "The oldmon turns into a newmon!" */
if (is_vampshifter(mtmp)) { if (is_vampshifter(mtmp)) {
Sprintf(msgtrail, " which was a shapeshifted %s", Sprintf(msgtrail, " which was a shapeshifted %s",
m_monnam(mtmp)); noname_monnam(mtmp, ARTICLE_NONE));
} else if (is_animal(mdat)) { } else if (is_animal(mdat)) {
Strcpy(msgtrail, "'s stomach"); Strcpy(msgtrail, "'s stomach");
} else { } else {
@@ -3493,16 +3500,7 @@ boolean msg; /* "The oldmon turns into a newmon!" */
newsym(mtmp->mx, mtmp->my); newsym(mtmp->mx, mtmp->my);
if (msg) { if (msg) {
char *save_mname = 0; Strcpy(newname, noname_monnam(mtmp, ARTICLE_A));
if (has_mname(mtmp)) {
save_mname = MNAME(mtmp);
MNAME(mtmp) = (char *) 0;
}
Strcpy(newname, (mdat == &mons[PM_GREEN_SLIME])
? "slime"
: x_monnam(mtmp, ARTICLE_A, (char *) 0,
SUPPRESS_SADDLE, FALSE));
/* oldname was capitalized above; newname will be lower case */ /* oldname was capitalized above; newname will be lower case */
if (!strcmpi(newname, "it")) { /* can't see or sense it now */ if (!strcmpi(newname, "it")) { /* can't see or sense it now */
if (!!strcmpi(oldname, "it")) /* could see or sense it before */ if (!!strcmpi(oldname, "it")) /* could see or sense it before */
@@ -3514,8 +3512,6 @@ boolean msg; /* "The oldmon turns into a newmon!" */
else else
pline("%s turns into %s!", oldname, newname); pline("%s turns into %s!", oldname, newname);
} }
if (save_mname)
MNAME(mtmp) = save_mname;
} }
/* when polymorph trap/wand/potion produces a vampire, turn in into /* when polymorph trap/wand/potion produces a vampire, turn in into
+13 -9
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 monmove.c $NHDT-Date: 1463704424 2016/05/20 00:33:44 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.87 $ */ /* NetHack 3.6 monmove.c $NHDT-Date: 1496534703 2017/06/04 00:05:03 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.91 $ */
/* 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. */
@@ -1250,10 +1250,12 @@ postmov:
|| (can_fog(mtmp) || (can_fog(mtmp)
&& vamp_shift(mtmp, &mons[PM_FOG_CLOUD], && vamp_shift(mtmp, &mons[PM_FOG_CLOUD],
canspotmon(mtmp))))) { canspotmon(mtmp))))) {
/* update cached value for vamp_shift() case */
ptr = mtmp->data;
if (flags.verbose && canseemon(mtmp)) if (flags.verbose && canseemon(mtmp))
pline("%s %s under the door.", Monnam(mtmp), pline("%s %s under the door.", Monnam(mtmp),
(ptr == &mons[PM_FOG_CLOUD] (ptr == &mons[PM_FOG_CLOUD]
|| ptr == &mons[PM_YELLOW_LIGHT]) || ptr->mlet == S_LIGHT)
? "flows" ? "flows"
: "oozes"); : "oozes");
} else if (here->doormask & D_LOCKED && can_unlock) { } else if (here->doormask & D_LOCKED && can_unlock) {
@@ -1625,13 +1627,11 @@ struct permonst *ptr;
boolean domsg; boolean domsg;
{ {
int reslt = 0; int reslt = 0;
char fmtstr[BUFSZ]; char oldmtype[BUFSZ];
/* remember current monster type before shapechange */
Strcpy(oldmtype, domsg ? noname_monnam(mon, ARTICLE_THE) : "");
if (domsg) {
Sprintf(fmtstr, "You %s %%s where %s was.",
sensemon(mon) ? "now detect" : "observe",
an(m_monnam(mon)));
}
if (mon->data == ptr) { if (mon->data == ptr) {
/* already right shape */ /* already right shape */
reslt = 1; reslt = 1;
@@ -1639,9 +1639,13 @@ boolean domsg;
} else if (is_vampshifter(mon)) { } else if (is_vampshifter(mon)) {
reslt = newcham(mon, ptr, FALSE, FALSE); reslt = newcham(mon, ptr, FALSE, FALSE);
} }
if (reslt && domsg) { if (reslt && domsg) {
pline(fmtstr, an(m_monnam(mon))); pline("You %s %s where %s was.",
!canseemon(mon) ? "now detect" : "observe",
noname_monnam(mon, ARTICLE_A), oldmtype);
} }
return reslt; return reslt;
} }
+9 -3
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 region.c $NHDT-Date: 1446892454 2015/11/07 10:34:14 $ $NHDT-Branch: master $:$NHDT-Revision: 1.36 $ */ /* NetHack 3.6 region.c $NHDT-Date: 1496087244 2017/05/29 19:47:24 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.40 $ */
/* Copyright (c) 1996 by Jean-Christophe Collet */ /* Copyright (c) 1996 by Jean-Christophe Collet */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -969,9 +969,15 @@ genericptr_t p2;
} else { /* A monster is inside the cloud */ } else { /* A monster is inside the cloud */
mtmp = (struct monst *) p2; mtmp = (struct monst *) p2;
/* Non living and non breathing monsters are not concerned */ /* Non living and non breathing monsters are not concerned;
adult green dragon is not affected by gas cloud, baby one is */
if (!(nonliving(mtmp->data) || is_vampshifter(mtmp)) if (!(nonliving(mtmp->data) || is_vampshifter(mtmp))
&& !breathless(mtmp->data)) { && !breathless(mtmp->data)
/* exclude monsters with poison gas breath attack:
adult green dragon and Chromatic Dragon (and iron golem,
but nonliving() and breathless() tests also catch that) */
&& !(attacktype_fordmg(mtmp->data, AT_BREA, AD_DRST)
|| attacktype_fordmg(mtmp->data, AT_BREA, AD_RBRE))) {
if (cansee(mtmp->mx, mtmp->my)) if (cansee(mtmp->mx, mtmp->my))
pline("%s coughs!", Monnam(mtmp)); pline("%s coughs!", Monnam(mtmp));
if (heros_fault(reg)) if (heros_fault(reg))
+8 -7
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 steal.c $NHDT-Date: 1456618998 2016/02/28 00:23:18 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.67 $ */ /* NetHack 3.6 steal.c $NHDT-Date: 1496614914 2017/06/04 22:21:54 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.69 $ */
/* 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. */
@@ -560,18 +560,19 @@ struct monst *mtmp;
/* take off outer gear if we're targetting [hypothetical] /* take off outer gear if we're targetting [hypothetical]
quest artifact suit, shirt, gloves, or rings */ quest artifact suit, shirt, gloves, or rings */
if ((otmp == uarm || otmp == uarmu) && uarmc) if ((otmp == uarm || otmp == uarmu) && uarmc)
(void) Cloak_off(); remove_worn_item(uarmc, FALSE);
if (otmp == uarmu && uarm) if (otmp == uarmu && uarm)
(void) Armor_off(); remove_worn_item(uarm, FALSE);
if ((otmp == uarmg || ((otmp == uright || otmp == uleft) && uarmg)) if ((otmp == uarmg || ((otmp == uright || otmp == uleft) && uarmg))
&& uwep) { && uwep) {
/* gloves are about to be unworn; unwield weapon(s) first */ /* gloves are about to be unworn; unwield weapon(s) first */
if (u.twoweap) if (u.twoweap) /* remove_worn_item(uswapwep) indirectly */
uswapwepgone(); /* will clear u.twoweap */ remove_worn_item(uswapwep, FALSE); /* clears u.twoweap */
uwepgone(); remove_worn_item(uwep, FALSE);
} }
if ((otmp == uright || otmp == uleft) && uarmg) if ((otmp == uright || otmp == uleft) && uarmg)
(void) Gloves_off(); /* handles wielded cockatrice corpse */ /* calls Gloves_off() to handle wielded cockatrice corpse */
remove_worn_item(uarmg, FALSE);
/* finally, steal the target item */ /* finally, steal the target item */
if (otmp->owornmask) if (otmp->owornmask)
+3 -1
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 timeout.c $NHDT-Date: 1493510119 2017/04/29 23:55:19 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.70 $ */ /* NetHack 3.6 timeout.c $NHDT-Date: 1496619133 2017/06/04 23:32:13 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.71 $ */
/* 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. */
@@ -613,6 +613,8 @@ long timeout;
boolean siblings = (hatchcount > 1), redraw = FALSE; boolean siblings = (hatchcount > 1), redraw = FALSE;
if (cansee_hatchspot) { if (cansee_hatchspot) {
/* [bug? m_monnam() yields accurate monster type
regardless of hallucination] */
Sprintf(monnambuf, "%s%s", siblings ? "some " : "", Sprintf(monnambuf, "%s%s", siblings ? "some " : "",
siblings ? makeplural(m_monnam(mon)) : an(m_monnam(mon))); siblings ? makeplural(m_monnam(mon)) : an(m_monnam(mon)));
/* we don't learn the egg type here because learning /* we don't learn the egg type here because learning
+6 -2
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 uhitm.c $NHDT-Date: 1470819843 2016/08/10 09:04:03 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.164 $ */ /* NetHack 3.6 uhitm.c $NHDT-Date: 1496860757 2017/06/07 18:39:17 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.166 $ */
/* 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. */
@@ -1123,9 +1123,13 @@ int thrown; /* HMON_xxx (0 => hand-to-hand, other => ranged) */
else if (barehand_silver_rings == 2) else if (barehand_silver_rings == 2)
fmt = "Your silver rings sear %s!"; fmt = "Your silver rings sear %s!";
else if (silverobj && saved_oname[0]) { else if (silverobj && saved_oname[0]) {
Sprintf(silverobjbuf, "Your %s%s %s %%s!", /* guard constructed format string against '%' in
saved_oname[] from xname(via cxname()) */
Sprintf(silverobjbuf, "Your %s%s %s",
strstri(saved_oname, "silver") ? "" : "silver ", strstri(saved_oname, "silver") ? "" : "silver ",
saved_oname, vtense(saved_oname, "sear")); saved_oname, vtense(saved_oname, "sear"));
(void) strNsubst(silverobjbuf, "%", "%%", 0);
Strcat(silverobjbuf, " %s!");
fmt = silverobjbuf; fmt = silverobjbuf;
} else } else
fmt = "The silver sears %s!"; fmt = "The silver sears %s!";
+1 -1
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 wield.c $NHDT-Date: 1461967849 2016/04/29 22:10:49 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.49 $ */ /* NetHack 3.6 wield.c $NHDT-Date: 1496959480 2017/06/08 22:04:40 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.54 $ */
/* 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. */
+4 -4
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 windows.c $NHDT-Date: 1488075979 2017/02/26 02:26:19 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.39 $ */ /* NetHack 3.6 windows.c $NHDT-Date: 1495232365 2017/05/19 22:19:25 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.41 $ */
/* Copyright (c) D. Cohrs, 1993. */ /* Copyright (c) D. Cohrs, 1993. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -1033,7 +1033,7 @@ int behavior UNUSED, under UNUSED, over UNUSED;
#endif /* STATUS_VIA_WINDOWPORT */ #endif /* STATUS_VIA_WINDOWPORT */
STATIC_VAR struct window_procs dumplog_windowprocs_backup; STATIC_VAR struct window_procs dumplog_windowprocs_backup;
STATIC_PTR FILE *dumplog_file; STATIC_VAR FILE *dumplog_file;
#ifdef DUMPLOG #ifdef DUMPLOG
STATIC_VAR time_t dumplog_now; STATIC_VAR time_t dumplog_now;
@@ -1152,8 +1152,8 @@ void
dump_close_log() dump_close_log()
{ {
if (dumplog_file) { if (dumplog_file) {
fclose(dumplog_file); (void) fclose(dumplog_file);
dumplog_file = NULL; dumplog_file = (FILE *) 0;
} }
} }
+8 -1
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 worn.c $NHDT-Date: 1493510127 2017/04/29 23:55:27 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.48 $ */ /* NetHack 3.6 worn.c $NHDT-Date: 1496959481 2017/06/08 22:04:41 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.49 $ */
/* 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. */
@@ -77,6 +77,9 @@ long mask;
if (oobj->oartifact) if (oobj->oartifact)
set_artifact_intrinsic(oobj, 0, mask); set_artifact_intrinsic(oobj, 0, mask);
} }
/* in case wearing or removal is in progress or removal
is pending (via 'A' command for multiple items) */
cancel_doff(oobj, wp->w_mask);
} }
*(wp->w_obj) = obj; *(wp->w_obj) = obj;
if (obj) { if (obj) {
@@ -119,6 +122,10 @@ register struct obj *obj;
u.twoweap = 0; u.twoweap = 0;
for (wp = worn; wp->w_mask; wp++) for (wp = worn; wp->w_mask; wp++)
if (obj == *(wp->w_obj)) { if (obj == *(wp->w_obj)) {
/* in case wearing or removal is in progress or removal
is pending (via 'A' command for multiple items) */
cancel_doff(obj, wp->w_mask);
*(wp->w_obj) = 0; *(wp->w_obj) = 0;
p = objects[obj->otyp].oc_oprop; p = objects[obj->otyp].oc_oprop;
u.uprops[p].extrinsic = u.uprops[p].extrinsic & ~wp->w_mask; u.uprops[p].extrinsic = u.uprops[p].extrinsic & ~wp->w_mask;