This commit is contained in:
keni
2015-04-30 22:01:12 -04:00
29 changed files with 634 additions and 245 deletions
+16 -4
View File
@@ -1,4 +1,4 @@
.\" $NHDT-Branch$:$NHDT-Revision$ $NHDT-Date$ .\" $NHDT-Branch: master $:$NHDT-Revision: 1.160 $ $NHDT-Date: 1430043650 2015/04/26 10:20:50 $
.\" $Revision: 1.130 $ $Date: 2015/03/27 00:38:30 $ .\" $Revision: 1.130 $ $Date: 2015/03/27 00:38:30 $
.ds h0 "NetHack Guidebook .ds h0 "NetHack Guidebook
.ds h1 .ds h1
@@ -607,12 +607,17 @@ is true.
.lp i .lp i
List your inventory (everything you're carrying). List your inventory (everything you're carrying).
.lp I .lp I
List selected parts of your inventory. List selected parts of your inventory, usually be specifying the character
for a particular set of objects, like `[' for armor or `!' for potions.
.sd .sd
.si .si
I* - list all gems in inventory; I* - list all gems in inventory;
Iu - list all unpaid items; Iu - list all unpaid items;
Ix - list all used up items that are on your shopping bill; Ix - list all used up items that are on your shopping bill;
IB - list all items known to be blessed;
IU - list all items known to be uncursed;
IC - list all items known to be cursed;
IX - list all items whose bless/curse status is known;
I$ - count your money. I$ - count your money.
.ei .ei
.ed .ed
@@ -1256,6 +1261,11 @@ Objects can also be blessed. Blessed items usually work better or
more beneficially than normal uncursed items. For example, a blessed more beneficially than normal uncursed items. For example, a blessed
weapon will do more damage against demons. weapon will do more damage against demons.
.pg .pg
Objects which are neither cursed nor blessed are referred to as uncursed.
They could just as easily have been described as unblessed, but the
uncursed designation is what you will see within the game. A ``glass
half full versus glass half empty'' situation; make of that what you will.
.pg
There are magical means of bestowing or removing curses upon objects, There are magical means of bestowing or removing curses upon objects,
so even if you are stuck with one, you can still have the curse so even if you are stuck with one, you can still have the curse
lifted and the item removed. Priests and Priestesses have an innate lifted and the item removed. Priests and Priestesses have an innate
@@ -1266,6 +1276,8 @@ An item with unknown status will be reported in your inventory with no prefix.
An item which you know the state of will be distinguished in your inventory An item which you know the state of will be distinguished in your inventory
by the presence of the word ``cursed'', ``uncursed'' or ``blessed'' in the by the presence of the word ``cursed'', ``uncursed'' or ``blessed'' in the
description of the item. description of the item.
In some cases ``uncursed'' will be omitted as being redundant when
enough other information is displayed.
.hn 2 .hn 2
Weapons (`)') Weapons (`)')
.pg .pg
@@ -2085,8 +2097,8 @@ Implemented by the Amiga, Gem and tty ports.
Default '^'. Default '^'.
.lp menu_headings .lp menu_headings
Controls how the headings in a menu are highlighted. Controls how the headings in a menu are highlighted.
Values are 'bold', 'inverse', or 'underline'. Values are 'none', 'bold', 'dim', 'underline', 'blink', or 'inverse'.
Not all ports can actually display all three types. Not all ports can actually display all types.
.lp menu_invert_all .lp menu_invert_all
Menu character accelerator to invert all items in a menu. Menu character accelerator to invert all items in a menu.
Implemented by the Amiga, Gem, X11 and tty ports. Implemented by the Amiga, Gem, X11 and tty ports.
+18 -3
View File
@@ -742,12 +742,18 @@ something appropriate if {\it autoquiver\/} is true.
List your inventory (everything you're carrying). List your inventory (everything you're carrying).
%.lp %.lp
\item[\tb{I}] \item[\tb{I}]
List selected parts of your inventory.\\ List selected parts of your inventory, usually be specifying the character
for a particular set of objects, like `{\tt [}' for armor or `{\tt !}'
for potions.\\
%.sd %.sd
%.si %.si
{\tt I*} --- list all gems in inventory;\\ {\tt I*} --- list all gems in inventory;\\
{\tt Iu} --- list all unpaid items;\\ {\tt Iu} --- list all unpaid items;\\
{\tt Ix} --- list all used up items that are on your shopping bill;\\ {\tt Ix} --- list all used up items that are on your shopping bill;\\
{\tt IB} --- list all items known to be blessed;\\
{\tt IU} --- list all items known to be uncursed;\\
{\tt IC} --- list all items known to be cursed;\\
{\tt IX} --- list all items whose bless/curse status is unknown;\\
{\tt I\$} --- count your money. {\tt I\$} --- count your money.
%.ei %.ei
%.ed %.ed
@@ -1543,6 +1549,12 @@ Objects can also be blessed. Blessed items usually work better or
more beneficially than normal uncursed items. For example, a blessed more beneficially than normal uncursed items. For example, a blessed
weapon will do more damage against demons. weapon will do more damage against demons.
%.pg
Objects which are neither cursed nor blessed are referred to as uncursed.
They could just as easily have been described as unblessed, but the
uncursed designation is what you will see within the game. A ``glass
half full versus glass half empty'' situation; make of that what you will.
%.pg %.pg
There are magical means of bestowing or removing curses upon objects, There are magical means of bestowing or removing curses upon objects,
so even if you are stuck with one, you can still have the curse so even if you are stuck with one, you can still have the curse
@@ -1555,6 +1567,8 @@ An item with unknown status will be reported in your inventory with no prefix.
An item which you know the state of will be distinguished in your inventory An item which you know the state of will be distinguished in your inventory
by the presence of the word ``cursed'', ``uncursed'' or ``blessed'' in the by the presence of the word ``cursed'', ``uncursed'' or ``blessed'' in the
description of the item. description of the item.
In some cases ``uncursed'' will be omitted as being redundant when
enough other information is displayed.
%.hn 2 %.hn 2
\subsection*{Weapons (`{\tt )}')} \subsection*{Weapons (`{\tt )}')}
@@ -2516,8 +2530,9 @@ Implemented by the Amiga, Gem and tty ports.
Default `\verb+^+'. Default `\verb+^+'.
\item[\ib{menu\_headings}] \item[\ib{menu\_headings}]
Controls how the headings in a menu are highlighted. Controls how the headings in a menu are highlighted.
Values are ``{\tt bold}'', ``{\tt inverse}'', or ``{\tt underline}''. Values are ``{\tt none}'', ``{\tt bold}'', ``{\tt dim}'',
Not all ports can actually display all three types. ``{\tt underline}'', ``{\tt blink}'', or ``{\tt inverse}''.
Not all ports can actually display all types.
\item[\ib{menu\_invert\_all}] \item[\ib{menu\_invert\_all}]
Menu character accelerator to invert all items in a menu. Menu character accelerator to invert all items in a menu.
Implemented by the Amiga, Gem, X11 and tty ports. Implemented by the Amiga, Gem, X11 and tty ports.
+5
View File
@@ -903,6 +903,9 @@ some monsters can eat through iron bars
inaccessible niches occasionally have iron bars in front inaccessible niches occasionally have iron bars in front
sinks may teleport or polymorph sinks may teleport or polymorph
shopkeepers give honorifics to vampires and elves shopkeepers give honorifics to vampires and elves
when commands (D, A, object identify) mix object class filtering with BUCX
filtering, take the intersection rather than the union (so ?B picks
blessed scrolls rather than all scrolls plus blessed everything)
Platform- and/or Interface-Specific Fixes Platform- and/or Interface-Specific Fixes
@@ -1128,6 +1131,8 @@ Some levels in Gehennom now use the old corridor-style maze instead of
"beetle legs" are restored. "beetle legs" are restored.
gnomes will occasionally have a candle gnomes will occasionally have a candle
stop travel or run when you get hungry stop travel or run when you get hungry
'I' command can accept 'B','U','C',or 'X' as an alternative to normal object
class character to show inventory of items known to be blessed,&c
Platform- and/or Interface-Specific New Features Platform- and/or Interface-Specific New Features
+1
View File
@@ -53,6 +53,7 @@
struct menucoloring { struct menucoloring {
struct nhregex *match; struct nhregex *match;
char *origstr;
int color, attr; int color, attr;
struct menucoloring *next; struct menucoloring *next;
}; };
+3
View File
@@ -222,6 +222,7 @@ E boolean FDECL(is_lava, (int,int));
E boolean FDECL(is_pool_or_lava, (int,int)); E boolean FDECL(is_pool_or_lava, (int,int));
E boolean FDECL(is_ice, (int,int)); E boolean FDECL(is_ice, (int,int));
E boolean FDECL(is_moat, (int,int)); E boolean FDECL(is_moat, (int,int));
E schar FDECL(db_under_typ, (int));
E int FDECL(is_drawbridge_wall, (int,int)); E int FDECL(is_drawbridge_wall, (int,int));
E boolean FDECL(is_db_wall, (int,int)); E boolean FDECL(is_db_wall, (int,int));
E boolean FDECL(find_drawbridge, (int *,int*)); E boolean FDECL(find_drawbridge, (int *,int*));
@@ -570,6 +571,7 @@ E boolean FDECL(Invocation_lev, (d_level *));
E xchar NDECL(level_difficulty); E xchar NDECL(level_difficulty);
E schar FDECL(lev_by_name, (const char *)); E schar FDECL(lev_by_name, (const char *));
E schar FDECL(print_dungeon, (BOOLEAN_P,schar *,xchar *)); E schar FDECL(print_dungeon, (BOOLEAN_P,schar *,xchar *));
E char *FDECL(get_annotation, (d_level *));
E int NDECL(donamelevel); E int NDECL(donamelevel);
E int NDECL(dooverview); E int NDECL(dooverview);
E void FDECL(show_overview, (int,int)); E void FDECL(show_overview, (int,int));
@@ -1372,6 +1374,7 @@ E void FDECL(mon_regen, (struct monst *,BOOLEAN_P));
E int FDECL(dochugw, (struct monst *)); E int FDECL(dochugw, (struct monst *));
E boolean FDECL(onscary, (int,int,struct monst *)); E boolean FDECL(onscary, (int,int,struct monst *));
E void FDECL(monflee, (struct monst *, int, BOOLEAN_P, BOOLEAN_P)); E void FDECL(monflee, (struct monst *, int, BOOLEAN_P, BOOLEAN_P));
E void FDECL(mon_yells, (struct monst *, const char *));
E int FDECL(dochug, (struct monst *)); E int FDECL(dochug, (struct monst *));
E int FDECL(m_move, (struct monst *,int)); E int FDECL(m_move, (struct monst *,int));
E void FDECL(dissolve_bars, (int,int)); E void FDECL(dissolve_bars, (int,int));
+2
View File
@@ -134,6 +134,8 @@
#define is_displacer(ptr) (((ptr)->mflags3 & M3_DISPLACES) != 0L) #define is_displacer(ptr) (((ptr)->mflags3 & M3_DISPLACES) != 0L)
#define is_mplayer(ptr) (((ptr) >= &mons[PM_ARCHEOLOGIST]) && \ #define is_mplayer(ptr) (((ptr) >= &mons[PM_ARCHEOLOGIST]) && \
((ptr) <= &mons[PM_WIZARD])) ((ptr) <= &mons[PM_WIZARD]))
#define is_watch(ptr) ((ptr) == &mons[PM_WATCHMAN] || \
(ptr) == &mons[PM_WATCH_CAPTAIN])
#define is_rider(ptr) ((ptr) == &mons[PM_DEATH] || \ #define is_rider(ptr) ((ptr) == &mons[PM_DEATH] || \
(ptr) == &mons[PM_FAMINE] || \ (ptr) == &mons[PM_FAMINE] || \
(ptr) == &mons[PM_PESTILENCE]) (ptr) == &mons[PM_PESTILENCE])
+15 -3
View File
@@ -1,4 +1,4 @@
/* NetHack 3.5 ball.c $NHDT-Date$ $NHDT-Branch$:$NHDT-Revision$ */ /* NetHack 3.5 ball.c $NHDT-Date: 1430365884 2015/04/30 03:51:24 $ $NHDT-Branch: master $:$NHDT-Revision: 1.22 $ */
/* NetHack 3.5 ball.c $Date: 2011/08/30 22:13:26 $ $Revision: 1.17 $ */ /* NetHack 3.5 ball.c $Date: 2011/08/30 22:13:26 $ $Revision: 1.17 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -102,7 +102,7 @@ ballfall()
* It is assumed that when this is called, the ball and chain are NOT * It is assumed that when this is called, the ball and chain are NOT
* attached to the object list. * attached to the object list.
* *
* Should not be called while swallowed. * Should not be called while swallowed except on waterlevel.
*/ */
void void
placebc() placebc()
@@ -133,7 +133,19 @@ placebc()
void void
unplacebc() unplacebc()
{ {
if (u.uswallow) return; /* ball&chain not placed while swallowed */ if (u.uswallow) {
if (Is_waterlevel(&u.uz)) {
/* we need to proceed with the removal from the floor
* so that movebubbles() processing will disregard it as
* intended. Ignore all the vision stuff.
*/
if (!carried(uball))
obj_extract_self(uball);
obj_extract_self(uchain);
}
/* ball&chain not unplaced while swallowed */
return;
}
if (!carried(uball)) { if (!carried(uball)) {
obj_extract_self(uball); obj_extract_self(uball);
+12
View File
@@ -103,6 +103,18 @@ int x, y;
return FALSE; return FALSE;
} }
schar
db_under_typ(mask)
int mask;
{
switch (mask & DB_UNDER) {
case DB_ICE: return ICE; break;
case DB_LAVA: return LAVAPOOL; break;
case DB_MOAT: return MOAT; break;
default: return STONE; break;
}
}
/* /*
* We want to know whether a wall (or a door) is the portcullis (passageway) * We want to know whether a wall (or a door) is the portcullis (passageway)
* of an eventual drawbridge. * of an eventual drawbridge.
+1 -2
View File
@@ -1171,8 +1171,7 @@ watch_dig(mtmp, x, y, zap)
if (!mtmp) { if (!mtmp) {
for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) { for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
if (DEADMONSTER(mtmp)) continue; if (DEADMONSTER(mtmp)) continue;
if ((mtmp->data == &mons[PM_WATCHMAN] || if (is_watch(mtmp->data) &&
mtmp->data == &mons[PM_WATCH_CAPTAIN]) &&
mtmp->mcansee && m_canseeu(mtmp) && mtmp->mcansee && m_canseeu(mtmp) &&
couldsee(mtmp->mx, mtmp->my) && mtmp->mpeaceful) couldsee(mtmp->mx, mtmp->my) && mtmp->mpeaceful)
break; break;
+6 -1
View File
@@ -1,4 +1,4 @@
/* NetHack 3.5 display.c $NHDT-Date$ $NHDT-Branch$:$NHDT-Revision$ */ /* NetHack 3.5 display.c $NHDT-Date: 1430365890 2015/04/30 03:51:30 $ $NHDT-Branch: master $:$NHDT-Revision: 1.49 $ */
/* NetHack 3.5 display.c $Date: 2011/12/05 03:17:36 $ $Revision: 1.34 $ */ /* NetHack 3.5 display.c $Date: 2011/12/05 03:17:36 $ $Revision: 1.34 $ */
/* Copyright (c) Dean Luick, with acknowledgements to Kevin Darcy */ /* Copyright (c) Dean Luick, with acknowledgements to Kevin Darcy */
/* and Dave Cohrs, 1990. */ /* and Dave Cohrs, 1990. */
@@ -1363,11 +1363,16 @@ row_refresh(start,stop,y)
void void
cls() cls()
{ {
static boolean in_cls = 0;
if (in_cls) return;
in_cls = TRUE;
display_nhwindow(WIN_MESSAGE, FALSE); /* flush messages */ display_nhwindow(WIN_MESSAGE, FALSE); /* flush messages */
context.botlx = 1; /* force update of botl window */ context.botlx = 1; /* force update of botl window */
clear_nhwindow(WIN_MAP); /* clear physical screen */ clear_nhwindow(WIN_MAP); /* clear physical screen */
clear_glyph_buffer(); /* this is sort of an extra effort, but OK */ clear_glyph_buffer(); /* this is sort of an extra effort, but OK */
in_cls = FALSE;
} }
/* /*
+4
View File
@@ -1069,6 +1069,7 @@ boolean at_stairs, falling, portal;
boolean new = FALSE; /* made a new level? */ boolean new = FALSE; /* made a new level? */
struct monst *mtmp; struct monst *mtmp;
char whynot[BUFSZ]; char whynot[BUFSZ];
char *annotation;
if (dunlev(newlevel) > dunlevs_in_dungeon(newlevel)) if (dunlev(newlevel) > dunlevs_in_dungeon(newlevel))
newlevel->dlevel = dunlevs_in_dungeon(newlevel); newlevel->dlevel = dunlevs_in_dungeon(newlevel);
@@ -1458,6 +1459,9 @@ boolean at_stairs, falling, portal;
save_currentstate(); save_currentstate();
#endif #endif
if ((annotation = get_annotation(&u.uz)))
You("remember this level as %s.", annotation);
/* assume this will always return TRUE when changing level */ /* assume this will always return TRUE when changing level */
(void) in_out_region(u.ux, u.uy); (void) in_out_region(u.ux, u.uy);
(void) pickup(1); (void) pickup(1);
+6
View File
@@ -596,6 +596,9 @@ docallcmd()
any.a_char = 'd'; /* entry 'd' (or 'b'), group accelator 'd' */ any.a_char = 'd'; /* entry 'd' (or 'b'), group accelator 'd' */
add_menu(win, NO_GLYPH, &any, 0, any.a_char, ATR_NONE, add_menu(win, NO_GLYPH, &any, 0, any.a_char, ATR_NONE,
"the type of an object on discoveries list", MENU_UNSELECTED); "the type of an object on discoveries list", MENU_UNSELECTED);
any.a_char = 'e';
add_menu(win, NO_GLYPH, &any, 0, any.a_char, ATR_NONE,
"the current level", MENU_UNSELECTED);
#if 0 #if 0
any.a_char = 'f'; /* entry 'e' (or 'c'), group accelator 'f' */ any.a_char = 'f'; /* entry 'e' (or 'c'), group accelator 'f' */
add_menu(win, NO_GLYPH, &any, 0, any.a_char, ATR_NONE, add_menu(win, NO_GLYPH, &any, 0, any.a_char, ATR_NONE,
@@ -643,6 +646,9 @@ docallcmd()
case 'd': /* name a type of object on the discoveries list */ case 'd': /* name a type of object on the discoveries list */
rename_disco(); rename_disco();
break; break;
case 'e': /* annotate level */
donamelevel();
break;
#if 0 #if 0
case 'f': /* name a type of object visible on the floor */ case 'f': /* name a type of object visible on the floor */
/* [not implemented] */ /* [not implemented] */
+5 -15
View File
@@ -1198,15 +1198,10 @@ dumb:
if (in_town(x, y)) if (in_town(x, y))
for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) { for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
if (DEADMONSTER(mtmp)) continue; if (DEADMONSTER(mtmp)) continue;
if((mtmp->data == &mons[PM_WATCHMAN] || if (is_watch(mtmp->data) &&
mtmp->data == &mons[PM_WATCH_CAPTAIN]) &&
couldsee(mtmp->mx, mtmp->my) && couldsee(mtmp->mx, mtmp->my) &&
mtmp->mpeaceful) { mtmp->mpeaceful) {
if (canspotmon(mtmp)) mon_yells(mtmp, "Halt, thief! You're under arrest!");
pline("%s yells:", Amonnam(mtmp));
else
You_hear("someone yell:");
verbalize("Halt, thief! You're under arrest!");
(void) angry_guards(FALSE); (void) angry_guards(FALSE);
break; break;
} }
@@ -1218,18 +1213,13 @@ dumb:
if (in_town(x, y)) if (in_town(x, y))
for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
if (DEADMONSTER(mtmp)) continue; if (DEADMONSTER(mtmp)) continue;
if ((mtmp->data == &mons[PM_WATCHMAN] || if (is_watch(mtmp->data) &&
mtmp->data == &mons[PM_WATCH_CAPTAIN]) &&
mtmp->mpeaceful && couldsee(mtmp->mx, mtmp->my)) { mtmp->mpeaceful && couldsee(mtmp->mx, mtmp->my)) {
if (canspotmon(mtmp))
pline("%s yells:", Amonnam(mtmp));
else
You_hear("someone yell:");
if(levl[x][y].looted & D_WARNED) { if(levl[x][y].looted & D_WARNED) {
verbalize("Halt, vandal! You're under arrest!"); mon_yells(mtmp, "Halt, vandal! You're under arrest!");
(void) angry_guards(FALSE); (void) angry_guards(FALSE);
} else { } else {
verbalize("Hey, stop damaging that door!"); mon_yells(mtmp, "Hey, stop damaging that door!");
levl[x][y].looted |= D_WARNED; levl[x][y].looted |= D_WARNED;
} }
break; break;
+18 -6
View File
@@ -1848,6 +1848,16 @@ d_level *dest;
} }
} }
char *
get_annotation(lev)
d_level *lev;
{
mapseen *mptr;
if ((mptr = find_mapseen(lev)))
return mptr->custom;
return NULL;
}
/* #annotate command - add a custom name to the current level */ /* #annotate command - add a custom name to the current level */
int int
donamelevel() donamelevel()
@@ -1857,8 +1867,15 @@ donamelevel()
if (!(mptr = find_mapseen(&u.uz))) return 0; if (!(mptr = find_mapseen(&u.uz))) return 0;
if (mptr->custom) {
char tmpbuf[BUFSZ];
Sprintf(tmpbuf, "Replace annotation \"%.30s%s\" with?",
mptr->custom, strlen(mptr->custom) > 30 ? "..." : "");
getlin(tmpbuf, nbuf);
} else
getlin("What do you want to call this dungeon level?", nbuf); getlin("What do you want to call this dungeon level?", nbuf);
if (index(nbuf, '\033')) return 0; if (index(nbuf, '\033')) return 0;
(void)mungspaces(nbuf);
/* discard old annotation, if any */ /* discard old annotation, if any */
if (mptr->custom) { if (mptr->custom) {
@@ -2190,12 +2207,7 @@ recalc_mapseen()
if (cansee(x, y) || (x == u.ux && y == u.uy && !Levitation)) { if (cansee(x, y) || (x == u.ux && y == u.uy && !Levitation)) {
ltyp = levl[x][y].typ; ltyp = levl[x][y].typ;
if (ltyp == DRAWBRIDGE_UP) if (ltyp == DRAWBRIDGE_UP)
switch (levl[x][y].drawbridgemask & DB_UNDER) { ltyp = db_under_typ(levl[x][y].drawbridgemask);
case DB_ICE: ltyp = ICE; break;
case DB_LAVA: ltyp = LAVAPOOL; break;
case DB_MOAT: ltyp = MOAT; break;
default: ltyp = STONE; break;
}
if ((mtmp = m_at(x, y)) != 0 && if ((mtmp = m_at(x, y)) != 0 &&
mtmp->m_ap_type == M_AP_FURNITURE && canseemon(mtmp)) mtmp->m_ap_type == M_AP_FURNITURE && canseemon(mtmp))
ltyp = cmap_to_type(mtmp->mappearance); ltyp = cmap_to_type(mtmp->mappearance);
+1 -2
View File
@@ -169,8 +169,7 @@ boolean isyou;
/* Warn about future fountain use. */ /* Warn about future fountain use. */
for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) { for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
if (DEADMONSTER(mtmp)) continue; if (DEADMONSTER(mtmp)) continue;
if ((mtmp->data == &mons[PM_WATCHMAN] || if (is_watch(mtmp->data) &&
mtmp->data == &mons[PM_WATCH_CAPTAIN]) &&
couldsee(mtmp->mx, mtmp->my) && couldsee(mtmp->mx, mtmp->my) &&
mtmp->mpeaceful) { mtmp->mpeaceful) {
pline("%s yells:", Amonnam(mtmp)); pline("%s yells:", Amonnam(mtmp));
+92 -18
View File
@@ -24,6 +24,7 @@ STATIC_PTR char *FDECL(safeq_xprname, (struct obj *));
STATIC_PTR char *FDECL(safeq_shortxprname, (struct obj *)); STATIC_PTR char *FDECL(safeq_shortxprname, (struct obj *));
STATIC_DCL char FDECL(display_pickinv, (const char *,BOOLEAN_P, long *)); STATIC_DCL char FDECL(display_pickinv, (const char *,BOOLEAN_P, long *));
STATIC_DCL char FDECL(display_used_invlets, (CHAR_P)); STATIC_DCL char FDECL(display_used_invlets, (CHAR_P));
STATIC_DCL void FDECL(tally_BUCX, (struct obj *,int *,int *,int *,int *,int *));
STATIC_DCL boolean FDECL(this_type_only, (struct obj *)); STATIC_DCL boolean FDECL(this_type_only, (struct obj *));
STATIC_DCL void NDECL(dounpaid); STATIC_DCL void NDECL(dounpaid);
STATIC_DCL struct obj *FDECL(find_unpaid,(struct obj *,struct obj **)); STATIC_DCL struct obj *FDECL(find_unpaid,(struct obj *,struct obj **));
@@ -394,6 +395,7 @@ addinv(obj)
struct obj *obj; struct obj *obj;
{ {
struct obj *otmp, *prev; struct obj *otmp, *prev;
int saved_otyp = (int)obj->otyp; /* for panic */
if (obj->where != OBJ_FREE) if (obj->where != OBJ_FREE)
panic("addinv: obj not free"); panic("addinv: obj not free");
@@ -410,12 +412,16 @@ struct obj *obj;
extra to quivered stack is more useful than to wielded one */ extra to quivered stack is more useful than to wielded one */
if (uquiver && merged(&uquiver, &obj)) { if (uquiver && merged(&uquiver, &obj)) {
obj = uquiver; obj = uquiver;
if (!obj)
panic("addinv: null obj after quiver merge otyp=%d", saved_otyp);
goto added; goto added;
} }
/* merge if possible; find end of chain in the process */ /* merge if possible; find end of chain in the process */
for (prev = 0, otmp = invent; otmp; prev = otmp, otmp = otmp->nobj) for (prev = 0, otmp = invent; otmp; prev = otmp, otmp = otmp->nobj)
if (merged(&otmp, &obj)) { if (merged(&otmp, &obj)) {
obj = otmp; obj = otmp;
if (!obj)
panic("addinv: null obj after merge otyp=%d", saved_otyp);
goto added; goto added;
} }
/* didn't merge, so insert into chain */ /* didn't merge, so insert into chain */
@@ -2067,6 +2073,33 @@ count_buc(list, type)
return count; return count;
} }
/* similar to count_buc(), but tallies all states at once
rather than looking for a specific type */
STATIC_OVL void
tally_BUCX(list, bcp, ucp, ccp, xcp, ocp)
struct obj *list;
int *bcp, *ucp, *ccp, *xcp, *ocp;
{
*bcp = *ucp = *ccp = *xcp = *ocp = 0;
for ( ; list; list = list->nobj) {
if (list->oclass == COIN_CLASS) {
++(*ocp); /* "other" */
continue;
}
/* priests always know bless/curse state */
if (Role_if(PM_PRIEST)) list->bknown = 1;
if (!list->bknown)
++(*xcp);
else if (list->blessed)
++(*bcp);
else if (list->cursed)
++(*ccp);
else /* neither blessed nor cursed => uncursed */
++(*ucp);
}
}
long long
count_contents(container, nested, quantity, everything) count_contents(container, nested, quantity, everything)
struct obj *container; struct obj *container;
@@ -2189,7 +2222,18 @@ STATIC_OVL boolean
this_type_only(obj) this_type_only(obj)
struct obj *obj; struct obj *obj;
{ {
return (obj->oclass == this_type); boolean res = (obj->oclass == this_type);
if (obj->oclass != COIN_CLASS) {
switch (this_type) {
case 'B': res = (obj->bknown && obj->blessed); break;
case 'U': res = (obj->bknown && !(obj->blessed || obj->cursed)); break;
case 'C': res = (obj->bknown && obj->cursed); break;
case 'X': res = !obj->bknown; break;
default: break; /* use 'res' as-is */
}
}
return res;
} }
/* the 'I' command */ /* the 'I' command */
@@ -2200,6 +2244,7 @@ dotypeinv()
int n, i = 0; int n, i = 0;
char *extra_types, types[BUFSZ]; char *extra_types, types[BUFSZ];
int class_count, oclass, unpaid_count, itemcount; int class_count, oclass, unpaid_count, itemcount;
int bcnt, ccnt, ucnt, xcnt, ocnt;
boolean billx = *u.ushops && doinvbill(0); boolean billx = *u.ushops && doinvbill(0);
menu_item *pick_list; menu_item *pick_list;
boolean traditional = TRUE; boolean traditional = TRUE;
@@ -2210,12 +2255,18 @@ dotypeinv()
return 0; return 0;
} }
unpaid_count = count_unpaid(invent); unpaid_count = count_unpaid(invent);
tally_BUCX(invent, &bcnt, &ucnt, &ccnt, &xcnt, &ocnt);
if (flags.menu_style != MENU_TRADITIONAL) { if (flags.menu_style != MENU_TRADITIONAL) {
if (flags.menu_style == MENU_FULL || if (flags.menu_style == MENU_FULL ||
flags.menu_style == MENU_PARTIAL) { flags.menu_style == MENU_PARTIAL) {
traditional = FALSE; traditional = FALSE;
i = UNPAID_TYPES; i = UNPAID_TYPES;
if (billx) i |= BILLED_TYPES; if (billx) i |= BILLED_TYPES;
if (bcnt) i |= BUC_BLESSED;
if (ucnt) i |= BUC_UNCURSED;
if (ccnt) i |= BUC_CURSED;
if (xcnt) i |= BUC_UNKNOWN;
n = query_category(prompt, invent, i, &pick_list, PICK_ONE); n = query_category(prompt, invent, i, &pick_list, PICK_ONE);
if (!n) return 0; if (!n) return 0;
this_type = c = pick_list[0].item.a_int; this_type = c = pick_list[0].item.a_int;
@@ -2225,22 +2276,27 @@ dotypeinv()
if (traditional) { if (traditional) {
/* collect a list of classes of objects carried, for use as a prompt */ /* collect a list of classes of objects carried, for use as a prompt */
types[0] = 0; types[0] = 0;
class_count = collect_obj_classes(types, invent, class_count = collect_obj_classes(types, invent, FALSE,
FALSE, (boolean FDECL((*),(OBJ_P))) 0,
(boolean FDECL((*),(OBJ_P))) 0, &itemcount); &itemcount);
if (unpaid_count) { if (unpaid_count || billx || (bcnt + ccnt + ucnt + xcnt) != 0)
Strcat(types, "u"); types[class_count++] = ' ';
class_count++; if (unpaid_count) types[class_count++] = 'u';
} if (billx) types[class_count++] = 'x';
if (billx) { if (bcnt) types[class_count++] = 'B';
Strcat(types, "x"); if (ucnt) types[class_count++] = 'U';
class_count++; if (ccnt) types[class_count++] = 'C';
} if (xcnt) types[class_count++] = 'X';
types[class_count] = '\0';
/* add everything not already included; user won't see these */ /* add everything not already included; user won't see these */
extra_types = eos(types); extra_types = eos(types);
*extra_types++ = '\033'; *extra_types++ = '\033';
if (!unpaid_count) *extra_types++ = 'u'; if (!unpaid_count) *extra_types++ = 'u';
if (!billx) *extra_types++ = 'x'; if (!billx) *extra_types++ = 'x';
if (!bcnt) *extra_types++ = 'B';
if (!ucnt) *extra_types++ = 'U';
if (!ccnt) *extra_types++ = 'C';
if (!xcnt) *extra_types++ = 'X';
*extra_types = '\0'; /* for index() */ *extra_types = '\0'; /* for index() */
for (i = 0; i < MAXOCLASSES; i++) for (i = 0; i < MAXOCLASSES; i++)
if (!index(types, def_oc_syms[i].sym)) { if (!index(types, def_oc_syms[i].sym)) {
@@ -2265,14 +2321,15 @@ dotypeinv()
c = types[0]; c = types[0];
} }
} }
if (c == 'x') { if (c == 'x' || (c == 'X' && billx && !xcnt)) {
if (billx) if (billx)
(void) doinvbill(1); (void) doinvbill(1);
else else
pline("No used-up objects on your shopping bill."); pline("No used-up objects%s.",
unpaid_count ? " on your shopping bill" : "");
return 0; return 0;
} }
if (c == 'u') { if (c == 'u' || (c == 'U' && unpaid_count && !ucnt)) {
if (unpaid_count) if (unpaid_count)
dounpaid(); dounpaid();
else else
@@ -2280,11 +2337,28 @@ dotypeinv()
return 0; return 0;
} }
if (traditional) { if (traditional) {
if (index("BUCX", c))
oclass = c; /* not a class but understood by this_type_only() */
else
oclass = def_char_to_objclass(c); /* change to object class */ oclass = def_char_to_objclass(c); /* change to object class */
if (oclass == COIN_CLASS) {
if (oclass == COIN_CLASS)
return doprgold(); return doprgold();
} else if (index(types, c) > index(types, '\033')) { if (index(types, c) > index(types, '\033')) {
You("have no such objects."); /* '> ESC' => "hidden choice", something known not to be carried */
const char *which = 0;
switch (c) {
case 'B': which = "known to be blessed"; break;
case 'U': which = "known to be uncursed"; break;
case 'C': which = "known to be cursed"; break;
case 'X': You(
"have no objects whose blessed/uncursed/cursed status is unknown.");
break; /* better phrasing is desirable */
default: which = "such"; break;
}
if (which)
You("have no %s objects.", which);
return 0; return 0;
} }
this_type = oclass; this_type = oclass;
+1 -6
View File
@@ -1157,12 +1157,7 @@ xchar x,y;
lev = &levl[x][y]; lev = &levl[x][y];
ltyp = lev->typ; ltyp = lev->typ;
if (ltyp == DRAWBRIDGE_UP) if (ltyp == DRAWBRIDGE_UP)
switch (lev->drawbridgemask & DB_UNDER) { ltyp = db_under_typ(lev->drawbridgemask);
case DB_ICE: ltyp = ICE; break;
case DB_LAVA: ltyp = LAVAPOOL; break;
case DB_MOAT: ltyp = MOAT; break;
default: ltyp = STONE; break;
}
if (ltyp == LAVAPOOL) if (ltyp == LAVAPOOL)
return "lava"; return "lava";
+1 -1
View File
@@ -2194,7 +2194,7 @@ unsigned oid;
for (fx = ex; abs(fx - ex) < 3; fx += dx) { for (fx = ex; abs(fx - ex) < 3; fx += dx) {
for (fy = ey; abs(fy - ey) < 3; fy += dy) { for (fy = ey; abs(fy - ey) < 3; fy += dy) {
/* 0, 0 was checked above */ /* 0, 0 was checked above */
if (fx != x || fy != y) { if (isok(fx,fy) && (fx != x || fy != y)) {
if ((otmp = sobj_at(otyp, fx, fy)) != 0) { if ((otmp = sobj_at(otyp, fx, fy)) != 0) {
return otmp; return otmp;
} }
+4 -7
View File
@@ -1,4 +1,4 @@
/* NetHack 3.5 mon.c $NHDT-Date: 1429666918 2015/04/22 01:41:58 $ $NHDT-Branch: master $:$NHDT-Revision: 1.165 $ */ /* NetHack 3.5 mon.c $NHDT-Date: 1430396792 2015/04/30 12:26:32 $ $NHDT-Branch: master $:$NHDT-Revision: 1.169 $ */
/* NetHack 3.5 mon.c $Date: 2012/05/16 02:15:10 $ $Revision: 1.126 $ */ /* NetHack 3.5 mon.c $Date: 2012/05/16 02:15:10 $ $Revision: 1.126 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -1850,7 +1850,7 @@ register struct monst *mtmp;
u.uy = mtmp->my; u.uy = mtmp->my;
u.uswallow = 0; u.uswallow = 0;
u.uswldtim = 0; u.uswldtim = 0;
if (Punished) placebc(); if (Punished && uball->where == OBJ_FREE) placebc();
vision_full_recalc = 1; vision_full_recalc = 1;
docrt(); docrt();
} }
@@ -3117,9 +3117,7 @@ register boolean silent;
for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) { for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
if (DEADMONSTER(mtmp)) continue; if (DEADMONSTER(mtmp)) continue;
if((mtmp->data == &mons[PM_WATCHMAN] || if (is_watch(mtmp->data) && mtmp->mpeaceful) {
mtmp->data == &mons[PM_WATCH_CAPTAIN])
&& mtmp->mpeaceful) {
ct++; ct++;
if(cansee(mtmp->mx, mtmp->my) && mtmp->mcanmove) { if(cansee(mtmp->mx, mtmp->my) && mtmp->mcanmove) {
if (distu(mtmp->mx, mtmp->my) == 2) nct++; if (distu(mtmp->mx, mtmp->my) == 2) nct++;
@@ -3157,8 +3155,7 @@ pacify_guards()
for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
if (DEADMONSTER(mtmp)) continue; if (DEADMONSTER(mtmp)) continue;
if (mtmp->data == &mons[PM_WATCHMAN] || if (is_watch(mtmp->data))
mtmp->data == &mons[PM_WATCH_CAPTAIN])
mtmp->mpeaceful = 1; mtmp->mpeaceful = 1;
} }
} }
+18 -13
View File
@@ -50,6 +50,18 @@ boolean for_unlocking; /* true => credit card ok, false => not ok */
return m_carrying(mon, SKELETON_KEY) || m_carrying(mon, LOCK_PICK); return m_carrying(mon, SKELETON_KEY) || m_carrying(mon, LOCK_PICK);
} }
void
mon_yells(mon, shout)
struct monst *mon;
const char *shout;
{
if (canspotmon(mon))
pline("%s yells:", Amonnam(mon));
else
You_hear("someone yell:");
verbalize(shout);
}
STATIC_OVL void STATIC_OVL void
watch_on_duty(mtmp) watch_on_duty(mtmp)
register struct monst *mtmp; register struct monst *mtmp;
@@ -63,13 +75,11 @@ register struct monst *mtmp;
(levl[x][y].doormask & D_LOCKED)) { (levl[x][y].doormask & D_LOCKED)) {
if(couldsee(mtmp->mx, mtmp->my)) { if(couldsee(mtmp->mx, mtmp->my)) {
pline("%s yells:", Amonnam(mtmp));
if(levl[x][y].looted & D_WARNED) { if(levl[x][y].looted & D_WARNED) {
verbalize("Halt, thief! You're under arrest!"); mon_yells(mtmp, "Halt, thief! You're under arrest!");
(void) angry_guards(!!Deaf); (void) angry_guards(!!Deaf);
} else { } else {
verbalize("Hey, stop picking that lock!"); mon_yells(mtmp, "Hey, stop picking that lock!");
levl[x][y].looted |= D_WARNED; levl[x][y].looted |= D_WARNED;
} }
stop_occupation(); stop_occupation();
@@ -400,7 +410,7 @@ register struct monst *mtmp;
} }
/* the watch will look around and see if you are up to no good :-) */ /* the watch will look around and see if you are up to no good :-) */
if (mdat == &mons[PM_WATCHMAN] || mdat == &mons[PM_WATCH_CAPTAIN]) if (is_watch(mdat))
watch_on_duty(mtmp); watch_on_duty(mtmp);
else if (is_mind_flayer(mdat) && !rn2(20)) { else if (is_mind_flayer(mdat) && !rn2(20)) {
@@ -1295,15 +1305,10 @@ register int x, y;
{ {
int levtyp = levl[x][y].typ; int levtyp = levl[x][y].typ;
if (levtyp == DRAWBRIDGE_UP) {
/* use underlying terrain in front of closed drawbridge */ /* use underlying terrain in front of closed drawbridge */
switch (levl[x][y].drawbridgemask & DB_UNDER) { if (levtyp == DRAWBRIDGE_UP)
case DB_MOAT: levtyp = MOAT; break; levtyp = db_under_typ(levl[x][y].drawbridgemask);
case DB_LAVA: levtyp = LAVAPOOL; break;
case DB_ICE: levtyp = ICE; break;
case DB_FLOOR: levtyp = ROOM; break;
}
}
return (boolean)(ACCESSIBLE(levtyp) && !closed_door(x, y)); return (boolean)(ACCESSIBLE(levtyp) && !closed_door(x, y));
} }
+3 -2
View File
@@ -421,7 +421,8 @@ struct obj *obj; /* missile (or stack providing it) */
(void) drop_throw(singleobj, hitu, u.ux, u.uy); (void) drop_throw(singleobj, hitu, u.ux, u.uy);
break; break;
} }
} else if (!range /* reached end of path */ }
if (!range /* reached end of path */
/* missile hits edge of screen */ /* missile hits edge of screen */
|| !isok(bhitpos.x+dx,bhitpos.y+dy) || !isok(bhitpos.x+dx,bhitpos.y+dy)
/* missile hits the wall */ /* missile hits the wall */
@@ -440,7 +441,7 @@ struct obj *obj; /* missile (or stack providing it) */
tmp_at(bhitpos.x, bhitpos.y); tmp_at(bhitpos.x, bhitpos.y);
delay_output(); delay_output();
} }
if (isok(bhitpos.x, bhitpos.y)) tmp_at(bhitpos.x, bhitpos.y); tmp_at(bhitpos.x, bhitpos.y);
delay_output(); delay_output();
tmp_at(DISP_END, 0); tmp_at(DISP_END, 0);
+274 -91
View File
@@ -1,4 +1,4 @@
/* NetHack 3.5 options.c $NHDT-Date: 1429953065 2015/04/25 09:11:05 $ $NHDT-Branch: master $:$NHDT-Revision: 1.186 $ */ /* NetHack 3.5 options.c $NHDT-Date: 1430441885 2015/05/01 00:58:05 $ $NHDT-Branch: master $:$NHDT-Revision: 1.191 $ */
/* NetHack 3.5 options.c $Date: 2012/04/09 02:56:30 $ $Revision: 1.153 $ */ /* NetHack 3.5 options.c $Date: 2012/04/09 02:56:30 $ $Revision: 1.153 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -283,7 +283,7 @@ static struct Comp_Opt
4, SET_IN_FILE }, 4, SET_IN_FILE },
{ "menu_first_page", "jump to the first page in a menu", { "menu_first_page", "jump to the first page in a menu",
4, SET_IN_FILE }, 4, SET_IN_FILE },
{ "menu_headings", "bold, inverse, or underline headings", 9, SET_IN_GAME }, { "menu_headings", "text attribute for menu headings", 9, SET_IN_GAME },
{ "menu_invert_all", "invert all items in a menu", 4, SET_IN_FILE }, { "menu_invert_all", "invert all items in a menu", 4, SET_IN_FILE },
{ "menu_invert_page", "invert all items on this page of a menu", { "menu_invert_page", "invert all items on this page of a menu",
4, SET_IN_FILE }, 4, SET_IN_FILE },
@@ -498,6 +498,13 @@ STATIC_OVL boolean FDECL(is_wc2_option, (const char *));
STATIC_OVL boolean FDECL(wc2_supported, (const char *)); STATIC_OVL boolean FDECL(wc2_supported, (const char *));
STATIC_DCL void FDECL(remove_autopickup_exception, (struct autopickup_exception *)); STATIC_DCL void FDECL(remove_autopickup_exception, (struct autopickup_exception *));
STATIC_OVL int FDECL(count_ape_maps, (int *, int *)); STATIC_OVL int FDECL(count_ape_maps, (int *, int *));
STATIC_DCL const char *FDECL(clr2colorname, (int));
STATIC_DCL const char *FDECL(attr2attrname, (int));
STATIC_DCL int NDECL(query_color);
STATIC_DCL int FDECL(query_attr, (const char *));
STATIC_DCL boolean FDECL(add_menu_coloring_parsed, (char *, int, int));
STATIC_DCL void FDECL(free_one_menu_coloring, (int));
STATIC_DCL int NDECL(count_menucolors);
void void
@@ -1163,13 +1170,117 @@ static const struct {
{"inverse", ATR_INVERSE} {"inverse", ATR_INVERSE}
}; };
const char *
clr2colorname(clr)
int clr;
{
int i;
for (i = 0; i < SIZE(colornames); i++)
if (colornames[i].color == clr)
return colornames[i].name;
return NULL;
}
const char *
attr2attrname(attr)
int attr;
{
int i;
for (i = 0; i < SIZE(attrnames); i++)
if (attrnames[i].attr == attr)
return attrnames[i].name;
return NULL;
}
int
query_color()
{
winid tmpwin;
anything any;
int i, pick_cnt;
menu_item *picks = (menu_item *)0;
tmpwin = create_nhwindow(NHW_MENU);
start_menu(tmpwin);
any = zeroany;
for (i = 0; i < SIZE(colornames); i++) {
if (!strcmp(colornames[i].name, "grey")) continue;
any.a_int = i + 1;
add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, colornames[i].name, MENU_UNSELECTED);
}
end_menu(tmpwin, "Pick a color");
pick_cnt = select_menu(tmpwin, PICK_ONE, &picks);
destroy_nhwindow(tmpwin);
if (pick_cnt > 0) {
i = colornames[picks->item.a_int - 1].color;
free((genericptr_t)picks);
return i;
}
return -1;
}
int
query_attr(prompt)
const char *prompt;
{
winid tmpwin;
anything any;
int i, pick_cnt;
menu_item *picks = (menu_item *)0;
tmpwin = create_nhwindow(NHW_MENU);
start_menu(tmpwin);
any = zeroany;
for (i = 0; i < SIZE(attrnames); i++) {
any.a_int = i + 1;
add_menu(tmpwin, NO_GLYPH, &any, 0, 0,
attrnames[i].attr, attrnames[i].name, MENU_UNSELECTED);
}
end_menu(tmpwin, prompt ? prompt : "Pick an attribute");
pick_cnt = select_menu(tmpwin, PICK_ONE, &picks);
destroy_nhwindow(tmpwin);
if (pick_cnt > 0) {
i = attrnames[picks->item.a_int - 1].attr;
free((genericptr_t)picks);
return i;
}
return -1;
}
boolean
add_menu_coloring_parsed(str, c, a)
char *str;
int c, a;
{
struct menucoloring *tmp;
if (!str) return FALSE;
tmp = (struct menucoloring *)alloc(sizeof(struct menucoloring));
tmp->match = regex_init();
if (!regex_compile(str, tmp->match)) {
static const char *re_error = "Menucolor regex error";
if (!iflags.window_inited)
raw_printf("\n%s: %s\n", re_error, regex_error_desc(tmp->match));
else
pline("%s: %s", re_error, regex_error_desc(tmp->match));
wait_synch();
free(tmp);
return FALSE;
} else {
tmp->next = menu_colorings;
tmp->origstr = dupstr(str);
tmp->color = c;
tmp->attr = a;
menu_colorings = tmp;
return TRUE;
}
}
/* parse '"regex_string"=color&attr' and add it to menucoloring */ /* parse '"regex_string"=color&attr' and add it to menucoloring */
boolean boolean
add_menu_coloring(str) add_menu_coloring(str)
char *str; char *str;
{ {
int i, c = NO_COLOR, a = ATR_NONE; int i, c = NO_COLOR, a = ATR_NONE;
struct menucoloring *tmp;
char *tmps, *cs = strchr(str, '='); char *tmps, *cs = strchr(str, '=');
if (!cs || !str) return FALSE; if (!cs || !str) return FALSE;
@@ -1212,20 +1323,7 @@ char *str;
} }
} }
tmp = (struct menucoloring *)alloc(sizeof(struct menucoloring)); return add_menu_coloring_parsed(tmps, c, a);
tmp->match = regex_init();
if (!regex_compile(tmps, tmp->match)) {
raw_printf("\nMenucolor regex error: %s\n", regex_error_desc(tmp->match));
wait_synch();
free(tmp);
return FALSE;
} else {
tmp->next = menu_colorings;
tmp->color = c;
tmp->attr = a;
menu_colorings = tmp;
return TRUE;
}
} }
boolean boolean
@@ -1252,11 +1350,48 @@ free_menu_coloring()
while (tmp) { while (tmp) {
struct menucoloring *tmp2 = tmp->next; struct menucoloring *tmp2 = tmp->next;
regex_free(tmp->match); regex_free(tmp->match);
free(tmp->origstr);
free(tmp); free(tmp);
tmp = tmp2; tmp = tmp2;
} }
} }
void
free_one_menu_coloring(idx)
int idx; /* 0 .. */
{
struct menucoloring *tmp = menu_colorings;
struct menucoloring *prev = NULL;
while (tmp) {
if (idx == 0) {
struct menucoloring *next = tmp->next;
regex_free(tmp->match);
free(tmp->origstr);
free(tmp);
if (prev) prev->next = next;
else menu_colorings = next;
return;
}
idx--;
prev = tmp;
tmp = tmp->next;
}
}
int
count_menucolors()
{
int count = 0;
struct menucoloring *tmp = menu_colorings;
while (tmp) {
count++;
tmp = tmp->next;
}
return count;
}
void void
parseoptions(opts, tinitial, tfrom_file) parseoptions(opts, tinitial, tfrom_file)
@@ -2618,13 +2753,11 @@ goodfruit:
else if (!(opts = string_for_env_opt(fullname, opts, FALSE))) { else if (!(opts = string_for_env_opt(fullname, opts, FALSE))) {
return; return;
} }
if (!strcmpi(opts,"bold")) for (i = 0; i < SIZE(attrnames); i++)
iflags.menu_headings = ATR_BOLD; if (!strcmpi(opts, attrnames[i].name)) {
else if (!strcmpi(opts,"inverse")) iflags.menu_headings = attrnames[i].attr;
iflags.menu_headings = ATR_INVERSE; return;
else if (!strcmpi(opts,"underline")) }
iflags.menu_headings = ATR_ULINE;
else
badoption(opts); badoption(opts);
return; return;
} }
@@ -3087,6 +3220,11 @@ doset()
doset_add_menu(tmpwin, compopt[i].name, doset_add_menu(tmpwin, compopt[i].name,
(pass == DISP_IN_GAME) ? 0 : indexoffset); (pass == DISP_IN_GAME) ? 0 : indexoffset);
} }
any.a_int = -3;
Sprintf(buf2, "(%d currently set)", count_menucolors());
Sprintf(buf, fmtstr_doset_add_menu, any.a_int ? "" : " ",
"menucolors", buf2);
add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, MENU_UNSELECTED);
#ifdef STATUS_VIA_WINDOWPORT #ifdef STATUS_VIA_WINDOWPORT
# ifdef STATUS_HILITES # ifdef STATUS_HILITES
any.a_int = -2; any.a_int = -2;
@@ -3138,6 +3276,10 @@ doset()
} else } else
# endif # endif
#endif #endif
if (opt_indx == -4) {
(void)special_handling("menucolors",
setinitial, fromfile);
} else
if (opt_indx < boolcount) { if (opt_indx < boolcount) {
/* boolean option */ /* boolean option */
Sprintf(buf, "%s%s", *boolopt[opt_indx].addr ? "!" : "", Sprintf(buf, "%s%s", *boolopt[opt_indx].addr ? "!" : "",
@@ -3177,6 +3319,57 @@ doset()
return 0; return 0;
} }
int
handle_add_list_remove(optname, numtotal)
char *optname;
int numtotal;
{
winid tmpwin;
anything any;
int i, pick_cnt, pick_idx, opt_idx;
menu_item *pick_list = (menu_item *)0;
static const struct action {
char letr;
const char *desc;
} action_titles[] = {
{ 'a', "add new %s" }, /* [0] */
{ 'l', "list %s" }, /* [1] */
{ 'r', "remove existing %s" }, /* [2] */
{ 'x', "exit this menu" }, /* [3] */
};
opt_idx = 0;
tmpwin = create_nhwindow(NHW_MENU);
start_menu(tmpwin);
any = zeroany;
for (i = 0; i < SIZE(action_titles); i++) {
char tmpbuf[BUFSZ];
any.a_int++;
/* omit list and remove if there aren't any yet */
if (!numtotal && (i == 1 || i == 2)) continue;
Sprintf(tmpbuf, action_titles[i].desc, (i == 1) ? makeplural(optname) : optname);
add_menu(tmpwin, NO_GLYPH, &any, action_titles[i].letr,
0, ATR_NONE, tmpbuf,
#if 0 /* this ought to work but doesn't... */
(action_titles[i].letr == 'x') ? MENU_SELECTED :
#endif
MENU_UNSELECTED);
}
end_menu(tmpwin, "Do what?");
if ((pick_cnt = select_menu(tmpwin, PICK_ONE, &pick_list)) > 0) {
for (pick_idx = 0; pick_idx < pick_cnt; ++pick_idx) {
opt_idx = pick_list[pick_idx].item.a_int - 1;
}
free((genericptr_t)pick_list);
pick_list = (menu_item *)0;
}
destroy_nhwindow(tmpwin);
if (pick_cnt < 1) opt_idx = 3; /* none selected, exit menu */
return opt_idx;
}
struct symsetentry *symset_list = 0; /* files.c will populate this with struct symsetentry *symset_list = 0; /* files.c will populate this with
list of available sets */ list of available sets */
@@ -3454,79 +3647,70 @@ boolean setinitial,setfromfile;
} }
destroy_nhwindow(tmpwin); destroy_nhwindow(tmpwin);
} else if (!strcmp("menu_headings", optname)) { } else if (!strcmp("menu_headings", optname)) {
static const char *mhchoices[3] = {"bold", "inverse", "underline"}; int mhattr = query_attr("How to highlight menu headings:");
const char *npletters = "biu"; if (mhattr != -1) iflags.menu_headings = mhattr;
menu_item *mode_pick = (menu_item *)0; } else if (!strcmp("menucolors", optname)) {
int opt_idx, nmc, mcclr, mcattr;
tmpwin = create_nhwindow(NHW_MENU); char mcbuf[BUFSZ];
start_menu(tmpwin); menucolors_again:
any = zeroany; nmc = count_menucolors();
for (i = 0; i < SIZE(mhchoices); i++) { opt_idx = handle_add_list_remove("menucolor", nmc);
any.a_int = i + 1; if (opt_idx == 3) {
add_menu(tmpwin, NO_GLYPH, &any, npletters[i], 0, ; /* done--fall through to function exit */
ATR_NONE, mhchoices[i], MENU_UNSELECTED); } else if (opt_idx == 0) { /* add new */
getlin("What new menucolor pattern?", mcbuf);
if (*mcbuf == '\033' || !*mcbuf) goto menucolors_again;
mcclr = query_color();
if (mcclr == -1) goto menucolors_again;
mcattr = query_attr(NULL);
if (mcattr == -1) goto menucolors_again;
if (!add_menu_coloring_parsed(mcbuf, mcclr, mcattr)) {
pline("Error adding the menu color.");
wait_synch();
goto menucolors_again;
} }
end_menu(tmpwin, "How to highlight menu headings:"); } else { /* list or remove */
if (select_menu(tmpwin, PICK_ONE, &mode_pick) > 0) { int pick_idx, pick_cnt;
int mode = mode_pick->item.a_int - 1; int mc_idx;
switch(mode) {
case 2:
iflags.menu_headings = ATR_ULINE;
break;
case 0:
iflags.menu_headings = ATR_BOLD;
break;
case 1:
default:
iflags.menu_headings = ATR_INVERSE;
}
free((genericptr_t)mode_pick);
}
destroy_nhwindow(tmpwin);
} else if (!strcmp("autopickup_exception", optname)) {
int pick_cnt, pick_idx, opt_idx, pass;
int totalapes = 0, numapes[2] = {0,0};
menu_item *pick_list = (menu_item *)0; menu_item *pick_list = (menu_item *)0;
char apebuf[1+BUFSZ]; /* so &apebuf[1] is BUFSZ long for getlin() */ struct menucoloring *tmp = menu_colorings;
struct autopickup_exception *ape;
static const struct ape_action {
char letr;
const char *desc;
} action_titles[] = {
{ 'a', "add new autopickup exception" }, /* [0] */
{ 'l', "list autopickup exceptions" }, /* [1] */
{ 'r', "remove existing autopickup exception" }, /* [2] */
{ 'x', "exit this menu" }, /* [3] */
};
ape_again:
opt_idx = 0;
totalapes = count_ape_maps(&numapes[AP_LEAVE], &numapes[AP_GRAB]);
tmpwin = create_nhwindow(NHW_MENU); tmpwin = create_nhwindow(NHW_MENU);
start_menu(tmpwin); start_menu(tmpwin);
any = zeroany; any = zeroany;
for (i = 0; i < SIZE(action_titles); i++) { mc_idx = 0;
any.a_int++; while (tmp) {
/* omit list and remove if there aren't any yet */ const char *sattr = attr2attrname(tmp->attr);
if (!totalapes && (i == 1 || i == 2)) continue; const char *sclr = clr2colorname(tmp->color);
add_menu(tmpwin, NO_GLYPH, &any, action_titles[i].letr, any.a_int = (++mc_idx);
0, ATR_NONE, action_titles[i].desc, Sprintf(mcbuf, "\"%s\"=%s%s%s", tmp->origstr, sclr,
#if 0 /* this ought to work but doesn't... */ (tmp->attr != ATR_NONE) ? " & " : "",
(action_titles[i].letr == 'x') ? MENU_SELECTED : (tmp->attr != ATR_NONE) ? sattr : "");
#endif add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, mcbuf, MENU_UNSELECTED);
MENU_UNSELECTED); tmp = tmp->next;
} }
end_menu(tmpwin, "Do what?"); Sprintf(mcbuf, "%s menu colors",
if ((pick_cnt = select_menu(tmpwin, PICK_ONE, &pick_list)) > 0) { (opt_idx == 1) ? "List of" : "Remove which");
for (pick_idx = 0; pick_idx < pick_cnt; ++pick_idx) { end_menu(tmpwin, mcbuf);
opt_idx = pick_list[pick_idx].item.a_int - 1; pick_cnt = select_menu(tmpwin,
(opt_idx == 1) ? PICK_NONE : PICK_ANY,
&pick_list);
if (pick_cnt > 0) {
for (pick_idx = 0; pick_idx < pick_cnt; ++pick_idx)
free_one_menu_coloring(pick_list[pick_idx].item.a_int - 1 - pick_idx);
} }
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);
if (pick_cnt >= 0) goto menucolors_again;
if (pick_cnt < 1 || opt_idx == 3) { }
} else if (!strcmp("autopickup_exception", optname)) {
int opt_idx, pass, totalapes = 0, numapes[2] = {0,0};
char apebuf[1+BUFSZ]; /* so &apebuf[1] is BUFSZ long for getlin() */
struct autopickup_exception *ape;
ape_again:
totalapes = count_ape_maps(&numapes[AP_LEAVE], &numapes[AP_GRAB]);
opt_idx = handle_add_list_remove("autopickup exception", totalapes);
if (opt_idx == 3) {
; /* done--fall through to function exit */ ; /* done--fall through to function exit */
} else if (opt_idx == 0) { /* add new */ } else if (opt_idx == 0) { /* add new */
getlin("What new autopickup exception pattern?", &apebuf[1]); getlin("What new autopickup exception pattern?", &apebuf[1]);
@@ -3546,6 +3730,8 @@ boolean setinitial,setfromfile;
goto ape_again; goto ape_again;
} }
} else { /* list or remove */ } else { /* list or remove */
int pick_idx, pick_cnt;
menu_item *pick_list = (menu_item *)0;
tmpwin = create_nhwindow(NHW_MENU); tmpwin = create_nhwindow(NHW_MENU);
start_menu(tmpwin); start_menu(tmpwin);
for (pass = AP_LEAVE; pass <= AP_GRAB; ++pass) { for (pass = AP_LEAVE; pass <= AP_GRAB; ++pass) {
@@ -3870,10 +4056,7 @@ char *buf;
else if (!strcmp(optname, "menu_invert_all")) else if (!strcmp(optname, "menu_invert_all"))
Sprintf(buf, "%s", to_be_done); Sprintf(buf, "%s", to_be_done);
else if (!strcmp(optname, "menu_headings")) { else if (!strcmp(optname, "menu_headings")) {
Sprintf(buf, "%s", (iflags.menu_headings == ATR_BOLD) ? Sprintf(buf, "%s", attr2attrname(iflags.menu_headings));
"bold" : (iflags.menu_headings == ATR_INVERSE) ?
"inverse" : (iflags.menu_headings == ATR_ULINE) ?
"underline" : "unknown");
} }
else if (!strcmp(optname, "menu_invert_page")) else if (!strcmp(optname, "menu_invert_page"))
Sprintf(buf, "%s", to_be_done); Sprintf(buf, "%s", to_be_done);
+52 -20
View File
@@ -1,4 +1,4 @@
/* NetHack 3.5 pickup.c $NHDT-Date: 1426558927 2015/03/17 02:22:07 $ $NHDT-Branch: master $:$NHDT-Revision: 1.131 $ */ /* NetHack 3.5 pickup.c $NHDT-Date: 1430122768 2015/04/27 08:19:28 $ $NHDT-Branch: master $:$NHDT-Revision: 1.150 $ */
/* NetHack 3.5 pickup.c $Date: 2012/02/16 03:01:38 $ $Revision: 1.123 $ */ /* NetHack 3.5 pickup.c $Date: 2012/02/16 03:01:38 $ $Revision: 1.123 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -308,8 +308,10 @@ struct obj *obj;
return (obj->quan >= val_for_n_or_more); return (obj->quan >= val_for_n_or_more);
} }
/* List of valid menu classes for query_objlist() and allow_category callback */ /* list of valid menu classes for query_objlist() and allow_category callback
static char valid_menu_classes[MAXOCLASSES + 2]; (with room for all object classes, 'u'npaid, BUCX, and terminator) */
static char valid_menu_classes[MAXOCLASSES + 1 + 4 + 1];
static boolean class_filter, bucx_filter, shop_filter;
void void
add_valid_menu_class(c) add_valid_menu_class(c)
@@ -317,10 +319,19 @@ int c;
{ {
static int vmc_count = 0; static int vmc_count = 0;
if (c == 0) /* reset */ if (c == 0) { /* reset */
vmc_count = 0; vmc_count = 0;
else class_filter = bucx_filter = shop_filter = FALSE;
} else {
valid_menu_classes[vmc_count++] = (char)c; valid_menu_classes[vmc_count++] = (char)c;
/* categorize the new class */
switch (c) {
case 'B': case 'U': case 'C': /*FALLTHRU*/
case 'X': bucx_filter = TRUE; break;
case 'u': shop_filter = TRUE; break;
default: class_filter = TRUE; break;
}
}
valid_menu_classes[vmc_count] = '\0'; valid_menu_classes[vmc_count] = '\0';
} }
@@ -345,27 +356,48 @@ boolean
allow_category(obj) allow_category(obj)
struct obj *obj; struct obj *obj;
{ {
if (Role_if(PM_PRIEST)) obj->bknown = TRUE;
/* if obj's class is in the list, then obj is acceptable */
if (index(valid_menu_classes, obj->oclass))
return TRUE;
/* unpaid and BUC checks don't apply to coins */ /* unpaid and BUC checks don't apply to coins */
if (obj->oclass == COIN_CLASS) if (obj->oclass == COIN_CLASS)
return index(valid_menu_classes, COIN_CLASS) ? TRUE : FALSE;
if (Role_if(PM_PRIEST)) obj->bknown = TRUE;
/*
* There are three types of filters possible and the first and
* third can have more than one entry:
* 1) object class (armor, potion, &c);
* 2) unpaid shop item;
* 3) bless/curse state (blessed, uncursed, cursed, BUC-unknown).
* When only one type is present, the situation is simple:
* to be accepted, obj's status must match one of the entries.
* When more than one type is present, the obj will now only
* be accepted when it matches one entry of each type.
* So ?!B will accept blessed scrolls or potions, and [u will
* accept unpaid armor. (In 3.4.3, an object was accepted by
* this filter if it met any entry of any type, so ?!B resulted
* in accepting all scrolls and potions regardless of bless/curse
* state plus all blessed non-scroll, non-potion objects.)
*/
/* if class is expected but obj's class is not in the list, reject */
if (class_filter && !index(valid_menu_classes, obj->oclass))
return FALSE;
/* if unpaid is expected and obj isn't unpaid, reject (treat a container
holding any unpaid object as unpaid even if isn't unpaid itself) */
if (shop_filter && !obj->unpaid
&& !(Has_contents(obj) && count_unpaid(obj) > 0))
return FALSE; return FALSE;
/* check for unpaid item */
if (index(valid_menu_classes, 'u') &&
(obj->unpaid || (Has_contents(obj) && count_unpaid(obj))))
return TRUE;
/* check for particular bless/curse state */ /* check for particular bless/curse state */
if (!obj->bknown ? index(valid_menu_classes, 'X') : /* unknown BUC state */ if (bucx_filter) {
obj->blessed ? index(valid_menu_classes, 'B') : /* known blessed */ /* first categorize this object's bless/curse state */
!obj->cursed ? index(valid_menu_classes, 'U') : /* known uncursed */ char bucx = !obj->bknown ? 'X'
index(valid_menu_classes, 'C')) /* known cursed */ : obj->blessed ? 'B' : obj->cursed ? 'C' : 'U';
return TRUE;
/* obj isn't acceptable */ /* if its category is not in the list, reject */
if (!index(valid_menu_classes, bucx))
return FALSE; return FALSE;
} }
/* obj didn't fail any of the filter checks, so accept */
return TRUE;
}
#if 0 /* not used */ #if 0 /* not used */
/* query_objlist callback: return TRUE if valid category (class), no uchain */ /* query_objlist callback: return TRUE if valid category (class), no uchain */
+1
View File
@@ -15,6 +15,7 @@ take_gold()
nobj = otmp->nobj; nobj = otmp->nobj;
if (otmp->oclass == COIN_CLASS) { if (otmp->oclass == COIN_CLASS) {
lost_money = 1; lost_money = 1;
remove_worn_item(otmp, FALSE);
delobj(otmp); delobj(otmp);
} }
} }
+1 -1
View File
@@ -1401,7 +1401,7 @@ int *spell_no;
Sprintf(buf, "Name\tLevel\tCategory\tFail\tRetention"); Sprintf(buf, "Name\tLevel\tCategory\tFail\tRetention");
fmt = "%s\t%-d\t%s\t%-d%%\t%s"; fmt = "%s\t%-d\t%s\t%-d%%\t%s";
} }
add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_BOLD, buf, MENU_UNSELECTED); add_menu(tmpwin, NO_GLYPH, &any, 0, 0, iflags.menu_headings, buf, MENU_UNSELECTED);
for (i = 0; i < MAXSPELL && spellid(i) != NO_SPELL; i++) { for (i = 0; i < MAXSPELL && spellid(i) != NO_SPELL; i++) {
splnum = !spl_orderindx ? i : spl_orderindx[i]; splnum = !spl_orderindx ? i : spl_orderindx[i];
Sprintf(buf, fmt, Sprintf(buf, fmt,
+1 -2
View File
@@ -516,8 +516,7 @@ int thrown; /* HMON_xxx (0 => hand-to-hand, other => ranged) */
anger_guards = (mon->mpeaceful && anger_guards = (mon->mpeaceful &&
(mon->ispriest || mon->isshk || (mon->ispriest || mon->isshk ||
mon->data == &mons[PM_WATCHMAN] || is_watch(mon->data)));
mon->data == &mons[PM_WATCH_CAPTAIN]));
result = hmon_hitmon(mon, obj, thrown); result = hmon_hitmon(mon, obj, thrown);
if (mon->ispriest && !rn2(2)) ghod_hitsu(mon); if (mon->ispriest && !rn2(2)) ghod_hitsu(mon);
if (anger_guards) (void)angry_guards(!!Deaf); if (anger_guards) (void)angry_guards(!!Deaf);
+5 -3
View File
@@ -1,4 +1,4 @@
/* NetHack 3.5 zap.c $NHDT-Date: 1428207622 2015/04/05 04:20:22 $ $NHDT-Branch: nhmall-booktribute $:$NHDT-Revision: 1.215 $ */ /* NetHack 3.5 zap.c $NHDT-Date: 1430355196 2015/04/30 00:53:16 $ $NHDT-Branch: master $:$NHDT-Revision: 1.218 $ */
/* NetHack 3.5 zap.c $Date: 2013/11/05 00:57:56 $ $Revision: 1.183 $ */ /* NetHack 3.5 zap.c $Date: 2013/11/05 00:57:56 $ $Revision: 1.183 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -2870,9 +2870,11 @@ int skill;
else if (dex < 8) else if (dex < 8)
hit_bon -= 1; hit_bon -= 1;
else if (dex < 14) else if (dex < 14)
hit_bon -= 0; /* Will change when print stuff below removed */ /* Will change when print stuff below removed */
hit_bon -= 0;
else else
hit_bon += dex - 14; /* Even increment for dextrous heroes (see weapon.c abon) */ /* Even increment for dextrous heroes (see weapon.c abon) */
hit_bon += dex - 14;
return hit_bon; return hit_bon;
} }
+12 -1
View File
@@ -1,4 +1,4 @@
/* NetHack 3.5 winX.c $NHDT-Date$ $NHDT-Branch$:$NHDT-Revision$ */ /* NetHack 3.5 winX.c $NHDT-Date: 1430040327 2015/04/26 09:25:27 $ $NHDT-Branch: master $:$NHDT-Revision: 1.28 $ */
/* NetHack 3.5 winX.c $Date: 2012/01/24 04:26:26 $ $Revision: 1.27 $ */ /* NetHack 3.5 winX.c $Date: 2012/01/24 04:26:26 $ $Revision: 1.27 $ */
/* Copyright (c) Dean Luick, 1992 */ /* Copyright (c) Dean Luick, 1992 */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -1532,6 +1532,7 @@ static char yn_esc_map; /* ESC maps to this char. */
static Widget yn_popup; /* popup for the yn fuction (created once) */ static Widget yn_popup; /* popup for the yn fuction (created once) */
static Widget yn_label; /* label for yn function (created once) */ static Widget yn_label; /* label for yn function (created once) */
static boolean yn_getting_num; /* TRUE if accepting digits */ static boolean yn_getting_num; /* TRUE if accepting digits */
static boolean yn_preserve_case; /* default is to force yn to lower case */
static int yn_ndigits; /* digit count */ static int yn_ndigits; /* digit count */
static long yn_val; /* accumulated value */ static long yn_val; /* accumulated value */
@@ -1604,6 +1605,7 @@ yn_key(w, event, params, num_params)
if (!yn_choices) { /* accept any input */ if (!yn_choices) { /* accept any input */
yn_return = ch; yn_return = ch;
} else { } else {
if (!yn_preserve_case)
ch = lowc(ch); /* move to lower case */ ch = lowc(ch); /* move to lower case */
if (ch == '\033') { if (ch == '\033') {
@@ -1664,6 +1666,7 @@ X11_yn_function(ques, choices, def)
yn_choices = choices; /* set up globals for callback to use */ yn_choices = choices; /* set up globals for callback to use */
yn_def = def; yn_def = def;
yn_preserve_case = !choices; /* preserve when arbitrary response allowed */
/* /*
* This is sort of a kludge. There are quite a few places in the main * This is sort of a kludge. There are quite a few places in the main
@@ -1679,6 +1682,14 @@ X11_yn_function(ques, choices, def)
char *cb, choicebuf[QBUFSZ]; char *cb, choicebuf[QBUFSZ];
Strcpy(choicebuf, choices); /* anything beyond <esc> is hidden */ Strcpy(choicebuf, choices); /* anything beyond <esc> is hidden */
/* default when choices are present is to force yn answer to
lowercase unless one or more choices are explicitly uppercase;
check this before stripping the hidden choices */
for (cb = choicebuf; *cb; ++cb)
if ('A' <= *cb && *cb <= 'Z') {
yn_preserve_case = TRUE;
break;
}
if ((cb = index(choicebuf, '\033')) != 0) *cb = '\0'; if ((cb = index(choicebuf, '\033')) != 0) *cb = '\0';
/* ques [choices] (def) */ /* ques [choices] (def) */
if ((int)(1 + strlen(ques) + 2 + strlen(choicebuf) + 4) >= BUFSZ) if ((int)(1 + strlen(ques) + 2 + strlen(choicebuf) + 4) >= BUFSZ)
+16 -4
View File
@@ -1,4 +1,4 @@
/* NetHack 3.5 topl.c $NHDT-Date: 1425081315 2015/02/27 23:55:15 $ $NHDT-Branch: master $:$NHDT-Revision: 1.24 $ */ /* NetHack 3.5 topl.c $NHDT-Date: 1430040322 2015/04/26 09:25:22 $ $NHDT-Branch: master $:$NHDT-Revision: 1.29 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -333,7 +333,7 @@ char def;
{ {
register char q; register char q;
char rtmp[40]; char rtmp[40];
boolean digit_ok, allow_num; boolean digit_ok, allow_num, preserve_case = FALSE;
struct WinDesc *cw = wins[WIN_MESSAGE]; struct WinDesc *cw = wins[WIN_MESSAGE];
boolean doprev = 0; boolean doprev = 0;
char prompt[BUFSZ]; char prompt[BUFSZ];
@@ -347,6 +347,14 @@ char def;
allow_num = (index(resp, '#') != 0); allow_num = (index(resp, '#') != 0);
Strcpy(respbuf, resp); Strcpy(respbuf, resp);
/* normally we force lowercase, but if any uppercase letters
are present in the allowed response, preserve case;
check this before stripping the hidden choices */
for (rb = respbuf; *rb; ++rb)
if ('A' <= *rb && *rb <= 'Z') {
preserve_case = TRUE;
break;
}
/* any acceptable responses that follow <esc> aren't displayed */ /* any acceptable responses that follow <esc> aren't displayed */
if ((rb = index(respbuf, '\033')) != 0) *rb = '\0'; if ((rb = index(respbuf, '\033')) != 0) *rb = '\0';
(void)strncpy(prompt, query, QBUFSZ-1); (void)strncpy(prompt, query, QBUFSZ-1);
@@ -358,13 +366,16 @@ char def;
Strcat(prompt, " "); Strcat(prompt, " ");
pline("%s", prompt); pline("%s", prompt);
} else { } else {
/* no restriction on allowed response, so always preserve case */
/* preserve_case = TRUE; -- moot since we're jumping to the end */
pline("%s ", query); pline("%s ", query);
q = readchar(); q = readchar();
goto clean_up; goto clean_up;
} }
do { /* loop until we get valid input */ do { /* loop until we get valid input */
q = lowc(readchar()); q = readchar();
if (!preserve_case) q = lowc(q);
if (q == '\020') { /* ctrl-P */ if (q == '\020') { /* ctrl-P */
if (iflags.prevmsg_window != 's') { if (iflags.prevmsg_window != 's') {
int sav = ttyDisplay->inread; int sav = ttyDisplay->inread;
@@ -422,7 +433,8 @@ char def;
q = '#'; q = '#';
} }
do { /* loop until we get a non-digit */ do { /* loop until we get a non-digit */
z = lowc(readchar()); z = readchar();
if (!preserve_case) z = lowc(z);
if (digit(z)) { if (digit(z)) {
value = (10 * value) + (z - '0'); value = (10 * value) + (z - '0');
if (value < 0) break; /* overflow: try again */ if (value < 0) break; /* overflow: try again */