Merge branch 'NetHack-3.6'
This commit is contained in:
@@ -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 */
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
50
src/files.c
50
src/files.c
@@ -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 */
|
||||
|
||||
128
src/mkobj.c
128
src/mkobj.c
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
24
src/sounds.c
24
src/sounds.c
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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))
|
||||
|
||||
Reference in New Issue
Block a user