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
and float-up messages, taking off such boots didn't report increase
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
@@ -418,6 +439,13 @@ humanoid pet could become hostile but still remain tame if it observed hero
attacking a peaceful creature
minor ^X/enlightenment bugs: grammar when poly'd into '1 hit dice' critter,
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
+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. */
/* NetHack may be freely redistributed. See license for details. */
@@ -317,6 +317,7 @@ E const char *materialnm[];
#define SUPPRESS_HALLUCINATION 0x04
#define SUPPRESS_SADDLE 0x08
#define EXACT_NAME 0x0F
#define SUPPRESS_NAME 0x10
/* Vision */
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. */
/* NetHack may be freely redistributed. See license for details. */
@@ -270,7 +270,9 @@ E void NDECL(warnreveal);
E int FDECL(dosearch0, (int));
E int NDECL(dosearch);
E void NDECL(sokoban_detect);
#ifdef DUMPLOG
E void NDECL(dump_map);
#endif
E void FDECL(reveal_terrain, (int, int));
/* ### dig.c ### */
@@ -402,6 +404,7 @@ E char *FDECL(mon_nam, (struct monst *));
E char *FDECL(noit_mon_nam, (struct monst *));
E char *FDECL(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(y_monnam, (struct monst *));
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 boolean FDECL(donning, (struct obj *));
E boolean FDECL(doffing, (struct obj *));
E void FDECL(cancel_doff, (struct obj *, long));
E void NDECL(cancel_don);
E int FDECL(stop_donning, (struct obj *));
E int NDECL(Armor_off);
@@ -873,6 +877,7 @@ E boolean FDECL(onlyspace, (const char *));
E char *FDECL(tabexpand, (char *));
E char *FDECL(visctrl, (CHAR_P));
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 char *FDECL(sitoa, (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. */
/* NetHack may be freely redistributed. See license for details. */
@@ -2060,6 +2060,7 @@ long timeout;
char and_vanish[BUFSZ];
struct obj *mshelter = level.objects[mtmp->mx][mtmp->my];
/* [m_monnam() yields accurate mon type, overriding hallucination] */
Sprintf(monnambuf, "%s", an(m_monnam(mtmp)));
and_vanish[0] = '\0';
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. */
/* NetHack may be freely redistributed. See license for details. */
@@ -184,8 +184,8 @@ static const char *readchar_queue = "";
static coord clicklook_cc;
STATIC_DCL char *NDECL(parse);
STATIC_DCL void FDECL(show_direction_keys, (winid, BOOLEAN_P));
STATIC_DCL boolean FDECL(help_dir, (CHAR_P, const char *));
STATIC_DCL void FDECL(show_direction_keys, (winid, CHAR_P, BOOLEAN_P));
STATIC_DCL boolean FDECL(help_dir, (CHAR_P, int, const char *));
STATIC_PTR int
doprev_message(VOID_ARGS)
@@ -3073,7 +3073,11 @@ dokeylist(VOID_ARGS)
boolean keys_used[256] = {0};
winid datawin;
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;
const char *desc;
boolean numpad;
@@ -3081,22 +3085,18 @@ dokeylist(VOID_ARGS)
{ NHKF_ESC, "escape from the current query/action", FALSE },
{ NHKF_RUSH,
"Prefix: rush until something interesting is seen", FALSE },
{ NHKF_RUN,
"Prefix: run until something extremely interesting is seen", FALSE },
{ NHKF_RUN2,
"Prefix: run until something extremely interesting is seen", 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_RUN, run_desc, FALSE },
{ NHKF_RUN2, run_desc, TRUE },
{ NHKF_FIGHT, forcefight_desc, FALSE },
{ NHKF_FIGHT2, forcefight_desc, TRUE } ,
{ NHKF_NOPICKUP,
"Prefix: move without picking up objects/fighting", FALSE },
{ NHKF_RUN_NOPICKUP,
"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 },
#ifdef REDO
{ NHKF_DOAGAIN , "redo the previous command", FALSE },
{ NHKF_DOAGAIN , "re-do: perform the previous command again", FALSE },
#endif
{ 0, (const char *) 0, FALSE }
};
@@ -3108,7 +3108,7 @@ dokeylist(VOID_ARGS)
/* directional keys */
putstr(datawin, 0, "");
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_NE] = keys_used[(uchar) Cmd.move_W]
@@ -3942,11 +3942,12 @@ int NDECL((*cmd_func));
}
int
ch2spkeys(c, start,end)
ch2spkeys(c, start, end)
char c;
int start,end;
{
int i;
for (i = start; i <= end; i++)
if (Cmd.spkeys[i] == c)
return i;
@@ -3957,6 +3958,7 @@ void
rhack(cmd)
register char *cmd;
{
int spkey;
boolean do_walk, do_rush, prefix_seen, bad_command,
firsttime = (cmd == 0);
@@ -3990,7 +3992,9 @@ register char *cmd;
/* handle most movement commands */
do_walk = do_rush = prefix_seen = FALSE;
context.travel = context.travel1 = 0;
switch (ch2spkeys(*cmd, NHKF_RUN,NHKF_CLICKLOOK)) {
spkey = ch2spkeys(*cmd, NHKF_RUN, NHKF_CLICKLOOK);
switch (spkey) {
case NHKF_RUSH:
if (movecmd(cmd[1])) {
context.run = 2;
@@ -4161,14 +4165,13 @@ register char *cmd;
if (bad_command) {
char expcmd[20]; /* we expect 'cmd' to point to 1 or 2 chars */
register char c;
char c, c1 = cmd[1];
expcmd[0] = '\0';
while ((c = *cmd++) != '\0')
Strcat(expcmd, visctrl(c)); /* add 1..4 chars plus terminator */
if (!prefix_seen || !iflags.cmdassist
|| !help_dir(0, "Invalid direction key!"))
if (!prefix_seen || !help_dir(c1, spkey, "Invalid direction key!"))
Norep("Unknown command '%s'.", expcmd);
}
/* didn't move */
@@ -4319,7 +4322,8 @@ retry:
if (!index(quitchars, dirsym)) {
help_requested = (dirsym == Cmd.spkeys[NHKF_GETDIR_HELP]);
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
: "Invalid direction key!");
if (help_requested)
@@ -4339,61 +4343,144 @@ retry:
}
STATIC_OVL void
show_direction_keys(win, nodiag)
winid win;
show_direction_keys(win, centerchar, nodiag)
winid win; /* should specify a window which is using a fixed-width font... */
char centerchar; /* '.' or '@' or ' ' */
boolean nodiag;
{
char buf[BUFSZ];
if (!centerchar)
centerchar = ' ';
if (nodiag) {
Sprintf(buf, " %c ", Cmd.move_N);
putstr(win, 0, buf);
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, " | ");
Sprintf(buf, " %c ", Cmd.move_S);
putstr(win, 0, buf);
} else {
Sprintf(buf, " %c %c %c", Cmd.move_NW, Cmd.move_N,
Cmd.move_NE);
Sprintf(buf, " %c %c %c",
Cmd.move_NW, Cmd.move_N, Cmd.move_NE);
putstr(win, 0, buf);
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, " / | \\ ");
Sprintf(buf, " %c %c %c", Cmd.move_SW, Cmd.move_S,
Cmd.move_SE);
Sprintf(buf, " %c %c %c",
Cmd.move_SW, Cmd.move_S, Cmd.move_SE);
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
help_dir(sym, msg)
help_dir(sym, spkey, msg)
char sym;
int spkey; /* NHKF_ code for prefix key, if one was used, or for ESC */
const char *msg;
{
static const char wiz_only_list[] = "EFGIVW";
char ctrl;
winid win;
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);
if (!win)
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);
putstr(win, 0, buf);
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 '@') */
ctrl = (sym - 'A') + 1; /* 0-27 (note: 28-31 aren't applicable) */
if ((explain = dowhatdoes_core(ctrl, buf2)) != 0
&& (!index(wiz_only_list, sym) || wizard)) {
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");
putstr(win, 0, buf);
putstr(win, 0, "");
@@ -4407,17 +4494,29 @@ const char *msg;
}
}
Sprintf(buf, "Valid direction keys %sare:",
NODIAG(u.umonnum) ? "in your current form " : "");
Sprintf(buf, "Valid direction keys%s%s%s are:",
prefixhandling ? " to " : "", prefixhandling ? dothat : "",
NODIAG(u.umonnum) ? " in your current form" : "");
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) {
/* non-null msg means that this wasn't an explicit user request */
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. */
/* NetHack may be freely redistributed. See license for details. */
@@ -1799,15 +1799,28 @@ int default_glyph, which_subset;
return glyph;
}
#ifdef DUMPLOG
void
dump_map()
{
int x, y, glyph;
int x, y, glyph, skippedrows;
int subset = TER_MAP | TER_TRP | TER_OBJ | TER_MON;
int default_glyph = cmap_to_glyph(level.flags.arboreal ? S_tree : S_stone);
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++) {
blankrow = TRUE; /* assume blank until we discover otherwise */
for (x = 1; x < COLNO; x++) {
int ch, color;
unsigned special;
@@ -1815,12 +1828,27 @@ dump_map()
glyph = reveal_terrain_getglyph(x,y, FALSE, u.uswallow,
default_glyph, subset);
(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,
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 */
/* and Dave Cohrs, 1990. */
/* 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) {
int num;
/* [ALI] Only use detected glyphs when monster wouldn't be
* 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 (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 (mon->mtame && !Hallucination) {
if (worm_tail)
num = petnum_to_glyph(PM_LONG_WORM_TAIL);
else
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 {
if (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));
}
/* 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,
(tp_sensemon(mon) || MATCH_WARN_OF_MON(mon))
? 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. */
/* 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));
display_nhwindow(WIN_MESSAGE, FALSE);
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... */
obj = oname(obj, buf);
@@ -1389,6 +1392,8 @@ rndghostname()
* a_monnam: a newt it an invisible orc Fido
* m_monnam: newt xan 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
@@ -1409,13 +1414,14 @@ const char *adjective;
int suppress;
/* SUPPRESS_IT, SUPPRESS_INVISIBLE, SUPPRESS_HALLUCINATION, SUPPRESS_SADDLE.
* EXACT_NAME: combination of all the above
* SUPPRESS_NAME: omit monster's assigned name (unless uniq w/ pname).
*/
boolean called;
{
char *buf = nextmbuf();
struct permonst *mdat = mtmp->data;
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;
char *bp;
@@ -1430,6 +1436,7 @@ boolean called;
&& !program_state.gameover && mtmp != u.usteed
&& !(u.uswallow && mtmp == u.ustuck) && !(suppress & SUPPRESS_IT);
do_saddle = !(suppress & SUPPRESS_SADDLE);
do_name = !(suppress & SUPPRESS_NAME) || type_is_pname(mdat);
buf[0] = '\0';
@@ -1510,7 +1517,7 @@ boolean called;
Strcat(buf, rname);
name_at_start = bogon_is_pname(rnamecode);
} else if (has_mname(mtmp)) {
} else if (do_name && has_mname(mtmp)) {
char *name = MNAME(mtmp);
if (mdat == &mons[PM_GHOST]) {
@@ -1605,7 +1612,7 @@ struct monst *mtmp;
{
return x_monnam(mtmp, ARTICLE_THE, (char *) 0,
(has_mname(mtmp)) ? (SUPPRESS_SADDLE | SUPPRESS_IT)
: SUPPRESS_IT,
: SUPPRESS_IT,
FALSE);
}
@@ -1629,7 +1636,17 @@ struct monst *mtmp;
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 *
m_monnam(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. */
/* 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--
also checks for doffing) */
also checks for doffing--[why?]) */
boolean
donning(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;
/* 'W' and 'T' set afternmv, 'A' sets context.takeoff.what */
if (otmp == uarm)
result = (afternmv == Armor_on || afternmv == Armor_off
|| what == WORN_ARMOR);
/* 'W' (or 'P' used for armor) sets afternmv */
if (doffing(otmp))
result = TRUE;
else if (otmp == uarm)
result = (afternmv == Armor_on);
else if (otmp == uarmu)
result = (afternmv == Shirt_on || afternmv == Shirt_off
|| what == WORN_SHIRT);
result = (afternmv == Shirt_on);
else if (otmp == uarmc)
result = (afternmv == Cloak_on || afternmv == Cloak_off
|| what == WORN_CLOAK);
result = (afternmv == Cloak_on);
else if (otmp == uarmf)
result = (afternmv == Boots_on || afternmv == Boots_off
|| what == WORN_BOOTS);
result = (afternmv == Boots_on);
else if (otmp == uarmh)
result = (afternmv == Helmet_on || afternmv == Helmet_off
|| what == WORN_HELMET);
result = (afternmv == Helmet_on);
else if (otmp == uarmg)
result = (afternmv == Gloves_on || afternmv == Gloves_off
|| what == WORN_GLOVES);
result = (afternmv == Gloves_on);
else if (otmp == uarms)
result = (afternmv == Shield_on || afternmv == Shield_off
|| what == WORN_SHIELD);
result = (afternmv == Shield_on);
return result;
}
@@ -1244,7 +1237,7 @@ struct obj *otmp;
long what = context.takeoff.what;
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)
result = (afternmv == Armor_off || what == WORN_ARMOR);
else if (otmp == uarmu)
@@ -1259,10 +1252,48 @@ struct obj *otmp;
result = (afternmv == Gloves_off || what == WORN_GLOVES);
else if (otmp == uarms)
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;
}
/* 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
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 */
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();
/* don't want <armor>_on() or <armor>_off() being called
by unmul() since the on or off action isn't completing */
afternmv = 0;
afternmv = (int NDECL((*))) 0;
if (putting_on || otmp != stolenobj) {
Sprintf(buf, "You stop %s %s.",
putting_on ? "putting on" : "taking off",
@@ -2293,6 +2324,7 @@ do_takeoff()
struct obj *otmp = (struct obj *) 0;
struct takeoff_info *doff = &context.takeoff;
context.takeoff.mask |= I_SPECIAL; /* set flag for cancel_doff() */
if (doff->what == W_WEP) {
if (!cursed(uwep)) {
setuwep((struct obj *) 0);
@@ -2352,6 +2384,7 @@ do_takeoff()
} else {
impossible("do_takeoff: taking off %lx", doff->what);
}
context.takeoff.mask &= ~I_SPECIAL; /* clear cancel_doff() flag */
return otmp;
}
@@ -2369,10 +2402,9 @@ take_off(VOID_ARGS)
if (doff->delay > 0) {
doff->delay--;
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->what = 0L;
}
@@ -2427,7 +2459,9 @@ take_off(VOID_ARGS)
} else if (doff->what == RIGHT_RING) {
doff->delay = 1;
} 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 {
impossible("take_off: taking off %lx", doff->what);
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. */
/* 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
STATIC_DCL void NDECL(dump_plines);
#endif
STATIC_DCL void FDECL(dump_everything, (int));
STATIC_DCL void FDECL(dump_everything, (int, time_t));
STATIC_DCL int NDECL(num_extinct);
#if defined(__BEOS__) || defined(MICRO) || defined(WIN32) || defined(OS2)
@@ -680,8 +680,7 @@ dump_plines()
extern char *saved_plines[];
extern unsigned saved_pline_index;
Strcpy(buf, " ");
putstr(0, 0, "");
Strcpy(buf, " "); /* one space for indentation */
putstr(0, 0, "Latest messages:");
for (i = 0, j = (int) saved_pline_index; i < DUMPLOG_MSG_COUNT;
++i, j = (j + 1) % DUMPLOG_MSG_COUNT) {
@@ -697,27 +696,41 @@ dump_plines()
}
#endif
/*ARGSUSED*/
STATIC_OVL void
dump_everything(how)
dump_everything(how, when)
int how;
time_t when; /* date+time at end of game */
{
#ifdef DUMPLOG
struct obj *obj;
char pbuf[BUFSZ];
char pbuf[BUFSZ], datetimebuf[24]; /* [24]: room for 64-bit bogus value */
dump_redirect(TRUE);
if (!iflags.in_dumplog)
return;
init_symbols();
init_symbols(); /* revert to default symbol set */
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;
}
/* one line version ID, which includes build date+time;
it's conceivable that the game started with a different
build date+time or even with an older nethack version,
but we only have access to the one it finished under */
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,
aligns[1 - u.ualign.type].adj,
genders[flags.female].adj,
@@ -772,14 +785,7 @@ boolean taken;
ask = should_query_disclose_option('i', &defquery);
c = ask ? yn_function(qbuf, ynqchars, defquery) : defquery;
if (c == 'y') {
struct obj *obj;
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;
}
/* caller has already ID'd everything */
(void) display_inventory((char *) 0, TRUE);
container_contents(invent, TRUE, TRUE, FALSE);
}
@@ -1166,10 +1172,26 @@ int how;
if (have_windows)
display_nhwindow(WIN_MESSAGE, FALSE);
if (strcmp(flags.end_disclose, "none") && how != PANICKED)
disclose(how, taken);
if (how != PANICKED) {
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 */
if (bones_ok && taken)
@@ -1319,11 +1341,6 @@ int how;
/* count the points for artifacts */
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 */
mtmp = mydogs;
@@ -1418,7 +1435,7 @@ int how;
plur(umoney), moves, plur(moves));
dump_forward_putstr(endwin, 0, pbuf, done_stopprint);
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]);
dump_forward_putstr(endwin, 0, pbuf, 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 */
/* NetHack may be freely redistributed. See license for details. */
@@ -174,7 +174,7 @@ int expltype;
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);
if (!mtmp && i + x - 1 == u.ux && j + y - 1 == u.uy)
mtmp = u.usteed;
@@ -392,8 +392,7 @@ int expltype;
} else {
/* call resist with 0 and do damage manually so 1) we can
* get out the message before doing the damage, and 2) we
* can
* call mondied, not killed, if it's not your blast
* can call mondied, not killed, if it's not your blast
*/
int mdam = dam;
@@ -512,12 +511,10 @@ int expltype;
}
if (shopdamage) {
pay_for_damage(adtyp == AD_FIRE
? "burn away"
: adtyp == AD_COLD
? "shatter"
: adtyp == AD_DISN ? "disintegrate"
: "destroy",
pay_for_damage((adtyp == AD_FIRE) ? "burn away"
: (adtyp == AD_COLD) ? "shatter"
: (adtyp == AD_DISN) ? "disintegrate"
: "destroy",
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. */
/* NetHack may be freely redistributed. See license for details. */
@@ -1526,6 +1526,7 @@ domove()
&& !sensemon(mtmp))
stumble_onto_mimic(mtmp);
else if (mtmp->mpeaceful && !Hallucination)
/* m_monnam(): "dog" or "Fido", no "invisible dog" or "it" */
pline("Pardon me, %s.", m_monnam(mtmp));
else
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) Robert Patrick Rankin, 1991 */
/* NetHack may be freely redistributed. See license for details. */
@@ -33,6 +33,7 @@
char * tabexpand (char *)
char * visctrl (char)
char * strsubst (char *, const char *, const char *)
int strNsubst (char *,const char *,const char *,int)
const char * ordin (int)
char * sitoa (int)
int sgn (int)
@@ -45,7 +46,7 @@
boolean pmatchz (const char *, const char *)
int strncmpi (const char *, const char *, int)
char * strstri (const char *, const char *)
boolean fuzzymatch (const char *,const char *,
boolean fuzzymatch (const char *, const char *,
const char *, boolean)
void setrandom (void)
time_t getnow (void)
@@ -442,6 +443,7 @@ const char *orig, *replacement;
char *found, buf[BUFSZ];
if (bp) {
/* [this could be replaced by strNsubst(bp, orig, replacement, 1)] */
found = strstr(bp, orig);
if (found) {
Strcpy(buf, found + strlen(orig));
@@ -452,6 +454,52 @@ const char *orig, *replacement;
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 */
const char *
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. */
/* NetHack may be freely redistributed. See license for details. */
@@ -903,7 +903,7 @@ boolean ghostly;
result = (((int) mvitals[mndx].born < lim) && !gone) ? TRUE : FALSE;
/* 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;
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. */
/* NetHack may be freely redistributed. See license for details. */
@@ -322,11 +322,16 @@ register struct monst *magr, *mdef;
mdef->mundetected = 0;
newsym(mdef->mx, mdef->my);
if (canseemon(mdef) && !sensemon(mdef)) {
if (Unaware)
You("dream of %s.", (mdef->data->geno & G_UNIQ)
? a_monnam(mdef)
: makeplural(m_monnam(mdef)));
else
if (Unaware) {
boolean justone = (mdef->data->geno & G_UNIQ) != 0L;
const char *montype;
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));
}
}
@@ -1551,8 +1556,10 @@ int mdead;
tmp = 127;
if (magr->mcansee && haseyes(madat) && mdef->mcansee
&& (perceives(madat) || !mdef->minvis)) {
Sprintf(buf, "%s gaze is reflected by %%s %%s.",
s_suffix(Monnam(mdef)));
/* construct format string; guard against '%' in Monnam */
Strcpy(buf, s_suffix(Monnam(mdef)));
(void) strNsubst(buf, "%", "%%", 0);
Strcat(buf, " gaze is reflected by %s %s.");
if (mon_reflects(magr,
canseemon(magr) ? buf : (char *) 0))
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. */
/* NetHack may be freely redistributed. See license for details. */
@@ -486,6 +486,8 @@ register struct monst *mtmp;
if (obj->otyp == EGG)
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
|| u.umonnum == PM_TRAPPER)
pline(
@@ -515,7 +517,7 @@ register struct monst *mtmp;
map_invisible(mtmp->mx, mtmp->my);
if (sticky && !youseeit)
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),
youmonst.data->mname, plname);
if (sticky)
@@ -536,7 +538,7 @@ register struct monst *mtmp;
&& youmonst.mappearance == GOLD_PIECE)
? "tries to pick you up"
: "disturbs you");
else
else /* see note about m_monnam() above */
pline("Wait, %s! That %s is really %s named %s!", m_monnam(mtmp),
mimic_obj_name(&youmonst), an(mons[u.umonnum].mname),
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. */
/* NetHack may be freely redistributed. See license for details. */
@@ -11,7 +11,7 @@
#include "mfndpos.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,
const char *));
@@ -1826,16 +1826,20 @@ register struct monst *mtmp;
/* alternate message phrasing for some monster types */
spec_mon = (nonliving(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 */
Sprintf(buf, "The %s%s suddenly %s and rises as %%s!",
spec_mon ? "" : "seemingly dead ",
x_monnam(mtmp, ARTICLE_NONE, (char *) 0,
/* construct a format string before transformation;
will be capitalized when used, expects one %s arg */
Sprintf(buf, "%s suddenly %s and rises as %%s!",
x_monnam(mtmp, ARTICLE_THE,
spec_mon ? (char *) 0 : "seemingly dead",
SUPPRESS_SADDLE | SUPPRESS_HALLUCINATION
| SUPPRESS_INVISIBLE | SUPPRESS_IT,
FALSE),
spec_mon ? "reconstitutes" : "transforms");
spec_death ? "reconstitutes" : "transforms");
mtmp->mcanmove = 1;
mtmp->mfrozen = 0;
if (mtmp->mhpmax <= 0)
@@ -1857,7 +1861,9 @@ register struct monst *mtmp;
else
mtmp->cham = mndx;
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;
}
newsym(x, y);
@@ -1887,9 +1893,7 @@ register struct monst *mtmp;
else if (mtmp->data == &mons[PM_WERERAT])
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
* and as experience factor for the player killing more monsters.
* this means that a dragon dying by other means reduces the
@@ -2145,7 +2149,8 @@ int how;
be_sad = (mdef->mtame != 0);
/* no corpses if digested or disintegrated */
if (how == AD_DGST || how == -AD_RBRE)
disintegested = (how == AD_DGST || how == -AD_RBRE);
if (disintegested)
mondead(mdef);
else
mondied(mdef);
@@ -2241,16 +2246,18 @@ int xkill_flags; /* 1: suppress message, 2: suppress corpse, 4: pacifist */
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 */
if (stoned)
monstone(mtmp);
else
mondead(mtmp);
disintegested = FALSE; /* reset */
if (mtmp->mhp > 0) { /* monster lifesaved */
/* 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).
*/
stoned = FALSE;
@@ -3451,7 +3458,7 @@ boolean msg; /* "The oldmon turns into a newmon!" */
if (is_vampshifter(mtmp)) {
Sprintf(msgtrail, " which was a shapeshifted %s",
m_monnam(mtmp));
noname_monnam(mtmp, ARTICLE_NONE));
} else if (is_animal(mdat)) {
Strcpy(msgtrail, "'s stomach");
} else {
@@ -3493,16 +3500,7 @@ boolean msg; /* "The oldmon turns into a newmon!" */
newsym(mtmp->mx, mtmp->my);
if (msg) {
char *save_mname = 0;
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));
Strcpy(newname, noname_monnam(mtmp, ARTICLE_A));
/* oldname was capitalized above; newname will be lower case */
if (!strcmpi(newname, "it")) { /* can't see or sense it now */
if (!!strcmpi(oldname, "it")) /* could see or sense it before */
@@ -3514,8 +3512,6 @@ boolean msg; /* "The oldmon turns into a newmon!" */
else
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
+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. */
/* NetHack may be freely redistributed. See license for details. */
@@ -1250,10 +1250,12 @@ postmov:
|| (can_fog(mtmp)
&& vamp_shift(mtmp, &mons[PM_FOG_CLOUD],
canspotmon(mtmp))))) {
/* update cached value for vamp_shift() case */
ptr = mtmp->data;
if (flags.verbose && canseemon(mtmp))
pline("%s %s under the door.", Monnam(mtmp),
(ptr == &mons[PM_FOG_CLOUD]
|| ptr == &mons[PM_YELLOW_LIGHT])
|| ptr->mlet == S_LIGHT)
? "flows"
: "oozes");
} else if (here->doormask & D_LOCKED && can_unlock) {
@@ -1625,13 +1627,11 @@ struct permonst *ptr;
boolean domsg;
{
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) {
/* already right shape */
reslt = 1;
@@ -1639,9 +1639,13 @@ boolean domsg;
} else if (is_vampshifter(mon)) {
reslt = newcham(mon, ptr, FALSE, FALSE);
}
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;
}
+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 */
/* NetHack may be freely redistributed. See license for details. */
@@ -969,9 +969,15 @@ genericptr_t p2;
} else { /* A monster is inside the cloud */
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))
&& !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))
pline("%s coughs!", Monnam(mtmp));
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. */
/* 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]
quest artifact suit, shirt, gloves, or rings */
if ((otmp == uarm || otmp == uarmu) && uarmc)
(void) Cloak_off();
remove_worn_item(uarmc, FALSE);
if (otmp == uarmu && uarm)
(void) Armor_off();
remove_worn_item(uarm, FALSE);
if ((otmp == uarmg || ((otmp == uright || otmp == uleft) && uarmg))
&& uwep) {
/* gloves are about to be unworn; unwield weapon(s) first */
if (u.twoweap)
uswapwepgone(); /* will clear u.twoweap */
uwepgone();
if (u.twoweap) /* remove_worn_item(uswapwep) indirectly */
remove_worn_item(uswapwep, FALSE); /* clears u.twoweap */
remove_worn_item(uwep, FALSE);
}
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 */
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. */
/* NetHack may be freely redistributed. See license for details. */
@@ -613,6 +613,8 @@ long timeout;
boolean siblings = (hatchcount > 1), redraw = FALSE;
if (cansee_hatchspot) {
/* [bug? m_monnam() yields accurate monster type
regardless of hallucination] */
Sprintf(monnambuf, "%s%s", siblings ? "some " : "",
siblings ? makeplural(m_monnam(mon)) : an(m_monnam(mon)));
/* 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. */
/* 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)
fmt = "Your silver rings sear %s!";
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 ",
saved_oname, vtense(saved_oname, "sear"));
(void) strNsubst(silverobjbuf, "%", "%%", 0);
Strcat(silverobjbuf, " %s!");
fmt = silverobjbuf;
} else
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. */
/* 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. */
/* NetHack may be freely redistributed. See license for details. */
@@ -1033,7 +1033,7 @@ int behavior UNUSED, under UNUSED, over UNUSED;
#endif /* STATUS_VIA_WINDOWPORT */
STATIC_VAR struct window_procs dumplog_windowprocs_backup;
STATIC_PTR FILE *dumplog_file;
STATIC_VAR FILE *dumplog_file;
#ifdef DUMPLOG
STATIC_VAR time_t dumplog_now;
@@ -1152,8 +1152,8 @@ void
dump_close_log()
{
if (dumplog_file) {
fclose(dumplog_file);
dumplog_file = NULL;
(void) fclose(dumplog_file);
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. */
/* NetHack may be freely redistributed. See license for details. */
@@ -77,6 +77,9 @@ long mask;
if (oobj->oartifact)
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;
if (obj) {
@@ -119,6 +122,10 @@ register struct obj *obj;
u.twoweap = 0;
for (wp = worn; wp->w_mask; wp++)
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;
p = objects[obj->otyp].oc_oprop;
u.uprops[p].extrinsic = u.uprops[p].extrinsic & ~wp->w_mask;