Merge remote-tracking branch 'origin/NetHack-3.6.0'
This commit is contained in:
@@ -34,9 +34,6 @@ boolean resuming;
|
||||
monstr_init(); /* monster strengths */
|
||||
objects_init();
|
||||
|
||||
if (wizard)
|
||||
add_debug_extended_commands();
|
||||
|
||||
/* if a save file created in normal mode is now being restored in
|
||||
explore mode, treat it as normal restore followed by 'X' command
|
||||
to use up the save file and require confirmation for explore mode */
|
||||
|
||||
244
src/do_name.c
244
src/do_name.c
@@ -59,45 +59,90 @@ const char *goal;
|
||||
putstr(tmpwin, 0, sbuf);
|
||||
putstr(tmpwin, 0, "Use 'H', 'J', 'K', 'L' to move the cursor 8 units at a time.");
|
||||
putstr(tmpwin, 0, "Or enter a background symbol (ex. '<').");
|
||||
putstr(tmpwin, 0, "Use '@' to move the cursor on yourself.");
|
||||
if (!iflags.terrainmode || (iflags.terrainmode & TER_MON) != 0)
|
||||
putstr(tmpwin, 0, "Use 'm' or 'M' to move the cursor to next monster.");
|
||||
if (!iflags.terrainmode || (iflags.terrainmode & TER_OBJ) != 0)
|
||||
putstr(tmpwin, 0, "Use 'o' or 'O' to move the cursor to next object.");
|
||||
Sprintf(sbuf, "Use '%s' to move the cursor on yourself.",
|
||||
visctrl(Cmd.spkeys[NHKF_GETPOS_SELF]));
|
||||
putstr(tmpwin, 0, sbuf);
|
||||
if (!iflags.terrainmode || (iflags.terrainmode & TER_MON) != 0) {
|
||||
Sprintf(sbuf, "Use '%s' or '%s' to move the cursor to next monster.",
|
||||
visctrl(Cmd.spkeys[NHKF_GETPOS_MON_NEXT]),
|
||||
visctrl(Cmd.spkeys[NHKF_GETPOS_MON_PREV]));
|
||||
putstr(tmpwin, 0, sbuf);
|
||||
}
|
||||
if (!iflags.terrainmode || (iflags.terrainmode & TER_OBJ) != 0) {
|
||||
Sprintf(sbuf, "Use '%s' or '%s' to move the cursor to next object.",
|
||||
visctrl(Cmd.spkeys[NHKF_GETPOS_OBJ_NEXT]),
|
||||
visctrl(Cmd.spkeys[NHKF_GETPOS_OBJ_PREV]));
|
||||
putstr(tmpwin, 0, sbuf);
|
||||
}
|
||||
if (!iflags.terrainmode || (iflags.terrainmode & TER_MAP) != 0) {
|
||||
/* both of these are primarily useful when choosing a travel
|
||||
destination for the '_' command */
|
||||
putstr(tmpwin, 0,
|
||||
"Use 'd' or 'D' to move the cursor to next door or doorway.");
|
||||
putstr(tmpwin, 0,
|
||||
"Use 'x' or 'X' to move the cursor to unexplored location.");
|
||||
Sprintf(sbuf,
|
||||
"Use '%s' or '%s' to move the cursor to next door or doorway.",
|
||||
visctrl(Cmd.spkeys[NHKF_GETPOS_DOOR_NEXT]),
|
||||
visctrl(Cmd.spkeys[NHKF_GETPOS_DOOR_PREV]));
|
||||
putstr(tmpwin, 0, sbuf);
|
||||
Sprintf(sbuf,
|
||||
"Use '%s' or '%s' to move the cursor to unexplored location.",
|
||||
visctrl(Cmd.spkeys[NHKF_GETPOS_UNEX_NEXT]),
|
||||
visctrl(Cmd.spkeys[NHKF_GETPOS_UNEX_PREV]));
|
||||
putstr(tmpwin, 0, sbuf);
|
||||
}
|
||||
Sprintf(sbuf, "Use '%s' for a menu of interesting targets in view.",
|
||||
visctrl(Cmd.spkeys[NHKF_GETPOS_MENU_FOV]));
|
||||
putstr(tmpwin, 0, sbuf);
|
||||
Sprintf(sbuf, "Use '%s' for a menu of all interesting targets.",
|
||||
visctrl(Cmd.spkeys[NHKF_GETPOS_MENU]));
|
||||
putstr(tmpwin, 0, sbuf);
|
||||
if (!iflags.terrainmode) {
|
||||
if (getpos_hilitefunc)
|
||||
putstr(tmpwin, 0, "Use '$' to display valid locations.");
|
||||
putstr(tmpwin, 0, "Use '#' to toggle automatic description.");
|
||||
if (iflags.cmdassist) /* assisting the '/' command, I suppose... */
|
||||
putstr(tmpwin, 0,
|
||||
(iflags.getpos_coords == GPCOORDS_NONE)
|
||||
? "(Set 'whatis_coord' option to include coordinates with '#' text.)"
|
||||
: "(Reset 'whatis_coord' option to omit coordinates from '#' text.)");
|
||||
char kbuf[BUFSZ];
|
||||
if (getpos_hilitefunc) {
|
||||
Sprintf(sbuf, "Use '%s' to display valid locations.",
|
||||
visctrl(Cmd.spkeys[NHKF_GETPOS_SHOWVALID]));
|
||||
putstr(tmpwin, 0, sbuf);
|
||||
}
|
||||
Sprintf(sbuf, "Use '%s' to toggle automatic description.",
|
||||
visctrl(Cmd.spkeys[NHKF_GETPOS_AUTODESC]));
|
||||
putstr(tmpwin, 0, sbuf);
|
||||
if (iflags.cmdassist) { /* assisting the '/' command, I suppose... */
|
||||
Sprintf(sbuf,
|
||||
(iflags.getpos_coords == GPCOORDS_NONE)
|
||||
? "(Set 'whatis_coord' option to include coordinates with '%s' text.)"
|
||||
: "(Reset 'whatis_coord' option to omit coordinates from '%s' text.)",
|
||||
visctrl(Cmd.spkeys[NHKF_GETPOS_AUTODESC]));
|
||||
}
|
||||
/* disgusting hack; the alternate selection characters work for any
|
||||
getpos call, but only matter for dowhatis (and doquickwhatis) */
|
||||
doing_what_is = (goal == what_is_an_unknown_object);
|
||||
Sprintf(sbuf, "Type a '.'%s when you are at the right place.",
|
||||
doing_what_is ? " or ',' or ';' or ':'" : "");
|
||||
doing_what_is = (goal == what_is_an_unknown_object);
|
||||
if (doing_what_is) {
|
||||
Sprintf(kbuf, "'%s' or '%s' or '%s' or '%s'",
|
||||
visctrl(Cmd.spkeys[NHKF_GETPOS_PICK]),
|
||||
visctrl(Cmd.spkeys[NHKF_GETPOS_PICK_Q]),
|
||||
visctrl(Cmd.spkeys[NHKF_GETPOS_PICK_O]),
|
||||
visctrl(Cmd.spkeys[NHKF_GETPOS_PICK_V]));
|
||||
} else {
|
||||
Sprintf(kbuf, "'%s'", visctrl(Cmd.spkeys[NHKF_GETPOS_PICK]));
|
||||
}
|
||||
Sprintf(sbuf, "Type a %s when you are at the right place.", kbuf);
|
||||
putstr(tmpwin, 0, sbuf);
|
||||
if (doing_what_is) {
|
||||
putstr(tmpwin, 0,
|
||||
" ':' describe current spot, show 'more info', move to another spot.");
|
||||
Sprintf(sbuf,
|
||||
" '.' describe current spot,%s move to another spot;",
|
||||
" '%s' describe current spot, show 'more info', move to another spot.",
|
||||
visctrl(Cmd.spkeys[NHKF_GETPOS_PICK_V]));
|
||||
putstr(tmpwin, 0, sbuf);
|
||||
Sprintf(sbuf,
|
||||
" '%s' describe current spot,%s move to another spot;",
|
||||
visctrl(Cmd.spkeys[NHKF_GETPOS_PICK]),
|
||||
flags.help ? " prompt if 'more info'," : "");
|
||||
putstr(tmpwin, 0, sbuf);
|
||||
putstr(tmpwin, 0,
|
||||
" ',' describe current spot, move to another spot;");
|
||||
putstr(tmpwin, 0,
|
||||
" ';' describe current spot, stop looking at things;");
|
||||
Sprintf(sbuf,
|
||||
" '%s' describe current spot, move to another spot;",
|
||||
visctrl(Cmd.spkeys[NHKF_GETPOS_PICK_Q]));
|
||||
putstr(tmpwin, 0, sbuf);
|
||||
Sprintf(sbuf,
|
||||
" '%s' describe current spot, stop looking at things;",
|
||||
visctrl(Cmd.spkeys[NHKF_GETPOS_PICK_O]));
|
||||
putstr(tmpwin, 0, sbuf);
|
||||
}
|
||||
}
|
||||
if (!force)
|
||||
@@ -135,7 +180,10 @@ enum gloctypes {
|
||||
GLOC_DOOR,
|
||||
GLOC_EXPLORE,
|
||||
|
||||
NUM_GLOCS
|
||||
NUM_GLOCS,
|
||||
|
||||
GLOC_INTERESTING,
|
||||
GLOC_INTERESTING_FOV
|
||||
};
|
||||
|
||||
|
||||
@@ -183,6 +231,26 @@ int x,y, gloc;
|
||||
|| IS_UNEXPLORED_LOC(x - 1, y)
|
||||
|| IS_UNEXPLORED_LOC(x, y + 1)
|
||||
|| IS_UNEXPLORED_LOC(x, y - 1)));
|
||||
case GLOC_INTERESTING_FOV:
|
||||
if (!cansee(x,y))
|
||||
return FALSE;
|
||||
case GLOC_INTERESTING:
|
||||
return gather_locs_interesting(x,y, GLOC_DOOR)
|
||||
|| !(glyph_is_cmap(glyph)
|
||||
&& (is_cmap_wall(glyph_to_cmap(glyph))
|
||||
|| glyph_to_cmap(glyph) == S_tree
|
||||
|| glyph_to_cmap(glyph) == S_bars
|
||||
|| glyph_to_cmap(glyph) == S_ice
|
||||
|| glyph_to_cmap(glyph) == S_air
|
||||
|| glyph_to_cmap(glyph) == S_cloud
|
||||
|| glyph_to_cmap(glyph) == S_lava
|
||||
|| glyph_to_cmap(glyph) == S_water
|
||||
|| glyph_to_cmap(glyph) == S_pool
|
||||
|| glyph_to_cmap(glyph) == S_ndoor
|
||||
|| glyph_to_cmap(glyph) == S_room
|
||||
|| glyph_to_cmap(glyph) == S_darkroom
|
||||
|| glyph_to_cmap(glyph) == S_corr
|
||||
|| glyph_to_cmap(glyph) == S_litcorr));
|
||||
}
|
||||
/*NOTREACHED*/
|
||||
return FALSE;
|
||||
@@ -331,15 +399,88 @@ int cx, cy;
|
||||
}
|
||||
}
|
||||
|
||||
boolean
|
||||
getpos_menu(ccp, fovonly)
|
||||
coord *ccp;
|
||||
boolean fovonly;
|
||||
{
|
||||
coord *garr = DUMMY;
|
||||
int gcount = 0;
|
||||
winid tmpwin;
|
||||
anything any;
|
||||
int i, pick_cnt;
|
||||
menu_item *picks = (menu_item *) 0;
|
||||
char tmpbuf[BUFSZ];
|
||||
|
||||
gather_locs(&garr, &gcount,
|
||||
fovonly ? GLOC_INTERESTING_FOV : GLOC_INTERESTING);
|
||||
if (gcount < 2) { /* gcount always includes the hero */
|
||||
You("cannot %s anything interesting.", fovonly ? "see" : "detect");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
tmpwin = create_nhwindow(NHW_MENU);
|
||||
start_menu(tmpwin);
|
||||
any = zeroany;
|
||||
|
||||
for (i = 0; i < gcount; i++) {
|
||||
char fullbuf[BUFSZ];
|
||||
coord tmpcc;
|
||||
const char *firstmatch = "unknown";
|
||||
int sym = 0;
|
||||
any.a_int = i + 1;
|
||||
tmpcc.x = garr[i].x;
|
||||
tmpcc.y = garr[i].y;
|
||||
if (do_screen_description(tmpcc, TRUE, sym, tmpbuf, &firstmatch)) {
|
||||
(void) coord_desc(garr[i].x, garr[i].y, tmpbuf, iflags.getpos_coords);
|
||||
Sprintf(fullbuf, "%s%s%s", firstmatch, (*tmpbuf ? " " : ""), tmpbuf);
|
||||
add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, fullbuf,
|
||||
MENU_UNSELECTED);
|
||||
}
|
||||
}
|
||||
|
||||
Sprintf(tmpbuf, "Pick a target%s%s",
|
||||
fovonly ? " in view" : "",
|
||||
iflags.getloc_travelmode ? " for travel" : "");
|
||||
end_menu(tmpwin, tmpbuf);
|
||||
pick_cnt = select_menu(tmpwin, PICK_ONE, &picks);
|
||||
destroy_nhwindow(tmpwin);
|
||||
if (pick_cnt > 0) {
|
||||
ccp->x = garr[picks->item.a_int - 1].x;
|
||||
ccp->y = garr[picks->item.a_int - 1].y;
|
||||
free((genericptr_t) picks);
|
||||
}
|
||||
free((genericptr_t) garr);
|
||||
return (pick_cnt > 0);
|
||||
}
|
||||
|
||||
int
|
||||
getpos(ccp, force, goal)
|
||||
coord *ccp;
|
||||
boolean force;
|
||||
const char *goal;
|
||||
{
|
||||
static const char pick_chars[] = ".,;:",
|
||||
mMoOdDxX[] = "mMoOdDxX";
|
||||
const char *cp;
|
||||
struct {
|
||||
int nhkf, ret;
|
||||
} const pick_chars_def[] = {
|
||||
{ NHKF_GETPOS_PICK, LOOK_TRADITIONAL },
|
||||
{ NHKF_GETPOS_PICK_Q, LOOK_QUICK },
|
||||
{ NHKF_GETPOS_PICK_O, LOOK_ONCE },
|
||||
{ NHKF_GETPOS_PICK_V, LOOK_VERBOSE }
|
||||
};
|
||||
const int mMoOdDxX_def[] = {
|
||||
NHKF_GETPOS_MON_NEXT,
|
||||
NHKF_GETPOS_MON_PREV,
|
||||
NHKF_GETPOS_OBJ_NEXT,
|
||||
NHKF_GETPOS_OBJ_PREV,
|
||||
NHKF_GETPOS_DOOR_NEXT,
|
||||
NHKF_GETPOS_DOOR_PREV,
|
||||
NHKF_GETPOS_UNEX_NEXT,
|
||||
NHKF_GETPOS_UNEX_PREV
|
||||
};
|
||||
char pick_chars[6];
|
||||
char mMoOdDxX[9];
|
||||
int result = 0;
|
||||
int cx, cy, i, c;
|
||||
int sidx, tx, ty;
|
||||
@@ -350,10 +491,19 @@ const char *goal;
|
||||
int gcount[NUM_GLOCS] = DUMMY;
|
||||
int gidx[NUM_GLOCS] = DUMMY;
|
||||
|
||||
for (i = 0; i < SIZE(pick_chars_def); i++)
|
||||
pick_chars[i] = Cmd.spkeys[pick_chars_def[i].nhkf];
|
||||
pick_chars[SIZE(pick_chars_def)] = '\0';
|
||||
|
||||
for (i = 0; i < SIZE(mMoOdDxX_def); i++)
|
||||
mMoOdDxX[i] = Cmd.spkeys[mMoOdDxX_def[i]];
|
||||
mMoOdDxX[SIZE(mMoOdDxX_def)] = '\0';
|
||||
|
||||
if (!goal)
|
||||
goal = "desired location";
|
||||
if (flags.verbose) {
|
||||
pline("(For instructions type a '?')");
|
||||
pline("(For instructions type a '%s')",
|
||||
visctrl(Cmd.spkeys[NHKF_GETPOS_HELP]));
|
||||
msg_given = TRUE;
|
||||
}
|
||||
cx = ccp->x;
|
||||
@@ -388,7 +538,7 @@ const char *goal;
|
||||
if (iflags.autodescribe)
|
||||
msg_given = FALSE;
|
||||
|
||||
if (c == '\033') {
|
||||
if (c == Cmd.spkeys[NHKF_ESC]) {
|
||||
cx = cy = -10;
|
||||
msg_given = TRUE; /* force clear */
|
||||
result = -1;
|
||||
@@ -404,7 +554,7 @@ const char *goal;
|
||||
}
|
||||
if ((cp = index(pick_chars, c)) != 0) {
|
||||
/* '.' => 0, ',' => 1, ';' => 2, ':' => 3 */
|
||||
result = (int) (cp - pick_chars);
|
||||
result = pick_chars_def[(int) (cp - pick_chars)].ret;
|
||||
break;
|
||||
}
|
||||
for (i = 0; i < 8; i++) {
|
||||
@@ -442,26 +592,23 @@ const char *goal;
|
||||
goto nxtc;
|
||||
}
|
||||
|
||||
if (c == '?' || redraw_cmd(c)) {
|
||||
if (c == '?')
|
||||
if (c == Cmd.spkeys[NHKF_GETPOS_HELP] || redraw_cmd(c)) {
|
||||
if (c == Cmd.spkeys[NHKF_GETPOS_HELP])
|
||||
getpos_help(force, goal);
|
||||
else /* ^R */
|
||||
docrt(); /* redraw */
|
||||
/* update message window to reflect that we're still targetting */
|
||||
show_goal_msg = TRUE;
|
||||
msg_given = TRUE;
|
||||
} else if (c == '$' && getpos_hilitefunc) {
|
||||
} else if (c == Cmd.spkeys[NHKF_GETPOS_SHOWVALID]
|
||||
&& getpos_hilitefunc) {
|
||||
if (!hilite_state) {
|
||||
(*getpos_hilitefunc)(0);
|
||||
(*getpos_hilitefunc)(1);
|
||||
hilite_state = TRUE;
|
||||
}
|
||||
goto nxtc;
|
||||
} else if (c == '#') {
|
||||
/* unfortunately, using '#' as a command means we can't move
|
||||
cursor to sinks, iron bars, and poison clouds; perhaps
|
||||
when autodescribe is already on, next '#' should try to
|
||||
move to '#' rather than to toggle off? (or ask; ick...) */
|
||||
} else if (c == Cmd.spkeys[NHKF_GETPOS_AUTODESC]) {
|
||||
iflags.autodescribe = !iflags.autodescribe;
|
||||
pline("Automatic description %sis %s.",
|
||||
flags.verbose ? "of features under cursor " : "",
|
||||
@@ -470,7 +617,15 @@ const char *goal;
|
||||
show_goal_msg = TRUE;
|
||||
msg_given = TRUE;
|
||||
goto nxtc;
|
||||
} else if (c == '@') { /* return to hero's spot */
|
||||
} else if (c == Cmd.spkeys[NHKF_GETPOS_MENU]
|
||||
|| c == Cmd.spkeys[NHKF_GETPOS_MENU_FOV]) {
|
||||
coord tmpcrd;
|
||||
if (getpos_menu(&tmpcrd, (c == Cmd.spkeys[NHKF_GETPOS_MENU_FOV]))) {
|
||||
cx = tmpcrd.x;
|
||||
cy = tmpcrd.y;
|
||||
}
|
||||
goto nxtc;
|
||||
} else if (c == Cmd.spkeys[NHKF_GETPOS_SELF]) {
|
||||
/* reset 'm&M', 'o&O', &c; otherwise, there's no way for player
|
||||
to achieve that except by manually cycling through all spots */
|
||||
for (i = 0; i < NUM_GLOCS; i++)
|
||||
@@ -568,9 +723,10 @@ const char *goal;
|
||||
if (!force)
|
||||
Strcpy(note, "aborted");
|
||||
else
|
||||
Sprintf(note, "use '%c', '%c', '%c', '%c' or '.'", /* hjkl */
|
||||
Sprintf(note, "use '%c', '%c', '%c', '%c' or '%s'", /* hjkl */
|
||||
Cmd.move_W, Cmd.move_S, Cmd.move_N,
|
||||
Cmd.move_E);
|
||||
Cmd.move_E,
|
||||
visctrl(Cmd.spkeys[NHKF_GETPOS_PICK]));
|
||||
pline("Unknown direction: '%s' (%s).", visctrl((char) c),
|
||||
note);
|
||||
msg_given = TRUE;
|
||||
|
||||
@@ -41,7 +41,7 @@ register struct monst *mtmp;
|
||||
mtmp->meating = 0;
|
||||
EDOG(mtmp)->droptime = 0;
|
||||
EDOG(mtmp)->dropdist = 10000;
|
||||
EDOG(mtmp)->apport = 10;
|
||||
EDOG(mtmp)->apport = ACURR(A_CHA);
|
||||
EDOG(mtmp)->whistletime = 0;
|
||||
EDOG(mtmp)->hungrytime = 1000 + monstermoves;
|
||||
EDOG(mtmp)->ogoal.x = -1; /* force error if used before set */
|
||||
|
||||
23
src/dokick.c
23
src/dokick.c
@@ -497,15 +497,20 @@ xchar x, y;
|
||||
|| kickedobj == uchain)
|
||||
return 0;
|
||||
|
||||
if ((trap = t_at(x, y)) != 0
|
||||
&& (((trap->ttyp == PIT || trap->ttyp == SPIKED_PIT) && !Passes_walls)
|
||||
|| trap->ttyp == WEB)) {
|
||||
if (!trap->tseen)
|
||||
find_trap(trap);
|
||||
You_cant("kick %s that's in a %s!", something,
|
||||
Hallucination ? "tizzy" : (trap->ttyp == WEB) ? "web"
|
||||
: "pit");
|
||||
return 1;
|
||||
if ((trap = t_at(x, y)) != 0) {
|
||||
if (((trap->ttyp == PIT || trap->ttyp == SPIKED_PIT) && !Passes_walls)
|
||||
|| trap->ttyp == WEB) {
|
||||
if (!trap->tseen)
|
||||
find_trap(trap);
|
||||
You_cant("kick %s that's in a %s!", something,
|
||||
Hallucination ? "tizzy" :
|
||||
(trap->ttyp == WEB) ? "web" : "pit");
|
||||
return 1;
|
||||
}
|
||||
if (trap->ttyp == STATUE_TRAP) {
|
||||
activate_statue_trap(trap, x,y, FALSE);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (Fumbling && !rn2(3)) {
|
||||
|
||||
@@ -671,6 +671,7 @@ struct symparse loadsyms[] = {
|
||||
{ SYM_PCHAR, S_explode7, "S_explode7" },
|
||||
{ SYM_PCHAR, S_explode8, "S_explode8" },
|
||||
{ SYM_PCHAR, S_explode9, "S_explode9" },
|
||||
{ SYM_OC, ILLOBJ_CLASS + SYM_OFF_O, "S_strange_obj" },
|
||||
{ SYM_OC, WEAPON_CLASS + SYM_OFF_O, "S_weapon" },
|
||||
{ SYM_OC, ARMOR_CLASS + SYM_OFF_O, "S_armor" },
|
||||
{ SYM_OC, ARMOR_CLASS + SYM_OFF_O, "S_armour" },
|
||||
|
||||
@@ -93,6 +93,12 @@ register struct obj *obj;
|
||||
&& (youmonst.data != &mons[PM_RUST_MONSTER] || is_rustprone(obj)))
|
||||
return TRUE;
|
||||
|
||||
/* Ghouls only eat non-veggy corpses or eggs (see dogfood()) */
|
||||
if (u.umonnum == PM_GHOUL)
|
||||
return (boolean)((obj->otyp == CORPSE
|
||||
&& !vegan(&mons[obj->corpsenm]))
|
||||
|| (obj->otyp == EGG));
|
||||
|
||||
if (u.umonnum == PM_GELATINOUS_CUBE && is_organic(obj)
|
||||
/* [g.cubes can eat containers and retain all contents
|
||||
as engulfed items, but poly'd player can't do that] */
|
||||
@@ -1622,7 +1628,7 @@ struct obj *otmp;
|
||||
pline("Ecch - that must have been poisonous!");
|
||||
if (!Poison_resistance) {
|
||||
losestr(rnd(4));
|
||||
losehp(rnd(15), !glob ? "poisonous corpse" : "posionous glob",
|
||||
losehp(rnd(15), !glob ? "poisonous corpse" : "poisonous glob",
|
||||
KILLED_BY_AN);
|
||||
} else
|
||||
You("seem unaffected by the poison.");
|
||||
|
||||
@@ -2152,6 +2152,10 @@ int src;
|
||||
parseoptions(bufp, TRUE, TRUE);
|
||||
} else if (match_varname(buf, "AUTOPICKUP_EXCEPTION", 5)) {
|
||||
add_autopickup_exception(bufp);
|
||||
} else if (match_varname(buf, "BINDINGS", 4)) {
|
||||
parsebindings(bufp);
|
||||
} else if (match_varname(buf, "AUTOCOMPLETE", 5)) {
|
||||
parseautocomplete(bufp, TRUE);
|
||||
} else if (match_varname(buf, "MSGTYPE", 7)) {
|
||||
(void) msgtype_parse_add(bufp);
|
||||
#ifdef NOCWD_ASSUMPTIONS
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
char * ucase (char *)
|
||||
char * upstart (char *)
|
||||
char * mungspaces (char *)
|
||||
char * trimspaces (char *)
|
||||
char * strip_newline (char *)
|
||||
char * eos (char *)
|
||||
boolean str_end_is (const char *, const char *)
|
||||
@@ -159,6 +160,22 @@ char *bp;
|
||||
return bp;
|
||||
}
|
||||
|
||||
/* remove leading and trailing whitespace, in place */
|
||||
char*
|
||||
trimspaces(txt)
|
||||
char* txt;
|
||||
{
|
||||
char* end;
|
||||
|
||||
while (*txt == ' ' || *txt == '\t')
|
||||
txt++;
|
||||
end = eos(txt);
|
||||
while (--end >= txt && (*end == ' ' || *end == '\t'))
|
||||
*end = '\0';
|
||||
|
||||
return txt;
|
||||
}
|
||||
|
||||
/* remove \n from end of line; remove \r too if one is there */
|
||||
char *
|
||||
strip_newline(str)
|
||||
@@ -385,13 +402,17 @@ char *sbuf;
|
||||
return strcpy(sbuf, buf);
|
||||
}
|
||||
|
||||
#define VISCTRL_NBUF 5
|
||||
/* make a displayable string from a character */
|
||||
char *
|
||||
visctrl(c)
|
||||
char c;
|
||||
{
|
||||
Static char ccc[5];
|
||||
Static char visctrl_bufs[VISCTRL_NBUF][5];
|
||||
static int nbuf = 0;
|
||||
register int i = 0;
|
||||
char *ccc = visctrl_bufs[nbuf];
|
||||
nbuf = (nbuf + 1) % VISCTRL_NBUF;
|
||||
|
||||
if ((uchar) c & 0200) {
|
||||
ccc[i++] = 'M';
|
||||
|
||||
@@ -269,6 +269,58 @@ register struct monst *mtmp;
|
||||
} else if (mm == PM_NINJA) { /* extra quest villains */
|
||||
(void) mongets(mtmp, rn2(4) ? SHURIKEN : DART);
|
||||
(void) mongets(mtmp, rn2(4) ? SHORT_SWORD : AXE);
|
||||
} else if (ptr->msound == MS_GUARDIAN) {
|
||||
/* quest "guardians" */
|
||||
switch (mm) {
|
||||
case PM_STUDENT:
|
||||
case PM_ATTENDANT:
|
||||
case PM_ABBOT:
|
||||
case PM_ACOLYTE:
|
||||
case PM_GUIDE:
|
||||
case PM_APPRENTICE:
|
||||
if (rn2(2))
|
||||
(void) mongets(mtmp, rn2(3) ? DAGGER : KNIFE);
|
||||
if (rn2(5))
|
||||
(void) mongets(mtmp, rn2(3) ? LEATHER_JACKET : LEATHER_CLOAK);
|
||||
if (rn2(3))
|
||||
(void) mongets(mtmp, rn2(3) ? LOW_BOOTS : HIGH_BOOTS);
|
||||
if (rn2(3))
|
||||
(void) mongets(mtmp, POT_HEALING);
|
||||
break;
|
||||
case PM_CHIEFTAIN:
|
||||
case PM_PAGE:
|
||||
case PM_ROSHI:
|
||||
case PM_WARRIOR:
|
||||
(void) mongets(mtmp, rn2(3) ? LONG_SWORD : SHORT_SWORD);
|
||||
(void) mongets(mtmp, rn2(3) ? CHAIN_MAIL : LEATHER_ARMOR);
|
||||
if (rn2(2))
|
||||
(void) mongets(mtmp, rn2(2) ? LOW_BOOTS : HIGH_BOOTS);
|
||||
if (!rn2(3))
|
||||
(void) mongets(mtmp, LEATHER_CLOAK);
|
||||
if (!rn2(3)) {
|
||||
(void) mongets(mtmp, BOW);
|
||||
m_initthrow(mtmp, ARROW, 12);
|
||||
}
|
||||
break;
|
||||
case PM_HUNTER:
|
||||
(void) mongets(mtmp, rn2(3) ? SHORT_SWORD : DAGGER);
|
||||
if (rn2(2))
|
||||
(void) mongets(mtmp, rn2(2) ? LEATHER_JACKET : LEATHER_ARMOR);
|
||||
(void) mongets(mtmp, BOW);
|
||||
m_initthrow(mtmp, ARROW, 12);
|
||||
break;
|
||||
case PM_THUG:
|
||||
(void) mongets(mtmp, CLUB);
|
||||
(void) mongets(mtmp, rn2(3) ? DAGGER : KNIFE);
|
||||
if (rn2(2))
|
||||
(void) mongets(mtmp, LEATHER_GLOVES);
|
||||
(void) mongets(mtmp, rn2(2) ? LEATHER_JACKET : LEATHER_ARMOR);
|
||||
break;
|
||||
case PM_NEANDERTHAL:
|
||||
(void) mongets(mtmp, CLUB);
|
||||
(void) mongets(mtmp, LEATHER_ARMOR);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
@@ -237,7 +237,7 @@ int dir;
|
||||
mz_move(x, y, dir);
|
||||
mz_move(x, y, dir);
|
||||
if (x < 3 || y < 3 || x > x_maze_max || y > y_maze_max
|
||||
|| levl[x][y].typ != 0)
|
||||
|| levl[x][y].typ != STONE)
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
146
src/options.c
146
src/options.c
@@ -469,21 +469,21 @@ static char def_inv_order[MAXOCLASSES] = {
|
||||
typedef struct {
|
||||
const char *name;
|
||||
char cmd;
|
||||
const char *desc;
|
||||
} menu_cmd_t;
|
||||
|
||||
#define NUM_MENU_CMDS 11
|
||||
static const menu_cmd_t default_menu_cmd_info[NUM_MENU_CMDS] = {
|
||||
/* 0*/ { "menu_first_page", MENU_FIRST_PAGE },
|
||||
{ "menu_last_page", MENU_LAST_PAGE },
|
||||
{ "menu_next_page", MENU_NEXT_PAGE },
|
||||
{ "menu_previous_page", MENU_PREVIOUS_PAGE },
|
||||
{ "menu_select_all", MENU_SELECT_ALL },
|
||||
/* 5*/ { "menu_deselect_all", MENU_UNSELECT_ALL },
|
||||
{ "menu_invert_all", MENU_INVERT_ALL },
|
||||
{ "menu_select_page", MENU_SELECT_PAGE },
|
||||
{ "menu_deselect_page", MENU_UNSELECT_PAGE },
|
||||
{ "menu_invert_page", MENU_INVERT_PAGE },
|
||||
/*10*/ { "menu_search", MENU_SEARCH },
|
||||
static const menu_cmd_t default_menu_cmd_info[] = {
|
||||
{ "menu_first_page", MENU_FIRST_PAGE, "Go to first page" },
|
||||
{ "menu_last_page", MENU_LAST_PAGE, "Go to last page" },
|
||||
{ "menu_next_page", MENU_NEXT_PAGE, "Go to next page" },
|
||||
{ "menu_previous_page", MENU_PREVIOUS_PAGE, "Go to previous page" },
|
||||
{ "menu_select_all", MENU_SELECT_ALL, "Select all items" },
|
||||
{ "menu_deselect_all", MENU_UNSELECT_ALL, "Unselect all items" },
|
||||
{ "menu_invert_all", MENU_INVERT_ALL, "Insert selection" },
|
||||
{ "menu_select_page", MENU_SELECT_PAGE, "Select items in current page" },
|
||||
{ "menu_deselect_page", MENU_UNSELECT_PAGE, "Unselect items in current page" },
|
||||
{ "menu_invert_page", MENU_INVERT_PAGE, "Invert current page selection" },
|
||||
{ "menu_search", MENU_SEARCH, "Search and toggle matching items" },
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -833,6 +833,10 @@ int maxlen;
|
||||
* has the effect of 'meta'-ing the value which follows (so that the
|
||||
* alternate character set will be enabled).
|
||||
*
|
||||
* X normal key X
|
||||
* ^X control-X
|
||||
* \mX meta-X
|
||||
*
|
||||
* For 3.4.3 and earlier, input ending with "\M", backslash, or caret
|
||||
* prior to terminating '\0' would pull that '\0' into the output and then
|
||||
* keep processing past it, potentially overflowing the output buffer.
|
||||
@@ -3233,7 +3237,7 @@ boolean tinitial, tfrom_file;
|
||||
}
|
||||
|
||||
/* check for menu command mapping */
|
||||
for (i = 0; i < NUM_MENU_CMDS; i++) {
|
||||
for (i = 0; i < SIZE(default_menu_cmd_info); i++) {
|
||||
fullname = default_menu_cmd_info[i].name;
|
||||
if (duplicate)
|
||||
complain_about_duplicate(opts, 1);
|
||||
@@ -3241,7 +3245,6 @@ boolean tinitial, tfrom_file;
|
||||
if (negated) {
|
||||
bad_negation(fullname, FALSE);
|
||||
} else if ((op = string_for_opt(opts, FALSE)) != 0) {
|
||||
int j;
|
||||
char c, op_buf[BUFSZ];
|
||||
|
||||
escapes(op, op_buf);
|
||||
@@ -3475,6 +3478,56 @@ boolean tinitial, tfrom_file;
|
||||
badoption(opts);
|
||||
}
|
||||
|
||||
/* parse key:command */
|
||||
void
|
||||
parsebindings(bindings)
|
||||
char* bindings;
|
||||
{
|
||||
char *bind;
|
||||
char key;
|
||||
int i;
|
||||
|
||||
/* break off first binding from the rest; parse the rest */
|
||||
if ((bind = index(bindings, ',')) != 0) {
|
||||
*bind++ = 0;
|
||||
parsebindings(bind);
|
||||
}
|
||||
|
||||
/* parse a single binding: first split around : */
|
||||
if (! (bind = index(bindings, ':'))) return; /* it's not a binding */
|
||||
*bind++ = 0;
|
||||
|
||||
/* read the key to be bound */
|
||||
key = txt2key(bindings);
|
||||
if (!key) {
|
||||
raw_printf("Bad binding %s.", bindings);
|
||||
wait_synch();
|
||||
return;
|
||||
}
|
||||
|
||||
bind = trimspaces(bind);
|
||||
|
||||
/* is it a special key? */
|
||||
if (bind_specialkey(key, bind))
|
||||
return;
|
||||
|
||||
/* is it a menu command? */
|
||||
for (i = 0; i < SIZE(default_menu_cmd_info); i++) {
|
||||
if (!strcmp(default_menu_cmd_info[i].name, bind)) {
|
||||
if (illegal_menu_cmd_key(key)) {
|
||||
char tmp[BUFSZ];
|
||||
Sprintf(tmp, "Bad menu key %s:%s", visctrl(key), bind);
|
||||
badoption(tmp);
|
||||
} else
|
||||
add_menu_cmd_alias(key, default_menu_cmd_info[i].cmd);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* extended command? */
|
||||
bind_key(key, bind);
|
||||
}
|
||||
|
||||
static NEARDATA const char *menutype[] = { "traditional", "combination",
|
||||
"full", "partial" };
|
||||
|
||||
@@ -3525,6 +3578,18 @@ char from_ch, to_ch;
|
||||
}
|
||||
}
|
||||
|
||||
char
|
||||
get_menu_cmd_key(ch)
|
||||
char ch;
|
||||
{
|
||||
char *found = index(mapped_menu_op, ch);
|
||||
if (found) {
|
||||
int idx = (int) (found - mapped_menu_op);
|
||||
ch = mapped_menu_cmds[idx];
|
||||
}
|
||||
return ch;
|
||||
}
|
||||
|
||||
/*
|
||||
* Map the given character to its corresponding menu command. If it
|
||||
* doesn't match anything, just return the original.
|
||||
@@ -3541,6 +3606,57 @@ char ch;
|
||||
return ch;
|
||||
}
|
||||
|
||||
void
|
||||
show_menu_controls(win, dolist)
|
||||
winid win;
|
||||
boolean dolist;
|
||||
{
|
||||
char buf[BUFSZ];
|
||||
|
||||
putstr(win, 0, "Menu control keys:");
|
||||
if (dolist) {
|
||||
int i;
|
||||
for (i = 0; i < SIZE(default_menu_cmd_info); i++) {
|
||||
Sprintf(buf, "%-8s %s",
|
||||
visctrl(get_menu_cmd_key(default_menu_cmd_info[i].cmd)),
|
||||
default_menu_cmd_info[i].desc);
|
||||
putstr(win, 0, buf);
|
||||
}
|
||||
} else {
|
||||
putstr(win, 0, "");
|
||||
putstr(win, 0, " Page All items");
|
||||
Sprintf(buf, " Select %s %s",
|
||||
visctrl(get_menu_cmd_key(MENU_SELECT_PAGE)),
|
||||
visctrl(get_menu_cmd_key(MENU_SELECT_ALL)));
|
||||
putstr(win, 0, buf);
|
||||
Sprintf(buf, "Deselect %s %s",
|
||||
visctrl(get_menu_cmd_key(MENU_UNSELECT_PAGE)),
|
||||
visctrl(get_menu_cmd_key(MENU_UNSELECT_ALL)));
|
||||
putstr(win, 0, buf);
|
||||
Sprintf(buf, " Invert %s %s",
|
||||
visctrl(get_menu_cmd_key(MENU_INVERT_PAGE)),
|
||||
visctrl(get_menu_cmd_key(MENU_INVERT_ALL)));
|
||||
putstr(win, 0, buf);
|
||||
putstr(win, 0, "");
|
||||
Sprintf(buf, " Go to %s Next page",
|
||||
visctrl(get_menu_cmd_key(MENU_NEXT_PAGE)));
|
||||
putstr(win, 0, buf);
|
||||
Sprintf(buf, " %s Previous page",
|
||||
visctrl(get_menu_cmd_key(MENU_PREVIOUS_PAGE)));
|
||||
putstr(win, 0, buf);
|
||||
Sprintf(buf, " %s First page",
|
||||
visctrl(get_menu_cmd_key(MENU_FIRST_PAGE)));
|
||||
putstr(win, 0, buf);
|
||||
Sprintf(buf, " %s Last page",
|
||||
visctrl(get_menu_cmd_key(MENU_LAST_PAGE)));
|
||||
putstr(win, 0, buf);
|
||||
putstr(win, 0, "");
|
||||
Sprintf(buf, " %s Search and toggle matching entries",
|
||||
visctrl(get_menu_cmd_key(MENU_SEARCH)));
|
||||
putstr(win, 0, buf);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(MICRO) || defined(MAC) || defined(WIN32)
|
||||
#define OPTIONS_HEADING "OPTIONS"
|
||||
#else
|
||||
|
||||
28
src/pager.c
28
src/pager.c
@@ -1371,6 +1371,7 @@ whatdoes_help()
|
||||
destroy_nhwindow(tmpwin);
|
||||
}
|
||||
|
||||
#if 0
|
||||
#define WD_STACKLIMIT 5
|
||||
struct wd_stack_frame {
|
||||
Bitfield(active, 1);
|
||||
@@ -1501,18 +1502,31 @@ int *depth, lnum;
|
||||
}
|
||||
return stack[*depth].active ? TRUE : FALSE;
|
||||
}
|
||||
#endif /* 0 */
|
||||
|
||||
char *
|
||||
dowhatdoes_core(q, cbuf)
|
||||
char q;
|
||||
char *cbuf;
|
||||
{
|
||||
dlb *fp;
|
||||
char buf[BUFSZ];
|
||||
#if 0
|
||||
dlb *fp;
|
||||
struct wd_stack_frame stack[WD_STACKLIMIT];
|
||||
boolean cond;
|
||||
int ctrl, meta, depth = 0, lnum = 0;
|
||||
#endif /* 0 */
|
||||
const char *ec_desc;
|
||||
|
||||
if ((ec_desc = key2extcmddesc(q)) != NULL) {
|
||||
char keybuf[QBUFSZ];
|
||||
|
||||
Sprintf(buf, "%-8s%s.", key2txt(q, keybuf), ec_desc);
|
||||
Strcpy(cbuf, buf);
|
||||
return cbuf;
|
||||
}
|
||||
return 0;
|
||||
#if 0
|
||||
fp = dlb_fopen(CMDHELPFILE, "r");
|
||||
if (!fp) {
|
||||
pline("Cannot open \"%s\" data file!", CMDHELPFILE);
|
||||
@@ -1568,6 +1582,7 @@ char *cbuf;
|
||||
if (depth != 0)
|
||||
impossible("cmdhelp: mismatched &? &: &. conditionals.");
|
||||
return (char *) 0;
|
||||
#endif /* 0 */
|
||||
}
|
||||
|
||||
int
|
||||
@@ -1705,6 +1720,15 @@ hmenu_doextlist()
|
||||
(void) doextlist();
|
||||
}
|
||||
|
||||
void
|
||||
domenucontrols()
|
||||
{
|
||||
winid cwin = create_nhwindow(NHW_TEXT);
|
||||
show_menu_controls(cwin, FALSE);
|
||||
display_nhwindow(cwin, FALSE);
|
||||
destroy_nhwindow(cwin);
|
||||
}
|
||||
|
||||
/* data for dohelp() */
|
||||
static struct {
|
||||
void (*f)();
|
||||
@@ -1718,7 +1742,9 @@ static struct {
|
||||
{ hmenu_dowhatdoes, "Info on what a given key does." },
|
||||
{ option_help, "List of game options." },
|
||||
{ dispfile_optionfile, "Longer explanation of game options." },
|
||||
{ dokeylist, "Full list of keyboard commands" },
|
||||
{ hmenu_doextlist, "List of extended commands." },
|
||||
{ domenucontrols, "List menu control keys" },
|
||||
{ dispfile_license, "The NetHack license." },
|
||||
{ docontact, "Support information." },
|
||||
#ifdef PORT_HELP
|
||||
|
||||
@@ -814,7 +814,7 @@ nextpos:
|
||||
else
|
||||
ny += dy;
|
||||
|
||||
while ((typ = (crm = &levl[nx][ny])->typ) != 0) {
|
||||
while ((typ = (crm = &levl[nx][ny])->typ) != STONE) {
|
||||
/* in view of the above we must have IS_WALL(typ) or typ == POOL */
|
||||
/* must be a wall here */
|
||||
if (isok(nx + nx - x, ny + ny - y) && !IS_POOL(typ)
|
||||
|
||||
Reference in New Issue
Block a user