Merge branch 'master' of https://rodney.nethack.org:20040/git/NHsource
This commit is contained in:
@@ -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 $
|
||||
.ds h0 "NetHack Guidebook
|
||||
.ds h1
|
||||
@@ -607,12 +607,17 @@ is true.
|
||||
.lp i
|
||||
List your inventory (everything you're carrying).
|
||||
.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
|
||||
.si
|
||||
I* - list all gems in inventory;
|
||||
Iu - list all unpaid items;
|
||||
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.
|
||||
.ei
|
||||
.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
|
||||
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
|
||||
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
|
||||
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
|
||||
by the presence of the word ``cursed'', ``uncursed'' or ``blessed'' in the
|
||||
description of the item.
|
||||
In some cases ``uncursed'' will be omitted as being redundant when
|
||||
enough other information is displayed.
|
||||
.hn 2
|
||||
Weapons (`)')
|
||||
.pg
|
||||
@@ -2085,8 +2097,8 @@ Implemented by the Amiga, Gem and tty ports.
|
||||
Default '^'.
|
||||
.lp menu_headings
|
||||
Controls how the headings in a menu are highlighted.
|
||||
Values are 'bold', 'inverse', or 'underline'.
|
||||
Not all ports can actually display all three types.
|
||||
Values are 'none', 'bold', 'dim', 'underline', 'blink', or 'inverse'.
|
||||
Not all ports can actually display all types.
|
||||
.lp menu_invert_all
|
||||
Menu character accelerator to invert all items in a menu.
|
||||
Implemented by the Amiga, Gem, X11 and tty ports.
|
||||
|
||||
@@ -742,12 +742,18 @@ something appropriate if {\it autoquiver\/} is true.
|
||||
List your inventory (everything you're carrying).
|
||||
%.lp
|
||||
\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
|
||||
%.si
|
||||
{\tt I*} --- list all gems in inventory;\\
|
||||
{\tt Iu} --- list all unpaid items;\\
|
||||
{\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.
|
||||
%.ei
|
||||
%.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
|
||||
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
|
||||
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
|
||||
@@ -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
|
||||
by the presence of the word ``cursed'', ``uncursed'' or ``blessed'' in the
|
||||
description of the item.
|
||||
In some cases ``uncursed'' will be omitted as being redundant when
|
||||
enough other information is displayed.
|
||||
|
||||
%.hn 2
|
||||
\subsection*{Weapons (`{\tt )}')}
|
||||
@@ -2516,8 +2530,9 @@ Implemented by the Amiga, Gem and tty ports.
|
||||
Default `\verb+^+'.
|
||||
\item[\ib{menu\_headings}]
|
||||
Controls how the headings in a menu are highlighted.
|
||||
Values are ``{\tt bold}'', ``{\tt inverse}'', or ``{\tt underline}''.
|
||||
Not all ports can actually display all three types.
|
||||
Values are ``{\tt none}'', ``{\tt bold}'', ``{\tt dim}'',
|
||||
``{\tt underline}'', ``{\tt blink}'', or ``{\tt inverse}''.
|
||||
Not all ports can actually display all types.
|
||||
\item[\ib{menu\_invert\_all}]
|
||||
Menu character accelerator to invert all items in a menu.
|
||||
Implemented by the Amiga, Gem, X11 and tty ports.
|
||||
|
||||
@@ -903,6 +903,9 @@ some monsters can eat through iron bars
|
||||
inaccessible niches occasionally have iron bars in front
|
||||
sinks may teleport or polymorph
|
||||
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
|
||||
@@ -1128,6 +1131,8 @@ Some levels in Gehennom now use the old corridor-style maze instead of
|
||||
"beetle legs" are restored.
|
||||
gnomes will occasionally have a candle
|
||||
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
|
||||
|
||||
@@ -53,6 +53,7 @@
|
||||
|
||||
struct menucoloring {
|
||||
struct nhregex *match;
|
||||
char *origstr;
|
||||
int color, attr;
|
||||
struct menucoloring *next;
|
||||
};
|
||||
|
||||
@@ -222,6 +222,7 @@ E boolean FDECL(is_lava, (int,int));
|
||||
E boolean FDECL(is_pool_or_lava, (int,int));
|
||||
E boolean FDECL(is_ice, (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 boolean FDECL(is_db_wall, (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 schar FDECL(lev_by_name, (const char *));
|
||||
E schar FDECL(print_dungeon, (BOOLEAN_P,schar *,xchar *));
|
||||
E char *FDECL(get_annotation, (d_level *));
|
||||
E int NDECL(donamelevel);
|
||||
E int NDECL(dooverview);
|
||||
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 boolean FDECL(onscary, (int,int,struct monst *));
|
||||
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(m_move, (struct monst *,int));
|
||||
E void FDECL(dissolve_bars, (int,int));
|
||||
|
||||
@@ -134,6 +134,8 @@
|
||||
#define is_displacer(ptr) (((ptr)->mflags3 & M3_DISPLACES) != 0L)
|
||||
#define is_mplayer(ptr) (((ptr) >= &mons[PM_ARCHEOLOGIST]) && \
|
||||
((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] || \
|
||||
(ptr) == &mons[PM_FAMINE] || \
|
||||
(ptr) == &mons[PM_PESTILENCE])
|
||||
|
||||
18
src/ball.c
18
src/ball.c
@@ -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 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/* 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
|
||||
* attached to the object list.
|
||||
*
|
||||
* Should not be called while swallowed.
|
||||
* Should not be called while swallowed except on waterlevel.
|
||||
*/
|
||||
void
|
||||
placebc()
|
||||
@@ -133,7 +133,19 @@ placebc()
|
||||
void
|
||||
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)) {
|
||||
obj_extract_self(uball);
|
||||
|
||||
@@ -103,6 +103,18 @@ int x, y;
|
||||
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)
|
||||
* of an eventual drawbridge.
|
||||
|
||||
@@ -1171,8 +1171,7 @@ watch_dig(mtmp, x, y, zap)
|
||||
if (!mtmp) {
|
||||
for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
|
||||
if (DEADMONSTER(mtmp)) continue;
|
||||
if ((mtmp->data == &mons[PM_WATCHMAN] ||
|
||||
mtmp->data == &mons[PM_WATCH_CAPTAIN]) &&
|
||||
if (is_watch(mtmp->data) &&
|
||||
mtmp->mcansee && m_canseeu(mtmp) &&
|
||||
couldsee(mtmp->mx, mtmp->my) && mtmp->mpeaceful)
|
||||
break;
|
||||
|
||||
@@ -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 $ */
|
||||
/* Copyright (c) Dean Luick, with acknowledgements to Kevin Darcy */
|
||||
/* and Dave Cohrs, 1990. */
|
||||
@@ -1363,11 +1363,16 @@ row_refresh(start,stop,y)
|
||||
void
|
||||
cls()
|
||||
{
|
||||
static boolean in_cls = 0;
|
||||
|
||||
if (in_cls) return;
|
||||
in_cls = TRUE;
|
||||
display_nhwindow(WIN_MESSAGE, FALSE); /* flush messages */
|
||||
context.botlx = 1; /* force update of botl window */
|
||||
clear_nhwindow(WIN_MAP); /* clear physical screen */
|
||||
|
||||
clear_glyph_buffer(); /* this is sort of an extra effort, but OK */
|
||||
in_cls = FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
4
src/do.c
4
src/do.c
@@ -1069,6 +1069,7 @@ boolean at_stairs, falling, portal;
|
||||
boolean new = FALSE; /* made a new level? */
|
||||
struct monst *mtmp;
|
||||
char whynot[BUFSZ];
|
||||
char *annotation;
|
||||
|
||||
if (dunlev(newlevel) > dunlevs_in_dungeon(newlevel))
|
||||
newlevel->dlevel = dunlevs_in_dungeon(newlevel);
|
||||
@@ -1458,6 +1459,9 @@ boolean at_stairs, falling, portal;
|
||||
save_currentstate();
|
||||
#endif
|
||||
|
||||
if ((annotation = get_annotation(&u.uz)))
|
||||
You("remember this level as %s.", annotation);
|
||||
|
||||
/* assume this will always return TRUE when changing level */
|
||||
(void) in_out_region(u.ux, u.uy);
|
||||
(void) pickup(1);
|
||||
|
||||
@@ -596,6 +596,9 @@ docallcmd()
|
||||
any.a_char = 'd'; /* entry 'd' (or 'b'), group accelator 'd' */
|
||||
add_menu(win, NO_GLYPH, &any, 0, any.a_char, ATR_NONE,
|
||||
"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
|
||||
any.a_char = 'f'; /* entry 'e' (or 'c'), group accelator 'f' */
|
||||
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 */
|
||||
rename_disco();
|
||||
break;
|
||||
case 'e': /* annotate level */
|
||||
donamelevel();
|
||||
break;
|
||||
#if 0
|
||||
case 'f': /* name a type of object visible on the floor */
|
||||
/* [not implemented] */
|
||||
|
||||
20
src/dokick.c
20
src/dokick.c
@@ -1198,15 +1198,10 @@ dumb:
|
||||
if (in_town(x, y))
|
||||
for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
|
||||
if (DEADMONSTER(mtmp)) continue;
|
||||
if((mtmp->data == &mons[PM_WATCHMAN] ||
|
||||
mtmp->data == &mons[PM_WATCH_CAPTAIN]) &&
|
||||
if (is_watch(mtmp->data) &&
|
||||
couldsee(mtmp->mx, mtmp->my) &&
|
||||
mtmp->mpeaceful) {
|
||||
if (canspotmon(mtmp))
|
||||
pline("%s yells:", Amonnam(mtmp));
|
||||
else
|
||||
You_hear("someone yell:");
|
||||
verbalize("Halt, thief! You're under arrest!");
|
||||
mon_yells(mtmp, "Halt, thief! You're under arrest!");
|
||||
(void) angry_guards(FALSE);
|
||||
break;
|
||||
}
|
||||
@@ -1218,18 +1213,13 @@ dumb:
|
||||
if (in_town(x, y))
|
||||
for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
|
||||
if (DEADMONSTER(mtmp)) continue;
|
||||
if ((mtmp->data == &mons[PM_WATCHMAN] ||
|
||||
mtmp->data == &mons[PM_WATCH_CAPTAIN]) &&
|
||||
if (is_watch(mtmp->data) &&
|
||||
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) {
|
||||
verbalize("Halt, vandal! You're under arrest!");
|
||||
mon_yells(mtmp, "Halt, vandal! You're under arrest!");
|
||||
(void) angry_guards(FALSE);
|
||||
} else {
|
||||
verbalize("Hey, stop damaging that door!");
|
||||
mon_yells(mtmp, "Hey, stop damaging that door!");
|
||||
levl[x][y].looted |= D_WARNED;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -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 */
|
||||
int
|
||||
donamelevel()
|
||||
@@ -1857,8 +1867,15 @@ donamelevel()
|
||||
|
||||
if (!(mptr = find_mapseen(&u.uz))) return 0;
|
||||
|
||||
getlin("What do you want to call this dungeon level?", nbuf);
|
||||
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);
|
||||
if (index(nbuf, '\033')) return 0;
|
||||
(void)mungspaces(nbuf);
|
||||
|
||||
/* discard old annotation, if any */
|
||||
if (mptr->custom) {
|
||||
@@ -2190,12 +2207,7 @@ recalc_mapseen()
|
||||
if (cansee(x, y) || (x == u.ux && y == u.uy && !Levitation)) {
|
||||
ltyp = levl[x][y].typ;
|
||||
if (ltyp == DRAWBRIDGE_UP)
|
||||
switch (levl[x][y].drawbridgemask & DB_UNDER) {
|
||||
case DB_ICE: ltyp = ICE; break;
|
||||
case DB_LAVA: ltyp = LAVAPOOL; break;
|
||||
case DB_MOAT: ltyp = MOAT; break;
|
||||
default: ltyp = STONE; break;
|
||||
}
|
||||
ltyp = db_under_typ(levl[x][y].drawbridgemask);
|
||||
if ((mtmp = m_at(x, y)) != 0 &&
|
||||
mtmp->m_ap_type == M_AP_FURNITURE && canseemon(mtmp))
|
||||
ltyp = cmap_to_type(mtmp->mappearance);
|
||||
|
||||
@@ -169,8 +169,7 @@ boolean isyou;
|
||||
/* Warn about future fountain use. */
|
||||
for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
|
||||
if (DEADMONSTER(mtmp)) continue;
|
||||
if ((mtmp->data == &mons[PM_WATCHMAN] ||
|
||||
mtmp->data == &mons[PM_WATCH_CAPTAIN]) &&
|
||||
if (is_watch(mtmp->data) &&
|
||||
couldsee(mtmp->mx, mtmp->my) &&
|
||||
mtmp->mpeaceful) {
|
||||
pline("%s yells:", Amonnam(mtmp));
|
||||
|
||||
164
src/invent.c
164
src/invent.c
@@ -24,6 +24,7 @@ STATIC_PTR char *FDECL(safeq_xprname, (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_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 void NDECL(dounpaid);
|
||||
STATIC_DCL struct obj *FDECL(find_unpaid,(struct obj *,struct obj **));
|
||||
@@ -394,6 +395,7 @@ addinv(obj)
|
||||
struct obj *obj;
|
||||
{
|
||||
struct obj *otmp, *prev;
|
||||
int saved_otyp = (int)obj->otyp; /* for panic */
|
||||
|
||||
if (obj->where != OBJ_FREE)
|
||||
panic("addinv: obj not free");
|
||||
@@ -410,12 +412,16 @@ struct obj *obj;
|
||||
extra to quivered stack is more useful than to wielded one */
|
||||
if (uquiver && merged(&uquiver, &obj)) {
|
||||
obj = uquiver;
|
||||
if (!obj)
|
||||
panic("addinv: null obj after quiver merge otyp=%d", saved_otyp);
|
||||
goto added;
|
||||
}
|
||||
/* merge if possible; find end of chain in the process */
|
||||
for (prev = 0, otmp = invent; otmp; prev = otmp, otmp = otmp->nobj)
|
||||
if (merged(&otmp, &obj)) {
|
||||
obj = otmp;
|
||||
if (!obj)
|
||||
panic("addinv: null obj after merge otyp=%d", saved_otyp);
|
||||
goto added;
|
||||
}
|
||||
/* didn't merge, so insert into chain */
|
||||
@@ -2067,6 +2073,33 @@ count_buc(list, type)
|
||||
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
|
||||
count_contents(container, nested, quantity, everything)
|
||||
struct obj *container;
|
||||
@@ -2189,7 +2222,18 @@ STATIC_OVL boolean
|
||||
this_type_only(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 */
|
||||
@@ -2200,6 +2244,7 @@ dotypeinv()
|
||||
int n, i = 0;
|
||||
char *extra_types, types[BUFSZ];
|
||||
int class_count, oclass, unpaid_count, itemcount;
|
||||
int bcnt, ccnt, ucnt, xcnt, ocnt;
|
||||
boolean billx = *u.ushops && doinvbill(0);
|
||||
menu_item *pick_list;
|
||||
boolean traditional = TRUE;
|
||||
@@ -2210,12 +2255,18 @@ dotypeinv()
|
||||
return 0;
|
||||
}
|
||||
unpaid_count = count_unpaid(invent);
|
||||
tally_BUCX(invent, &bcnt, &ucnt, &ccnt, &xcnt, &ocnt);
|
||||
|
||||
if (flags.menu_style != MENU_TRADITIONAL) {
|
||||
if (flags.menu_style == MENU_FULL ||
|
||||
flags.menu_style == MENU_PARTIAL) {
|
||||
traditional = FALSE;
|
||||
i = UNPAID_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);
|
||||
if (!n) return 0;
|
||||
this_type = c = pick_list[0].item.a_int;
|
||||
@@ -2225,73 +2276,96 @@ dotypeinv()
|
||||
if (traditional) {
|
||||
/* collect a list of classes of objects carried, for use as a prompt */
|
||||
types[0] = 0;
|
||||
class_count = collect_obj_classes(types, invent,
|
||||
FALSE,
|
||||
(boolean FDECL((*),(OBJ_P))) 0, &itemcount);
|
||||
if (unpaid_count) {
|
||||
Strcat(types, "u");
|
||||
class_count++;
|
||||
}
|
||||
if (billx) {
|
||||
Strcat(types, "x");
|
||||
class_count++;
|
||||
}
|
||||
class_count = collect_obj_classes(types, invent, FALSE,
|
||||
(boolean FDECL((*),(OBJ_P))) 0,
|
||||
&itemcount);
|
||||
if (unpaid_count || billx || (bcnt + ccnt + ucnt + xcnt) != 0)
|
||||
types[class_count++] = ' ';
|
||||
if (unpaid_count) types[class_count++] = 'u';
|
||||
if (billx) types[class_count++] = 'x';
|
||||
if (bcnt) types[class_count++] = 'B';
|
||||
if (ucnt) types[class_count++] = 'U';
|
||||
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 */
|
||||
extra_types = eos(types);
|
||||
*extra_types++ = '\033';
|
||||
if (!unpaid_count) *extra_types++ = 'u';
|
||||
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() */
|
||||
for (i = 0; i < MAXOCLASSES; i++)
|
||||
if (!index(types, def_oc_syms[i].sym)) {
|
||||
*extra_types++ = def_oc_syms[i].sym;
|
||||
*extra_types = '\0';
|
||||
}
|
||||
if (!index(types, def_oc_syms[i].sym)) {
|
||||
*extra_types++ = def_oc_syms[i].sym;
|
||||
*extra_types = '\0';
|
||||
}
|
||||
|
||||
if(class_count > 1) {
|
||||
c = yn_function(prompt, types, '\0');
|
||||
savech(c);
|
||||
if(c == '\0') {
|
||||
clear_nhwindow(WIN_MESSAGE);
|
||||
return 0;
|
||||
}
|
||||
if (class_count > 1) {
|
||||
c = yn_function(prompt, types, '\0');
|
||||
savech(c);
|
||||
if (c == '\0') {
|
||||
clear_nhwindow(WIN_MESSAGE);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
/* only one thing to itemize */
|
||||
if (unpaid_count)
|
||||
c = 'u';
|
||||
else if (billx)
|
||||
c = 'x';
|
||||
else
|
||||
c = types[0];
|
||||
/* only one thing to itemize */
|
||||
if (unpaid_count)
|
||||
c = 'u';
|
||||
else if (billx)
|
||||
c = 'x';
|
||||
else
|
||||
c = types[0];
|
||||
}
|
||||
}
|
||||
if (c == 'x') {
|
||||
if (c == 'x' || (c == 'X' && billx && !xcnt)) {
|
||||
if (billx)
|
||||
(void) doinvbill(1);
|
||||
else
|
||||
pline("No used-up objects on your shopping bill.");
|
||||
(void) doinvbill(1);
|
||||
else
|
||||
pline("No used-up objects%s.",
|
||||
unpaid_count ? " on your shopping bill" : "");
|
||||
return 0;
|
||||
}
|
||||
if (c == 'u') {
|
||||
if (c == 'u' || (c == 'U' && unpaid_count && !ucnt)) {
|
||||
if (unpaid_count)
|
||||
dounpaid();
|
||||
dounpaid();
|
||||
else
|
||||
You("are not carrying any unpaid objects.");
|
||||
You("are not carrying any unpaid objects.");
|
||||
return 0;
|
||||
}
|
||||
if (traditional) {
|
||||
oclass = def_char_to_objclass(c); /* change to object class */
|
||||
if (oclass == COIN_CLASS) {
|
||||
return doprgold();
|
||||
} else if (index(types, c) > index(types, '\033')) {
|
||||
You("have no such objects.");
|
||||
return 0;
|
||||
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 */
|
||||
|
||||
if (oclass == COIN_CLASS)
|
||||
return doprgold();
|
||||
if (index(types, c) > index(types, '\033')) {
|
||||
/* '> 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;
|
||||
}
|
||||
this_type = oclass;
|
||||
}
|
||||
if (query_objlist((char *) 0, invent,
|
||||
(flags.invlet_constant ? USE_INVLET : 0)|INVORDER_SORT,
|
||||
&pick_list, PICK_NONE, this_type_only) > 0)
|
||||
(flags.invlet_constant ? USE_INVLET : 0)|INVORDER_SORT,
|
||||
&pick_list, PICK_NONE, this_type_only) > 0)
|
||||
free((genericptr_t)pick_list);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1157,12 +1157,7 @@ xchar x,y;
|
||||
lev = &levl[x][y];
|
||||
ltyp = lev->typ;
|
||||
if (ltyp == DRAWBRIDGE_UP)
|
||||
switch (lev->drawbridgemask & DB_UNDER) {
|
||||
case DB_ICE: ltyp = ICE; break;
|
||||
case DB_LAVA: ltyp = LAVAPOOL; break;
|
||||
case DB_MOAT: ltyp = MOAT; break;
|
||||
default: ltyp = STONE; break;
|
||||
}
|
||||
ltyp = db_under_typ(lev->drawbridgemask);
|
||||
|
||||
if (ltyp == LAVAPOOL)
|
||||
return "lava";
|
||||
|
||||
@@ -2194,7 +2194,7 @@ unsigned oid;
|
||||
for (fx = ex; abs(fx - ex) < 3; fx += dx) {
|
||||
for (fy = ey; abs(fy - ey) < 3; fy += dy) {
|
||||
/* 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) {
|
||||
return otmp;
|
||||
}
|
||||
|
||||
13
src/mon.c
13
src/mon.c
@@ -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 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -1850,7 +1850,7 @@ register struct monst *mtmp;
|
||||
u.uy = mtmp->my;
|
||||
u.uswallow = 0;
|
||||
u.uswldtim = 0;
|
||||
if (Punished) placebc();
|
||||
if (Punished && uball->where == OBJ_FREE) placebc();
|
||||
vision_full_recalc = 1;
|
||||
docrt();
|
||||
}
|
||||
@@ -3117,9 +3117,7 @@ register boolean silent;
|
||||
|
||||
for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
|
||||
if (DEADMONSTER(mtmp)) continue;
|
||||
if((mtmp->data == &mons[PM_WATCHMAN] ||
|
||||
mtmp->data == &mons[PM_WATCH_CAPTAIN])
|
||||
&& mtmp->mpeaceful) {
|
||||
if (is_watch(mtmp->data) && mtmp->mpeaceful) {
|
||||
ct++;
|
||||
if(cansee(mtmp->mx, mtmp->my) && mtmp->mcanmove) {
|
||||
if (distu(mtmp->mx, mtmp->my) == 2) nct++;
|
||||
@@ -3157,9 +3155,8 @@ pacify_guards()
|
||||
|
||||
for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
|
||||
if (DEADMONSTER(mtmp)) continue;
|
||||
if (mtmp->data == &mons[PM_WATCHMAN] ||
|
||||
mtmp->data == &mons[PM_WATCH_CAPTAIN])
|
||||
mtmp->mpeaceful = 1;
|
||||
if (is_watch(mtmp->data))
|
||||
mtmp->mpeaceful = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
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
|
||||
watch_on_duty(mtmp)
|
||||
register struct monst *mtmp;
|
||||
@@ -63,13 +75,11 @@ register struct monst *mtmp;
|
||||
(levl[x][y].doormask & D_LOCKED)) {
|
||||
|
||||
if(couldsee(mtmp->mx, mtmp->my)) {
|
||||
|
||||
pline("%s yells:", Amonnam(mtmp));
|
||||
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);
|
||||
} else {
|
||||
verbalize("Hey, stop picking that lock!");
|
||||
mon_yells(mtmp, "Hey, stop picking that lock!");
|
||||
levl[x][y].looted |= D_WARNED;
|
||||
}
|
||||
stop_occupation();
|
||||
@@ -400,7 +410,7 @@ register struct monst *mtmp;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
|
||||
else if (is_mind_flayer(mdat) && !rn2(20)) {
|
||||
@@ -1295,15 +1305,10 @@ register int x, y;
|
||||
{
|
||||
int levtyp = levl[x][y].typ;
|
||||
|
||||
if (levtyp == DRAWBRIDGE_UP) {
|
||||
/* use underlying terrain in front of closed drawbridge */
|
||||
switch (levl[x][y].drawbridgemask & DB_UNDER) {
|
||||
case DB_MOAT: levtyp = MOAT; break;
|
||||
case DB_LAVA: levtyp = LAVAPOOL; break;
|
||||
case DB_ICE: levtyp = ICE; break;
|
||||
case DB_FLOOR: levtyp = ROOM; break;
|
||||
}
|
||||
}
|
||||
/* use underlying terrain in front of closed drawbridge */
|
||||
if (levtyp == DRAWBRIDGE_UP)
|
||||
levtyp = db_under_typ(levl[x][y].drawbridgemask);
|
||||
|
||||
return (boolean)(ACCESSIBLE(levtyp) && !closed_door(x, y));
|
||||
}
|
||||
|
||||
|
||||
@@ -421,7 +421,8 @@ struct obj *obj; /* missile (or stack providing it) */
|
||||
(void) drop_throw(singleobj, hitu, u.ux, u.uy);
|
||||
break;
|
||||
}
|
||||
} else if (!range /* reached end of path */
|
||||
}
|
||||
if (!range /* reached end of path */
|
||||
/* missile hits edge of screen */
|
||||
|| !isok(bhitpos.x+dx,bhitpos.y+dy)
|
||||
/* missile hits the wall */
|
||||
@@ -440,7 +441,7 @@ struct obj *obj; /* missile (or stack providing it) */
|
||||
tmp_at(bhitpos.x, bhitpos.y);
|
||||
delay_output();
|
||||
}
|
||||
if (isok(bhitpos.x, bhitpos.y)) tmp_at(bhitpos.x, bhitpos.y);
|
||||
tmp_at(bhitpos.x, bhitpos.y);
|
||||
delay_output();
|
||||
tmp_at(DISP_END, 0);
|
||||
|
||||
|
||||
377
src/options.c
377
src/options.c
@@ -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 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -283,7 +283,7 @@ static struct Comp_Opt
|
||||
4, SET_IN_FILE },
|
||||
{ "menu_first_page", "jump to the first page in a menu",
|
||||
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_page", "invert all items on this page of a menu",
|
||||
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_DCL void FDECL(remove_autopickup_exception, (struct autopickup_exception *));
|
||||
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
|
||||
@@ -1163,13 +1170,117 @@ static const struct {
|
||||
{"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 */
|
||||
boolean
|
||||
add_menu_coloring(str)
|
||||
char *str;
|
||||
{
|
||||
int i, c = NO_COLOR, a = ATR_NONE;
|
||||
struct menucoloring *tmp;
|
||||
char *tmps, *cs = strchr(str, '=');
|
||||
|
||||
if (!cs || !str) return FALSE;
|
||||
@@ -1212,20 +1323,7 @@ char *str;
|
||||
}
|
||||
}
|
||||
|
||||
tmp = (struct menucoloring *)alloc(sizeof(struct menucoloring));
|
||||
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;
|
||||
}
|
||||
return add_menu_coloring_parsed(tmps, c, a);
|
||||
}
|
||||
|
||||
boolean
|
||||
@@ -1252,11 +1350,48 @@ free_menu_coloring()
|
||||
while (tmp) {
|
||||
struct menucoloring *tmp2 = tmp->next;
|
||||
regex_free(tmp->match);
|
||||
free(tmp->origstr);
|
||||
free(tmp);
|
||||
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
|
||||
parseoptions(opts, tinitial, tfrom_file)
|
||||
@@ -2618,14 +2753,12 @@ goodfruit:
|
||||
else if (!(opts = string_for_env_opt(fullname, opts, FALSE))) {
|
||||
return;
|
||||
}
|
||||
if (!strcmpi(opts,"bold"))
|
||||
iflags.menu_headings = ATR_BOLD;
|
||||
else if (!strcmpi(opts,"inverse"))
|
||||
iflags.menu_headings = ATR_INVERSE;
|
||||
else if (!strcmpi(opts,"underline"))
|
||||
iflags.menu_headings = ATR_ULINE;
|
||||
else
|
||||
badoption(opts);
|
||||
for (i = 0; i < SIZE(attrnames); i++)
|
||||
if (!strcmpi(opts, attrnames[i].name)) {
|
||||
iflags.menu_headings = attrnames[i].attr;
|
||||
return;
|
||||
}
|
||||
badoption(opts);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -3087,6 +3220,11 @@ doset()
|
||||
doset_add_menu(tmpwin, compopt[i].name,
|
||||
(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_HILITES
|
||||
any.a_int = -2;
|
||||
@@ -3138,6 +3276,10 @@ doset()
|
||||
} else
|
||||
# endif
|
||||
#endif
|
||||
if (opt_indx == -4) {
|
||||
(void)special_handling("menucolors",
|
||||
setinitial, fromfile);
|
||||
} else
|
||||
if (opt_indx < boolcount) {
|
||||
/* boolean option */
|
||||
Sprintf(buf, "%s%s", *boolopt[opt_indx].addr ? "!" : "",
|
||||
@@ -3177,6 +3319,57 @@ doset()
|
||||
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
|
||||
list of available sets */
|
||||
|
||||
@@ -3454,79 +3647,70 @@ boolean setinitial,setfromfile;
|
||||
}
|
||||
destroy_nhwindow(tmpwin);
|
||||
} else if (!strcmp("menu_headings", optname)) {
|
||||
static const char *mhchoices[3] = {"bold", "inverse", "underline"};
|
||||
const char *npletters = "biu";
|
||||
menu_item *mode_pick = (menu_item *)0;
|
||||
|
||||
tmpwin = create_nhwindow(NHW_MENU);
|
||||
start_menu(tmpwin);
|
||||
any = zeroany;
|
||||
for (i = 0; i < SIZE(mhchoices); i++) {
|
||||
any.a_int = i + 1;
|
||||
add_menu(tmpwin, NO_GLYPH, &any, npletters[i], 0,
|
||||
ATR_NONE, mhchoices[i], MENU_UNSELECTED);
|
||||
}
|
||||
end_menu(tmpwin, "How to highlight menu headings:");
|
||||
if (select_menu(tmpwin, PICK_ONE, &mode_pick) > 0) {
|
||||
int mode = mode_pick->item.a_int - 1;
|
||||
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;
|
||||
int mhattr = query_attr("How to highlight menu headings:");
|
||||
if (mhattr != -1) iflags.menu_headings = mhattr;
|
||||
} else if (!strcmp("menucolors", optname)) {
|
||||
int opt_idx, nmc, mcclr, mcattr;
|
||||
char mcbuf[BUFSZ];
|
||||
menucolors_again:
|
||||
nmc = count_menucolors();
|
||||
opt_idx = handle_add_list_remove("menucolor", nmc);
|
||||
if (opt_idx == 3) {
|
||||
; /* done--fall through to function exit */
|
||||
} 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;
|
||||
}
|
||||
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;
|
||||
char apebuf[1+BUFSZ]; /* so &apebuf[1] is BUFSZ long for getlin() */
|
||||
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);
|
||||
start_menu(tmpwin);
|
||||
any = zeroany;
|
||||
for (i = 0; i < SIZE(action_titles); i++) {
|
||||
any.a_int++;
|
||||
/* omit list and remove if there aren't any yet */
|
||||
if (!totalapes && (i == 1 || i == 2)) continue;
|
||||
add_menu(tmpwin, NO_GLYPH, &any, action_titles[i].letr,
|
||||
0, ATR_NONE, action_titles[i].desc,
|
||||
#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;
|
||||
} else { /* list or remove */
|
||||
int pick_idx, pick_cnt;
|
||||
int mc_idx;
|
||||
menu_item *pick_list = (menu_item *)0;
|
||||
struct menucoloring *tmp = menu_colorings;
|
||||
tmpwin = create_nhwindow(NHW_MENU);
|
||||
start_menu(tmpwin);
|
||||
any = zeroany;
|
||||
mc_idx = 0;
|
||||
while (tmp) {
|
||||
const char *sattr = attr2attrname(tmp->attr);
|
||||
const char *sclr = clr2colorname(tmp->color);
|
||||
any.a_int = (++mc_idx);
|
||||
Sprintf(mcbuf, "\"%s\"=%s%s%s", tmp->origstr, sclr,
|
||||
(tmp->attr != ATR_NONE) ? " & " : "",
|
||||
(tmp->attr != ATR_NONE) ? sattr : "");
|
||||
add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, mcbuf, MENU_UNSELECTED);
|
||||
tmp = tmp->next;
|
||||
}
|
||||
Sprintf(mcbuf, "%s menu colors",
|
||||
(opt_idx == 1) ? "List of" : "Remove which");
|
||||
end_menu(tmpwin, mcbuf);
|
||||
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);
|
||||
pick_list = (menu_item *)0;
|
||||
destroy_nhwindow(tmpwin);
|
||||
if (pick_cnt >= 0) goto menucolors_again;
|
||||
}
|
||||
destroy_nhwindow(tmpwin);
|
||||
|
||||
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 */
|
||||
} else if (opt_idx == 0) { /* add new */
|
||||
getlin("What new autopickup exception pattern?", &apebuf[1]);
|
||||
@@ -3546,6 +3730,8 @@ boolean setinitial,setfromfile;
|
||||
goto ape_again;
|
||||
}
|
||||
} else { /* list or remove */
|
||||
int pick_idx, pick_cnt;
|
||||
menu_item *pick_list = (menu_item *)0;
|
||||
tmpwin = create_nhwindow(NHW_MENU);
|
||||
start_menu(tmpwin);
|
||||
for (pass = AP_LEAVE; pass <= AP_GRAB; ++pass) {
|
||||
@@ -3870,10 +4056,7 @@ char *buf;
|
||||
else if (!strcmp(optname, "menu_invert_all"))
|
||||
Sprintf(buf, "%s", to_be_done);
|
||||
else if (!strcmp(optname, "menu_headings")) {
|
||||
Sprintf(buf, "%s", (iflags.menu_headings == ATR_BOLD) ?
|
||||
"bold" : (iflags.menu_headings == ATR_INVERSE) ?
|
||||
"inverse" : (iflags.menu_headings == ATR_ULINE) ?
|
||||
"underline" : "unknown");
|
||||
Sprintf(buf, "%s", attr2attrname(iflags.menu_headings));
|
||||
}
|
||||
else if (!strcmp(optname, "menu_invert_page"))
|
||||
Sprintf(buf, "%s", to_be_done);
|
||||
|
||||
78
src/pickup.c
78
src/pickup.c
@@ -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 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -308,8 +308,10 @@ struct obj *obj;
|
||||
return (obj->quan >= val_for_n_or_more);
|
||||
}
|
||||
|
||||
/* List of valid menu classes for query_objlist() and allow_category callback */
|
||||
static char valid_menu_classes[MAXOCLASSES + 2];
|
||||
/* list of valid menu classes for query_objlist() and allow_category callback
|
||||
(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
|
||||
add_valid_menu_class(c)
|
||||
@@ -317,10 +319,19 @@ int c;
|
||||
{
|
||||
static int vmc_count = 0;
|
||||
|
||||
if (c == 0) /* reset */
|
||||
vmc_count = 0;
|
||||
else
|
||||
valid_menu_classes[vmc_count++] = (char)c;
|
||||
if (c == 0) { /* reset */
|
||||
vmc_count = 0;
|
||||
class_filter = bucx_filter = shop_filter = FALSE;
|
||||
} else {
|
||||
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';
|
||||
}
|
||||
|
||||
@@ -345,26 +356,47 @@ boolean
|
||||
allow_category(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 */
|
||||
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;
|
||||
/* 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 */
|
||||
if (!obj->bknown ? index(valid_menu_classes, 'X') : /* unknown BUC state */
|
||||
obj->blessed ? index(valid_menu_classes, 'B') : /* known blessed */
|
||||
!obj->cursed ? index(valid_menu_classes, 'U') : /* known uncursed */
|
||||
index(valid_menu_classes, 'C')) /* known cursed */
|
||||
return TRUE;
|
||||
/* obj isn't acceptable */
|
||||
return FALSE;
|
||||
if (bucx_filter) {
|
||||
/* first categorize this object's bless/curse state */
|
||||
char bucx = !obj->bknown ? 'X'
|
||||
: obj->blessed ? 'B' : obj->cursed ? 'C' : 'U';
|
||||
|
||||
/* if its category is not in the list, reject */
|
||||
if (!index(valid_menu_classes, bucx))
|
||||
return FALSE;
|
||||
}
|
||||
/* obj didn't fail any of the filter checks, so accept */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#if 0 /* not used */
|
||||
|
||||
@@ -15,6 +15,7 @@ take_gold()
|
||||
nobj = otmp->nobj;
|
||||
if (otmp->oclass == COIN_CLASS) {
|
||||
lost_money = 1;
|
||||
remove_worn_item(otmp, FALSE);
|
||||
delobj(otmp);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1401,7 +1401,7 @@ int *spell_no;
|
||||
Sprintf(buf, "Name\tLevel\tCategory\tFail\tRetention");
|
||||
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++) {
|
||||
splnum = !spl_orderindx ? i : spl_orderindx[i];
|
||||
Sprintf(buf, fmt,
|
||||
|
||||
@@ -516,8 +516,7 @@ int thrown; /* HMON_xxx (0 => hand-to-hand, other => ranged) */
|
||||
|
||||
anger_guards = (mon->mpeaceful &&
|
||||
(mon->ispriest || mon->isshk ||
|
||||
mon->data == &mons[PM_WATCHMAN] ||
|
||||
mon->data == &mons[PM_WATCH_CAPTAIN]));
|
||||
is_watch(mon->data)));
|
||||
result = hmon_hitmon(mon, obj, thrown);
|
||||
if (mon->ispriest && !rn2(2)) ghod_hitsu(mon);
|
||||
if (anger_guards) (void)angry_guards(!!Deaf);
|
||||
|
||||
@@ -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 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -2870,9 +2870,11 @@ int skill;
|
||||
else if (dex < 8)
|
||||
hit_bon -= 1;
|
||||
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
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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 $ */
|
||||
/* Copyright (c) Dean Luick, 1992 */
|
||||
/* 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_label; /* label for yn function (created once) */
|
||||
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 long yn_val; /* accumulated value */
|
||||
|
||||
@@ -1604,7 +1605,8 @@ yn_key(w, event, params, num_params)
|
||||
if (!yn_choices) { /* accept any input */
|
||||
yn_return = ch;
|
||||
} else {
|
||||
ch = lowc(ch); /* move to lower case */
|
||||
if (!yn_preserve_case)
|
||||
ch = lowc(ch); /* move to lower case */
|
||||
|
||||
if (ch == '\033') {
|
||||
yn_getting_num = FALSE;
|
||||
@@ -1664,6 +1666,7 @@ X11_yn_function(ques, choices, def)
|
||||
|
||||
yn_choices = choices; /* set up globals for callback to use */
|
||||
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
|
||||
@@ -1679,6 +1682,14 @@ X11_yn_function(ques, choices, def)
|
||||
char *cb, choicebuf[QBUFSZ];
|
||||
|
||||
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';
|
||||
/* ques [choices] (def) */
|
||||
if ((int)(1 + strlen(ques) + 2 + strlen(choicebuf) + 4) >= BUFSZ)
|
||||
|
||||
@@ -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. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
@@ -333,7 +333,7 @@ char def;
|
||||
{
|
||||
register char q;
|
||||
char rtmp[40];
|
||||
boolean digit_ok, allow_num;
|
||||
boolean digit_ok, allow_num, preserve_case = FALSE;
|
||||
struct WinDesc *cw = wins[WIN_MESSAGE];
|
||||
boolean doprev = 0;
|
||||
char prompt[BUFSZ];
|
||||
@@ -347,6 +347,14 @@ char def;
|
||||
|
||||
allow_num = (index(resp, '#') != 0);
|
||||
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 */
|
||||
if ((rb = index(respbuf, '\033')) != 0) *rb = '\0';
|
||||
(void)strncpy(prompt, query, QBUFSZ-1);
|
||||
@@ -358,13 +366,16 @@ char def;
|
||||
Strcat(prompt, " ");
|
||||
pline("%s", prompt);
|
||||
} else {
|
||||
/* no restriction on allowed response, so always preserve case */
|
||||
/* preserve_case = TRUE; -- moot since we're jumping to the end */
|
||||
pline("%s ", query);
|
||||
q = readchar();
|
||||
goto clean_up;
|
||||
}
|
||||
|
||||
do { /* loop until we get valid input */
|
||||
q = lowc(readchar());
|
||||
q = readchar();
|
||||
if (!preserve_case) q = lowc(q);
|
||||
if (q == '\020') { /* ctrl-P */
|
||||
if (iflags.prevmsg_window != 's') {
|
||||
int sav = ttyDisplay->inread;
|
||||
@@ -422,7 +433,8 @@ char def;
|
||||
q = '#';
|
||||
}
|
||||
do { /* loop until we get a non-digit */
|
||||
z = lowc(readchar());
|
||||
z = readchar();
|
||||
if (!preserve_case) z = lowc(z);
|
||||
if (digit(z)) {
|
||||
value = (10 * value) + (z - '0');
|
||||
if (value < 0) break; /* overflow: try again */
|
||||
|
||||
Reference in New Issue
Block a user