Merge branch 'NetHack-3.6.2'

This commit is contained in:
nhmall
2019-01-04 23:08:49 -05:00
9 changed files with 407 additions and 199 deletions
+10 -1
View File
@@ -1,4 +1,4 @@
$NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.221 $ $NHDT-Date: 1546467443 2019/01/02 22:17:23 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.223 $ $NHDT-Date: 1546655319 2019/01/05 02:28:39 $
This fixes36.2 file is here to capture information about updates in the 3.6.x This fixes36.2 file is here to capture information about updates in the 3.6.x
lineage following the release of 3.6.1 in April 2018. Please note, however, lineage following the release of 3.6.1 in April 2018. Please note, however,
@@ -322,6 +322,11 @@ since knives became stackable in 3.6.0, fake player monsters could be given
using 'O' to attempt to set bouldersym to a monster letter or warning digit using 'O' to attempt to set bouldersym to a monster letter or warning digit
while it still had its default value would override the display value while it still had its default value would override the display value
for it to be <NUL> ('\0') after 'badoption' feedback for it to be <NUL> ('\0') after 'badoption' feedback
when ^T resorted to the teleport-away spell if hero didn't have intrinsic
telepotation, it used different hunger/strength/energy requirements
than casting with 'Z'; ^T also required that the corresponding book
be known even though knowing and casting a spell should be (and is
with 'Z') possible after forgetting the spellbook due to amnesia
Fixes to Post-3.6.1 Problems that Were Exposed Via git Repository Fixes to Post-3.6.1 Problems that Were Exposed Via git Repository
@@ -366,6 +371,8 @@ wizard mode ^G, creating a monster via class name using "lo" through "long wor"
if bouldersym bug (via 'O', above) put a <NUL> ('\0') on the map, examining if bouldersym bug (via 'O', above) put a <NUL> ('\0') on the map, examining
that spot matched placeholder monster class #0 and triggered impossible that spot matched placeholder monster class #0 and triggered impossible
"Alphabet soup: 'an("")'." "Alphabet soup: 'an("")'."
wizard mode m^T, not selecting a teleport choice didn't teardown the menu
properly and could eventually lead to "No window slots!" panic
tty: turn off an optimization that is the suspected cause of Windows reported tty: turn off an optimization that is the suspected cause of Windows reported
partial status lines following level changes partial status lines following level changes
tty: ensure that current status fields are always copied to prior status tty: ensure that current status fields are always copied to prior status
@@ -493,6 +500,8 @@ when sortloot is enabled, gems are grouped in subsets (1) unseen gems and
(4) identified glass, (5) unseen stones (includes unseen rocks), (4) identified glass, (5) unseen stones (includes unseen rocks),
(6) seen but unidentified gray stones, (7) identified gray stones, (6) seen but unidentified gray stones, (7) identified gray stones,
and (8) seen rocks (IDed/unIDed not applicable) and (8) seen rocks (IDed/unIDed not applicable)
in wizard mode, ^T can be preceded by 'm' prefix in order to test teleporting
without having wizard mode override various restrictions
NetHack Community Patches (or Variation) Included NetHack Community Patches (or Variation) Included
+2 -1
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 extern.h $NHDT-Date: 1545964581 2018/12/28 02:36:21 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.678 $ */ /* NetHack 3.6 extern.h $NHDT-Date: 1546565812 2019/01/04 01:36:52 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.680 $ */
/* Copyright (c) Steve Creps, 1988. */ /* Copyright (c) Steve Creps, 1988. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -2330,6 +2330,7 @@ E void NDECL(age_spells);
E int NDECL(docast); E int NDECL(docast);
E int FDECL(spell_skilltype, (int)); E int FDECL(spell_skilltype, (int));
E int FDECL(spelleffects, (int, BOOLEAN_P)); E int FDECL(spelleffects, (int, BOOLEAN_P));
E int FDECL(tport_spell, (int));
E void NDECL(losespells); E void NDECL(losespells);
E int NDECL(dovspell); E int NDECL(dovspell);
E void FDECL(initialspell, (struct obj *)); E void FDECL(initialspell, (struct obj *));
+3 -3
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 cmd.c $NHDT-Date: 1546038393 2018/12/28 23:06:33 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.323 $ */ /* NetHack 3.6 cmd.c $NHDT-Date: 1546565813 2019/01/04 01:36:53 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.324 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2013. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -4393,8 +4393,8 @@ int NDECL((*cmd_func));
|| cmd_func == doloot || cmd_func == doloot
/* travel: pop up a menu of interesting targets in view */ /* travel: pop up a menu of interesting targets in view */
|| cmd_func == dotravel || cmd_func == dotravel
/* wizard mode ^V */ /* wizard mode ^V and ^T */
|| cmd_func == wiz_level_tele || cmd_func == wiz_level_tele || cmd_func == dotelecmd
/* 'm' prefix allowed for some extended commands */ /* 'm' prefix allowed for some extended commands */
|| cmd_func == doextcmd || cmd_func == doextlist) || cmd_func == doextcmd || cmd_func == doextlist)
return TRUE; return TRUE;
+1 -1
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 drawing.c $NHDT-Date: 1546212616 2018/12/30 23:30:16 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.58 $ */ /* 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 $ */
/* Copyright (c) NetHack Development Team 1992. */ /* Copyright (c) NetHack Development Team 1992. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
+15 -14
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 hack.c $NHDT-Date: 1545530973 2018/12/23 02:09:33 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.202 $ */ /* NetHack 3.6 hack.c $NHDT-Date: 1546656413 2019/01/05 02:46:53 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.203 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Derek S. Ray, 2015. */ /*-Copyright (c) Derek S. Ray, 2015. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -277,7 +277,7 @@ moverock()
/* note: reset to zero after save/restore cycle */ /* note: reset to zero after save/restore cycle */
static NEARDATA long lastmovetime; static NEARDATA long lastmovetime;
#endif #endif
dopush: dopush:
if (!u.usteed) { if (!u.usteed) {
if (g.moves > lastmovetime + 2 || g.moves < lastmovetime) if (g.moves > lastmovetime + 2 || g.moves < lastmovetime)
pline("With %s effort you move %s.", pline("With %s effort you move %s.",
@@ -302,7 +302,7 @@ moverock()
newsym(sx, sy); newsym(sx, sy);
} }
} else { } else {
nopushmsg: nopushmsg:
if (u.usteed) if (u.usteed)
pline("%s tries to move %s, but cannot.", pline("%s tries to move %s, but cannot.",
upstart(y_monnam(u.usteed)), the(xname(otmp))); upstart(y_monnam(u.usteed)), the(xname(otmp)));
@@ -310,7 +310,7 @@ moverock()
You("try to move %s, but in vain.", the(xname(otmp))); You("try to move %s, but in vain.", the(xname(otmp)));
if (Blind) if (Blind)
feel_location(sx, sy); feel_location(sx, sy);
cannot_push: cannot_push:
if (throws_rocks(g.youmonst.data)) { if (throws_rocks(g.youmonst.data)) {
boolean boolean
canpickup = (!Sokoban canpickup = (!Sokoban
@@ -795,7 +795,7 @@ int mode;
return FALSE; return FALSE;
} }
} else { } else {
testdiag: testdiag:
if (dx && dy && !Passes_walls if (dx && dy && !Passes_walls
&& (!doorless_door(x, y) || block_door(x, y))) { && (!doorless_door(x, y) || block_door(x, y))) {
/* Diagonal moves into a door are not allowed. */ /* Diagonal moves into a door are not allowed. */
@@ -953,8 +953,8 @@ int mode;
uy = u.uy; uy = u.uy;
} }
noguess: noguess:
(void) memset((genericptr_t) travel, 0, sizeof(travel)); (void) memset((genericptr_t) travel, 0, sizeof travel);
travelstepx[0][0] = tx; travelstepx[0][0] = tx;
travelstepy[0][0] = ty; travelstepy[0][0] = ty;
@@ -1139,7 +1139,7 @@ int mode;
return FALSE; return FALSE;
} }
found: found:
u.dx = 0; u.dx = 0;
u.dy = 0; u.dy = 0;
nomul(0); nomul(0);
@@ -1292,7 +1292,7 @@ struct trap *desttrap; /* nonnull if another trap at <x,y> */
Norep("You are %s %s.", predicament, culprit); Norep("You are %s %s.", predicament, culprit);
} }
} else { } else {
wriggle_free: wriggle_free:
if (u.usteed) if (u.usteed)
pline("%s finally %s free.", upstart(steedname), pline("%s finally %s free.", upstart(steedname),
!anchored ? "lurches" : "wrenches the ball"); !anchored ? "lurches" : "wrenches the ball");
@@ -1491,7 +1491,7 @@ domove()
case 0: case 0:
case 1: case 1:
case 2: case 2:
pull_free: pull_free:
You("pull free from %s.", mon_nam(u.ustuck)); You("pull free from %s.", mon_nam(u.ustuck));
u.ustuck = 0; u.ustuck = 0;
break; break;
@@ -2201,7 +2201,7 @@ boolean pick;
} }
mnexto(mtmp); /* have to move the monster */ mnexto(mtmp); /* have to move the monster */
} }
spotdone: spotdone:
if (!--inspoteffects) { if (!--inspoteffects) {
spotterrain = STONE; /* 0 */ spotterrain = STONE; /* 0 */
spotloc.x = spotloc.y = 0; spotloc.x = spotloc.y = 0;
@@ -2579,7 +2579,8 @@ dopickup(VOID_ARGS)
int count, tmpcount, ret; int count, tmpcount, ret;
/* awful kludge to work around parse()'s pre-decrement */ /* awful kludge to work around parse()'s pre-decrement */
count = (g.multi || (g.save_cm && *g.save_cm == cmd_from_func(dopickup))) ? g.multi + 1 : 0; count = (g.multi || (g.save_cm && *g.save_cm == cmd_from_func(dopickup)))
? g.multi + 1 : 0;
g.multi = 0; /* always reset */ g.multi = 0; /* always reset */
if ((ret = pickup_checks() >= 0)) if ((ret = pickup_checks() >= 0))
@@ -2652,7 +2653,7 @@ lookaround()
} }
goto bcorr; goto bcorr;
} else if (levl[x][y].typ == CORR) { } else if (levl[x][y].typ == CORR) {
bcorr: bcorr:
if (levl[u.ux][u.uy].typ != ROOM) { if (levl[u.ux][u.uy].typ != ROOM) {
if (g.context.run == 1 || g.context.run == 3 if (g.context.run == 1 || g.context.run == 3
|| g.context.run == 8) { || g.context.run == 8) {
@@ -2710,7 +2711,7 @@ lookaround()
|| ((y == u.uy - u.dy) && (x != u.ux + u.dx))) || ((y == u.uy - u.dy) && (x != u.ux + u.dx)))
continue; continue;
} }
stop: stop:
nomul(0); nomul(0);
return; return;
} /* end for loops */ } /* end for loops */
+146 -129
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 options.c $NHDT-Date: 1546212618 2018/12/30 23:30:18 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.350 $ */ /* NetHack 3.6 options.c $NHDT-Date: 1546657409 2019/01/05 03:03:29 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.351 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Michael Allison, 2008. */ /*-Copyright (c) Michael Allison, 2008. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -279,7 +279,7 @@ static struct Comp_Opt {
{ "catname", "the name of your (first) cat (e.g., catname:Tabby)", { "catname", "the name of your (first) cat (e.g., catname:Tabby)",
PL_PSIZ, DISP_IN_GAME }, PL_PSIZ, DISP_IN_GAME },
{ "disclose", "the kinds of information to disclose at end of game", { "disclose", "the kinds of information to disclose at end of game",
sizeof(flags.end_disclose) * 2, SET_IN_GAME }, sizeof flags.end_disclose * 2, SET_IN_GAME },
{ "dogname", "the name of your (first) dog (e.g., dogname:Fang)", PL_PSIZ, { "dogname", "the name of your (first) dog (e.g., dogname:Fang)", PL_PSIZ,
DISP_IN_GAME }, DISP_IN_GAME },
{ "dungeon", "the symbols to use in drawing the dungeon map", { "dungeon", "the symbols to use in drawing the dungeon map",
@@ -712,7 +712,7 @@ initoptions_init()
#endif #endif
#ifdef SYSFLAGS #ifdef SYSFLAGS
Strcpy(sysflags.sysflagsid, "sysflags"); Strcpy(sysflags.sysflagsid, "sysflags");
sysflags.sysflagsid[9] = (char) sizeof(struct sysflag); sysflags.sysflagsid[9] = (char) sizeof (struct sysflag);
#endif #endif
flags.end_own = FALSE; flags.end_own = FALSE;
flags.end_top = 3; flags.end_top = 3;
@@ -900,6 +900,8 @@ int maxlen;
/* /*
* escapes(): escape expansion for showsyms. C-style escapes understood * escapes(): escape expansion for showsyms. C-style escapes understood
* include \n, \b, \t, \r, \xnnn (hex), \onnn (octal), \nnn (decimal). * include \n, \b, \t, \r, \xnnn (hex), \onnn (octal), \nnn (decimal).
* (Note: unlike in C, leading digit 0 is not used to indicate octal;
* the letter o (either upper or lower case) is used for that.
* The ^-prefix for control characters is also understood, and \[mM] * The ^-prefix for control characters is also understood, and \[mM]
* has the effect of 'meta'-ing the value which follows (so that the * has the effect of 'meta'-ing the value which follows (so that the
* alternate character set will be enabled). * alternate character set will be enabled).
@@ -1005,7 +1007,7 @@ const char *optname;
/* /*
# errors: # errors:
OPTIONS=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa OPTIONS=aaaaaaaaaa[ more than 247 (255 - 8 for 'OPTIONS=') total ]aaaaaaaaaa
OPTIONS OPTIONS
OPTIONS= OPTIONS=
MSGTYPE=stop"You swap places with " MSGTYPE=stop"You swap places with "
@@ -1376,7 +1378,7 @@ char *str;
/* allow "lightblue", "light blue", and "light-blue" to match "light blue" /* allow "lightblue", "light blue", and "light-blue" to match "light blue"
(also junk like "_l i-gh_t---b l u e" but we won't worry about that); (also junk like "_l i-gh_t---b l u e" but we won't worry about that);
also copes with trailing space; mungspaces removed any leading space */ also copes with trailing space; caller has removed any leading space */
for (i = 0; i < SIZE(colornames); i++) for (i = 0; i < SIZE(colornames); i++)
if (colornames[i].name if (colornames[i].name
&& fuzzymatch(str, colornames[i].name, " -_", TRUE)) { && fuzzymatch(str, colornames[i].name, " -_", TRUE)) {
@@ -1603,8 +1605,7 @@ msgtype_add(typ, pattern)
int typ; int typ;
char *pattern; char *pattern;
{ {
struct plinemsg_type struct plinemsg_type *tmp = (struct plinemsg_type *) alloc(sizeof *tmp);
*tmp = (struct plinemsg_type *) alloc(sizeof (struct plinemsg_type));
tmp->msgtype = typ; tmp->msgtype = typ;
tmp->regex = regex_init(); tmp->regex = regex_init();
@@ -1775,7 +1776,7 @@ int c, a;
if (!str) if (!str)
return FALSE; return FALSE;
tmp = (struct menucoloring *) alloc(sizeof (struct menucoloring)); tmp = (struct menucoloring *) alloc(sizeof *tmp);
tmp->match = regex_init(); tmp->match = regex_init();
if (!regex_compile(str, tmp->match)) { if (!regex_compile(str, tmp->match)) {
config_error_add("%s: %s", re_error, regex_error_desc(tmp->match)); config_error_add("%s: %s", re_error, regex_error_desc(tmp->match));
@@ -1836,7 +1837,6 @@ char *tmpstr;
tmps++; tmps++;
} }
} }
return add_menu_coloring_parsed(tmps, c, a); return add_menu_coloring_parsed(tmps, c, a);
} }
@@ -1860,15 +1860,13 @@ int *color, *attr;
void void
free_menu_coloring() free_menu_coloring()
{ {
struct menucoloring *tmp = g.menu_colorings; struct menucoloring *tmp, *tmp2;
while (tmp) {
struct menucoloring *tmp2 = tmp->next;
for (tmp = menu_colorings; tmp; tmp = tmp2) {
tmp2 = tmp->next;
regex_free(tmp->match); regex_free(tmp->match);
free((genericptr_t) tmp->origstr); free((genericptr_t) tmp->origstr);
free((genericptr_t) tmp); free((genericptr_t) tmp);
tmp = tmp2;
} }
} }
@@ -1901,13 +1899,11 @@ int idx; /* 0 .. */
STATIC_OVL int STATIC_OVL int
count_menucolors(VOID_ARGS) count_menucolors(VOID_ARGS)
{ {
struct menucoloring *tmp;
int count = 0; int count = 0;
struct menucoloring *tmp = g.menu_colorings;
while (tmp) { for (tmp = g.menu_colorings; tmp; tmp = tmp->next)
count++; count++;
tmp = tmp->next;
}
return count; return count;
} }
@@ -2056,7 +2052,7 @@ boolean tinitial, tfrom_file;
/* align:string */ /* align:string */
fullname = "align"; fullname = "align";
if (match_optname(opts, fullname, sizeof("align") - 1, TRUE)) { if (match_optname(opts, fullname, sizeof "align" - 1, TRUE)) {
if (parse_role_opts(negated, fullname, opts, &op)) { if (parse_role_opts(negated, fullname, opts, &op)) {
if ((flags.initalign = str2align(op)) == ROLE_NONE) { if ((flags.initalign = str2align(op)) == ROLE_NONE) {
config_error_add("Unknown %s '%s'", fullname, op); config_error_add("Unknown %s '%s'", fullname, op);
@@ -2610,7 +2606,7 @@ boolean tinitial, tfrom_file;
} }
} }
} }
goodfruit: goodfruit:
nmcpy(g.pl_fruit, op, PL_FSIZ); nmcpy(g.pl_fruit, op, PL_FSIZ);
sanitize_name(g.pl_fruit); sanitize_name(g.pl_fruit);
/* OBJ_NAME(objects[SLIME_MOLD]) won't work for this after /* OBJ_NAME(objects[SLIME_MOLD]) won't work for this after
@@ -2783,16 +2779,16 @@ boolean tinitial, tfrom_file;
/* WINCAP /* WINCAP
* align_status:[left|top|right|bottom] */ * align_status:[left|top|right|bottom] */
fullname = "align_status"; fullname = "align_status";
if (match_optname(opts, fullname, sizeof("align_status") - 1, TRUE)) { if (match_optname(opts, fullname, sizeof "align_status" - 1, TRUE)) {
op = string_for_opt(opts, negated); op = string_for_opt(opts, negated);
if (op && !negated) { if (op && !negated) {
if (!strncmpi(op, "left", sizeof("left") - 1)) if (!strncmpi(op, "left", sizeof "left" - 1))
iflags.wc_align_status = ALIGN_LEFT; iflags.wc_align_status = ALIGN_LEFT;
else if (!strncmpi(op, "top", sizeof("top") - 1)) else if (!strncmpi(op, "top", sizeof "top" - 1))
iflags.wc_align_status = ALIGN_TOP; iflags.wc_align_status = ALIGN_TOP;
else if (!strncmpi(op, "right", sizeof("right") - 1)) else if (!strncmpi(op, "right", sizeof "right" - 1))
iflags.wc_align_status = ALIGN_RIGHT; iflags.wc_align_status = ALIGN_RIGHT;
else if (!strncmpi(op, "bottom", sizeof("bottom") - 1)) else if (!strncmpi(op, "bottom", sizeof "bottom" - 1))
iflags.wc_align_status = ALIGN_BOTTOM; iflags.wc_align_status = ALIGN_BOTTOM;
else { else {
config_error_add("Unknown %s parameter '%s'", fullname, op); config_error_add("Unknown %s parameter '%s'", fullname, op);
@@ -2808,18 +2804,18 @@ boolean tinitial, tfrom_file;
/* WINCAP /* WINCAP
* align_message:[left|top|right|bottom] */ * align_message:[left|top|right|bottom] */
fullname = "align_message"; fullname = "align_message";
if (match_optname(opts, fullname, sizeof("align_message") - 1, TRUE)) { if (match_optname(opts, fullname, sizeof "align_message" - 1, TRUE)) {
if (duplicate) if (duplicate)
complain_about_duplicate(opts, 1); complain_about_duplicate(opts, 1);
op = string_for_opt(opts, negated); op = string_for_opt(opts, negated);
if (op && !negated) { if (op && !negated) {
if (!strncmpi(op, "left", sizeof("left") - 1)) if (!strncmpi(op, "left", sizeof "left" - 1))
iflags.wc_align_message = ALIGN_LEFT; iflags.wc_align_message = ALIGN_LEFT;
else if (!strncmpi(op, "top", sizeof("top") - 1)) else if (!strncmpi(op, "top", sizeof "top" - 1))
iflags.wc_align_message = ALIGN_TOP; iflags.wc_align_message = ALIGN_TOP;
else if (!strncmpi(op, "right", sizeof("right") - 1)) else if (!strncmpi(op, "right", sizeof "right" - 1))
iflags.wc_align_message = ALIGN_RIGHT; iflags.wc_align_message = ALIGN_RIGHT;
else if (!strncmpi(op, "bottom", sizeof("bottom") - 1)) else if (!strncmpi(op, "bottom", sizeof "bottom" - 1))
iflags.wc_align_message = ALIGN_BOTTOM; iflags.wc_align_message = ALIGN_BOTTOM;
else { else {
config_error_add("Unknown %s parameter '%s'", fullname, op); config_error_add("Unknown %s parameter '%s'", fullname, op);
@@ -2873,7 +2869,7 @@ boolean tinitial, tfrom_file;
pp = index(op, ' '); pp = index(op, ' ');
if (pp) if (pp)
*pp = '\0'; *pp = '\0';
/* we aren't matching option names but match_optname /* we aren't matching option names but match_optname()
does what we want once we've broken the space does what we want once we've broken the space
delimited aggregate into separate tokens */ delimited aggregate into separate tokens */
for (i = 0; i < SIZE(paranoia); ++i) { for (i = 0; i < SIZE(paranoia); ++i) {
@@ -2958,8 +2954,8 @@ boolean tinitial, tfrom_file;
/* types of objects to pick up automatically */ /* types of objects to pick up automatically */
fullname = "pickup_types"; fullname = "pickup_types";
if (match_optname(opts, fullname, 8, TRUE)) { if (match_optname(opts, fullname, 8, TRUE)) {
char ocl[MAXOCLASSES + 1], tbuf[MAXOCLASSES + 1], qbuf[QBUFSZ], char ocl[MAXOCLASSES + 1], tbuf[MAXOCLASSES + 1],
abuf[BUFSZ] = DUMMY; qbuf[QBUFSZ], abuf[BUFSZ];
int oc_sym; int oc_sym;
boolean badopt = FALSE, compat = (strlen(opts) <= 6), use_menu; boolean badopt = FALSE, compat = (strlen(opts) <= 6), use_menu;
@@ -2985,6 +2981,7 @@ boolean tinitial, tfrom_file;
use_menu = FALSE; use_menu = FALSE;
Sprintf(qbuf, "New %s: [%s am] (%s)", fullname, ocl, Sprintf(qbuf, "New %s: [%s am] (%s)", fullname, ocl,
*tbuf ? tbuf : "all"); *tbuf ? tbuf : "all");
abuf[0] = '\0';
getlin(qbuf, abuf); getlin(qbuf, abuf);
wasspace = (abuf[0] == ' '); /* before mungspaces */ wasspace = (abuf[0] == ' '); /* before mungspaces */
op = mungspaces(abuf); op = mungspaces(abuf);
@@ -2994,6 +2991,8 @@ boolean tinitial, tfrom_file;
op = tbuf; /* restore */ op = tbuf; /* restore */
else if (abuf[0] == 'm') else if (abuf[0] == 'm')
use_menu = TRUE; use_menu = TRUE;
/* note: abuf[0]=='a' is already handled via clearing the
the old value (above) as a default action */
} }
if (use_menu) { if (use_menu) {
if (wizard && !index(ocl, VENOM_SYM)) if (wizard && !index(ocl, VENOM_SYM))
@@ -3077,18 +3076,18 @@ boolean tinitial, tfrom_file;
} }
/* WINCAP /* WINCAP
* player_selection: dialog | prompts */ * player_selection: dialog | prompt/prompts/prompting */
fullname = "player_selection"; fullname = "player_selection";
if (match_optname(opts, fullname, sizeof("player_selection") - 1, TRUE)) { if (match_optname(opts, fullname, sizeof "player_selection" - 1, TRUE)) {
if (duplicate) if (duplicate)
complain_about_duplicate(opts, 1); complain_about_duplicate(opts, 1);
op = string_for_opt(opts, negated); op = string_for_opt(opts, negated);
if (op && !negated) { if (op && !negated) {
if (!strncmpi(op, "dialog", sizeof("dialog") - 1)) if (!strncmpi(op, "dialog", sizeof "dialog" - 1)) {
iflags.wc_player_selection = VIA_DIALOG; iflags.wc_player_selection = VIA_DIALOG;
else if (!strncmpi(op, "prompt", sizeof("prompt") - 1)) } else if (!strncmpi(op, "prompt", sizeof "prompt" - 1)) {
iflags.wc_player_selection = VIA_PROMPTS; iflags.wc_player_selection = VIA_PROMPTS;
else { } else {
config_error_add("Unknown %s parameter '%s'", fullname, op); config_error_add("Unknown %s parameter '%s'", fullname, op);
return FALSE; return FALSE;
} }
@@ -3110,11 +3109,13 @@ boolean tinitial, tfrom_file;
* end_disclose[NUM_DISCLOSURE_OPT]; * end_disclose[NUM_DISCLOSURE_OPT];
* with option settings for the each of the following: * with option settings for the each of the following:
* iagvc [see disclosure_options in decl.c]: * iagvc [see disclosure_options in decl.c]:
* Legal setting values in that array are: * Allowed setting values in that array are:
* DISCLOSE_PROMPT_DEFAULT_YES ask with default answer yes * DISCLOSE_PROMPT_DEFAULT_YES ask with default answer yes
* DISCLOSE_PROMPT_DEFAULT_NO ask with default answer no * DISCLOSE_PROMPT_DEFAULT_NO ask with default answer no
* DISCLOSE_YES_WITHOUT_PROMPT always disclose and don't ask * DISCLOSE_YES_WITHOUT_PROMPT always disclose and don't ask
* DISCLOSE_NO_WITHOUT_PROMPT never disclose and don't ask * DISCLOSE_NO_WITHOUT_PROMPT never disclose and don't ask
* DISCLOSE_PROMPT_DEFAULT_SPECIAL for 'vanquished' only...
* DISCLOSE_SPECIAL_WITHOUT_PROMPT ...to set up sort order.
* *
* Those setting values can be used in the option * Those setting values can be used in the option
* string as a prefix to get the desired behaviour. * string as a prefix to get the desired behaviour.
@@ -3350,33 +3351,33 @@ boolean tinitial, tfrom_file;
* |ascii8x12|ascii16x12|ascii12x16|ascii10x18|fit_to_screen] * |ascii8x12|ascii16x12|ascii12x16|ascii10x18|fit_to_screen]
*/ */
fullname = "map_mode"; fullname = "map_mode";
if (match_optname(opts, fullname, sizeof("map_mode") - 1, TRUE)) { if (match_optname(opts, fullname, sizeof "map_mode" - 1, TRUE)) {
if (duplicate) if (duplicate)
complain_about_duplicate(opts, 1); complain_about_duplicate(opts, 1);
op = string_for_opt(opts, negated); op = string_for_opt(opts, negated);
if (op && !negated) { if (op && !negated) {
if (!strncmpi(op, "tiles", sizeof("tiles") - 1)) if (!strncmpi(op, "tiles", sizeof "tiles" - 1))
iflags.wc_map_mode = MAP_MODE_TILES; iflags.wc_map_mode = MAP_MODE_TILES;
else if (!strncmpi(op, "ascii4x6", sizeof("ascii4x6") - 1)) else if (!strncmpi(op, "ascii4x6", sizeof "ascii4x6" - 1))
iflags.wc_map_mode = MAP_MODE_ASCII4x6; iflags.wc_map_mode = MAP_MODE_ASCII4x6;
else if (!strncmpi(op, "ascii6x8", sizeof("ascii6x8") - 1)) else if (!strncmpi(op, "ascii6x8", sizeof "ascii6x8" - 1))
iflags.wc_map_mode = MAP_MODE_ASCII6x8; iflags.wc_map_mode = MAP_MODE_ASCII6x8;
else if (!strncmpi(op, "ascii8x8", sizeof("ascii8x8") - 1)) else if (!strncmpi(op, "ascii8x8", sizeof "ascii8x8" - 1))
iflags.wc_map_mode = MAP_MODE_ASCII8x8; iflags.wc_map_mode = MAP_MODE_ASCII8x8;
else if (!strncmpi(op, "ascii16x8", sizeof("ascii16x8") - 1)) else if (!strncmpi(op, "ascii16x8", sizeof "ascii16x8" - 1))
iflags.wc_map_mode = MAP_MODE_ASCII16x8; iflags.wc_map_mode = MAP_MODE_ASCII16x8;
else if (!strncmpi(op, "ascii7x12", sizeof("ascii7x12") - 1)) else if (!strncmpi(op, "ascii7x12", sizeof "ascii7x12" - 1))
iflags.wc_map_mode = MAP_MODE_ASCII7x12; iflags.wc_map_mode = MAP_MODE_ASCII7x12;
else if (!strncmpi(op, "ascii8x12", sizeof("ascii8x12") - 1)) else if (!strncmpi(op, "ascii8x12", sizeof "ascii8x12" - 1))
iflags.wc_map_mode = MAP_MODE_ASCII8x12; iflags.wc_map_mode = MAP_MODE_ASCII8x12;
else if (!strncmpi(op, "ascii16x12", sizeof("ascii16x12") - 1)) else if (!strncmpi(op, "ascii16x12", sizeof "ascii16x12" - 1))
iflags.wc_map_mode = MAP_MODE_ASCII16x12; iflags.wc_map_mode = MAP_MODE_ASCII16x12;
else if (!strncmpi(op, "ascii12x16", sizeof("ascii12x16") - 1)) else if (!strncmpi(op, "ascii12x16", sizeof "ascii12x16" - 1))
iflags.wc_map_mode = MAP_MODE_ASCII12x16; iflags.wc_map_mode = MAP_MODE_ASCII12x16;
else if (!strncmpi(op, "ascii10x18", sizeof("ascii10x18") - 1)) else if (!strncmpi(op, "ascii10x18", sizeof "ascii10x18" - 1))
iflags.wc_map_mode = MAP_MODE_ASCII10x18; iflags.wc_map_mode = MAP_MODE_ASCII10x18;
else if (!strncmpi(op, "fit_to_screen", else if (!strncmpi(op, "fit_to_screen",
sizeof("fit_to_screen") - 1)) sizeof "fit_to_screen" - 1))
iflags.wc_map_mode = MAP_MODE_ASCII_FIT_TO_SCREEN; iflags.wc_map_mode = MAP_MODE_ASCII_FIT_TO_SCREEN;
else { else {
config_error_add("Unknown %s parameter '%s'", fullname, op); config_error_add("Unknown %s parameter '%s'", fullname, op);
@@ -3443,7 +3444,7 @@ boolean tinitial, tfrom_file;
/* WINCAP /* WINCAP
* tile_width:nn */ * tile_width:nn */
fullname = "tile_width"; fullname = "tile_width";
if (match_optname(opts, fullname, sizeof("tile_width") - 1, TRUE)) { if (match_optname(opts, fullname, sizeof "tile_width" - 1, TRUE)) {
if (duplicate) if (duplicate)
complain_about_duplicate(opts, 1); complain_about_duplicate(opts, 1);
op = string_for_opt(opts, negated); op = string_for_opt(opts, negated);
@@ -3458,7 +3459,7 @@ boolean tinitial, tfrom_file;
/* WINCAP /* WINCAP
* tile_file:name */ * tile_file:name */
fullname = "tile_file"; fullname = "tile_file";
if (match_optname(opts, fullname, sizeof("tile_file") - 1, TRUE)) { if (match_optname(opts, fullname, sizeof "tile_file" - 1, TRUE)) {
if (duplicate) if (duplicate)
complain_about_duplicate(opts, 1); complain_about_duplicate(opts, 1);
if ((op = string_for_opt(opts, FALSE)) != 0) { if ((op = string_for_opt(opts, FALSE)) != 0) {
@@ -3472,7 +3473,7 @@ boolean tinitial, tfrom_file;
/* WINCAP /* WINCAP
* tile_height:nn */ * tile_height:nn */
fullname = "tile_height"; fullname = "tile_height";
if (match_optname(opts, fullname, sizeof("tile_height") - 1, TRUE)) { if (match_optname(opts, fullname, sizeof "tile_height" - 1, TRUE)) {
if (duplicate) if (duplicate)
complain_about_duplicate(opts, 1); complain_about_duplicate(opts, 1);
op = string_for_opt(opts, negated); op = string_for_opt(opts, negated);
@@ -3488,7 +3489,7 @@ boolean tinitial, tfrom_file;
/* WINCAP /* WINCAP
* vary_msgcount:nn */ * vary_msgcount:nn */
fullname = "vary_msgcount"; fullname = "vary_msgcount";
if (match_optname(opts, fullname, sizeof("vary_msgcount") - 1, TRUE)) { if (match_optname(opts, fullname, sizeof "vary_msgcount" - 1, TRUE)) {
if (duplicate) if (duplicate)
complain_about_duplicate(opts, 1); complain_about_duplicate(opts, 1);
op = string_for_opt(opts, negated); op = string_for_opt(opts, negated);
@@ -3511,7 +3512,8 @@ boolean tinitial, tfrom_file;
* OPTIONS=windowtype:Foo * OPTIONS=windowtype:Foo
* as the first non-comment line of the file. * as the first non-comment line of the file.
* Making it first in NETHACKOPTIONS requires it to be at the _end_ * Making it first in NETHACKOPTIONS requires it to be at the _end_
* because option strings are processed from right to left. * because comma-separated option strings are processed from right
* to left.
*/ */
fullname = "windowtype"; fullname = "windowtype";
if (match_optname(opts, fullname, 3, TRUE)) { if (match_optname(opts, fullname, 3, TRUE)) {
@@ -3530,7 +3532,7 @@ boolean tinitial, tfrom_file;
choose_windows(buf); choose_windows(buf);
} else { } else {
nmcpy(g.chosen_windowtype, op, WINTYPELEN); nmcpy(g.chosen_windowtype, op, WINTYPELEN);
} }
} else } else
return FALSE; return FALSE;
return retval; return retval;
@@ -3572,7 +3574,7 @@ boolean tinitial, tfrom_file;
/* WINCAP2 /* WINCAP2
* term_cols:amount */ * term_cols:amount */
fullname = "term_cols"; fullname = "term_cols";
if (match_optname(opts, fullname, sizeof("term_cols")-1, TRUE)) { if (match_optname(opts, fullname, sizeof "term_cols" - 1, TRUE)) {
op = string_for_opt(opts, negated); op = string_for_opt(opts, negated);
iflags.wc2_term_cols = atoi(op); iflags.wc2_term_cols = atoi(op);
if (negated) if (negated)
@@ -3583,7 +3585,7 @@ boolean tinitial, tfrom_file;
/* WINCAP2 /* WINCAP2
* term_rows:amount */ * term_rows:amount */
fullname = "term_rows"; fullname = "term_rows";
if (match_optname(opts, fullname, sizeof("term_rows")-1, TRUE)) { if (match_optname(opts, fullname, sizeof "term_rows" - 1, TRUE)) {
op = string_for_opt(opts, negated); op = string_for_opt(opts, negated);
iflags.wc2_term_rows = atoi(op); iflags.wc2_term_rows = atoi(op);
if (negated) if (negated)
@@ -3594,7 +3596,7 @@ boolean tinitial, tfrom_file;
/* WINCAP2 /* WINCAP2
* petattr:string */ * petattr:string */
fullname = "petattr"; fullname = "petattr";
if (match_optname(opts, fullname, sizeof("petattr")-1, TRUE)) { if (match_optname(opts, fullname, sizeof "petattr" - 1, TRUE)) {
op = string_for_opt(opts, negated); op = string_for_opt(opts, negated);
if (op && !negated) { if (op && !negated) {
#ifdef CURSES_GRAPHICS #ifdef CURSES_GRAPHICS
@@ -3615,7 +3617,7 @@ boolean tinitial, tfrom_file;
/* WINCAP2 /* WINCAP2
* windowborders:n */ * windowborders:n */
fullname = "windowborders"; fullname = "windowborders";
if (match_optname(opts, fullname, sizeof("windowborders")-1, TRUE)) { if (match_optname(opts, fullname, sizeof "windowborders" - 1, TRUE)) {
op = string_for_opt(opts, negated); op = string_for_opt(opts, negated);
if (negated && op) if (negated && op)
bad_negation(fullname, TRUE); bad_negation(fullname, TRUE);
@@ -3627,10 +3629,9 @@ boolean tinitial, tfrom_file;
else /* Value supplied */ else /* Value supplied */
iflags.wc2_windowborders = atoi(op); iflags.wc2_windowborders = atoi(op);
if ((iflags.wc2_windowborders > 3) if ((iflags.wc2_windowborders > 3)
|| (iflags.wc2_windowborders < 1)) { || (iflags.wc2_windowborders < 1)) {
iflags.wc2_windowborders = 0; iflags.wc2_windowborders = 0;
config_error_add( config_error_add("Badoption - windowborders %s.", opts);
"Badoption - windowborders %s.", opts);
} }
} }
return retval; return retval;
@@ -3712,10 +3713,10 @@ boolean tinitial, tfrom_file;
escapes(op, op_buf); escapes(op, op_buf);
c = *op_buf; c = *op_buf;
if (illegal_menu_cmd_key(c)) { if (illegal_menu_cmd_key(c))
return FALSE; return FALSE;
} else
add_menu_cmd_alias(c, default_menu_cmd_info[i].cmd); add_menu_cmd_alias(c, default_menu_cmd_info[i].cmd);
} }
return retval; return retval;
} }
@@ -3877,8 +3878,9 @@ boolean tinitial, tfrom_file;
#endif /* ?(MAC_GRAPHICS_ENV && BACKWARD_COMPAT) */ #endif /* ?(MAC_GRAPHICS_ENV && BACKWARD_COMPAT) */
} /* "MACgraphics" */ } /* "MACgraphics" */
/* OK, if we still haven't recognized the option, check the boolean /*
* options list * OK, if we still haven't recognized the option, check the boolean
* options list.
*/ */
for (i = 0; boolopt[i].name; i++) { for (i = 0; boolopt[i].name; i++) {
if (match_optname(opts, boolopt[i].name, 3, TRUE)) { if (match_optname(opts, boolopt[i].name, 3, TRUE)) {
@@ -4111,8 +4113,8 @@ char from_ch, to_ch;
g.mapped_menu_cmds[g.n_menu_mapped] = from_ch; g.mapped_menu_cmds[g.n_menu_mapped] = from_ch;
g.mapped_menu_op[g.n_menu_mapped] = to_ch; g.mapped_menu_op[g.n_menu_mapped] = to_ch;
g.n_menu_mapped++; g.n_menu_mapped++;
g.mapped_menu_cmds[g.n_menu_mapped] = 0; g.mapped_menu_cmds[g.n_menu_mapped] = '\0';
g.mapped_menu_op[g.n_menu_mapped] = 0; g.mapped_menu_op[g.n_menu_mapped] = '\0';
} }
} }
@@ -4339,17 +4341,14 @@ doset() /* changing options via menu by Per Liboriussen */
and adjust the format string accordingly */ and adjust the format string accordingly */
longest_name_len = 0; longest_name_len = 0;
for (pass = 0; pass <= 2; pass++) for (pass = 0; pass <= 2; pass++)
for (i = 0; (name = ((pass == 0) for (i = 0; (name = ((pass == 0) ? boolopt[i].name
? boolopt[i].name : (pass == 1) ? compopt[i].name
: (pass == 1)
? compopt[i].name
: othropt[i].name)) != 0; i++) { : othropt[i].name)) != 0; i++) {
if (pass == 0 && !boolopt[i].addr) if (pass == 0 && !boolopt[i].addr)
continue; continue;
optflags = (pass == 0) ? boolopt[i].optflags optflags = (pass == 0) ? boolopt[i].optflags
: (pass == 1) : (pass == 1) ? compopt[i].optflags
? compopt[i].optflags : othropt[i].optflags;
: othropt[i].optflags;
if (optflags < startpass || optflags > endpass) if (optflags < startpass || optflags > endpass)
continue; continue;
if ((is_wc_option(name) && !wc_supported(name)) if ((is_wc_option(name) && !wc_supported(name))
@@ -4501,8 +4500,7 @@ doset() /* changing options via menu by Per Liboriussen */
preference_update(compopt[opt_indx].name); preference_update(compopt[opt_indx].name);
} }
} }
free((genericptr_t) pick_list); free((genericptr_t) pick_list), pick_list = (menu_item *) 0;
pick_list = (menu_item *) 0;
} }
destroy_nhwindow(tmpwin); destroy_nhwindow(tmpwin);
@@ -4514,6 +4512,7 @@ doset() /* changing options via menu by Per Liboriussen */
return 0; return 0;
} }
/* common to msg-types, menu-colors, autopickup-exceptions */
STATIC_OVL int STATIC_OVL int
handle_add_list_remove(optname, numtotal) handle_add_list_remove(optname, numtotal)
const char *optname; const char *optname;
@@ -4764,24 +4763,24 @@ boolean setinitial, setfromfile;
start_menu(tmpwin); start_menu(tmpwin);
any = g.zeroany; any = g.zeroany;
any.a_char = GPCOORDS_COMPASS; any.a_char = GPCOORDS_COMPASS;
add_menu(tmpwin, NO_GLYPH, &any, GPCOORDS_COMPASS, add_menu(tmpwin, NO_GLYPH, &any, GPCOORDS_COMPASS, 0, ATR_NONE,
0, ATR_NONE, "compass ('east' or '3s' or '2n,4w')", "compass ('east' or '3s' or '2n,4w')",
(gp == GPCOORDS_COMPASS) ? MENU_SELECTED : MENU_UNSELECTED); (gp == GPCOORDS_COMPASS) ? MENU_SELECTED : MENU_UNSELECTED);
any.a_char = GPCOORDS_COMFULL; any.a_char = GPCOORDS_COMFULL;
add_menu(tmpwin, NO_GLYPH, &any, GPCOORDS_COMFULL, 0, ATR_NONE, add_menu(tmpwin, NO_GLYPH, &any, GPCOORDS_COMFULL, 0, ATR_NONE,
"full compass ('east' or '3south' or '2north,4west')", "full compass ('east' or '3south' or '2north,4west')",
(gp == GPCOORDS_COMFULL) ? MENU_SELECTED : MENU_UNSELECTED); (gp == GPCOORDS_COMFULL) ? MENU_SELECTED : MENU_UNSELECTED);
any.a_char = GPCOORDS_MAP; any.a_char = GPCOORDS_MAP;
add_menu(tmpwin, NO_GLYPH, &any, GPCOORDS_MAP, add_menu(tmpwin, NO_GLYPH, &any, GPCOORDS_MAP, 0, ATR_NONE,
0, ATR_NONE, "map <x,y>", "map <x,y>",
(gp == GPCOORDS_MAP) ? MENU_SELECTED : MENU_UNSELECTED); (gp == GPCOORDS_MAP) ? MENU_SELECTED : MENU_UNSELECTED);
any.a_char = GPCOORDS_SCREEN; any.a_char = GPCOORDS_SCREEN;
add_menu(tmpwin, NO_GLYPH, &any, GPCOORDS_SCREEN, add_menu(tmpwin, NO_GLYPH, &any, GPCOORDS_SCREEN, 0, ATR_NONE,
0, ATR_NONE, "screen [row,column]", "screen [row,column]",
(gp == GPCOORDS_SCREEN) ? MENU_SELECTED : MENU_UNSELECTED); (gp == GPCOORDS_SCREEN) ? MENU_SELECTED : MENU_UNSELECTED);
any.a_char = GPCOORDS_NONE; any.a_char = GPCOORDS_NONE;
add_menu(tmpwin, NO_GLYPH, &any, GPCOORDS_NONE, add_menu(tmpwin, NO_GLYPH, &any, GPCOORDS_NONE, 0, ATR_NONE,
0, ATR_NONE, "none (no coordinates displayed)", "none (no coordinates displayed)",
(gp == GPCOORDS_NONE) ? MENU_SELECTED : MENU_UNSELECTED); (gp == GPCOORDS_NONE) ? MENU_SELECTED : MENU_UNSELECTED);
any.a_long = 0L; any.a_long = 0L;
add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, "", MENU_UNSELECTED); add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, "", MENU_UNSELECTED);
@@ -4789,7 +4788,7 @@ boolean setinitial, setfromfile;
1, 0, COLNO - 1, ROWNO - 1, 1, 0, COLNO - 1, ROWNO - 1,
flags.verbose ? "; column 0 unused, off left edge" : ""); flags.verbose ? "; column 0 unused, off left edge" : "");
add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, MENU_UNSELECTED); add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, MENU_UNSELECTED);
if (strcmp(windowprocs.name, "tty")) if (strcmp(windowprocs.name, "tty")) /* only show for non-tty */
add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE,
"screen: row is offset to accommodate tty interface's use of top line", "screen: row is offset to accommodate tty interface's use of top line",
MENU_UNSELECTED); MENU_UNSELECTED);
@@ -4989,7 +4988,7 @@ boolean setinitial, setfromfile;
int opt_idx, nmt, mttyp; int opt_idx, nmt, mttyp;
char mtbuf[BUFSZ] = DUMMY; char mtbuf[BUFSZ] = DUMMY;
msgtypes_again: msgtypes_again:
nmt = msgtype_count(); nmt = msgtype_count();
opt_idx = handle_add_list_remove("message type", nmt); opt_idx = handle_add_list_remove("message type", nmt);
if (opt_idx == 3) { /* done */ if (opt_idx == 3) { /* done */
@@ -5051,11 +5050,11 @@ boolean setinitial, setfromfile;
int opt_idx, nmc, mcclr, mcattr; int opt_idx, nmc, mcclr, mcattr;
char mcbuf[BUFSZ] = DUMMY; char mcbuf[BUFSZ] = DUMMY;
menucolors_again: menucolors_again:
nmc = count_menucolors(); nmc = count_menucolors();
opt_idx = handle_add_list_remove("menucolor", nmc); opt_idx = handle_add_list_remove("menucolor", nmc);
if (opt_idx == 3) { /* done */ if (opt_idx == 3) { /* done */
menucolors_done: menucolors_done:
if (nmc > 0 && !iflags.use_menu_color) if (nmc > 0 && !iflags.use_menu_color)
pline( pline(
"To have menu colors become active, toggle 'menucolors' option to True."); "To have menu colors become active, toggle 'menucolors' option to True.");
@@ -5126,15 +5125,18 @@ boolean setinitial, setfromfile;
} }
} else if (!strcmp("autopickup_exception", optname)) { } else if (!strcmp("autopickup_exception", optname)) {
int opt_idx, pass, totalapes = 0, numapes[2] = { 0, 0 }; int opt_idx, pass, totalapes = 0, numapes[2] = { 0, 0 };
char apebuf[1 + BUFSZ] = DUMMY; /* so &apebuf[1] is BUFSZ long for getlin() */ char apebuf[1 + BUFSZ]; /* so &apebuf[1] is BUFSZ long for getlin() */
struct autopickup_exception *ape; struct autopickup_exception *ape;
ape_again: ape_again:
totalapes = count_ape_maps(&numapes[AP_LEAVE], &numapes[AP_GRAB]); totalapes = count_ape_maps(&numapes[AP_LEAVE], &numapes[AP_GRAB]);
opt_idx = handle_add_list_remove("autopickup exception", totalapes); opt_idx = handle_add_list_remove("autopickup exception", totalapes);
if (opt_idx == 3) { /* done */ if (opt_idx == 3) { /* done */
return TRUE; return TRUE;
} else if (opt_idx == 0) { /* add new */ } else if (opt_idx == 0) { /* add new */
/* EDIT_GETLIN: assume user doesn't user want previous
exception used as default input string for this one... */
apebuf[0] = apebuf[1] = '\0';
getlin("What new autopickup exception pattern?", &apebuf[1]); getlin("What new autopickup exception pattern?", &apebuf[1]);
mungspaces(&apebuf[1]); /* regularize whitespace */ mungspaces(&apebuf[1]); /* regularize whitespace */
if (apebuf[1] == '\033') if (apebuf[1] == '\033')
@@ -5206,7 +5208,6 @@ boolean setinitial, setfromfile;
g.symset[which_set].name = (char *) 0; g.symset[which_set].name = (char *) 0;
res = read_sym_file(which_set); res = read_sym_file(which_set);
/* put symset name back */ /* put symset name back */
g.symset[which_set].name = symset_name; g.symset[which_set].name = symset_name;
@@ -5685,9 +5686,10 @@ char *buf;
#ifdef CURSES_GRAPHICS #ifdef CURSES_GRAPHICS
} else if (!strcmp(optname,"windowborders")) { } else if (!strcmp(optname,"windowborders")) {
Sprintf(buf, "%s", Sprintf(buf, "%s",
iflags.wc2_windowborders == 1 ? "1=on" : (iflags.wc2_windowborders == 1) ? "1=on"
iflags.wc2_windowborders == 2 ? "2=off" : : (iflags.wc2_windowborders == 2) ? "2=off"
iflags.wc2_windowborders == 3 ? "3=auto" : defopt); : (iflags.wc2_windowborders == 3) ? "3=auto"
: defopt);
#endif #endif
} else if (!strcmp(optname, "windowtype")) { } else if (!strcmp(optname, "windowtype")) {
Sprintf(buf, "%s", windowprocs.name); Sprintf(buf, "%s", windowprocs.name);
@@ -5712,10 +5714,9 @@ char *buf;
#endif #endif
} }
if (buf[0]) if (!buf[0])
return buf; Strcpy(buf, "unknown");
else return buf;
return "unknown";
} }
int int
@@ -5794,13 +5795,12 @@ STATIC_OVL void
remove_autopickup_exception(whichape) remove_autopickup_exception(whichape)
struct autopickup_exception *whichape; struct autopickup_exception *whichape;
{ {
struct autopickup_exception *ape, *prev = 0; struct autopickup_exception *ape, *freeape, *prev = 0;
int chain = whichape->grab ? AP_GRAB : AP_LEAVE; int chain = whichape->grab ? AP_GRAB : AP_LEAVE;
for (ape = iflags.autopickup_exceptions[chain]; ape;) { for (ape = iflags.autopickup_exceptions[chain]; ape;) {
if (ape == whichape) { if (ape == whichape) {
struct autopickup_exception *freeape = ape; freeape = ape;
ape = ape->next; ape = ape->next;
if (prev) if (prev)
prev->next = ape; prev->next = ape;
@@ -5993,7 +5993,8 @@ const char *strval;
/* data for option_help() */ /* data for option_help() */
static const char *opt_intro[] = { static const char *opt_intro[] = {
"", " NetHack Options Help:", "", "",
" NetHack Options Help:", "",
#define CONFIG_SLOT 3 /* fill in next value at run-time */ #define CONFIG_SLOT 3 /* fill in next value at run-time */
(char *) 0, (char *) 0,
#if !defined(MICRO) && !defined(MAC) #if !defined(MICRO) && !defined(MAC)
@@ -6003,7 +6004,8 @@ static const char *opt_intro[] = {
#ifdef VMS #ifdef VMS
"-- for example, $ DEFINE NETHACKOPTIONS \"noautopickup,fruit:kumquat\"", "-- for example, $ DEFINE NETHACKOPTIONS \"noautopickup,fruit:kumquat\"",
#endif #endif
"or press \"O\" while playing and use the menu.", "", "or press \"O\" while playing and use the menu.",
"",
"Boolean options (which can be negated by prefixing them with '!' or \"no\"):", "Boolean options (which can be negated by prefixing them with '!' or \"no\"):",
(char *) 0 (char *) 0
}; };
@@ -6011,7 +6013,8 @@ static const char *opt_intro[] = {
static const char *opt_epilog[] = { static const char *opt_epilog[] = {
"", "",
"Some of the options can be set only before the game is started; those", "Some of the options can be set only before the game is started; those",
"items will not be selectable in the 'O' command's menu.", (char *) 0 "items will not be selectable in the 'O' command's menu.",
(char *) 0
}; };
void void
@@ -6108,11 +6111,11 @@ struct fruit *replace_fruit;
{ {
register int i; register int i;
register struct fruit *f; register struct fruit *f;
int highest_fruit_id = 0; int highest_fruit_id = 0, globpfx;
char buf[PL_FSIZ], altname[PL_FSIZ]; char buf[PL_FSIZ], altname[PL_FSIZ];
boolean user_specified = (str == g.pl_fruit); boolean user_specified = (str == g.pl_fruit);
/* if not user-specified, then it's a fruit name for a fruit on /* if not user-specified, then it's a fruit name for a fruit on
* a bones level... * a bones level or from orctown raider's loot...
*/ */
/* Note: every fruit has an id (kept in obj->spe) of at least 1; /* Note: every fruit has an id (kept in obj->spe) of at least 1;
@@ -6123,39 +6126,54 @@ struct fruit *replace_fruit;
/* force fruit to be singular; this handling is not /* force fruit to be singular; this handling is not
needed--or wanted--for fruits from bones because needed--or wanted--for fruits from bones because
they already received it in their original game */ they already received it in their original game;
str==pl_fruit but makesingular() creates a copy
so we need to copy that back into pl_fruit */
nmcpy(g.pl_fruit, makesingular(str), PL_FSIZ); nmcpy(g.pl_fruit, makesingular(str), PL_FSIZ);
/* (assertion doesn't matter; we use 'g.pl_fruit' from here on out) */
/* assert( str == g.pl_fruit ); */ /* assert( str == g.pl_fruit ); */
/* disallow naming after other foods (since it'd be impossible /* disallow naming after other foods (since it'd be impossible
* to tell the difference) * to tell the difference); globs might have a size prefix which
* needs to be skipped in order to match the object type name
*/ */
globpfx = (!strncmp(g.pl_fruit, "small ", 6)
|| !strncmp(g.pl_fruit, "large ", 6)) ? 6
: (!strncmp(g.pl_fruit, "very large ", 11)) ? 11
: 0;
for (i = g.bases[FOOD_CLASS]; objects[i].oc_class == FOOD_CLASS; i++) { for (i = g.bases[FOOD_CLASS]; objects[i].oc_class == FOOD_CLASS; i++) {
if (!strcmp(OBJ_NAME(objects[i]), g.pl_fruit)) { if (!strcmp(OBJ_NAME(objects[i]), g.pl_fruit)
|| (globpfx > 0
&& !strcmp(OBJ_NAME(objects[i]), &g.pl_fruit[globpfx]))) {
found = TRUE; found = TRUE;
break; break;
} }
} }
{ if (!found) {
char *c; char *c;
for (c = g.pl_fruit; *c >= '0' && *c <= '9'; c++) for (c = g.pl_fruit; *c >= '0' && *c <= '9'; c++)
continue; continue;
if (isspace((uchar) *c) || *c == 0) if (!*c || isspace((uchar) *c))
numeric = TRUE; numeric = TRUE;
} }
if (found || numeric if (found || numeric
|| !strncmp(str, "cursed ", 7) /* these checks for applying food attributes to actual items
|| !strncmp(str, "uncursed ", 9) are case sensitive; "glob of foo" is caught by 'found'
|| !strncmp(str, "blessed ", 8) if 'foo' is a valid glob; when not valid, allow it as-is */
|| !strncmp(str, "partly eaten ", 13) || !strncmp(g.pl_fruit, "cursed ", 7)
|| (!strncmp(str, "tin of ", 7) || !strncmp(g.pl_fruit, "uncursed ", 9)
&& (!strcmp(str + 7, "spinach") || !strncmp(g.pl_fruit, "blessed ", 8)
|| name_to_mon(str + 7) >= LOW_PM)) || !strncmp(g.pl_fruit, "partly eaten ", 13)
|| !strcmp(str, "empty tin") || (!strncmp(g.pl_fruit, "tin of ", 7)
|| ((str_end_is(str, " corpse") && (!strcmp(g.pl_fruit + 7, "spinach")
|| str_end_is(str, " egg")) || name_to_mon(g.pl_fruit + 7) >= LOW_PM))
&& name_to_mon(str) >= LOW_PM)) { || !strcmp(g.pl_fruit, "empty tin")
|| (!strcmp(g.pl_fruit, "glob")
|| (globpfx > 0 && !strcmp("glob", &g.pl_fruit[globpfx])))
|| ((str_end_is(g.pl_fruit, " corpse")
|| str_end_is(g.pl_fruit, " egg"))
&& name_to_mon(g.pl_fruit) >= LOW_PM)) {
Strcpy(buf, g.pl_fruit); Strcpy(buf, g.pl_fruit);
Strcpy(g.pl_fruit, "candied "); Strcpy(g.pl_fruit, "candied ");
nmcpy(g.pl_fruit + 8, buf, PL_FSIZ - 8); nmcpy(g.pl_fruit + 8, buf, PL_FSIZ - 8);
@@ -6173,11 +6191,11 @@ struct fruit *replace_fruit;
/* replace_fruit is already part of the fruit chain; /* replace_fruit is already part of the fruit chain;
update it in place rather than looking it up again */ update it in place rather than looking it up again */
f = replace_fruit; f = replace_fruit;
copynchars(f->fname, str, PL_FSIZ - 1); copynchars(f->fname, g.pl_fruit, PL_FSIZ - 1);
goto nonew; goto nonew;
} }
} else { } else {
/* not user_supplied, so assumed to be from bones */ /* not user_supplied, so assumed to be from bones (or orc gang) */
copynchars(altname, str, PL_FSIZ - 1); copynchars(altname, str, PL_FSIZ - 1);
sanitize_name(altname); sanitize_name(altname);
flags.made_fruit = TRUE; /* for safety. Any fruit name added from a flags.made_fruit = TRUE; /* for safety. Any fruit name added from a
@@ -6682,5 +6700,4 @@ set_playmode()
#endif /* OPTION_LISTS_ONLY */ #endif /* OPTION_LISTS_ONLY */
/*options.c*/ /*options.c*/
+3 -3
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 pager.c $NHDT-Date: 1546144745 2018/12/30 04:39:05 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.146 $ */ /* NetHack 3.6 pager.c $NHDT-Date: 1546656415 2019/01/05 02:46:55 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.147 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2018. */ /*-Copyright (c) Robert Patrick Rankin, 2018. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -117,7 +117,7 @@ char *outbuf;
} else if (mon->m_ap_type == M_AP_OBJECT } else if (mon->m_ap_type == M_AP_OBJECT
/* remembered glyph, not glyph_at() which is 'mon' */ /* remembered glyph, not glyph_at() which is 'mon' */
&& glyph_is_object(glyph)) { && glyph_is_object(glyph)) {
objfrommap: objfrommap:
otmp = (struct obj *) 0; otmp = (struct obj *) 0;
fakeobj = object_from_map(glyph, x, y, &otmp); fakeobj = object_from_map(glyph, x, y, &otmp);
Strcat(outbuf, (otmp && otmp->otyp != STRANGE_OBJECT) Strcat(outbuf, (otmp && otmp->otyp != STRANGE_OBJECT)
@@ -1421,7 +1421,7 @@ boolean without_asking;
} else { } else {
textp = suptext2; textp = suptext2;
gang = ""; gang = "";
} }
datawin = create_nhwindow(NHW_MENU); datawin = create_nhwindow(NHW_MENU);
for (i = 0; textp[i]; i++) { for (i = 0; textp[i]; i++) {
char buf[BUFSZ]; char buf[BUFSZ];
+61 -1
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 spell.c $NHDT-Date: 1542765363 2018/11/21 01:56:03 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.87 $ */ /* NetHack 3.6 spell.c $NHDT-Date: 1546565814 2019/01/04 01:36:54 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.88 $ */
/* Copyright (c) M. Stephenson 1988 */ /* Copyright (c) M. Stephenson 1988 */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -923,6 +923,10 @@ boolean atme;
} else if (spellknow(spell) <= KEEN / 10) { /* 2000 turns left */ } else if (spellknow(spell) <= KEEN / 10) { /* 2000 turns left */
Your("recall of this spell is gradually fading."); Your("recall of this spell is gradually fading.");
} }
/*
* Note: dotele() also calculates energy use and checks nutrition
* and strength requirements; it any of these change, update it too.
*/
energy = (spellev(spell) * 5); /* 5 <= energy <= 35 */ energy = (spellev(spell) * 5); /* 5 <= energy <= 35 */
if (u.uhunger <= 10 && spellid(spell) != SPE_DETECT_FOOD) { if (u.uhunger <= 10 && spellid(spell) != SPE_DETECT_FOOD) {
@@ -1269,6 +1273,62 @@ throwspell()
return 1; return 1;
} }
/* add/hide/remove/unhide teleport-away on behalf of dotelecmd() to give
more control to behavior of ^T when used in wizard mode */
int
tport_spell(what)
int what;
{
static struct tport_hideaway {
struct spell savespell;
int tport_indx;
} save_tport;
int i;
/* also defined in teleport.c */
#define NOOP_SPELL 0
#define HIDE_SPELL 1
#define ADD_SPELL 2
#define UNHIDESPELL 3
#define REMOVESPELL 4
for (i = 0; i < MAXSPELL; i++)
if (spellid(i) == SPE_TELEPORT_AWAY || spellid(i) == NO_SPELL)
break;
if (i == MAXSPELL) {
impossible("tport_spell: spellbook full");
/* wizard mode ^T is not able to honor player's menu choice */
} else if (spellid(i) == NO_SPELL) {
if (what == HIDE_SPELL || what == REMOVESPELL) {
save_tport.tport_indx = MAXSPELL;
} else if (what == UNHIDESPELL) {
/*assert( save_tport.savespell.sp_id == SPE_TELEPORT_AWAY );*/
spl_book[save_tport.tport_indx] = save_tport.savespell;
save_tport.tport_indx = MAXSPELL; /* burn bridge... */
} else if (what == ADD_SPELL) {
save_tport.savespell = spl_book[i];
save_tport.tport_indx = i;
spl_book[i].sp_id = SPE_TELEPORT_AWAY;
spl_book[i].sp_lev = objects[SPE_TELEPORT_AWAY].oc_level;
spl_book[i].sp_know = KEEN;
return REMOVESPELL; /* operation needed to reverse */
}
} else { /* spellid(i) == SPE_TELEPORT_AWAY */
if (what == ADD_SPELL || what == UNHIDESPELL) {
save_tport.tport_indx = MAXSPELL;
} else if (what == REMOVESPELL) {
/*assert( i == save_tport.tport_indx );*/
spl_book[i] = save_tport.savespell;
save_tport.tport_indx = MAXSPELL;
} else if (what == HIDE_SPELL) {
save_tport.savespell = spl_book[i];
save_tport.tport_indx = i;
spl_book[i].sp_id = NO_SPELL;
return UNHIDESPELL; /* operation needed to reverse */
}
}
return NOOP_SPELL;
}
/* forget a random selection of known spells due to amnesia; /* forget a random selection of known spells due to amnesia;
they used to be lost entirely, as if never learned, but now we they used to be lost entirely, as if never learned, but now we
just set the memory retention to zero so that they can't be cast */ just set the memory retention to zero so that they can't be cast */
+165 -45
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 teleport.c $NHDT-Date: 1544401270 2018/12/10 00:21:10 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.81 $ */ /* NetHack 3.6 teleport.c $NHDT-Date: 1546655319 2019/01/05 02:28:39 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.83 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2011. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -493,17 +493,123 @@ struct obj *scroll;
return result; return result;
} }
/* ^T command; 'm ^T' == choose among several teleport modes */
int int
dotelecmd() dotelecmd()
{ {
return dotele((wizard) ? TRUE : FALSE); long save_HTele, save_ETele;
int res, added, hidden;
boolean ignore_restrictions = FALSE;
/* also defined in spell.c */
#define NOOP_SPELL 0
#define HIDE_SPELL 1
#define ADD_SPELL 2
#define UNHIDESPELL 3
#define REMOVESPELL 4
/* normal mode; ignore 'm' prefix if it was given */
if (!wizard)
return dotele(FALSE);
added = hidden = NOOP_SPELL;
save_HTele = HTeleportation, save_ETele = ETeleportation;
if (!iflags.menu_requested) {
ignore_restrictions = TRUE;
} else {
static const struct tporttypes {
char menulet;
const char *menudesc;
} tports[] = {
/*
* Potential combinations:
* 1) attempt ^T without intrinsic, not know spell;
* 2) via intrinsic, not know spell, obey restrictions;
* 3) via intrinsic, not know spell, ignore restrictions;
* 4) via intrinsic, know spell, obey restrictions;
* 5) via intrinsic, know spell, ignore restrictions;
* 6) via spell, not have intrinsic, obey restrictions;
* 7) via spell, not have intrinsic, ignore restrictions;
* 8) force, obey other restrictions;
* 9) force, ignore restrictions.
* We only support the 1st (t), 2nd (n), 6th (s), and 9th (w).
*
* This ignores the fact that there is an experience level
* (or poly-form) requirement which might make normal ^T fail.
*/
{ 'n', "normal ^T on demand; no spell, obey restrictions" },
{ 's', "via spellcast; no intrinsic teleport" },
{ 't', "try ^T without having it; no spell" },
{ 'w', "debug mode; ignore restrictions" }, /* trad wizard mode */
};
menu_item *picks = (menu_item *) 0;
anything any;
winid win;
int i, tmode;
win = create_nhwindow(NHW_MENU);
start_menu(win);
any = zeroany;
for (i = 0; i < SIZE(tports); ++i) {
any.a_int = (int) tports[i].menulet;
add_menu(win, NO_GLYPH, &any, (char) any.a_int, 0, ATR_NONE,
tports[i].menudesc,
(tports[i].menulet == 'w') ? MENU_SELECTED
: MENU_UNSELECTED);
}
end_menu(win, "Which way do you want to teleport?");
i = select_menu(win, PICK_ONE, &picks);
destroy_nhwindow(win);
if (i > 0) {
tmode = picks[0].item.a_int;
/* if we got 2, use the one which wasn't preselected */
if (i > 1 && tmode == 'w')
tmode = picks[1].item.a_int;
free((genericptr_t) picks);
} else if (i == 0) {
/* preselected one was explicitly chosen and got toggled off */
tmode = 'w';
} else { /* ESC */
return 0;
}
switch (tmode) {
case 'n':
HTeleportation |= I_SPECIAL; /* confer intrinsic teleportation */
hidden = tport_spell(HIDE_SPELL); /* hide teleport-away */
break;
case 's':
HTeleportation = ETeleportation = 0L; /* suppress intrinsic */
added = tport_spell(ADD_SPELL); /* add teleport-away */
break;
case 't':
HTeleportation = ETeleportation = 0L; /* suppress intrinsic */
hidden = tport_spell(HIDE_SPELL); /* hide teleport-away */
break;
case 'w':
ignore_restrictions = TRUE;
break;
}
}
/* if dotele() can be fatal, final disclosure might lie about
intrinsic teleportation; we should be able to live with that
since the menu finagling is only applicable in wizard mode */
res = dotele(ignore_restrictions);
HTeleportation = save_HTele;
ETeleportation = save_ETele;
if (added != NOOP_SPELL || hidden != NOOP_SPELL)
/* can't both be non-NOOP so addition will yield the non-NOOP one */
(void) tport_spell(added + hidden - NOOP_SPELL);
return res;
} }
int int
dotele(break_the_rules) dotele(break_the_rules)
boolean break_the_rules; boolean break_the_rules; /* True: wizard mode ^T */
{ {
struct trap *trap; struct trap *trap;
const char *cantdoit;
boolean trap_once = FALSE; boolean trap_once = FALSE;
trap = t_at(u.ux, u.uy); trap = t_at(u.ux, u.uy);
@@ -514,9 +620,9 @@ boolean break_the_rules;
trap_once = trap->once; /* trap may get deleted, save this */ trap_once = trap->once; /* trap may get deleted, save this */
if (trap->once) { if (trap->once) {
pline("This is a vault teleport, usable once only."); pline("This is a vault teleport, usable once only.");
if (yn("Jump in?") == 'n') if (yn("Jump in?") == 'n') {
trap = 0; trap = 0;
else { } else {
deltrap(trap); deltrap(trap);
newsym(u.ux, u.uy); newsym(u.ux, u.uy);
} }
@@ -531,58 +637,72 @@ boolean break_the_rules;
if (!Teleportation || (u.ulevel < (Role_if(PM_WIZARD) ? 8 : 12) if (!Teleportation || (u.ulevel < (Role_if(PM_WIZARD) ? 8 : 12)
&& !can_teleport(g.youmonst.data))) { && !can_teleport(g.youmonst.data))) {
/* Try to use teleport away spell. */ /* Try to use teleport away spell.
if (objects[SPE_TELEPORT_AWAY].oc_name_known && !Confusion) 3.6.2: this used to require that you know the spellbook
for (sp_no = 0; sp_no < MAXSPELL; sp_no++) (probably just intended as an optimization to skip the
if (g.spl_book[sp_no].sp_id == SPE_TELEPORT_AWAY) { lookup loop) but it is possible to know and cast a spell
castit = TRUE; after forgetting its book due to amnesia. */
break; for (sp_no = 0; sp_no < MAXSPELL; sp_no++)
} if (g.spl_book[sp_no].sp_id == SPE_TELEPORT_AWAY)
if (!break_the_rules) { break;
if (!castit) { /* casting isn't inhibited by being Stunned (...it ought to be) */
if (!Teleportation) castit = (sp_no < MAXSPELL && !Confusion);
You("don't know that spell."); if (!castit && !break_the_rules) {
else You("%s.",
You("are not able to teleport at will."); !Teleportation ? ((sp_no < MAXSPELL)
return 0; ? "can't cast that spell"
} : "don't know that spell")
: "are not able to teleport at will");
return 0;
} }
} }
if (u.uhunger <= 100 || ACURR(A_STR) < 6) { cantdoit = 0;
if (!break_the_rules) { /* 3.6.2: the magic numbers for hunger, strength, and energy
You("lack the strength %s.", have been changed to match the ones used in spelleffects().
castit ? "for a teleport spell" : "to teleport"); Also, failing these tests used to return 1 and use a move
return 1; even though casting failure due to these reasons doesn't.
} [Note: this spellev() is different from the one in spell.c
but they both yield the same result.] */
#define spellev(spell_otyp) ((int) objects[spell_otyp].oc_level)
energy = 5 * spellev(SPE_TELEPORT_AWAY);
if (break_the_rules) {
if (!castit)
energy = 0;
/* spell will cost more if carrying the Amulet, but the
amount is rnd(2 * energy) so we can't know by how much;
average is twice the normal cost, but could be triple;
the extra energy is spent even if that results in not
having enough to cast (which also uses the move) */
else if (u.uen < energy)
u.uen = energy;
} else if (u.uhunger <= 10) {
cantdoit = "are too weak from hunger";
} else if (ACURR(A_STR) < 4) {
cantdoit = "lack the strength";
} else if (energy > u.uen) {
cantdoit = "lack the energy";
} }
if (cantdoit) {
energy = objects[SPE_TELEPORT_AWAY].oc_level * 7 / 2 - 2; You("%s %s.", cantdoit,
if (u.uen <= energy) { castit ? "for a teleport spell" : "to teleport");
if (break_the_rules) return 0;
energy = u.uen; } else if (check_capacity(
else { "Your concentration falters from carrying so much.")) {
You("lack the energy %s.", return 1; /* this failure in spelleffects() also uses the move */
castit ? "for a teleport spell" : "to teleport");
return 1;
}
} }
if (check_capacity(
"Your concentration falters from carrying so much."))
return 1;
if (castit) { if (castit) {
/* energy cost is deducted in spelleffects() */
exercise(A_WIS, TRUE); exercise(A_WIS, TRUE);
if (spelleffects(sp_no, TRUE)) if (spelleffects(sp_no, TRUE))
return 1; return 1;
else if (!break_the_rules) else if (!break_the_rules)
return 0; return 0;
} else { } else {
if (!break_the_rules) { /* bypassing spelleffects(); apply energy cost directly */
u.uen -= energy; u.uen -= energy;
g.context.botl = 1; g.context.botl = 1;
}
} }
} }
@@ -593,7 +713,7 @@ boolean break_the_rules;
tele(); tele();
(void) next_to_u(); (void) next_to_u();
} else { } else {
You1(shudder_for_moment); You("%s", shudder_for_moment);
return 0; return 0;
} }
if (!trap) if (!trap)