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

This commit is contained in:
keni
2016-09-12 15:30:39 -04:00
14 changed files with 176 additions and 49 deletions

View File

@@ -3352,6 +3352,15 @@ gives you the row and column of your review cursor and the PC cursor.
These co-ordinates are often useful in giving players a better sense of the
overall location of items on the screen.
.pg
NetHack can also be compiled with support for sending the game messages
to an external program, such as a text-to-speech synthesizer. If the #version
extended command shows "external program as a message handler", your NetHack
has been compiled with the capability. When compiling NetHack from source
on Linux and other POSIX systems, define MSGHANDLER to enable it. To use
the capability, set the environment variable NETHACK_MSGHANDLER to an
executable, which will be executed with the game message as the program's
only parameter.
.pg
While it is not difficult for experienced users to edit the \fBdefaults.nh\fP
file to accomplish this, novices may find this task somewhat daunting.
Included within the ``symbols'' file of all official distributions of NetHack
@@ -3369,10 +3378,20 @@ Load a symbol set for the rogue level that is appropriate for
use by blind players.
.lp menustyle:traditional
This will assist in the interface to speech synthesizers.
.lp nomenu_overlay
Show menus on a cleared screen and aligned to the left edge.
.lp number_pad
A lot of speech access programs use the number-pad to review the screen.
If this is the case, disable the number_pad option and use the traditional
Rogue-like commands.
.lp autodescribe
Automatically describe the terrain under the cursor when targeting.
.lp mention_walls
Give feedback messages when walking towards a wall or when travel command
was interrupted.
.lp whatis_coord:compass
When targeting with cursor, describe the cursor position with coordinates
relative to your character.
.hn 2
Global Configuration for System Administrators
.pg

View File

@@ -3995,6 +3995,15 @@ gives you the row and column of your review cursor and the PC cursor.
These co-ordinates are often useful in giving players a better sense of the
overall location of items on the screen.
%.pg
NetHack can also be compiled with support for sending the game messages
to an external program, such as a text-to-speech synthesizer. If the #version
extended command shows "external program as a message handler", your NetHack
has been compiled with the capability. When compiling NetHack from source
on Linux and other POSIX systems, define {\it MSGHANDLER\/} to enable it. To use
the capability, set the environment variable {\it NETHACK\_MSGHANDLER\/} to an
executable, which will be executed with the game message as the program's
only parameter.
%.pg
While it is not difficult for experienced users to edit the {\it defaults.nh\/}
file to accomplish this, novices may find this task somewhat daunting.
Included within the symbol file of all official distributions of NetHack
@@ -4017,10 +4026,24 @@ use by blind players.
\item[\ib{menustyle:traditional}]
This will assist in the interface to speech synthesizers.
%.lp
\item[\ib{nomenu\verb+_+overlay}]
Show menus on a cleared screen and aligned to the left edge.
%.lp
\item[\ib{number\verb+_+pad}]
A lot of speech access programs use the number-pad to review the screen.
If this is the case, disable the number\verb+_+pad option and use the traditional
Rogue-like commands.
%.lp
\item[\ib{autodescribe}]
Automatically describe the terrain under the cursor when targeting.
%.lp
\item[\ib{mention\verb+_+walls}]
Give feedback messages when walking towards a wall or when travel command
was interrupted.
%.lp
\item[\ib{whatis\verb+_+coord:compass}]
When targeting with cursor, describe the cursor position with coordinates
relative to your character.
\elist
%.hn2

View File

@@ -336,6 +336,9 @@ if user supplied a specific monster name when asked to choose a monster class,
S_quadruped due to being preceded by "titanothere" in mons[])
change ing_suffix() to not double final 'w' when adding 'ing' ('t=' yielded
"You mime throwwing something.")
using 'D' to drop when not carrying anything finished (after doing nothing)
without giving any feedback for menustyles "full" and "partial"
"you hear a distant <musical note> squeak" might actually be nearby
Fixes to Post-3.6.0 Problems that Were Exposed Via git Repository
@@ -483,6 +486,8 @@ undead #turning takes less time at higher experience level
peacefuls may react when you attack other peacefuls
prevent diagonal jumping through open doorways
different liquids when hallucinating
when moving a cursor for travel target, show if there is no known travel
path to that location, if "autodescribe" is on
Platform- and/or Interface-Specific New Features

View File

@@ -796,6 +796,7 @@ E void NDECL(drinksink);
/* ### hack.c ### */
E boolean FDECL(is_valid_travelpt, (int,int));
E anything *FDECL(uint_to_any, (unsigned));
E anything *FDECL(long_to_any, (long));
E anything *FDECL(monst_to_any, (struct monst *));

View File

@@ -192,6 +192,7 @@ struct instance_flags {
#define TER_OBJ 0x04
#define TER_MON 0x08
#define TER_DETECT 0x10 /* detect_foo magic rather than #terrain */
boolean getloc_travelmode;
coord travelcc; /* coordinates for travel_cache */
boolean window_inited; /* true if init_nhwindows() completed */
boolean vision_inited; /* true if vision is ready */

View File

@@ -4323,11 +4323,14 @@ dotravel(VOID_ARGS)
cc.x = u.ux;
cc.y = u.uy;
}
iflags.getloc_travelmode = TRUE;
pline("Where do you want to travel to?");
if (getpos(&cc, TRUE, "the desired destination") < 0) {
/* user pressed ESC */
iflags.getloc_travelmode = FALSE;
return 0;
}
iflags.getloc_travelmode = FALSE;
iflags.travelcc.x = u.tx = cc.x;
iflags.travelcc.y = u.ty = cc.y;
cmd[0] = CMD_TRAVEL;

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 do.c $NHDT-Date: 1464487100 2016/05/29 01:58:20 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.156 $ */
/* NetHack 3.6 do.c $NHDT-Date: 1472809073 2016/09/02 09:37:53 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.158 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -34,7 +34,8 @@ dodrop()
result = drop(getobj(&drop_types[i], "drop"));
if (*u.ushops)
sellobj_state(SELL_NORMAL);
reset_occupations();
if (result)
reset_occupations();
return result;
}
@@ -739,6 +740,10 @@ doddrop()
{
int result = 0;
if (!invent) {
You("have nothing to drop.");
return 0;
}
add_valid_menu_class(0); /* clear any classes already there */
if (*u.ushops)
sellobj_state(SELL_DELIBERATE);
@@ -747,7 +752,8 @@ doddrop()
result = menu_drop(result);
if (*u.ushops)
sellobj_state(SELL_NORMAL);
reset_occupations();
if (result)
reset_occupations();
return result;
}
@@ -785,6 +791,7 @@ int retry;
free((genericptr_t) pick_list);
} else if (flags.menu_style == MENU_COMBINATION) {
unsigned ggoresults = 0;
all_categories = FALSE;
/* Gather valid classes via traditional NetHack method */
i = ggetobj("drop", drop, 0, TRUE, &ggoresults);

View File

@@ -316,7 +316,9 @@ int cx, cy;
cc.y = cy;
if (do_screen_description(cc, TRUE, sym, tmpbuf, &firstmatch)) {
(void) coord_desc(cx, cy, tmpbuf, iflags.getpos_coords);
pline("%s%s%s", firstmatch, *tmpbuf ? " " : "", tmpbuf);
pline("%s%s%s%s", firstmatch, *tmpbuf ? " " : "", tmpbuf,
(iflags.getloc_travelmode && !is_valid_travelpt(cx,cy))
? " (no travel path)" : "");
curs(WIN_MAP, cx, cy);
flush_screen(0);
}

View File

@@ -1675,20 +1675,18 @@ struct obj *otmp;
if (!strncmpi(pmxnam, "the ", 4))
pmxnam += 4;
pline("%s%s %s!",
pline("%s%s %s %s%c",
type_is_pname(&mons[mnum])
? "" : the_unique_pm(&mons[mnum]) ? "The " : "This ",
? "" : the_unique_pm(&mons[mnum]) ? "The " : "This ",
pmxnam,
Hallucination ? "is" : "tastes",
/* tiger reference is to TV ads for "Frosted Flakes",
breakfast cereal targeted at kids by "Tony the tiger" */
Hallucination
? (yummy ? ((u.umonnum == PM_TIGER) ? "is gr-r-reat"
: "is gnarly")
: palatable ? "is copacetic"
: "is grody")
: (yummy ? "tastes delicious"
: palatable ? "tastes okay"
: "tastes terrible"));
? (yummy ? ((u.umonnum == PM_TIGER) ? "gr-r-reat" : "gnarly")
: palatable ? "copacetic" : "grody")
: (yummy ? "delicious" : palatable ? "okay" : "terrible"),
(yummy || !palatable) ? '!' : '.');
}
return retcode;

View File

@@ -10,7 +10,7 @@ STATIC_DCL void NDECL(maybe_wail);
STATIC_DCL int NDECL(moverock);
STATIC_DCL int FDECL(still_chewing, (XCHAR_P, XCHAR_P));
STATIC_DCL void NDECL(dosinkfall);
STATIC_DCL boolean FDECL(findtravelpath, (BOOLEAN_P));
STATIC_DCL boolean FDECL(findtravelpath, (int));
STATIC_DCL boolean FDECL(trapmove, (int, int, struct trap *));
STATIC_DCL void NDECL(switch_terrain);
STATIC_DCL struct monst *FDECL(monstinroom, (struct permonst *, int));
@@ -19,6 +19,11 @@ STATIC_DCL void FDECL(move_update, (BOOLEAN_P));
#define IS_SHOP(x) (rooms[x].rtype >= SHOPBASE)
/* mode values for findtravelpath() */
#define TRAVP_TRAVEL 0
#define TRAVP_GUESS 1
#define TRAVP_VALID 2
static anything tmp_anything;
anything *
@@ -887,21 +892,25 @@ int wiz_debug_cmd_traveldisplay()
* Returns TRUE if a path was found.
*/
STATIC_OVL boolean
findtravelpath(guess)
boolean guess;
findtravelpath(mode)
int mode;
{
/* if travel to adjacent, reachable location, use normal movement rules */
if (!guess && context.travel1 && distmin(u.ux, u.uy, u.tx, u.ty) == 1
if ((mode == TRAVP_TRAVEL || mode == TRAVP_VALID) && context.travel1
&& distmin(u.ux, u.uy, u.tx, u.ty) == 1
&& !(u.ux != u.tx && u.uy != u.ty && NODIAG(u.umonnum))) {
context.run = 0;
if (test_move(u.ux, u.uy, u.tx - u.ux, u.ty - u.uy, TEST_MOVE)) {
u.dx = u.tx - u.ux;
u.dy = u.ty - u.uy;
nomul(0);
iflags.travelcc.x = iflags.travelcc.y = -1;
if (mode == TRAVP_TRAVEL) {
u.dx = u.tx - u.ux;
u.dy = u.ty - u.uy;
nomul(0);
iflags.travelcc.x = iflags.travelcc.y = -1;
}
return TRUE;
}
context.run = 8;
if (mode == TRAVP_TRAVEL)
context.run = 8;
}
if (u.tx != u.ux || u.ty != u.uy) {
xchar travel[COLNO][ROWNO];
@@ -917,7 +926,7 @@ boolean guess;
* goal is the position the player knows of, or might figure out
* (couldsee) that is closest to the target on a straight path.
*/
if (guess) {
if (mode == TRAVP_GUESS || mode == TRAVP_VALID) {
tx = u.ux;
ty = u.uy;
ux = u.tx;
@@ -987,7 +996,8 @@ boolean guess;
* example above is never included in it, preventing
* the cycle.
*/
if (!isok(nx, ny) || (guess && !couldsee(nx, ny)))
if (!isok(nx, ny)
|| ((mode == TRAVP_GUESS) && !couldsee(nx, ny)))
continue;
if ((!Passes_walls && !can_ooze(&youmonst)
&& closed_door(x, y)) || sobj_at(BOULDER, x, y)
@@ -1009,10 +1019,11 @@ boolean guess;
&& (levl[nx][ny].seenv
|| (!Blind && couldsee(nx, ny)))) {
if (nx == ux && ny == uy) {
if (!guess) {
if (mode == TRAVP_TRAVEL || mode == TRAVP_VALID) {
u.dx = x - ux;
u.dy = y - uy;
if (x == u.tx && y == u.ty) {
if (mode == TRAVP_TRAVEL
&& x == u.tx && y == u.ty) {
nomul(0);
/* reset run so domove run checks work */
context.run = 8;
@@ -1052,7 +1063,7 @@ boolean guess;
}
/* if guessing, find best location in travel matrix and go there */
if (guess) {
if (mode == TRAVP_GUESS) {
int px = tx, py = ty; /* pick location */
int dist, nxtdist, d2, nd2;
@@ -1107,7 +1118,7 @@ boolean guess;
uy = u.uy;
set = 0;
n = radius = 1;
guess = FALSE;
mode = TRAVP_TRAVEL;
goto noguess;
}
return FALSE;
@@ -1120,6 +1131,27 @@ found:
return FALSE;
}
boolean
is_valid_travelpt(x,y)
int x,y;
{
int tx = u.tx;
int ty = u.ty;
boolean ret;
int g = glyph_at(x,y);
if (x == u.ux && y == u.uy)
return TRUE;
if (isok(x,y) && glyph_is_cmap(g) && S_stone == glyph_to_cmap(g)
&& !levl[x][y].seenv)
return FALSE;
u.tx = x;
u.ty = y;
ret = findtravelpath(TRAVP_VALID);
u.tx = tx;
u.ty = ty;
return ret;
}
/* try to escape being stuck in a trapped state by walking out of it;
return true iff moving should continue to intended destination
(all failures and most successful escapes leave hero at original spot) */
@@ -1381,6 +1413,16 @@ domove()
|| (Blind && !Levitation && !Flying && !is_clinger(youmonst.data)
&& is_pool_or_lava(x, y) && levl[x][y].seenv)) {
if (context.run >= 2) {
if (iflags.mention_walls) {
if (trap && trap->tseen) {
int tt = what_trap(trap->ttyp);
You("stop in front of %s.",
an(defsyms[trap_to_defsym(tt)].explanation));
} else if (is_pool_or_lava(x,y) && levl[x][y].seenv) {
You("stop at the edge of the %s.",
hliquid(is_pool(x,y) ? "water" : "lava"));
}
}
nomul(0);
context.move = 0;
return;
@@ -2484,7 +2526,8 @@ lookaround()
/* Grid bugs stop if trying to move diagonal, even if blind. Maybe */
/* they polymorphed while in the middle of a long move. */
if (u.umonnum == PM_GRID_BUG && u.dx && u.dy) {
if (NODIAG(u.umonnum) && u.dx && u.dy) {
You("cannot move diagonally.");
nomul(0);
return;
}
@@ -2504,8 +2547,11 @@ lookaround()
&& (!mtmp->minvis || See_invisible) && !mtmp->mundetected) {
if ((context.run != 1 && !mtmp->mtame)
|| (x == u.ux + u.dx && y == u.uy + u.dy
&& !context.travel))
&& !context.travel)) {
if (iflags.mention_walls)
pline("%s blocks your path.", upstart(a_monnam(mtmp)));
goto stop;
}
}
if (levl[x][y].typ == STONE)
@@ -2519,8 +2565,11 @@ lookaround()
} else if (closed_door(x, y) || (mtmp && is_door_mappear(mtmp))) {
if (x != u.ux && y != u.uy)
continue;
if (context.run != 1)
if (context.run != 1) {
if (iflags.mention_walls)
You("stop in front of the door.");
goto stop;
}
goto bcorr;
} else if (levl[x][y].typ == CORR) {
bcorr:
@@ -2545,20 +2594,30 @@ lookaround()
} else if ((trap = t_at(x, y)) && trap->tseen) {
if (context.run == 1)
goto bcorr; /* if you must */
if (x == u.ux + u.dx && y == u.uy + u.dy)
if (x == u.ux + u.dx && y == u.uy + u.dy) {
if (iflags.mention_walls) {
int tt = what_trap(trap->ttyp);
You("stop in front of %s.",
an(defsyms[trap_to_defsym(tt)].explanation));
}
goto stop;
}
continue;
} else if (is_pool_or_lava(x, y)) {
/* water and lava only stop you if directly in front, and stop
* you even if you are running
*/
if (!Levitation && !Flying && !is_clinger(youmonst.data)
&& x == u.ux + u.dx && y == u.uy + u.dy)
&& x == u.ux + u.dx && y == u.uy + u.dy) {
/* No Wwalking check; otherwise they'd be able
* to test boots by trying to SHIFT-direction
* into a pool and seeing if the game allowed it
*/
if (iflags.mention_walls)
You("stop at the edge of the %s.",
hliquid(is_pool(x,y) ? "water" : "lava"));
goto stop;
}
continue;
} else { /* e.g. objects or trap or stairs */
if (context.run == 1)
@@ -2576,8 +2635,11 @@ lookaround()
return;
} /* end for loops */
if (corrct > 1 && context.run == 2)
if (corrct > 1 && context.run == 2) {
if (iflags.mention_walls)
pline_The("corridor widens here.");
goto stop;
}
if ((context.run == 1 || context.run == 3 || context.run == 8) && !noturn
&& !m0 && i0 && (corrct == 1 || (corrct == 2 && i0 == 1))) {
/* make sure that we do not turn too far */

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 invent.c $NHDT-Date: 1461967848 2016/04/29 22:10:48 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.208 $ */
/* NetHack 3.6 invent.c $NHDT-Date: 1472809075 2016/09/02 09:37:55 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.210 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -1573,13 +1573,15 @@ unsigned *resultflags;
char extra_removeables[3 + 1]; /* uwep,uswapwep,uquiver */
char buf[BUFSZ], qbuf[QBUFSZ];
if (!invent) {
You("have nothing to %s.", word);
if (resultflags)
*resultflags = ALL_FINISHED;
return 0;
}
if (resultflags)
*resultflags = 0;
takeoff = ident = allflag = m_seen = FALSE;
if (!invent) {
You("have nothing to %s.", word);
return 0;
}
add_valid_menu_class(0); /* reset */
if (taking_off(word)) {
takeoff = TRUE;

View File

@@ -987,11 +987,10 @@ register struct attack *mattk;
if (resists_acid(mdef)) {
if (vis)
pline("%s is covered in %s, but it seems harmless.",
hliquid("acid"),
Monnam(mdef));
Monnam(mdef), hliquid("acid"));
tmp = 0;
} else if (vis) {
pline("%s is covered in %s!", hliquid("acid"), Monnam(mdef));
pline("%s is covered in %s!", Monnam(mdef), hliquid("acid"));
pline("It burns %s!", mon_nam(mdef));
}
if (!rn2(30))
@@ -1506,8 +1505,7 @@ int mdead;
Strcpy(buf, Monnam(magr));
if (canseemon(magr))
pline("%s is splashed by %s %s!", buf,
hliquid("acid"),
s_suffix(mon_nam(mdef)));
s_suffix(mon_nam(mdef)), hliquid("acid"));
if (resists_acid(magr)) {
if (canseemon(magr))
pline("%s is not affected.", Monnam(magr));

View File

@@ -555,8 +555,7 @@ register struct monst *mtmp;
/* This can happen after a purple worm plucks you off a
flying steed while you are over water. */
pline("%s sinks as %s rushes in and flushes you out.",
hliquid("water"),
Monnam(mtmp));
Monnam(mtmp), hliquid("water"));
}
mondead(mtmp);
if (mtmp->mhp > 0) {

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 trap.c $NHDT-Date: 1464138044 2016/05/25 01:00:44 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.272 $ */
/* NetHack 3.6 trap.c $NHDT-Date: 1473665044 2016/09/12 07:24:04 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.274 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -2198,8 +2198,15 @@ register struct monst *mtmp;
pline("%s stops momentarily and appears to cringe.",
Monnam(mtmp));
}
} else
You_hear("a distant %s squeak.", trapnote(trap, 1));
} else {
/* same near/far threshold as mzapmsg() */
int range = couldsee(mtmp->mx, mtmp->my) /* 9 or 5 */
? (BOLT_LIM + 1) : (BOLT_LIM - 3);
You_hear("a %s squeak %s.", trapnote(trap, 1),
(distu(mtmp->mx, mtmp->my) <= range * range)
? "nearby" : "in the distance");
}
/* wake up nearby monsters */
wake_nearto(mtmp->mx, mtmp->my, 40);
break;