Merge branch 'NetHack-3.6'

This commit is contained in:
nhmall
2019-10-17 20:52:10 -04:00
19 changed files with 742 additions and 473 deletions

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 decl.c $NHDT-Date: 1547025164 2019/01/09 09:12:44 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.141 $ */
/* NetHack 3.6 decl.c $NHDT-Date: 1571352532 2019/10/17 22:48:52 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.146 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Michael Allison, 2009. */
/* NetHack may be freely redistributed. See license for details. */
@@ -40,6 +40,7 @@ NEARDATA struct obj *uwep, *uarm, *uswapwep,
#ifdef TEXTCOLOR
/*
* This must be the same order as used for buzz() in zap.c.
* (They're only used in mapglyph.c so probably shouldn't be here.)
*/
const int zapcolors[NUM_ZAP] = {
HI_ZAP, /* 0 - missile */
@@ -48,8 +49,10 @@ const int zapcolors[NUM_ZAP] = {
HI_ZAP, /* 3 - sleep */
CLR_BLACK, /* 4 - death */
CLR_WHITE, /* 5 - lightning */
CLR_YELLOW, /* 6 - poison gas */
CLR_GREEN, /* 7 - acid */
/* 3.6.3: poison gas zap used to be yellow and acid zap was green,
which conflicted with the corresponding dragon colors */
CLR_GREEN, /* 6 - poison gas */
CLR_YELLOW, /* 7 - acid */
};
#endif /* text color */

View File

@@ -1292,7 +1292,7 @@ boolean twoweap; /* used to restore twoweapon mode if wielded weapon returns */
|| !index(in_rooms(mon->mx, mon->my, SHOPBASE), *u.ushops)))
hot_pursuit(mon);
if (obj_gone)
if (obj_gone || obj == uball)
g.thrownobj = (struct obj *) 0;
}

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 drawing.c $NHDT-Date: 1546656404 2019/01/05 02:46:44 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.59 $ */
/* NetHack 3.6 drawing.c $NHDT-Date: 1571347973 2019/10/17 21:32:53 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.62 $ */
/* Copyright (c) NetHack Development Team 1992. */
/* NetHack may be freely redistributed. See license for details. */
@@ -246,9 +246,9 @@ static const uchar def_r_oc_syms[MAXOCLASSES] = {
#undef C
#ifdef TERMLIB
#if defined(TERMLIB) || defined(CURSES_GRAPHICS)
void NDECL((*decgraphics_mode_callback)) = 0; /* set in tty_start_screen() */
#endif /* TERMLIB */
#endif /* TERMLIB || CURSES */
#ifdef PC9800
void NDECL((*ibmgraphics_mode_callback)) = 0; /* set in tty_start_screen() */
@@ -487,17 +487,22 @@ int nondefault;
#ifdef PC9800
if (SYMHANDLING(H_IBM) && ibmgraphics_mode_callback)
(*ibmgraphics_mode_callback)();
else if (!g.symset[g.currentgraphics].name && ascgraphics_mode_callback)
else if (SYMHANDLING(H_UNK) && ascgraphics_mode_callback)
(*ascgraphics_mode_callback)();
#endif
#ifdef TERMLIB
#if defined(TERMLIB) || defined(CURSES_GRAPHICS)
/* curses doesn't assign any routine to dec..._callback but
probably does the expected initialization under the hood
for terminals capable of rendering DECgraphics */
if (SYMHANDLING(H_DEC) && decgraphics_mode_callback)
(*decgraphics_mode_callback)();
#endif
# ifdef CURSES_GRAPHICS
/* there aren't any symbol sets with CURS handling, and the
curses interface never assigns a routine to curses..._callback */
if (SYMHANDLING(H_CURS) && cursesgraphics_mode_callback)
(*cursesgraphics_mode_callback)();
# endif
#endif
} else {
init_l_symbols();
init_showsyms();
@@ -553,6 +558,7 @@ const char *known_handling[] = {
"IBM", /* H_IBM */
"DEC", /* H_DEC */
"CURS", /* H_CURS */
"MAC", /* H_MAC -- pre-OSX MACgraphics */
(const char *) 0,
};

View File

@@ -771,6 +771,9 @@ struct obj *obj; /* only scatter this obj */
newsym(x, y);
}
newsym(sx, sy);
if (sx == u.ux && sy == u.uy && u.uundetected
&& hides_under(g.youmonst.data))
(void) hideunder(&g.youmonst);
return total;
}

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 files.c $NHDT-Date: 1562719337 2019/07/10 00:42:17 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.252 $ */
/* NetHack 3.6 files.c $NHDT-Date: 1571347976 2019/10/17 21:32:56 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.254 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Derek S. Ray, 2015. */
/* NetHack may be freely redistributed. See license for details. */
@@ -2342,7 +2342,7 @@ const char *name; /* name of option for error message */
break;
default:
gi_error:
gi_error:
raw_printf("Syntax error in %s", name);
wait_synch();
return count;
@@ -3298,9 +3298,10 @@ boolean FDECL((*proc), (char *));
}
ep = inbuf;
while (*ep == ' ' || *ep == '\t') ep++;
while (*ep == ' ' || *ep == '\t')
++ep;
/* lines beginning with '#' are comments. ignore empty lines. */
/* ingore empty lines and full-line comment lines */
if (!*ep || *ep == '#')
ignoreline = TRUE;
@@ -3309,9 +3310,9 @@ boolean FDECL((*proc), (char *));
/* merge now read line with previous ones, if necessary */
if (!ignoreline) {
len = strlen(inbuf) + 1;
len = (int) strlen(inbuf) + 1;
if (buf)
len += strlen(buf);
len += (int) strlen(buf);
tmpbuf = (char *) alloc(len);
if (buf) {
Sprintf(tmpbuf, "%s %s", buf, inbuf);
@@ -3335,6 +3336,7 @@ boolean FDECL((*proc), (char *));
if (match_varname(buf, "CHOOSE", 6)) {
char *section;
char *bufp = find_optparam(buf);
if (!bufp) {
config_error_add(
"Format is CHOOSE=section1,section2,...");
@@ -3397,10 +3399,11 @@ int which_set;
{
FILE *fp;
g.symset[which_set].explicitly = FALSE;
if (!(fp = fopen_sym_file()))
return 0;
g.symset_count = 0;
g.symset[which_set].explicitly = TRUE;
g.chosen_symset_start = g.chosen_symset_end = FALSE;
g.symset_which_set = which_set;
@@ -3419,7 +3422,14 @@ int which_set;
|| !strcmpi(g.symset[which_set].name, "default")))
clear_symsetentry(which_set, TRUE);
config_error_done();
return (g.symset[which_set].name == 0) ? 1 : 0;
/* If name was defined, it was invalid... Then we're loading fallback */
if (g.symset[which_set].name) {
g.symset[which_set].explicitly = FALSE;
return 0;
}
return 1;
}
if (!g.chosen_symset_end)
config_error_add("Missing finish for symset \"%s\"",
@@ -3490,14 +3500,19 @@ int which_set;
building a pick-list of possible symset
values from the file, so only do that */
if (symp->range == SYM_CONTROL) {
struct symsetentry *tmpsp;
struct symsetentry *tmpsp, *lastsp;
for (lastsp = g.symset_list; lastsp; lastsp = lastsp->next)
if (!lastsp->next)
break;
switch (symp->idx) {
case 0:
tmpsp = (struct symsetentry *) alloc(sizeof *tmpsp);
tmpsp->next = g.symset_list;
g.symset_list = tmpsp;
tmpsp->idx = g.symset_count++;
tmpsp->next = (struct symsetentry *) 0;
if (!lastsp)
g.symset_list = tmpsp;
else
lastsp->next = tmpsp;
tmpsp->name = dupstr(bufp);
tmpsp->desc = (char *) 0;
tmpsp->handling = H_UNK;
@@ -3508,21 +3523,22 @@ int which_set;
break;
case 2:
/* handler type identified */
tmpsp = g.symset_list; /* most recent symset */
tmpsp = lastsp; /* most recent symset */
for (i = 0; known_handling[i]; ++i)
if (!strcmpi(known_handling[i], bufp)) {
tmpsp->handling = i;
break; /* for loop */
}
break;
case 3: /* description:something */
tmpsp = g.symset_list; /* most recent symset */
case 3:
/* description:something */
tmpsp = lastsp; /* most recent symset */
if (tmpsp && !tmpsp->desc)
tmpsp->desc = dupstr(bufp);
break;
case 5:
/* restrictions: xxxx*/
tmpsp = g.symset_list; /* most recent symset */
tmpsp = lastsp; /* most recent symset */
for (i = 0; known_restrictions[i]; ++i) {
if (!strcmpi(known_restrictions[i], bufp)) {
switch (i) {
@@ -4366,7 +4382,7 @@ unsigned oid; /* book identifier */
}
}
cleanup:
cleanup:
(void) dlb_fclose(fp);
if (nowin_buf) {
/* one-line buffer */

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 mkobj.c $NHDT-Date: 1570569798 2019/10/08 21:23:18 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.153 $ */
/* NetHack 3.6 mkobj.c $NHDT-Date: 1570872702 2019/10/12 09:31:42 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.155 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Derek S. Ray, 2015. */
/* NetHack may be freely redistributed. See license for details. */
@@ -235,15 +235,14 @@ boolean init, artif;
struct obj *otmp;
otmp = mksobj(otyp, init, artif);
if (otmp) {
add_to_migration(otmp);
otmp->owornmask = (long) MIGR_TO_SPECIES;
otmp->corpsenm = mflags2;
}
add_to_migration(otmp);
otmp->owornmask = (long) MIGR_TO_SPECIES;
otmp->corpsenm = mflags2;
return otmp;
}
/* mkobj(): select a type of item from a class, use mksobj() to create it */
/* mkobj(): select a type of item from a class, use mksobj() to create it;
result is always non-Null */
struct obj *
mkobj(oclass, artif)
char oclass;
@@ -309,8 +308,7 @@ struct obj *box;
for (n = rn2(n + 1); n > 0; n--) {
if (box->otyp == ICE_BOX) {
if (!(otmp = mksobj(CORPSE, TRUE, TRUE)))
continue;
otmp = mksobj(CORPSE, TRUE, TRUE);
/* Note: setting age to 0 is correct. Age has a different
* from usual meaning for objects stored in ice boxes. -KAA
*/
@@ -768,7 +766,7 @@ static const char dknowns[] = { WAND_CLASS, RING_CLASS, POTION_CLASS,
SCROLL_CLASS, GEM_CLASS, SPBOOK_CLASS,
WEAPON_CLASS, TOOL_CLASS, 0 };
/* mksobj(): create a specific type of object */
/* mksobj(): create a specific type of object; result it always non-Null */
struct obj *
mksobj(otyp, init, artif)
int otyp;
@@ -1062,10 +1060,12 @@ boolean artif;
case COIN_CLASS:
break; /* do nothing */
default:
impossible("impossible mkobj %d, sym '%c'.", otmp->otyp,
objects[otmp->otyp].oc_class);
dealloc_obj(otmp); /* free() would suffice here */
return (struct obj *) 0;
/* 3.6.3: this used to be impossible() followed by return 0
but most callers aren't prepared to deal with Null result
and cluttering them up to do so is pointless */
panic("mksobj tried to make type %d, class %d.",
(int) otmp->otyp, (int) objects[otmp->otyp].oc_class);
/*NOTREACHED*/
}
}
@@ -1473,6 +1473,7 @@ register struct obj *obj;
static const int treefruits[] = { APPLE, ORANGE, PEAR, BANANA, EUCALYPTUS_LEAF };
/* called when a tree is kicked; never returns Null */
struct obj *
rnd_treefruit_at(x, y)
int x, y;
@@ -1480,15 +1481,17 @@ int x, y;
return mksobj_at(treefruits[rn2(SIZE(treefruits))], x, y, TRUE, FALSE);
}
/* create a stack of N gold pieces; never returns Null */
struct obj *
mkgold(amount, x, y)
long amount;
int x, y;
{
register struct obj *gold = g_at(x, y);
struct obj *gold = g_at(x, y);
if (amount <= 0L) {
long mul = rnd(30 / max(12-depth(&u.uz), 2));
amount = (long) (1 + rnd(level_difficulty() + 2) * mul);
}
if (gold) {
@@ -1501,12 +1504,14 @@ int x, y;
return gold;
}
/* return TRUE if the corpse has special timing */
#define special_corpse(num) \
(((num) == PM_LIZARD) || ((num) == PM_LICHEN) || (is_rider(&mons[num])) \
|| (mons[num].mlet == S_TROLL))
/* return TRUE if the corpse has special timing;
lizards and lichen don't rot, trolls and Riders auto-revive */
#define special_corpse(num) \
(((num) == PM_LIZARD || (num) == PM_LICHEN) \
|| (mons[num].mlet == S_TROLL || is_rider(&mons[num])))
/*
/* mkcorpstat: make a corpse or statue; never returns Null.
*
* OEXTRA note: Passing mtmp causes mtraits to be saved
* even if ptr passed as well, but ptr is always used for
* the corpse type (corpsenm). That allows the corpse type
@@ -1523,40 +1528,39 @@ struct permonst *ptr;
int x, y;
unsigned corpstatflags;
{
register struct obj *otmp;
struct obj *otmp;
boolean init = ((corpstatflags & CORPSTAT_INIT) != 0);
if (objtype != CORPSE && objtype != STATUE)
impossible("making corpstat type %d", objtype);
if (x == 0 && y == 0) { /* special case - random placement */
otmp = mksobj(objtype, init, FALSE);
if (otmp)
(void) rloco(otmp);
} else
(void) rloco(otmp);
} else {
otmp = mksobj_at(objtype, x, y, init, FALSE);
if (otmp) {
if (mtmp) {
struct obj *otmp2;
}
if (!ptr)
ptr = mtmp->data;
/* save_mtraits frees original data pointed to by otmp */
otmp2 = save_mtraits(otmp, mtmp);
if (otmp2)
otmp = otmp2;
}
/* use the corpse or statue produced by mksobj() as-is
unless `ptr' is non-null */
if (ptr) {
int old_corpsenm = otmp->corpsenm;
/* when 'mtmp' is non-null save the monster's details with the
corpse or statue; it will also force the 'ptr' override below */
if (mtmp) {
/* save_mtraits updates otmp->oextra->omonst in place */
(void) save_mtraits(otmp, mtmp);
otmp->corpsenm = monsndx(ptr);
otmp->owt = weight(otmp);
if (otmp->otyp == CORPSE && (special_corpse(old_corpsenm)
|| special_corpse(otmp->corpsenm))) {
obj_stop_timers(otmp);
start_corpse_timeout(otmp);
}
if (!ptr)
ptr = mtmp->data;
}
/* when 'ptr' is non-null it comes from our caller or from 'mtmp';
override mkobjs()'s initialization of a random monster type */
if (ptr) {
int old_corpsenm = otmp->corpsenm;
otmp->corpsenm = monsndx(ptr);
otmp->owt = weight(otmp);
if (otmp->otyp == CORPSE && (special_corpse(old_corpsenm)
|| special_corpse(otmp->corpsenm))) {
obj_stop_timers(otmp);
start_corpse_timeout(otmp);
}
}
return otmp;
@@ -1574,15 +1578,14 @@ int
corpse_revive_type(obj)
struct obj *obj;
{
int revivetype;
int revivetype = obj->corpsenm;
struct monst *mtmp;
if (has_omonst(obj)
&& ((mtmp = get_mtraits(obj, FALSE)) != (struct monst *) 0)) {
if (has_omonst(obj) && ((mtmp = get_mtraits(obj, FALSE)) != 0)) {
/* mtmp is a temporary pointer to a monster's stored
attributes, not a real monster */
revivetype = mtmp->mnum;
} else
revivetype = obj->corpsenm;
}
return revivetype;
}
@@ -1658,26 +1661,29 @@ boolean copyof;
return mnew;
}
/* make an object named after someone listed in the scoreboard file */
/* make an object named after someone listed in the scoreboard file;
never returns Null */
struct obj *
mk_tt_object(objtype, x, y)
int objtype; /* CORPSE or STATUE */
register int x, y;
int x, y;
{
register struct obj *otmp, *otmp2;
struct obj *otmp;
boolean initialize_it;
/* player statues never contain books */
initialize_it = (objtype != STATUE);
if ((otmp = mksobj_at(objtype, x, y, initialize_it, FALSE)) != 0) {
/* tt_oname will return null if the scoreboard is empty */
if ((otmp2 = tt_oname(otmp)) != 0)
otmp = otmp2;
}
otmp = mksobj_at(objtype, x, y, initialize_it, FALSE);
/* tt_oname() will return null if the scoreboard is empty;
assigning an object name used to allocate a new obj but
doesn't any more so we can safely ignore the return value */
(void) tt_oname(otmp);
return otmp;
}
/* make a new corpse or statue, uninitialized if a statue (i.e. no books) */
/* make a new corpse or statue, uninitialized if a statue (i.e. no books);
never returns Null */
struct obj *
mk_named_object(objtype, ptr, x, y, nm)
int objtype; /* CORPSE or STATUE */
@@ -1686,8 +1692,8 @@ int x, y;
const char *nm;
{
struct obj *otmp;
unsigned corpstatflags =
(objtype != STATUE) ? CORPSTAT_INIT : CORPSTAT_NONE;
unsigned corpstatflags = (objtype != STATUE) ? CORPSTAT_INIT
: CORPSTAT_NONE;
otmp = mkcorpstat(objtype, (struct monst *) 0, ptr, x, y, corpstatflags);
if (nm)

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 options.c $NHDT-Date: 1567240693 2019/08/31 08:38:13 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.369 $ */
/* NetHack 3.6 options.c $NHDT-Date: 1571347977 2019/10/17 21:32:57 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.379 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Michael Allison, 2008. */
/* NetHack may be freely redistributed. See license for details. */
@@ -803,8 +803,9 @@ initoptions_init()
iflags.wc_align_message = ALIGN_TOP;
iflags.wc_align_status = ALIGN_BOTTOM;
/* these are currently only used by curses */
/* used by tty and curses */
iflags.wc2_statuslines = 2;
/* only used by curses */
iflags.wc2_windowborders = 2; /* 'Auto' */
/* since this is done before init_objects(), do partial init here */
@@ -5268,8 +5269,8 @@ boolean setinitial, setfromfile;
MENU_UNSELECTED);
for (i = 0; i < numapes && ape; i++) {
any.a_void = (opt_idx == 1) ? 0 : ape;
/* length of pattern plus quotes (plus '<'/'>') is less than
BUFSZ */
/* length of pattern plus quotes (plus '<'/'>') is
less than BUFSZ */
Sprintf(apebuf, "\"%c%s\"", ape->grab ? '<' : '>',
ape->pattern);
add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, apebuf,
@@ -5315,18 +5316,27 @@ boolean setinitial, setfromfile;
g.symset[which_set].name = symset_name;
if (res && g.symset_list) {
int thissize, biggest = 0;
int thissize,
biggest = (int) (sizeof "Default Symbols" - sizeof ""),
big_desc = 0;
for (sl = g.symset_list; sl; sl = sl->next) {
/* check restrictions */
if (rogueflag ? sl->primary : sl->rogue)
continue;
#ifndef MAC_GRAPHICS_ENV
if (sl->handling == H_MAC)
continue;
#endif
setcount++;
/* find biggest name */
thissize = sl->name ? (int) strlen(sl->name) : 0;
if (thissize > biggest)
biggest = thissize;
thissize = sl->desc ? (int) strlen(sl->desc) : 0;
if (thissize > big_desc)
big_desc = thissize;
}
if (!setcount) {
pline("There are no appropriate %s symbol sets available.",
@@ -5334,10 +5344,48 @@ boolean setinitial, setfromfile;
return TRUE;
}
Sprintf(fmtstr, "%%-%ds %%s", biggest + 5);
Sprintf(fmtstr, "%%-%ds %%s", biggest + 2);
tmpwin = create_nhwindow(NHW_MENU);
start_menu(tmpwin);
any = cg.zeroany;
#ifdef CURSES_GRAPHICS /* this ought to be handled within curses... */
/*
* Symbol sets are formatted in two columns, "name description",
* on selectable lines. curses bases menu width on the length
* of non-selectable lines (main header, separators if present,
* with trailing spaces ignored) and defaults to half the map.
* Without something like this separator (shown after the menu
* title and a blank line which follows that) to force a wider
* menu, entries with long descriptions wrap. That would be
* ok if wrapping operated on the same two columns, but the
* menu doesn't know anything about those and the description
* is wrapping into the next line's name column, making long
* descriptions--and menus containing them--hard to read.
*/
if (WINDOWPORT("curses")) {
char tmp1[BUFSZ], tmp2[BUFSZ], bigbuf[BUFSZ + 1 + BUFSZ];
/* 4: room for space+letter+paren+space, fake selector;
2: added to 'biggest' when constructing 'fmtstr';
1: space between symset name+2 and symset description */
if (4 + biggest + 2 + 1 > (int) sizeof tmp1 - 1)
biggest = (int) sizeof tmp1 - 1 - (4 + 2 + 1);
(void) memset((genericptr_t) tmp1, '-', biggest);
tmp1[biggest] = '\0';
if (big_desc > (int) sizeof tmp2 - 1)
big_desc = (int) sizeof tmp2 - 1;
(void) memset((genericptr_t) tmp2, '-', big_desc);
tmp2[big_desc] = '\0';
Sprintf(bigbuf, "%4s", "");
Sprintf(eos(bigbuf), fmtstr, tmp1, tmp2);
bigbuf[BUFSZ - 1] = '\0';
any.a_int = 0;
add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE,
bigbuf, MENU_UNSELECTED);
}
#else
nhUse(big_desc);
#endif
any.a_int = 1;
add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE,
"Default Symbols", MENU_UNSELECTED);
@@ -5346,6 +5394,10 @@ boolean setinitial, setfromfile;
/* check restrictions */
if (rogueflag ? sl->primary : sl->rogue)
continue;
#ifndef MAC_GRAPHICS_ENV
if (sl->handling == H_MAC)
continue;
#endif
if (sl->name) {
any.a_int = sl->idx + 2;

View File

@@ -118,6 +118,8 @@ pick_move:
}
if (nix != omx || niy != omy) {
if (MON_AT(nix, niy))
return 0;
remove_monster(omx, omy);
place_monster(mtmp, nix, niy);
newsym(nix, niy);

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 sounds.c $NHDT-Date: 1542765362 2018/11/21 01:56:02 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.81 $ */
/* NetHack 3.6 sounds.c $NHDT-Date: 1570844005 2019/10/12 01:33:25 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.83 $ */
/* Copyright (c) 1989 Janet Walz, Mike Threepoint */
/* NetHack may be freely redistributed. See license for details. */
@@ -496,7 +496,7 @@ register struct monst *mtmp;
*verbl_msg = 0, /* verbalize() */
*verbl_msg_mcan = 0; /* verbalize() if cancelled */
struct permonst *ptr = mtmp->data;
int msound = ptr->msound;
int msound = ptr->msound, gnomeplan = 0;
/* presumably nearness and sleep checks have already been made */
if (Deaf)
@@ -512,8 +512,9 @@ register struct monst *mtmp;
msound = mons[genus(monsndx(ptr), 1)].msound;
/* some normally non-speaking types can/will speak if hero is similar */
else if (msound == MS_ORC /* note: MS_ORC is same as MS_GRUNT */
&& (same_race(ptr, g.youmonst.data) /* current form, */
|| same_race(ptr, &mons[Race_switch]))) /* unpoly'd form */
&& ((same_race(ptr, g.youmonst.data) /* current form, */
|| same_race(ptr, &mons[Race_switch])) /* unpoly'd form */
|| Hallucination))
msound = MS_HUMANOID;
/* silliness, with slight chance to interfere with shopping */
else if (Hallucination && mon_is_gecko(mtmp))
@@ -588,13 +589,14 @@ register struct monst *mtmp;
} else
verbl_msg = "I only drink... potions.";
} else {
int vampindex;
static const char *const vampmsg[] = {
/* These first two (0 and 1) are specially handled below */
"I vant to suck your %s!",
"I vill come after %s without regret!",
/* other famous vampire quotes can follow here if desired */
};
int vampindex;
if (kindred)
verbl_msg =
"This is my hunting ground that you dare to prowl!";
@@ -803,6 +805,18 @@ register struct monst *mtmp;
pline_msg = "talks about spellcraft.";
else if (ptr->mlet == S_CENTAUR)
pline_msg = "discusses hunting.";
else if (is_gnome(ptr) && Hallucination && (gnomeplan = rn2(4)) % 2)
/* skipped for rn2(4) result of 0 or 2;
gag from an early episode of South Park called "Gnomes";
initially, Tweek (introduced in that episode) is the only
one aware of the tiny gnomes after spotting them sneaking
about; they are embarked upon a three-step business plan;
a diagram of the plan shows:
Phase 1 Phase 2 Phase 3
Collect underpants ? Profit
and they never verbalize step 2 so we don't either */
verbl_msg = (gnomeplan == 1) ? "Phase one, collect underpants."
: "Phase three, profit!";
else
switch (monsndx(ptr)) {
case PM_HOBBIT:

View File

@@ -1827,7 +1827,6 @@ int style;
g.bhitpos.x += dx;
g.bhitpos.y += dy;
t = t_at(g.bhitpos.x, g.bhitpos.y);
if ((mtmp = m_at(g.bhitpos.x, g.bhitpos.y)) != 0) {
if (otyp == BOULDER && throws_rocks(mtmp->data)) {
@@ -1862,7 +1861,7 @@ int style;
break;
}
}
if (t && otyp == BOULDER) {
if ((t = t_at(g.bhitpos.x, g.bhitpos.y)) != 0 && otyp == BOULDER) {
switch (t->ttyp) {
case LANDMINE:
if (rn2(10) > 2) {
@@ -2155,6 +2154,7 @@ register struct monst *mtmp;
inescapable = g.force_mintrap || ((tt == HOLE || tt == PIT)
&& Sokoban && !trap->madeby_u);
const char *fallverb;
xchar tx = trap->tx, ty = trap->ty;
/* true when called from dotrap, inescapable is not an option */
if (mtmp == u.usteed)
@@ -2637,7 +2637,7 @@ register struct monst *mtmp;
trapkilled = TRUE;
}
/* a boulder may fill the new pit, crushing monster */
fill_pit(trap->tx, trap->ty);
fill_pit(tx, ty); /* thitm may have already destroyed the trap */
if (DEADMONSTER(mtmp))
trapkilled = TRUE;
if (unconscious()) {
@@ -4325,8 +4325,8 @@ struct trap *ttmp;
You("pull %s out of the pit.", mon_nam(mtmp));
mtmp->mtrapped = 0;
fill_pit(mtmp->mx, mtmp->my);
reward_untrap(ttmp, mtmp);
fill_pit(mtmp->mx, mtmp->my);
return 1;
}

View File

@@ -775,9 +775,10 @@ register struct monst *grd;
if (!u_in_vault
&& (grd_in_vault || (in_fcorridor(grd, grd->mx, grd->my)
&& !in_fcorridor(grd, u.ux, u.uy)))) {
(void) rloc(grd, FALSE);
(void) rloc(grd, TRUE);
wallify_vault(grd);
(void) clear_fcorr(grd, TRUE);
if (!in_fcorridor(grd, grd->mx, grd->my))
(void) clear_fcorr(grd, TRUE);
goto letknow;
}
if (!in_fcorridor(grd, grd->mx, grd->my))