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

This commit is contained in:
keni
2016-10-02 15:26:11 -04:00
15 changed files with 686 additions and 307 deletions

View File

@@ -3747,6 +3747,16 @@ char c;
return (boolean) (c == C('r') || (Cmd.num_pad && c == C('l')));
}
boolean
prefix_cmd(c)
char c;
{
return (boolean) (c == 'g' || c == 'G'
|| c == 'm' || c == 'M'
|| c == 'F'
|| (Cmd.num_pad && (c == '5' || c == '-')));
}
/*
* uses getdir() but unlike getdir() it specifically
* produces coordinates using the direction from getdir()
@@ -4193,8 +4203,7 @@ parse()
in_line[0] = foo;
in_line[1] = '\0';
if (foo == 'g' || foo == 'G' || foo == 'm' || foo == 'M' || foo == 'F'
|| (Cmd.num_pad && (foo == '5' || foo == '-'))) {
if (prefix_cmd(foo)) {
foo = readchar();
savech((char) foo);
in_line[1] = foo;

View File

@@ -54,28 +54,28 @@ const char *goal;
boolean doing_what_is;
winid tmpwin = create_nhwindow(NHW_MENU);
Sprintf(sbuf, "Use [%c%c%c%c] to move the cursor to %s.", /* hjkl */
Sprintf(sbuf, "Use '%c', '%c', '%c', '%c' to move the cursor to %s.", /* hjkl */
Cmd.move_W, Cmd.move_S, Cmd.move_N, Cmd.move_E, goal);
putstr(tmpwin, 0, sbuf);
putstr(tmpwin, 0, "Use [HJKL] to move the cursor 8 units at a time.");
putstr(tmpwin, 0, "Or enter a background symbol (ex. <).");
putstr(tmpwin, 0, "Use @ to move the cursor on yourself.");
putstr(tmpwin, 0, "Use 'H', 'J', 'K', 'L' to move the cursor 8 units at a time.");
putstr(tmpwin, 0, "Or enter a background symbol (ex. '<').");
putstr(tmpwin, 0, "Use '@' to move the cursor on yourself.");
if (!iflags.terrainmode || (iflags.terrainmode & TER_MON) != 0)
putstr(tmpwin, 0, "Use m or M to move the cursor to next monster.");
putstr(tmpwin, 0, "Use 'm' or 'M' to move the cursor to next monster.");
if (!iflags.terrainmode || (iflags.terrainmode & TER_OBJ) != 0)
putstr(tmpwin, 0, "Use o or O to move the cursor to next object.");
putstr(tmpwin, 0, "Use 'o' or 'O' to move the cursor to next object.");
if (!iflags.terrainmode || (iflags.terrainmode & TER_MAP) != 0) {
/* both of these are primarily useful when choosing a travel
destination for the '_' command */
putstr(tmpwin, 0,
"Use d or D to move the cursor to next door or doorway.");
"Use 'd' or 'D' to move the cursor to next door or doorway.");
putstr(tmpwin, 0,
"Use x or X to move the cursor to unexplored location.");
"Use 'x' or 'X' to move the cursor to unexplored location.");
}
if (!iflags.terrainmode) {
if (getpos_hilitefunc)
putstr(tmpwin, 0, "Use $ to display valid locations.");
putstr(tmpwin, 0, "Use # to toggle automatic description.");
putstr(tmpwin, 0, "Use '$' to display valid locations.");
putstr(tmpwin, 0, "Use '#' to toggle automatic description.");
if (iflags.cmdassist) /* assisting the '/' command, I suppose... */
putstr(tmpwin, 0,
(iflags.getpos_coords == GPCOORDS_NONE)
@@ -84,20 +84,20 @@ const char *goal;
/* disgusting hack; the alternate selection characters work for any
getpos call, but only matter for dowhatis (and doquickwhatis) */
doing_what_is = (goal == what_is_an_unknown_object);
Sprintf(sbuf, "Type a .%s when you are at the right place.",
doing_what_is ? " or , or ; or :" : "");
Sprintf(sbuf, "Type a '.'%s when you are at the right place.",
doing_what_is ? " or ',' or ';' or ':'" : "");
putstr(tmpwin, 0, sbuf);
if (doing_what_is) {
putstr(tmpwin, 0,
" : describe current spot, show 'more info', move to another spot.");
" ':' describe current spot, show 'more info', move to another spot.");
Sprintf(sbuf,
" . describe current spot,%s move to another spot;",
" '.' describe current spot,%s move to another spot;",
flags.help ? " prompt if 'more info'," : "");
putstr(tmpwin, 0, sbuf);
putstr(tmpwin, 0,
" , describe current spot, move to another spot;");
" ',' describe current spot, move to another spot;");
putstr(tmpwin, 0,
" ; describe current spot, stop looking at things;");
" ';' describe current spot, stop looking at things;");
}
}
if (!force)
@@ -232,11 +232,11 @@ int gloc;
}
char *
dxdy_to_dist_descr(dx, dy)
dxdy_to_dist_descr(dx, dy, fulldir)
int dx, dy;
boolean fulldir;
{
/* [12] suffices, but guard against long translation for direction-name */
static char buf[20];
static char buf[30];
int dst;
if (!dx && !dy) {
@@ -245,18 +245,23 @@ int dx, dy;
/* explicit direction; 'one step' is implicit */
Sprintf(buf, "%s", directionname(dst));
} else {
const char *dirnames[4][2] = {
{ "n", "north" },
{ "s", "south" },
{ "w", "west" },
{ "e", "east" } };
buf[0] = '\0';
/* 9999: protect buf[] against overflow caused by invalid values */
if (dy) {
if (abs(dy) > 9999)
dy = sgn(dy) * 9999;
Sprintf(eos(buf), "%d%c%s", abs(dy), (dy > 0) ? 's' : 'n',
Sprintf(eos(buf), "%d%s%s", abs(dy), dirnames[(dy > 0)][fulldir],
dx ? "," : "");
}
if (dx) {
if (abs(dx) > 9999)
dx = sgn(dx) * 9999;
Sprintf(eos(buf), "%d%c", abs(dx), (dx > 0) ? 'e' : 'w');
Sprintf(eos(buf), "%d%s", abs(dx), dirnames[2 + (dx > 0)][fulldir]);
}
}
return buf;
@@ -275,11 +280,13 @@ char *outbuf, cmode;
switch (cmode) {
default:
break;
case GPCOORDS_COMFULL:
case GPCOORDS_COMPASS:
/* "east", "3s", "2n,4w" */
dx = x - u.ux;
dy = y - u.uy;
Sprintf(outbuf, "(%s)", dxdy_to_dist_descr(dx, dy));
Sprintf(outbuf, "(%s)",
dxdy_to_dist_descr(dx, dy, cmode == GPCOORDS_COMFULL));
break;
case GPCOORDS_MAP: /* x,y */
/* upper left corner of map is <1,0>;
@@ -346,7 +353,7 @@ const char *goal;
if (!goal)
goal = "desired location";
if (flags.verbose) {
pline("(For instructions type a ?)");
pline("(For instructions type a '?')");
msg_given = TRUE;
}
cx = ccp->x;
@@ -561,7 +568,7 @@ const char *goal;
if (!force)
Strcpy(note, "aborted");
else
Sprintf(note, "use %c%c%c%c or .", /* hjkl */
Sprintf(note, "use '%c', '%c', '%c', '%c' or '.'", /* hjkl */
Cmd.move_W, Cmd.move_S, Cmd.move_N,
Cmd.move_E);
pline("Unknown direction: '%s' (%s).", visctrl((char) c),

View File

@@ -498,7 +498,7 @@ int *dmg_p; /* for dishing out extra damage in lieu of Int loss */
} else if (mdef == &youmonst) {
Your("brain is eaten!");
} else { /* monster against monster */
if (visflag)
if (visflag && canspotmon(mdef))
pline("%s brain is eaten!", s_suffix(Monnam(mdef)));
}
@@ -512,7 +512,7 @@ int *dmg_p; /* for dishing out extra damage in lieu of Int loss */
} else {
/* no need to check for poly_when_stoned or Stone_resistance;
mind flayers don't have those capabilities */
if (visflag)
if (visflag && canseemon(magr))
pline("%s turns to stone!", Monnam(magr));
monstone(magr);
if (magr->mhp > 0) {
@@ -597,7 +597,7 @@ int *dmg_p; /* for dishing out extra damage in lieu of Int loss */
* monster mind flayer is eating another monster's brain
*/
if (mindless(pd)) {
if (visflag)
if (visflag && canspotmon(mdef))
pline("%s doesn't notice.", Monnam(mdef));
return MM_MISS;
} else if (is_rider(pd)) {
@@ -609,7 +609,7 @@ int *dmg_p; /* for dishing out extra damage in lieu of Int loss */
} else {
*dmg_p += xtra_dmg;
give_nutrit = TRUE;
if (*dmg_p >= mdef->mhp && visflag)
if (*dmg_p >= mdef->mhp && visflag && canspotmon(mdef))
pline("%s last thought fades away...",
s_suffix(Monnam(mdef)));
}

View File

@@ -1302,6 +1302,13 @@ int mmflags;
m_initweap(mtmp); /* equip with weapons / armor */
m_initinv(mtmp); /* add on a few special items incl. more armor */
m_dowear(mtmp, TRUE);
if (!rn2(100) && is_domestic(ptr)
&& can_saddle(mtmp) && !which_armor(mtmp, W_SADDLE)) {
struct obj *otmp = mksobj(SADDLE, TRUE, FALSE);
put_saddle_on_mon(otmp, mtmp);
}
} else {
/* no initial inventory is allowed */
if (mtmp->minvent)

View File

@@ -410,7 +410,7 @@ register struct monst *magr, *mdef;
&& mdef->mhp > 1
&& !mdef->mcan) {
if (clone_mon(mdef, 0, 0)) {
if (vis) {
if (vis && canspotmon(mdef)) {
char buf[BUFSZ];
Strcpy(buf, Monnam(mdef));
@@ -587,13 +587,17 @@ struct attack *mattk;
char buf[BUFSZ];
if (vis) {
if (mdef->data->mlet == S_MIMIC
&& mdef->m_ap_type != M_AP_NOTHING)
seemimic(mdef);
Sprintf(buf, "%s gazes at", Monnam(magr));
pline("%s %s...", buf, mon_nam(mdef));
pline("%s %s...", buf,
canspotmon(mdef) ? mon_nam(mdef) : "something");
}
if (magr->mcan || !magr->mcansee || !mdef->mcansee
|| (magr->minvis && !perceives(mdef->data)) || mdef->msleeping) {
if (vis)
if (vis && canspotmon(mdef))
pline("but nothing happens.");
return MM_MISS;
}
@@ -689,8 +693,10 @@ register struct attack *mattk;
if (vis) {
/* 'it' -- previous form is no longer available and
using that would be excessively verbose */
pline("%s expels it.", Monnam(magr));
pline("It turns into %s.", a_monnam(mdef));
pline("%s expels %s.", Monnam(magr),
canspotmon(mdef) ? "it" : something);
if (canspotmon(mdef))
pline("It turns into %s.", a_monnam(mdef));
}
return MM_HIT; /* bypass mdamagem() */
}
@@ -806,7 +812,7 @@ register struct attack *mattk;
mon_to_stone(magr);
return MM_HIT; /* no damage during the polymorph */
}
if (vis)
if (vis && canspotmon(magr))
pline("%s turns to stone!", Monnam(magr));
monstone(magr);
if (magr->mhp > 0)
@@ -825,7 +831,7 @@ register struct attack *mattk;
case AD_DGST:
/* eating a Rider or its corpse is fatal */
if (is_rider(pd)) {
if (vis)
if (vis && canseemon(magr))
pline("%s %s!", Monnam(magr),
(pd == &mons[PM_FAMINE])
? "belches feebly, shrivels up and dies"
@@ -921,10 +927,10 @@ register struct attack *mattk;
tmp = 0;
break;
}
if (vis)
if (vis && canseemon(mdef))
pline("%s is %s!", Monnam(mdef), on_fire(pd, mattk));
if (pd == &mons[PM_STRAW_GOLEM] || pd == &mons[PM_PAPER_GOLEM]) {
if (vis)
if (vis && canseemon(mdef))
pline("%s burns completely!", Monnam(mdef));
mondied(mdef);
if (mdef->mhp > 0)
@@ -936,7 +942,7 @@ register struct attack *mattk;
tmp += destroy_mitem(mdef, SCROLL_CLASS, AD_FIRE);
tmp += destroy_mitem(mdef, SPBOOK_CLASS, AD_FIRE);
if (resists_fire(mdef)) {
if (vis)
if (vis && canseemon(mdef))
pline_The("fire doesn't seem to burn %s!", mon_nam(mdef));
shieldeff(mdef->mx, mdef->my);
golemeffects(mdef, AD_FIRE, tmp);
@@ -950,10 +956,10 @@ register struct attack *mattk;
tmp = 0;
break;
}
if (vis)
if (vis && canseemon(mdef))
pline("%s is covered in frost!", Monnam(mdef));
if (resists_cold(mdef)) {
if (vis)
if (vis && canseemon(mdef))
pline_The("frost doesn't seem to chill %s!", mon_nam(mdef));
shieldeff(mdef->mx, mdef->my);
golemeffects(mdef, AD_COLD, tmp);
@@ -966,11 +972,11 @@ register struct attack *mattk;
tmp = 0;
break;
}
if (vis)
if (vis && canseemon(mdef))
pline("%s gets zapped!", Monnam(mdef));
tmp += destroy_mitem(mdef, WAND_CLASS, AD_ELEC);
if (resists_elec(mdef)) {
if (vis)
if (vis && canseemon(mdef))
pline_The("zap doesn't shock %s!", mon_nam(mdef));
shieldeff(mdef->mx, mdef->my);
golemeffects(mdef, AD_ELEC, tmp);
@@ -985,11 +991,11 @@ register struct attack *mattk;
break;
}
if (resists_acid(mdef)) {
if (vis)
if (vis && canseemon(mdef))
pline("%s is covered in %s, but it seems harmless.",
Monnam(mdef), hliquid("acid"));
tmp = 0;
} else if (vis) {
} else if (vis && canseemon(mdef)) {
pline("%s is covered in %s!", Monnam(mdef), hliquid("acid"));
pline("It burns %s!", mon_nam(mdef));
}
@@ -1002,7 +1008,7 @@ register struct attack *mattk;
if (magr->mcan)
break;
if (pd == &mons[PM_IRON_GOLEM]) {
if (vis)
if (vis && canseemon(mdef))
pline("%s falls to pieces!", Monnam(mdef));
mondied(mdef);
if (mdef->mhp > 0)
@@ -1026,7 +1032,7 @@ register struct attack *mattk;
if (magr->mcan)
break;
if (pd == &mons[PM_WOOD_GOLEM] || pd == &mons[PM_LEATHER_GOLEM]) {
if (vis)
if (vis && canseemon(mdef))
pline("%s falls to pieces!", Monnam(mdef));
mondied(mdef);
if (mdef->mhp > 0)
@@ -1052,7 +1058,7 @@ register struct attack *mattk;
break;
}
if (!resists_ston(mdef)) {
if (vis)
if (vis && canseemon(mdef))
pline("%s turns to stone!", Monnam(mdef));
monstone(mdef);
post_stone:
@@ -1067,20 +1073,21 @@ register struct attack *mattk;
case AD_TLPT:
if (!cancelled && tmp < mdef->mhp && !tele_restrict(mdef)) {
char mdef_Monnam[BUFSZ];
boolean wasseen = canspotmon(mdef);
/* save the name before monster teleports, otherwise
we'll get "it" in the suddenly disappears message */
if (vis)
if (vis && wasseen)
Strcpy(mdef_Monnam, Monnam(mdef));
mdef->mstrategy &= ~STRAT_WAITFORU;
(void) rloc(mdef, TRUE);
if (vis && !canspotmon(mdef) && mdef != u.usteed)
if (vis && wasseen && !canspotmon(mdef) && mdef != u.usteed)
pline("%s suddenly disappears!", mdef_Monnam);
}
break;
case AD_SLEE:
if (!cancelled && !mdef->msleeping
&& sleep_monst(mdef, rnd(10), -1)) {
if (vis) {
if (vis && canspotmon(mdef)) {
Strcpy(buf, Monnam(mdef));
pline("%s is put to sleep by %s.", buf, mon_nam(magr));
}
@@ -1090,7 +1097,7 @@ register struct attack *mattk;
break;
case AD_PLYS:
if (!cancelled && mdef->mcanmove) {
if (vis) {
if (vis && canspotmon(mdef)) {
Strcpy(buf, Monnam(mdef));
pline("%s is frozen by %s.", buf, mon_nam(magr));
}
@@ -1103,7 +1110,7 @@ register struct attack *mattk;
mon_adjust_speed(mdef, -1, (struct obj *) 0);
mdef->mstrategy &= ~STRAT_WAITFORU;
if (mdef->mspeed != oldspeed && vis)
if (mdef->mspeed != oldspeed && vis && canspotmon(mdef))
pline("%s slows down.", Monnam(mdef));
}
break;
@@ -1113,7 +1120,7 @@ register struct attack *mattk;
* we still should check for it).
*/
if (!magr->mcan && !mdef->mconf && !magr->mspec_used) {
if (vis)
if (vis && canseemon(mdef))
pline("%s looks confused.", Monnam(mdef));
mdef->mconf = 1;
mdef->mstrategy &= ~STRAT_WAITFORU;
@@ -1123,7 +1130,7 @@ register struct attack *mattk;
if (can_blnd(magr, mdef, mattk->aatyp, (struct obj *) 0)) {
register unsigned rnd_tmp;
if (vis && mdef->mcansee)
if (vis && mdef->mcansee && canspotmon(mdef))
pline("%s is blinded.", Monnam(mdef));
rnd_tmp = d((int) mattk->damn, (int) mattk->damd);
if ((rnd_tmp += mdef->mblinded) > 127)
@@ -1136,7 +1143,7 @@ register struct attack *mattk;
break;
case AD_HALU:
if (!magr->mcan && haseyes(pd) && mdef->mcansee) {
if (vis)
if (vis && canseemon(mdef))
pline("%s looks %sconfused.", Monnam(mdef),
mdef->mconf ? "more " : "");
mdef->mconf = 1;
@@ -1153,7 +1160,7 @@ register struct attack *mattk;
if (is_were(pd) && pd->mlet != S_HUMAN)
were_change(mdef);
if (pd == &mons[PM_CLAY_GOLEM]) {
if (vis) {
if (vis && canseemon(mdef)) {
pline("Some writing vanishes from %s head!",
s_suffix(mon_nam(mdef)));
pline("%s is destroyed!", Monnam(mdef));
@@ -1169,7 +1176,7 @@ register struct attack *mattk;
if (!Deaf) {
if (!vis)
You_hear("laughter.");
else
else if (canseemon(magr))
pline("%s chuckles.", Monnam(magr));
}
}
@@ -1190,20 +1197,21 @@ register struct attack *mattk;
add_to_minv(magr, gold);
}
mdef->mstrategy &= ~STRAT_WAITFORU;
if (vis) {
if (vis && canseemon(mdef)) {
Strcpy(buf, Monnam(magr));
pline("%s steals some gold from %s.", buf, mon_nam(mdef));
}
if (!tele_restrict(magr)) {
boolean couldspot = canspotmon(magr);
(void) rloc(magr, TRUE);
if (vis && !canspotmon(magr))
if (vis && couldspot && !canspotmon(magr))
pline("%s suddenly disappears!", buf);
}
break;
case AD_DRLI:
if (!cancelled && !rn2(3) && !resists_drli(mdef)) {
tmp = d(2, 6);
if (vis)
if (vis && canspotmon(mdef))
pline("%s suddenly seems weaker!", Monnam(mdef));
mdef->mhpmax -= tmp;
if (mdef->m_lev == 0)
@@ -1247,7 +1255,7 @@ register struct attack *mattk;
if (vis)
Strcpy(onambuf, doname(otmp));
(void) add_to_minv(magr, otmp);
if (vis) {
if (vis && canseemon(mdef)) {
Strcpy(buf, Monnam(magr));
pline("%s steals %s from %s!", buf, onambuf, mdefnambuf);
}
@@ -1258,8 +1266,9 @@ register struct attack *mattk;
return (MM_DEF_DIED
| (grow_up(magr, mdef) ? 0 : MM_AGR_DIED));
if (pa->mlet == S_NYMPH && !tele_restrict(magr)) {
boolean couldspot = canspotmon(magr);
(void) rloc(magr, TRUE);
if (vis && !canspotmon(magr))
if (vis && couldspot && !canspotmon(magr))
pline("%s suddenly disappears!", buf);
}
}
@@ -1267,25 +1276,25 @@ register struct attack *mattk;
break;
case AD_DREN:
if (!cancelled && !rn2(4))
xdrainenergym(mdef, vis && mattk->aatyp != AT_ENGL);
xdrainenergym(mdef, vis && canspotmon(mdef) && mattk->aatyp != AT_ENGL);
tmp = 0;
break;
case AD_DRST:
case AD_DRDX:
case AD_DRCO:
if (!cancelled && !rn2(8)) {
if (vis)
if (vis && canspotmon(magr))
pline("%s %s was poisoned!", s_suffix(Monnam(magr)),
mpoisons_subj(magr, mattk));
if (resists_poison(mdef)) {
if (vis)
if (vis && canspotmon(mdef) && canspotmon(magr))
pline_The("poison doesn't seem to affect %s.",
mon_nam(mdef));
} else {
if (rn2(10))
tmp += rn1(10, 6);
else {
if (vis)
if (vis && canspotmon(mdef))
pline_The("poison was deadly...");
tmp = mdef->mhp;
}
@@ -1294,14 +1303,14 @@ register struct attack *mattk;
break;
case AD_DRIN:
if (notonhead || !has_head(pd)) {
if (vis)
if (vis && canspotmon(mdef))
pline("%s doesn't seem harmed.", Monnam(mdef));
/* Not clear what to do for green slimes */
tmp = 0;
break;
}
if ((mdef->misc_worn_check & W_ARMH) && rn2(8)) {
if (vis) {
if (vis && canspotmon(magr) && canseemon(mdef)) {
Strcpy(buf, s_suffix(Monnam(mdef)));
pline("%s helmet blocks %s attack to %s head.", buf,
s_suffix(mon_nam(magr)), mhis(mdef));
@@ -1315,7 +1324,7 @@ register struct attack *mattk;
break; /* physical damage only */
if (!rn2(4) && !slimeproof(pd)) {
if (!munslime(mdef, FALSE) && mdef->mhp > 0) {
if (newcham(mdef, &mons[PM_GREEN_SLIME], FALSE, vis))
if (newcham(mdef, &mons[PM_GREEN_SLIME], FALSE, vis && canseemon(mdef)))
pd = mdef->data;
mdef->mstrategy &= ~STRAT_WAITFORU;
res = MM_HIT;

View File

@@ -1768,6 +1768,23 @@ char **opp;
return FALSE;
}
/* Check if character c is illegal as a menu command key */
boolean
illegal_menu_cmd_key(c)
char c;
{
if (c == 0 || c == '\r' || c == '\n' || c == '\033'
|| c == ' ' || digit(c) || (letter(c) && c != '@'))
return TRUE;
else { /* reject default object class symbols */
int j;
for (j = 1; j < MAXOCLASSES; j++)
if (c == def_oc_syms[j].sym)
return TRUE;
}
return FALSE;
}
void
parseoptions(opts, tinitial, tfrom_file)
register char *opts;
@@ -2362,7 +2379,8 @@ boolean tinitial, tfrom_file;
return;
} else if ((op = string_for_env_opt(fullname, opts, FALSE)) != 0) {
static char gpcoords[] = { GPCOORDS_NONE, GPCOORDS_COMPASS,
GPCOORDS_MAP, GPCOORDS_SCREEN, '\0' };
GPCOORDS_COMFULL, GPCOORDS_MAP,
GPCOORDS_SCREEN, '\0' };
char c = lowc(*op);
if (c && index(gpcoords, c))
@@ -3225,22 +3243,11 @@ boolean tinitial, tfrom_file;
} else if ((op = string_for_opt(opts, FALSE)) != 0) {
int j;
char c, op_buf[BUFSZ];
boolean isbad = FALSE;
escapes(op, op_buf);
c = *op_buf;
if (c == 0 || c == '\r' || c == '\n' || c == '\033'
|| c == ' ' || digit(c) || (letter(c) && c != '@'))
isbad = TRUE;
else /* reject default object class symbols */
for (j = 1; j < MAXOCLASSES; j++)
if (c == def_oc_syms[i].sym) {
isbad = TRUE;
break;
}
if (isbad)
if (illegal_menu_cmd_key(c))
badoption(opts);
else
add_menu_cmd_alias(c, default_menu_cmd_info[i].cmd);
@@ -4104,6 +4111,10 @@ boolean setinitial, setfromfile;
add_menu(tmpwin, NO_GLYPH, &any, GPCOORDS_COMPASS,
0, ATR_NONE, "compass ('east' or '3s' or '2n,4w')",
(gp == GPCOORDS_COMPASS) ? MENU_SELECTED : MENU_UNSELECTED);
any.a_char = GPCOORDS_COMFULL;
add_menu(tmpwin, NO_GLYPH, &any, GPCOORDS_COMFULL,
0, ATR_NONE, "full compass ('east' or '3south' or '2north,4west')",
(gp == GPCOORDS_COMFULL) ? MENU_SELECTED : MENU_UNSELECTED);
any.a_char = GPCOORDS_MAP;
add_menu(tmpwin, NO_GLYPH, &any, GPCOORDS_MAP,
0, ATR_NONE, "map <x,y>",
@@ -4561,7 +4572,8 @@ boolean setinitial, setfromfile;
}
sl = sl->next;
}
end_menu(tmpwin, "Select symbol set:");
Sprintf(buf, "Select %ssymbol set:", rogueflag ? "rogue level " : "");
end_menu(tmpwin, buf);
if (select_menu(tmpwin, PICK_ONE, &symset_pick) > 0) {
chosen = symset_pick->item.a_int - 2;
free((genericptr_t) symset_pick);
@@ -4916,6 +4928,7 @@ char *buf;
Sprintf(buf, "%s",
(iflags.getpos_coords == GPCOORDS_MAP) ? "map"
: (iflags.getpos_coords == GPCOORDS_COMPASS) ? "compass"
: (iflags.getpos_coords == GPCOORDS_COMFULL) ? "full compass"
: (iflags.getpos_coords == GPCOORDS_SCREEN) ? "screen"
: "none");
} else if (!strcmp(optname, "scores")) {

View File

@@ -18,8 +18,17 @@ STATIC_DCL void FDECL(checkfile, (char *, struct permonst *,
BOOLEAN_P, BOOLEAN_P));
STATIC_DCL void FDECL(look_all, (BOOLEAN_P,BOOLEAN_P));
STATIC_DCL void NDECL(whatdoes_help);
STATIC_DCL boolean FDECL(help_menu, (int *));
STATIC_DCL void NDECL(docontact);
STATIC_DCL void NDECL(dispfile_help);
STATIC_DCL void NDECL(dispfile_shelp);
STATIC_DCL void NDECL(dispfile_optionfile);
STATIC_DCL void NDECL(dispfile_license);
STATIC_DCL void NDECL(dispfile_debughelp);
STATIC_DCL void NDECL(hmenu_doextversion);
STATIC_DCL void NDECL(hmenu_dohistory);
STATIC_DCL void NDECL(hmenu_dowhatis);
STATIC_DCL void NDECL(hmenu_dowhatdoes);
STATIC_DCL void NDECL(hmenu_doextlist);
#ifdef PORT_HELP
extern void NDECL(port_help);
#endif
@@ -53,6 +62,8 @@ const char *new_str;
return 0;
space_left = BUFSZ - strlen(buf) - 1;
if (space_left < 1)
return 0;
(void) strncat(buf, " or ", space_left);
(void) strncat(buf, new_str, space_left - 4);
return 1;
@@ -918,6 +929,10 @@ const char **firstmatch;
* If we are looking at the screen, follow multiple possibilities or
* an ambiguous explanation by something more detailed.
*/
if (found > 4)
Sprintf(out_str, "%s", "That can be many things");
didlook:
if (looked) {
if (found > 1 || need_to_look) {
@@ -943,12 +958,6 @@ const char **firstmatch;
return found;
}
/* getpos() return values */
#define LOOK_TRADITIONAL 0 /* '.' -- ask about "more info?" */
#define LOOK_QUICK 1 /* ',' -- skip "more info?" */
#define LOOK_ONCE 2 /* ';' -- skip and stop looping */
#define LOOK_VERBOSE 3 /* ':' -- show more info w/o asking */
/* also used by getpos hack in do_name.c */
const char what_is_an_unknown_object[] = "an unknown object";
@@ -1636,123 +1645,124 @@ docontact()
destroy_nhwindow(cwin);
}
/* data for help_menu() */
static const char *help_menu_items[] = {
/* 0*/ "About NetHack (version information).",
/* 1*/ "Long description of the game and commands.",
/* 2*/ "List of game commands.",
/* 3*/ "Concise history of NetHack.",
/* 4*/ "Info on a character in the game display.",
/* 5*/ "Info on what a given key does.",
/* 6*/ "List of game options.",
/* 7*/ "Longer explanation of game options.",
/* 8*/ "List of extended commands.",
/* 9*/ "The NetHack license.",
/* 10*/ "Support information.",
#ifdef PORT_HELP
"%s-specific help and commands.",
#define PORT_HELP_ID 100
#define WIZHLP_SLOT 12
#else
#define WIZHLP_SLOT 11
#endif
"List of wizard-mode commands.", "", (char *) 0
};
STATIC_OVL boolean
help_menu(sel)
int *sel;
void
dispfile_help()
{
winid tmpwin = create_nhwindow(NHW_MENU);
#ifdef PORT_HELP
char helpbuf[QBUFSZ];
#endif
int i, n;
menu_item *selected;
anything any;
any = zeroany; /* zero all bits */
start_menu(tmpwin);
if (!wizard)
help_menu_items[WIZHLP_SLOT] = "",
help_menu_items[WIZHLP_SLOT + 1] = (char *) 0;
for (i = 0; help_menu_items[i]; i++)
#ifdef PORT_HELP
/* port-specific line has a %s in it for the PORT_ID */
if (help_menu_items[i][0] == '%') {
Sprintf(helpbuf, help_menu_items[i], PORT_ID);
any.a_int = PORT_HELP_ID + 1;
add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, helpbuf,
MENU_UNSELECTED);
} else
#endif
{
any.a_int = (*help_menu_items[i]) ? i + 1 : 0;
add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE,
help_menu_items[i], MENU_UNSELECTED);
}
end_menu(tmpwin, "Select one item:");
n = select_menu(tmpwin, PICK_ONE, &selected);
destroy_nhwindow(tmpwin);
if (n > 0) {
*sel = selected[0].item.a_int - 1;
free((genericptr_t) selected);
return TRUE;
}
return FALSE;
display_file(HELP, TRUE);
}
void
dispfile_shelp()
{
display_file(SHELP, TRUE);
}
void
dispfile_optionfile()
{
display_file(OPTIONFILE, TRUE);
}
void
dispfile_license()
{
display_file(LICENSE, TRUE);
}
void
dispfile_debughelp()
{
display_file(DEBUGHELP, TRUE);
}
void
hmenu_doextversion()
{
(void) doextversion();
}
void
hmenu_dohistory()
{
(void) dohistory();
}
void
hmenu_dowhatis()
{
(void) dowhatis();
}
void
hmenu_dowhatdoes()
{
(void) dowhatdoes();
}
void
hmenu_doextlist()
{
(void) doextlist();
}
/* data for dohelp() */
static struct {
void (*f)();
const char *text;
} help_menu_items[] = {
{ hmenu_doextversion, "About NetHack (version information)." },
{ dispfile_help, "Long description of the game and commands." },
{ dispfile_shelp, "List of game commands." },
{ hmenu_dohistory, "Concise history of NetHack." },
{ hmenu_dowhatis, "Info on a character in the game display." },
{ hmenu_dowhatdoes, "Info on what a given key does." },
{ option_help, "List of game options." },
{ dispfile_optionfile, "Longer explanation of game options." },
{ hmenu_doextlist, "List of extended commands." },
{ dispfile_license, "The NetHack license." },
{ docontact, "Support information." },
#ifdef PORT_HELP
{ port_help, "%s-specific help and commands." },
#endif
{ dispfile_debughelp, "List of wizard-mode commands." },
{ NULL, (char *) 0 }
};
/* the '?' command */
int
dohelp()
{
int sel = 0;
winid tmpwin = create_nhwindow(NHW_MENU);
char helpbuf[QBUFSZ];
int i, n;
menu_item *selected;
anything any;
int sel;
char *bufptr;
if (help_menu(&sel)) {
switch (sel) {
case 0:
(void) doextversion();
break;
case 1:
display_file(HELP, TRUE);
break;
case 2:
display_file(SHELP, TRUE);
break;
case 3:
(void) dohistory();
break;
case 4:
(void) dowhatis();
break;
case 5:
(void) dowhatdoes();
break;
case 6:
option_help();
break;
case 7:
display_file(OPTIONFILE, TRUE);
break;
case 8:
(void) doextlist();
break;
case 9:
display_file(LICENSE, TRUE);
break;
case 10:
(void) docontact();
break;
#ifdef PORT_HELP
case PORT_HELP_ID:
port_help();
break;
#endif
default:
/* handle slot 11 or 12 */
display_file(DEBUGHELP, TRUE);
break;
any = zeroany; /* zero all bits */
start_menu(tmpwin);
for (i = 0; help_menu_items[i].text; i++) {
if (!wizard && help_menu_items[i].f == dispfile_debughelp)
continue;
if (help_menu_items[i].text[0] == '%') {
Sprintf(helpbuf, help_menu_items[i].text, PORT_ID);
bufptr = helpbuf;
} else {
bufptr = (char *)help_menu_items[i].text;
}
any.a_int = i + 1;
add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE,
bufptr, MENU_UNSELECTED);
}
end_menu(tmpwin, "Select one item:");
n = select_menu(tmpwin, PICK_ONE, &selected);
destroy_nhwindow(tmpwin);
if (n > 0) {
sel = selected[0].item.a_int - 1;
free((genericptr_t) selected);
(void)(*help_menu_items[sel].f)();
}
return 0;
}

View File

@@ -8,6 +8,7 @@
STATIC_DCL void NDECL(stoned_dialogue);
STATIC_DCL void NDECL(vomiting_dialogue);
STATIC_DCL void NDECL(choke_dialogue);
STATIC_DCL void NDECL(levitation_dialogue);
STATIC_DCL void NDECL(slime_dialogue);
STATIC_DCL void NDECL(slip_or_trip);
STATIC_DCL void FDECL(see_lamp_flicker, (struct obj *, const char *));
@@ -122,14 +123,18 @@ vomiting_dialogue()
}
static NEARDATA const char *const choke_texts[] = {
"You find it hard to breathe.", "You're gasping for air.",
"You can no longer breathe.", "You're turning %s.", "You suffocate."
"You find it hard to breathe.",
"You're gasping for air.",
"You can no longer breathe.",
"You're turning %s.",
"You suffocate."
};
static NEARDATA const char *const choke_texts2[] = {
"Your %s is becoming constricted.",
"Your blood is having trouble reaching your brain.",
"The pressure on your %s increases.", "Your consciousness is fading.",
"The pressure on your %s increases.",
"Your consciousness is fading.",
"You suffocate."
};
@@ -153,6 +158,36 @@ choke_dialogue()
exercise(A_STR, FALSE);
}
static NEARDATA const char *const levi_texts[] = {
"You float slightly lower.",
"You wobble unsteadily %s the %s."
};
STATIC_OVL void
levitation_dialogue()
{
/* -1 because the last message comes via float_down() */
long i = (((HLevitation & TIMEOUT) - 1L) / 2L);
if (ELevitation)
return;
if (!ACCESSIBLE(levl[u.ux][u.uy].typ)
&& !is_pool_or_lava(u.ux,u.uy))
return;
if (((HLevitation & TIMEOUT) % 2L) && i > 0L && i <= SIZE(levi_texts)) {
const char *s = levi_texts[SIZE(levi_texts) - i];
if (index(s, '%')) {
boolean danger = is_pool_or_lava(u.ux, u.uy)
&& !Is_waterlevel(&u.uz);
pline(s, danger ? "over" : "in",
danger ? surface(u.ux, u.uy) : "air");
} else
pline1(s);
}
}
static NEARDATA const char *const slime_texts[] = {
"You are turning a little %s.", /* 5 */
"Your limbs are getting oozy.", /* 4 */
@@ -238,6 +273,8 @@ nh_timeout()
vomiting_dialogue();
if (Strangled)
choke_dialogue();
if (Levitation)
levitation_dialogue();
if (u.mtimedone && !--u.mtimedone) {
if (Unchanging)
u.mtimedone = rnd(100 * youmonst.data->mlevel + 1);
@@ -1453,6 +1490,26 @@ timer_element *base;
}
}
static boolean print_prop_header = TRUE;
void
print_prop(win, text, prop)
winid win;
const char *text;
long prop;
{
char buf[BUFSZ];
if (prop & TIMEOUT) {
if (print_prop_header) {
putstr(win, 0, "");
putstr(win, 0, "Properties:");
putstr(win, 0, "");
print_prop_header = FALSE;
}
Sprintf(buf, " %10s: %ld", text, (prop & TIMEOUT));
putstr(win, 0, buf);
}
}
int
wiz_timeout_queue()
{
@@ -1470,6 +1527,13 @@ wiz_timeout_queue()
putstr(win, 0, "");
print_queue(win, timer_base);
print_prop_header = TRUE;
print_prop(win, "Levitation", HLevitation);
print_prop(win, "Stoned", Stoned);
print_prop(win, "Vomiting", Vomiting);
print_prop(win, "Strangled", Strangled);
print_prop(win, "Slimed", Slimed);
display_nhwindow(win, FALSE);
destroy_nhwindow(win);