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

This commit is contained in:
keni
2017-10-08 14:00:50 -04:00
86 changed files with 8633 additions and 272 deletions
+1
View File
@@ -267,6 +267,7 @@ boolean resuming;
(void) dosearch0(1);
if (Warning)
warnreveal();
mkot_trap_warn();
dosounds();
do_storms();
gethungry();
+3 -13
View File
@@ -408,11 +408,8 @@ register struct obj *obj;
map_invisible(rx, ry);
return res;
}
if (glyph_is_invisible(levl[rx][ry].glyph)) {
unmap_object(rx, ry);
newsym(rx, ry);
if (unmap_invisible(rx,ry))
pline_The("invisible monster must have moved.");
}
lev = &levl[rx][ry];
switch (lev->typ) {
@@ -631,10 +628,7 @@ struct obj *obj;
if (!(mtmp = m_at(cc.x, cc.y))) {
There("is no creature there.");
if (glyph_is_invisible(levl[cc.x][cc.y].glyph)) {
unmap_object(cc.x, cc.y);
newsym(cc.x, cc.y);
}
(void) unmap_invisible(cc.x, cc.y);
return 1;
}
@@ -3030,11 +3024,7 @@ struct obj *obj;
}
} else {
/* no monster here and no statue seen or remembered here */
if (glyph_is_invisible(glyph)) {
/* now you know that nothing is there... */
unmap_object(bhitpos.x, bhitpos.y);
newsym(bhitpos.x, bhitpos.y);
}
(void) unmap_invisible(bhitpos.x, bhitpos.y);
You("miss; there is no one there to hit.");
}
u_wipe_engr(2); /* same as for melee or throwing */
+102
View File
@@ -27,6 +27,7 @@ STATIC_DCL boolean FDECL(Mb_hit, (struct monst * magr, struct monst *mdef,
STATIC_DCL unsigned long FDECL(abil_to_spfx, (long *));
STATIC_DCL uchar FDECL(abil_to_adtyp, (long *));
STATIC_DCL boolean FDECL(untouchable, (struct obj *, BOOLEAN_P));
STATIC_DCL int FDECL(count_surround_traps, (int, int));
/* The amount added to the victim's total hit points to insure that the
victim will be killed even after damage bonus/penalty adjustments.
@@ -2051,4 +2052,105 @@ int dropflag; /* 0==don't drop, 1==drop all, 2==drop weapon */
clear_bypasses(); /* reset upon final exit */
}
static int mkot_trap_warn_count = 0;
STATIC_OVL int
count_surround_traps(x, y)
int x, y;
{
struct rm *levp;
struct obj *otmp;
struct trap *ttmp;
int dx, dy, glyph, ret = 0;
for (dx = x - 1; dx < x + 2; ++dx)
for (dy = y - 1; dy < y + 2; ++dy) {
if (!isok(dx, dy))
continue;
/* If a trap is shown here, don't count it; the hero
* should be expecting it. But if there is a trap here
* that's not shown, either undiscovered or covered by
* something, do count it.
*/
glyph = glyph_at(dx, dy);
if (glyph_is_trap(glyph))
continue;
if ((ttmp = t_at(dx, dy)) != 0) {
++ret;
continue;
}
levp = &levl[dx][dy];
if (IS_DOOR(levp->typ) && (levp->doormask & D_TRAPPED) != 0) {
++ret;
continue;
}
for (otmp = level.objects[dx][dy]; otmp; otmp = otmp->nexthere)
if (Is_container(otmp) && otmp->otrapped) {
++ret; /* we're counting locations, so just */
break; /* count the first one in a pile */
}
}
/*
* [Shouldn't we also check inventory for a trapped container?
* Even if its trap has already been found, there's no 'tknown'
* flag to help hero remember that so we have nothing comparable
* to a shown glyph to justify skipping it.]
*/
return ret;
}
/* sense adjacent traps if wielding MKoT without wearing gloves */
void
mkot_trap_warn()
{
static const char *const heat[7] = {
"cool", "slightly warm", "warm", "very warm",
"hot", "very hot", "like fire"
};
if (!uarmg && uwep && uwep->oartifact == ART_MASTER_KEY_OF_THIEVERY) {
int idx, ntraps = count_surround_traps(u.ux, u.uy);
if (ntraps != mkot_trap_warn_count) {
idx = min(ntraps, SIZE(heat) - 1);
pline_The("Key feels %s%c", heat[idx], (ntraps > 3) ? '!' : '.');
}
mkot_trap_warn_count = ntraps;
} else
mkot_trap_warn_count = 0;
}
/* Master Key is magic key if its bless/curse state meets our criteria:
not cursed for rogues or blessed for non-rogues */
boolean
is_magic_key(mon, obj)
struct monst *mon; /* if null, non-rogue is assumed */
struct obj *obj;
{
if (((obj && obj->oartifact == ART_MASTER_KEY_OF_THIEVERY)
&& ((mon == &youmonst) ? Role_if(PM_ROGUE)
: (mon && mon->data == &mons[PM_ROGUE])))
? !obj->cursed : obj->blessed)
return TRUE;
return FALSE;
}
/* figure out whether 'mon' (usually youmonst) is carrying the magic key */
struct obj *
has_magic_key(mon)
struct monst *mon; /* if null, hero assumed */
{
struct obj *o;
short key = artilist[ART_MASTER_KEY_OF_THIEVERY].otyp;
if (!mon)
mon = &youmonst;
for (o = ((mon == &youmonst) ? invent : mon->minvent); o;
o = nxtobj(o, key, FALSE)) {
if (is_magic_key(mon, o))
return o;
}
return (struct obj *) 0;
}
/*artifact.c*/
+6 -2
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 botl.c $NHDT-Date: 1469930895 2016/07/31 02:08:15 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.75 $ */
/* NetHack 3.6 botl.c $NHDT-Date: 1506903619 2017/10/02 00:20:19 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.81 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -12,7 +12,9 @@ const char *const enc_stat[] = { "", "Burdened", "Stressed",
STATIC_OVL NEARDATA int mrank_sz = 0; /* loaded by max_rank_sz (from u_init) */
STATIC_DCL const char *NDECL(rank);
#ifdef STATUS_HILITES
STATIC_DCL void NDECL(bot_via_windowport);
#endif
static char *
get_strength_str()
@@ -1060,6 +1062,7 @@ int anytype;
return buf;
}
#ifdef STATUS_HILITES
STATIC_OVL void
s_to_anything(a, buf, anytype)
anything *a;
@@ -1107,6 +1110,7 @@ int anytype;
}
return;
}
#endif /* STATUS_HILITES */
STATIC_OVL int
percentage(bl, maxbl)
@@ -2330,7 +2334,7 @@ int fld;
}
int
count_status_hilites()
count_status_hilites(VOID_ARGS)
{
int count;
status_hilite_linestr_gather();
+3 -6
View File
@@ -117,7 +117,6 @@ static int NDECL((*timed_occ_fn));
STATIC_PTR int NDECL(doprev_message);
STATIC_PTR int NDECL(timed_occupation);
STATIC_PTR int NDECL(doextcmd);
STATIC_PTR int NDECL(domonability);
STATIC_PTR int NDECL(dotravel);
STATIC_PTR int NDECL(doterrain);
STATIC_PTR int NDECL(wiz_wish);
@@ -164,9 +163,7 @@ STATIC_DCL boolean FDECL(accept_menu_prefix, (int NDECL((*))));
STATIC_DCL int NDECL(wiz_port_debug);
#endif
STATIC_PTR int NDECL(wiz_rumor_check);
STATIC_DCL char FDECL(cmd_from_func, (int NDECL((*))));
STATIC_PTR int NDECL(doattributes);
STATIC_PTR int NDECL(doconduct); /**/
STATIC_DCL void FDECL(enlght_line, (const char *, const char *, const char *,
const char *));
@@ -523,7 +520,7 @@ extcmd_via_menu()
#endif /* TTY_GRAPHICS */
/* #monster command - use special monster ability while polymorphed */
STATIC_PTR int
int
domonability(VOID_ARGS)
{
if (can_breathe(youmonst.data))
@@ -2734,7 +2731,7 @@ int msgflag; /* for variant message phrasing */
/* KMH, #conduct
* (shares enlightenment's tense handling)
*/
STATIC_PTR int
int
doconduct(VOID_ARGS)
{
show_conduct(0);
@@ -3283,7 +3280,7 @@ dokeylist(VOID_ARGS)
destroy_nhwindow(datawin);
}
STATIC_OVL char
char
cmd_from_func(fn)
int NDECL((*fn));
{
+3 -8
View File
@@ -1394,9 +1394,7 @@ genericptr_t num;
}
if (!canspotmon(mtmp) && !glyph_is_invisible(levl[zx][zy].glyph))
map_invisible(zx, zy);
} else if (glyph_is_invisible(levl[zx][zy].glyph)) {
unmap_object(zx, zy);
newsym(zx, zy);
} else if (unmap_invisible(zx, zy)) {
(*(int *) num)++;
}
}
@@ -1646,11 +1644,8 @@ register int aflag; /* intrinsic autosearch vs explicit searching */
/* see if an invisible monster has moved--if Blind,
* feel_location() already did it
*/
if (!aflag && !mtmp && !Blind
&& glyph_is_invisible(levl[x][y].glyph)) {
unmap_object(x, y);
newsym(x, y);
}
if (!aflag && !mtmp && !Blind)
(void) unmap_invisible(x, y);
if ((trap = t_at(x, y)) && !trap->tseen && !rnl(8)) {
nomul(0);
+13
View File
@@ -277,6 +277,19 @@ register xchar x, y;
}
}
boolean
unmap_invisible(x, y)
int x, y;
{
if (isok(x,y) && glyph_is_invisible(levl[x][y].glyph)) {
unmap_object(x, y);
newsym(x, y);
return TRUE;
}
return FALSE;
}
/*
* unmap_object()
*
+2 -8
View File
@@ -262,10 +262,7 @@ doit:
} else {
maybe_mnexto(mon);
if (mon->mx != x || mon->my != y) {
if (glyph_is_invisible(levl[x][y].glyph)) {
unmap_object(x, y);
newsym(x, y);
}
(void) unmap_invisible(x, y);
pline("%s %s, %s evading your %skick.", Monnam(mon),
(!level.flags.noteleport && can_teleport(mon->data))
? "teleports"
@@ -946,10 +943,7 @@ dokick()
}
return 1;
}
if (glyph_is_invisible(levl[x][y].glyph)) {
unmap_object(x, y);
newsym(x, y);
}
(void) unmap_invisible(x, y);
if (is_pool(x, y) ^ !!u.uinwater) {
/* objects normally can't be removed from water by kicking */
You("splash some %s around.", hliquid("water"));
+2 -5
View File
@@ -219,11 +219,8 @@ int expltype;
}
if (mtmp && cansee(i + x - 1, j + y - 1) && !canspotmon(mtmp))
map_invisible(i + x - 1, j + y - 1);
else if (!mtmp && glyph_is_invisible(
levl[i + x - 1][j + y - 1].glyph)) {
unmap_object(i + x - 1, j + y - 1);
newsym(i + x - 1, j + y - 1);
}
else if (!mtmp)
(void) unmap_invisible(i + x - 1, j + y - 1);
if (cansee(i + x - 1, j + y - 1))
visible = TRUE;
if (explmask[i][j] == 1)
+1 -4
View File
@@ -1635,10 +1635,7 @@ domove()
}
return;
}
if (glyph_is_invisible(levl[x][y].glyph)) {
unmap_object(x, y);
newsym(x, y);
}
(void) unmap_invisible(x, y);
/* not attacking an animal, so we try to move */
if ((u.dx || u.dy) && u.usteed && stucksteed(FALSE)) {
nomul(0);
+48 -7
View File
@@ -4,17 +4,19 @@
#include "hack.h"
STATIC_PTR int NDECL(picklock);
STATIC_PTR int NDECL(forcelock);
/* at most one of `door' and `box' should be non-null at any given time */
STATIC_VAR NEARDATA struct xlock_s {
struct rm *door;
struct obj *box;
int picktyp, /* key|pick|card for unlock, sharp vs blunt for #force */
chance, usedtime;
boolean magic_key;
} xlock;
/* occupation callbacks */
STATIC_PTR int NDECL(picklock);
STATIC_PTR int NDECL(forcelock);
STATIC_DCL const char *NDECL(lock_action);
STATIC_DCL boolean FDECL(obstructed, (int, int, BOOLEAN_P));
STATIC_DCL void FDECL(chest_shatter_msg, (struct obj *));
@@ -105,6 +107,40 @@ picklock(VOID_ARGS)
if (rn2(100) >= xlock.chance)
return 1; /* still busy */
/* using the Master Key of Thievery finds traps if its bless/curse
state is adequate (non-cursed for rogues, blessed for others;
checked when setting up 'xlock') */
if ((!xlock.door ? (int) xlock.box->otrapped
: (xlock.door->doormask & D_TRAPPED) != 0)
&& xlock.magic_key) {
xlock.chance += 20; /* less effort needed next time */
/* unfortunately we don't have a 'tknown' flag to record
"known to be trapped" so declining to disarm and then
retrying lock manipulation will find it all over again */
if (yn("You find a trap! Do you want to try to disarm it?") == 'y') {
const char *what;
boolean alreadyunlocked;
/* disarming while using magic key always succeeds */
if (xlock.door) {
xlock.door->doormask &= ~D_TRAPPED;
what = "door";
alreadyunlocked = !(xlock.door->doormask & D_LOCKED);
} else {
xlock.box->otrapped = 0;
what = (xlock.box->otyp == CHEST) ? "chest" : "box";
alreadyunlocked = !xlock.box->olocked;
}
You("succeed in disarming the trap. The %s is still %slocked.",
what, alreadyunlocked ? "un" : "");
exercise(A_WIS, TRUE);
} else {
You("stop %s.", lock_action());
exercise(A_WIS, FALSE);
}
return ((xlock.usedtime = 0));
}
You("succeed in %s.", lock_action());
if (xlock.door) {
if (xlock.door->doormask & D_TRAPPED) {
@@ -225,6 +261,7 @@ void
reset_pick()
{
xlock.usedtime = xlock.chance = xlock.picktyp = 0;
xlock.magic_key = FALSE;
xlock.door = 0;
xlock.box = 0;
}
@@ -264,6 +301,7 @@ struct obj *pick;
if (nohands(youmonst.data)) {
const char *what = (picktyp == LOCK_PICK) ? "pick" : "key";
if (picktyp == CREDIT_CARD)
what = "card";
pline(no_longer, "hold the", what);
@@ -277,6 +315,7 @@ struct obj *pick;
const char *action = lock_action();
You("resume your attempt at %s.", action);
xlock.magic_key = is_magic_key(&youmonst, pick);
set_occupation(picklock, action, 0);
return PICKLOCK_DID_SOMETHING;
}
@@ -291,8 +330,9 @@ struct obj *pick;
return PICKLOCK_DID_NOTHING;
}
if ((picktyp != LOCK_PICK && picktyp != CREDIT_CARD
&& picktyp != SKELETON_KEY)) {
if (picktyp != LOCK_PICK
&& picktyp != CREDIT_CARD
&& picktyp != SKELETON_KEY) {
impossible("picking lock with object %d?", picktyp);
return PICKLOCK_DID_NOTHING;
}
@@ -375,7 +415,6 @@ struct obj *pick;
if (otmp->cursed)
ch /= 2;
xlock.picktyp = picktyp;
xlock.box = otmp;
xlock.door = 0;
break;
@@ -407,7 +446,7 @@ struct obj *pick;
} else if (mtmp && is_door_mappear(mtmp)) {
/* "The door actually was a <mimic>!" */
stumble_onto_mimic(mtmp);
/* mimic might keep the key (50% chance, 10% for PYEC) */
/* mimic might keep the key (50% chance, 10% for PYEC or MKoT) */
maybe_absorb_item(mtmp, pick, 50, 10);
return PICKLOCK_LEARNED_SOMETHING;
}
@@ -462,6 +501,7 @@ struct obj *pick;
context.move = 0;
xlock.chance = ch;
xlock.picktyp = picktyp;
xlock.magic_key = is_magic_key(&youmonst, pick);
xlock.usedtime = 0;
set_occupation(picklock, lock_action(), 0);
return PICKLOCK_DID_SOMETHING;
@@ -531,6 +571,7 @@ doforce()
xlock.box = otmp;
xlock.chance = objects[uwep->otyp].oc_wldam * 2;
xlock.picktyp = picktyp;
xlock.magic_key = FALSE;
xlock.usedtime = 0;
break;
}
+10
View File
@@ -1246,6 +1246,16 @@ postmov:
boolean btrapped = (here->doormask & D_TRAPPED) != 0,
observeit = canseeit && canspotmon(mtmp);
/* if mon has MKoT, disarm door trap; no message given */
if (btrapped && has_magic_key(mtmp)) {
/* BUG: this lets a vampire or blob or a doorbuster
holding the Key disarm the trap even though it isn't
using that Key when squeezing under or smashing the
door. Not significant enough to worry about; perhaps
the Key's magic is more powerful for monsters? */
here->doormask &= ~D_TRAPPED;
btrapped = FALSE;
}
if ((here->doormask & (D_LOCKED | D_CLOSED)) != 0
&& (amorphous(ptr)
|| (can_fog(mtmp)
+95 -35
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 options.c $NHDT-Date: 1505214875 2017/09/12 11:14:35 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.302 $ */
/* NetHack 3.6 options.c $NHDT-Date: 1507164574 2017/10/05 00:49:34 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.311 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -131,9 +131,7 @@ static struct Bool_Opt {
{ "help", &flags.help, TRUE, SET_IN_GAME },
{ "hilite_pet", &iflags.wc_hilite_pet, FALSE, SET_IN_GAME }, /*WC*/
{ "hilite_pile", &iflags.hilite_pile, FALSE, SET_IN_GAME },
#ifdef STATUS_HILITES
{ "hitpointbar", &iflags.wc2_hitpointbar, FALSE, SET_IN_GAME }, /*WC2*/
#endif
#ifndef MAC
{ "ignintr", &flags.ignintr, FALSE, SET_IN_GAME },
#else
@@ -654,7 +652,7 @@ initoptions()
* lists of usernames into arrays with one name per element.
*/
#endif
#endif
#endif /* SYSCF */
initoptions_finish();
}
@@ -811,12 +809,12 @@ initoptions_finish()
config_error_done();
}
} else
#endif
{
config_error_init(TRUE, (char *) 0, FALSE);
read_config_file((char *) 0, SET_IN_FILE);
config_error_done();
}
#endif /* !MAC */
/*else*/ {
config_error_init(TRUE, (char *) 0, FALSE);
read_config_file((char *) 0, SET_IN_FILE);
config_error_done();
}
(void) fruitadd(pl_fruit, (struct fruit *) 0);
/*
@@ -830,6 +828,19 @@ initoptions_finish()
if (iflags.bouldersym)
update_bouldersym();
reglyph_darkroom();
#ifdef STATUS_HILITES
/*
* A multi-interface binary might only support status highlighting
* for some of the interfaces; check whether we asked for it but are
* using one which doesn't.
*/
if (iflags.hilite_delta && !wc2_supported("statushilites")) {
raw_printf("Status highlighting not supported for %s interface.",
windowprocs.name);
iflags.hilite_delta = 0;
}
#endif
return;
}
@@ -1595,7 +1606,7 @@ int hide_mask;
}
STATIC_OVL int
msgtype_count()
msgtype_count(VOID_ARGS)
{
int c = 0;
struct plinemsg_type *tmp = plinemsg_types;
@@ -1736,7 +1747,7 @@ char *tmpstr;
boolean
get_menu_coloring(str, color, attr)
char *str;
const char *str;
int *color, *attr;
{
struct menucoloring *tmpmc;
@@ -1793,7 +1804,7 @@ int idx; /* 0 .. */
}
STATIC_OVL int
count_menucolors()
count_menucolors(VOID_ARGS)
{
int count = 0;
struct menucoloring *tmp = menu_colorings;
@@ -2172,8 +2183,9 @@ boolean tinitial, tfrom_file;
symset[PRIMARY].name = dupstr(op);
if (!read_sym_file(PRIMARY)) {
clear_symsetentry(PRIMARY, TRUE);
config_error_add("Unable to load symbol set \"%s\" from \"%s\"",
op, SYMBOLS);
config_error_add(
"Unable to load symbol set \"%s\" from \"%s\"",
op, SYMBOLS);
return FALSE;
} else {
switch_symbols(symset[PRIMARY].name != (char *) 0);
@@ -2558,11 +2570,12 @@ boolean tinitial, tfrom_file;
return warning_opts(opts, fullname);
}
#ifdef BACKWARD_COMPAT
/* boulder:symbol */
fullname = "boulder";
if (match_optname(opts, fullname, 7, TRUE)) {
#ifdef BACKWARD_COMPAT
int clash = 0;
if (duplicate)
complain_about_duplicate(opts, 1);
if (negated) {
@@ -2583,7 +2596,7 @@ boolean tinitial, tfrom_file;
symbol which is not good - reject it*/
config_error_add(
"Badoption - boulder symbol '%c' conflicts with a %s symbol.",
opts[0], (clash == 1) ? "monster" : "warning");
opts[0], (clash == 1) ? "monster" : "warning");
} else {
/*
* Override the default boulder symbol.
@@ -2597,8 +2610,12 @@ boolean tinitial, tfrom_file;
need_redraw = TRUE;
}
return retval;
}
#else
config_error_add("'%s' no longer supported; use S_boulder:c instead",
fullname);
return FALSE;
#endif
}
/* name:string */
fullname = "name";
@@ -2866,7 +2883,8 @@ boolean tinitial, tfrom_file;
op++;
}
if (badopt) {
config_error_add("Unknown %s parameter '%s'", "pickup_types", op);
config_error_add("Unknown %s parameter '%s'",
"pickup_types", op);
return FALSE;
}
}
@@ -3351,6 +3369,7 @@ boolean tinitial, tfrom_file;
return FALSE;
return retval;
}
#ifdef WINCHAIN
fullname = "windowchain";
if (match_optname(opts, fullname, 3, TRUE)) {
@@ -3465,9 +3484,10 @@ boolean tinitial, tfrom_file;
return retval;
}
}
#ifdef STATUS_HILITES
/* hilite fields in status prompt */
if (match_optname(opts, "hilite_status", 13, TRUE)) {
fullname = "hilite_status";
if (match_optname(opts, fullname, 13, TRUE)) {
#ifdef STATUS_HILITES
if (duplicate)
complain_about_duplicate(opts, 1);
op = string_for_opt(opts, TRUE);
@@ -3481,11 +3501,16 @@ boolean tinitial, tfrom_file;
if (!parse_status_hl1(op, tfrom_file))
return FALSE;
return retval;
#else
config_error_add("'%s' is not supported", fullname);
return FALSE;
#endif
}
/* control over whether highlights should be displayed, and for how long */
fullname = "statushilites";
if (match_optname(opts, fullname, 9, TRUE)) {
#ifdef STATUS_HILITES
if (negated) {
iflags.hilite_delta = 0L;
} else {
@@ -3497,12 +3522,15 @@ boolean tinitial, tfrom_file;
if (!tfrom_file)
reset_status_hilites();
return retval;
}
#else
config_error_add("'%s' is not supported", fullname);
return FALSE;
#endif
}
#if defined(BACKWARD_COMPAT)
fullname = "DECgraphics";
if (match_optname(opts, fullname, 3, TRUE)) {
#ifdef BACKWARD_COMPAT
boolean badflag = FALSE;
if (duplicate)
@@ -3525,9 +3553,16 @@ boolean tinitial, tfrom_file;
}
}
return retval;
}
#else
config_error_add("'%s' no longer supported; use 'symset:%s' instead",
fullname, fullname);
return FALSE;
#endif
} /* "DECgraphics" */
fullname = "IBMgraphics";
if (match_optname(opts, fullname, 3, TRUE)) {
#ifdef BACKWARD_COMPAT
const char *sym_name = fullname;
boolean badflag = FALSE;
@@ -3558,11 +3593,16 @@ boolean tinitial, tfrom_file;
}
}
return retval;
}
#else
config_error_add("'%s' no longer supported; use 'symset:%s' instead",
fullname, fullname);
return FALSE;
#endif
#ifdef MAC_GRAPHICS_ENV
} /* "IBMgraphics" */
fullname = "MACgraphics";
if (match_optname(opts, fullname, 3, TRUE)) {
#if defined(MAC_GRAPHICS_ENV) && defined(BACKWARD_COMPAT)
boolean badflag = FALSE;
if (duplicate)
@@ -3587,8 +3627,18 @@ boolean tinitial, tfrom_file;
}
}
return retval;
}
#else /* !(MAC_GRAPHICS_ENV && BACKWARD_COMPAT) */
config_error_add("'%s' %s; use 'symset:%s' instead",
fullname,
#ifdef MAC_GRAPHICS_ENV /* implies BACKWARD_COMPAT is not defined */
"no longer supported",
#else
"is not supported",
#endif
fullname);
return FALSE;
#endif /* ?(MAC_GRAPHICS_ENV && BACKWARD_COMPAT) */
} /* "MACgraphics" */
/* OK, if we still haven't recognized the option, check the boolean
* options list
@@ -3612,7 +3662,9 @@ boolean tinitial, tfrom_file;
if (op) {
if (negated) {
config_error_add("Negated boolean '%s' should not have a parameter", boolopt[i].name);
config_error_add(
"Negated boolean '%s' should not have a parameter",
boolopt[i].name);
return FALSE;
}
if (!strcmp(op, "true") || !strcmp(op, "yes")) {
@@ -3673,9 +3725,11 @@ boolean tinitial, tfrom_file;
|| boolopt[i].addr == &iflags.hilite_pile
|| boolopt[i].addr == &iflags.hilite_pet) {
need_redraw = TRUE;
} else if ((boolopt[i].addr) == &iflags.wc2_hitpointbar) {
#ifdef STATUS_HILITES
} else if (boolopt[i].addr == &iflags.wc2_hitpointbar) {
status_initialize(REASSESS_ONLY);
need_redraw = TRUE;
#endif
#ifdef TEXTCOLOR
} else if (boolopt[i].addr == &iflags.use_color) {
need_redraw = TRUE;
@@ -3964,7 +4018,7 @@ int nset;
}
int
count_apes()
count_apes(VOID_ARGS)
{
return count_ape_maps((int *) 0, (int *) 0);
}
@@ -4117,9 +4171,13 @@ doset() /* changing options via menu by Per Liboriussen */
"Other settings:",
MENU_UNSELECTED);
for (i = 0; othropt[i].name; i++)
opts_add_others(tmpwin, othropt[i].name, othropt[i].code,
NULL, othropt[i].othr_count_func());
for (i = 0; (name = othropt[i].name) != 0; i++) {
if ((is_wc_option(name) && !wc_supported(name))
|| (is_wc2_option(name) && !wc2_supported(name)))
continue;
opts_add_others(tmpwin, name, othropt[i].code,
(char *) 0, othropt[i].othr_count_func());
}
#ifdef PREFIXES_IN_USE
any = zeroany;
@@ -6037,10 +6095,12 @@ struct wc_Opt wc2_options[] = { { "fullscreen", WC2_FULLSCREEN },
{ "softkeyboard", WC2_SOFTKEYBOARD },
{ "wraptext", WC2_WRAPTEXT },
{ "use_darkgray", WC2_DARKGRAY },
#ifdef STATUS_HILITES
{ "hitpointbar", WC2_HITPOINTBAR },
{ "hilite_status", WC2_HILITE_STATUS },
#endif
/* name shown in 'O' menu is different */
{ "status hilite rules", WC2_HILITE_STATUS },
/* statushilites doesn't have its own bit */
{ "statushilites", WC2_HILITE_STATUS },
{ (char *) 0, 0L } };
/*
-2
View File
@@ -110,8 +110,6 @@ set_uasmon()
#ifdef STATUS_HILITES
status_initialize(REASSESS_ONLY);
#endif
polysense();
}
/* Levitation overrides Flying; set or clear BFlying|I_SPECIAL */
+1 -1
View File
@@ -1243,7 +1243,7 @@ const char *objphrase; /* "Your widget glows" or "Steed's saddle glows" */
return res;
}
/* potion obj hits monster mon, which might be youmonst; obj always use up */
/* potion obj hits monster mon, which might be youmonst; obj always used up */
void
potionhit(mon, obj, how)
struct monst *mon;
+1 -1
View File
@@ -7,7 +7,7 @@
STATIC_DCL void FDECL(center, (int, char *));
#if defined(TTY_GRAPHICS) || defined(X11_GRAPHICS) || defined(GEM_GRAPHICS) \
|| defined(MSWIN_GRAPHICS)
|| defined(MSWIN_GRAPHICS) || defined(DUMPLOG)
#define TEXT_TOMBSTONE
#endif
#if defined(mac) || defined(__BEOS__) || defined(WIN32_GRAPHICS)
+9 -3
View File
@@ -4242,8 +4242,9 @@ boolean force;
struct trap *ttmp;
struct monst *mtmp;
const char *trapdescr;
boolean here, useplural, confused = (Confusion || Hallucination),
trap_skipped = FALSE, deal_with_floor_trap;
boolean here, useplural, deal_with_floor_trap,
confused = (Confusion || Hallucination),
trap_skipped = FALSE;
int boxcnt = 0;
char the_trap[BUFSZ], qbuf[QBUFSZ];
@@ -4255,6 +4256,11 @@ boolean force;
pline_The("perils lurking there are beyond your grasp.");
return 0;
}
/* 'force' is true for #invoke; make it be true for #untrap if
carrying MKoT */
if (!force && has_magic_key(&youmonst))
force = TRUE;
ttmp = t_at(x, y);
if (ttmp && !ttmp->tseen)
ttmp = 0;
@@ -4434,7 +4440,7 @@ boolean force;
return 0;
}
if ((levl[x][y].doormask & D_TRAPPED
if (((levl[x][y].doormask & D_TRAPPED) != 0
&& (force || (!confused && rn2(MAXULEV - u.ulevel + 11) < 10)))
|| (!force && confused && !rn2(3))) {
You("find a trap on the door!");
+64
View File
@@ -8,6 +8,7 @@ STATIC_DCL boolean FDECL(known_hitum, (struct monst *, struct obj *, int *,
int, int, struct attack *, int));
STATIC_DCL boolean FDECL(theft_petrifies, (struct obj *));
STATIC_DCL void FDECL(steal_it, (struct monst *, struct attack *));
STATIC_DCL boolean FDECL(hitum_cleave, (struct monst *, struct attack *));
STATIC_DCL boolean FDECL(hitum, (struct monst *, struct attack *));
STATIC_DCL boolean FDECL(hmon_hitmon, (struct monst *, struct obj *, int,
int));
@@ -489,6 +490,65 @@ int dieroll;
return malive;
}
/* hit the monster next to you and the monsters to the left and right of it */
STATIC_OVL boolean
hitum_cleave(mon, uattk)
struct monst *mon;
struct attack *uattk;
{
int i = 0;
int x = u.ux;
int y = u.uy;
int count = 3;
boolean malive = TRUE;
struct monst *mtmp;
/* find the direction we're swinging */
while (i < 8) {
if (xdir[i] == u.dx && ydir[i] == u.dy)
break;
i++;
}
if (i == 8) {
impossible("hitum_cleave: failed to find target monster?");
return TRUE;
}
i = (i + 2) % 8;
/* swing from right to left */
while (count-- && uwep) {
boolean result;
int tmp, dieroll, mhit, attknum, armorpenalty;
if (!i)
i = 7;
else
i--;
mtmp = NULL;
if (isok(x + xdir[i], y + ydir[i]))
mtmp = m_at(x + xdir[i], y + ydir[i]);
if (!mtmp) {
(void) unmap_invisible(x + xdir[i], y + ydir[i]);
continue;
}
tmp = find_roll_to_hit(mtmp, uattk->aatyp, uwep,
&attknum, &armorpenalty);
dieroll = rnd(20);
mhit = (tmp > dieroll);
result = known_hitum(mtmp, uwep, &mhit, tmp, armorpenalty,
uattk, dieroll);
(void) passive(mtmp, mhit, DEADMONSTER(mtmp), AT_WEAP, !uwep);
if (mon == mtmp)
malive = result;
}
return malive;
}
/* hit target monster; returns TRUE if it still lives */
STATIC_OVL boolean
hitum(mon, uattk)
@@ -503,6 +563,10 @@ struct attack *uattk;
int dieroll = rnd(20);
int mhit = (tmp > dieroll || u.uswallow);
if (uwep && uwep->oartifact == ART_CLEAVER
&& !u.uswallow && !u.ustuck && !NODIAG(u.umonnum))
return hitum_cleave(mon, uattk);
if (tmp > dieroll)
exercise(A_DEX, TRUE);
malive = known_hitum(mon, uwep, &mhit, tmp, armorpenalty, uattk, dieroll);
+25 -65
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 version.c $NHDT-Date: 1449328116 2015/12/05 15:08:36 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.41 $ */
/* NetHack 3.6 version.c $NHDT-Date: 1506993902 2017/10/03 01:25:02 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.44 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -17,7 +17,7 @@
#define BETA_INFO ""
STATIC_DCL void FDECL(insert_rtoptions, (winid,char *,const char *));
STATIC_DCL void FDECL(insert_rtoption, (char *));
/* fill buffer with short version (so caller can avoid including date.h) */
char *
@@ -57,9 +57,8 @@ int
doextversion()
{
dlb *f;
char *pd, buf[BUFSZ];
char buf[BUFSZ];
winid win = create_nhwindow(NHW_TEXT);
boolean rtadded = FALSE;
/* instead of using ``display_file(OPTIONS_USED,TRUE)'' we handle
the file manually so we can include dynamic version info */
@@ -74,8 +73,7 @@ doextversion()
/*
* already inserted above:
* + outdented program name and version plus build date and time
* dat/options; display the contents with lines prefixed by '-'
* deleted:
* dat/options; display contents with lines prefixed by '-' deleted:
* - blank-line
* - indented program name and version
* blank-line
@@ -108,16 +106,9 @@ doextversion()
if (prolog || !*buf)
continue;
if (!rtadded) {
const char *catchphrase = ", and basic NetHack features.";
if (index(buf, ':'))
insert_rtoption(buf);
pd = strstri(buf, catchphrase);
if (pd) {
*pd = '\0';
insert_rtoptions(win, buf, &catchphrase[2]);
rtadded = TRUE; /* only do it once */
}
}
if (*buf)
putstr(win, 0, buf);
}
@@ -130,10 +121,19 @@ doextversion()
extern const char regex_id[];
static const char *rt_opts[] = {
"pattern matching via", regex_id,
/*
* makedefs should put the first token into dat/options; we'll substitute
* the second value for it. The token must contain at least one colon
* so that we can spot it, and should not contain spaces so that makedefs
* won't split it across lines. Ideally the length should be close to
* that of the substituted value since we don't do phrase-splitting/line-
* wrapping when displaying it.
*/
static struct rt_opt {
const char *token, *value;
} rt_opts[] = {
{ ":PATMATCH:", regex_id },
};
static const char indent[] = " ";
/*
* 3.6.0
@@ -142,57 +142,17 @@ static const char indent[] = " ";
* game image, so we insert those options here.
*/
STATIC_OVL void
insert_rtoptions(win, buf, finalphrase)
winid win;
insert_rtoption(buf)
char *buf;
const char *finalphrase;
{
char rtbuf[BUFSZ];
int l, i;
const char *s1 = 0, *s2 = 0, *s3 = 0, *s4 = 0;
int i;
if ((int) strlen(buf) >= (BUFSZ - 1))
return;
strcpy(rtbuf, buf);
for (i = 0; i < (SIZE(rt_opts) + 1); i += 2) {
if (i < SIZE(rt_opts)) {
s1 = ", ";
s2 = rt_opts[i];
s3 = " ";
s4 = rt_opts[i+1];
} else {
s1 = " ";
s2 = finalphrase;
s3 = "";
s4 = "";
}
l = (int) strlen(rtbuf) + (int) strlen(s1) + (int) strlen(s2)
+ (int) strlen(s3) + (int) strlen(s4) + 1;
if (l <= (COLNO - 5) && l < (BUFSZ - 1)) {
Strcat(rtbuf, s1);
Strcat(rtbuf, s2);
Strcat(rtbuf, s3);
Strcat(rtbuf, s4);
} else {
putstr(win, 0, rtbuf);
if (i >= SIZE(rt_opts))
s1 = "";
l = (int) strlen(indent) + (int) strlen(s1) + (int) strlen(s2)
+ (int) strlen(s3) + (int) strlen(s4) + 1;
if (l <= (COLNO - 5) && l < (BUFSZ - 1)) {
Strcpy(rtbuf, indent);
Strcat(rtbuf, s1);
Strcat(rtbuf, s2);
Strcat(rtbuf, s3);
Strcat(rtbuf, s4);
}
}
for (i = 0; i < SIZE(rt_opts); ++i) {
if (strstri(buf, rt_opts[i].token))
(void) strsubst(buf, rt_opts[i].token, rt_opts[i].value);
/* we don't break out of the loop after a match; there might be
other matches on the same line */
}
if (l)
putstr(win, 0, rtbuf);
*buf = '\0';
}
#ifdef MICRO
+2 -4
View File
@@ -3958,10 +3958,8 @@ boolean say; /* Announce out of sight hit/miss events if true */
/* reveal/unreveal invisible monsters before tmp_at() */
if (mon && !canspotmon(mon))
map_invisible(sx, sy);
else if (!mon && glyph_is_invisible(levl[sx][sy].glyph)) {
unmap_object(sx, sy);
newsym(sx, sy);
}
else if (!mon)
(void) unmap_invisible(sx, sy);
if (ZAP_POS(levl[sx][sy].typ)
|| (isok(lsx, lsy) && cansee(lsx, lsy)))
tmp_at(sx, sy);