Merge remote-tracking branch 'origin/NetHack-3.6.0'
This commit is contained in:
+83
-58
@@ -13,6 +13,7 @@
|
||||
#ifdef POSITIONBAR
|
||||
STATIC_DCL void NDECL(do_positionbar);
|
||||
#endif
|
||||
STATIC_DCL void FDECL(regen_hp, (int));
|
||||
STATIC_DCL void FDECL(interrupt_multi, (const char *));
|
||||
|
||||
void
|
||||
@@ -185,66 +186,20 @@ boolean resuming;
|
||||
|
||||
/* One possible result of prayer is healing. Whether or
|
||||
* not you get healed depends on your current hit points.
|
||||
* If you are allowed to regenerate during the prayer, the
|
||||
* end-of-prayer calculation messes up on this.
|
||||
* If you are allowed to regenerate during the prayer,
|
||||
* the end-of-prayer calculation messes up on this.
|
||||
* Another possible result is rehumanization, which
|
||||
* requires
|
||||
* that encumbrance and movement rate be recalculated.
|
||||
* requires that encumbrance and movement rate be
|
||||
* recalculated.
|
||||
*/
|
||||
if (u.uinvulnerable) {
|
||||
/* for the moment at least, you're in tiptop shape */
|
||||
wtcap = UNENCUMBERED;
|
||||
} else if (Upolyd && youmonst.data->mlet == S_EEL
|
||||
&& !is_pool(u.ux, u.uy)
|
||||
&& !Is_waterlevel(&u.uz)) {
|
||||
/* eel out of water loses hp, same as for monsters;
|
||||
as hp gets lower, rate of further loss slows down
|
||||
*/
|
||||
if (u.mh > 1 && rn2(u.mh) > rn2(8)
|
||||
&& (!Half_physical_damage || !(moves % 2L))) {
|
||||
u.mh--;
|
||||
context.botl = 1;
|
||||
} else if (u.mh < 1)
|
||||
rehumanize();
|
||||
} else if (Upolyd && u.mh < u.mhmax) {
|
||||
if (u.mh < 1)
|
||||
rehumanize();
|
||||
else if (Regeneration
|
||||
|| (wtcap < MOD_ENCUMBER && !(moves % 20))) {
|
||||
context.botl = 1;
|
||||
u.mh++;
|
||||
if (u.mh >= u.mhmax)
|
||||
interrupt_multi("You are in full health.");
|
||||
}
|
||||
} else if (u.uhp < u.uhpmax
|
||||
&& (wtcap < MOD_ENCUMBER || !u.umoved
|
||||
|| Regeneration)) {
|
||||
if (u.ulevel > 9 && !(moves % 3)) {
|
||||
int heal, Con = (int) ACURR(A_CON);
|
||||
|
||||
if (Con <= 12) {
|
||||
heal = 1;
|
||||
} else {
|
||||
heal = rnd(Con);
|
||||
if (heal > u.ulevel - 9)
|
||||
heal = u.ulevel - 9;
|
||||
}
|
||||
context.botl = 1;
|
||||
u.uhp += heal;
|
||||
if (u.uhp > u.uhpmax)
|
||||
u.uhp = u.uhpmax;
|
||||
if (u.uhp >= u.uhpmax)
|
||||
interrupt_multi("You are in full health.");
|
||||
} else if (Regeneration
|
||||
|| (u.ulevel <= 9
|
||||
&& !(moves
|
||||
% ((MAXULEV + 12) / (u.ulevel + 2)
|
||||
+ 1)))) {
|
||||
context.botl = 1;
|
||||
u.uhp++;
|
||||
if (u.uhp >= u.uhpmax)
|
||||
interrupt_multi("You are in full health.");
|
||||
}
|
||||
} else if (!Upolyd ? (u.uhp < u.uhpmax)
|
||||
: (u.mh < u.mhmax
|
||||
|| youmonst.data->mlet == S_EEL)) {
|
||||
/* maybe heal */
|
||||
regen_hp(wtcap);
|
||||
}
|
||||
|
||||
/* moving around while encumbered is hard work */
|
||||
@@ -263,7 +218,7 @@ boolean resuming;
|
||||
}
|
||||
}
|
||||
|
||||
if ((u.uen < u.uenmax)
|
||||
if (u.uen < u.uenmax
|
||||
&& ((wtcap < MOD_ENCUMBER
|
||||
&& (!(moves % ((MAXULEV + 8 - u.ulevel)
|
||||
* (Role_if(PM_WIZARD) ? 3 : 4)
|
||||
@@ -273,7 +228,7 @@ boolean resuming;
|
||||
if (u.uen > u.uenmax)
|
||||
u.uen = u.uenmax;
|
||||
context.botl = 1;
|
||||
if (u.uen >= u.uenmax)
|
||||
if (u.uen == u.uenmax)
|
||||
interrupt_multi("You feel full of energy.");
|
||||
}
|
||||
|
||||
@@ -493,6 +448,76 @@ boolean resuming;
|
||||
}
|
||||
}
|
||||
|
||||
/* maybe recover some lost health (or lose some when an eel out of water) */
|
||||
STATIC_OVL void
|
||||
regen_hp(wtcap)
|
||||
int wtcap;
|
||||
{
|
||||
int heal = 0;
|
||||
boolean reached_full = FALSE,
|
||||
encumbrance_ok = (wtcap < MOD_ENCUMBER || !u.umoved);
|
||||
|
||||
if (Upolyd) {
|
||||
if (u.mh < 1) { /* shouldn't happen... */
|
||||
rehumanize();
|
||||
} else if (youmonst.data->mlet == S_EEL
|
||||
&& !is_pool(u.ux, u.uy) && !Is_waterlevel(&u.uz)) {
|
||||
/* eel out of water loses hp, similar to monster eels;
|
||||
as hp gets lower, rate of further loss slows down */
|
||||
if (u.mh > 1 && !Regeneration && rn2(u.mh) > rn2(8)
|
||||
&& (!Half_physical_damage || !(moves % 2L)))
|
||||
heal = -1;
|
||||
} else if (u.mh < u.mhmax) {
|
||||
if (Regeneration || (encumbrance_ok && !(moves % 20L)))
|
||||
heal = 1;
|
||||
}
|
||||
if (heal) {
|
||||
context.botl = 1;
|
||||
u.mh += heal;
|
||||
reached_full = (u.mh == u.mhmax);
|
||||
}
|
||||
|
||||
/* !Upolyd */
|
||||
} else {
|
||||
/* [when this code was in-line within moveloop(), there was
|
||||
no !Upolyd check here, so poly'd hero recovered lost u.uhp
|
||||
once u.mh reached u.mhmax; that may have been convenient
|
||||
for the player, but it didn't make sense for gameplay...] */
|
||||
if (u.uhp < u.uhpmax && (encumbrance_ok || Regeneration)) {
|
||||
if (u.ulevel > 9) {
|
||||
if (!(moves % 3L)) {
|
||||
int Con = (int) ACURR(A_CON);
|
||||
|
||||
if (Con <= 12) {
|
||||
heal = 1;
|
||||
} else {
|
||||
heal = rnd(Con);
|
||||
if (heal > u.ulevel - 9)
|
||||
heal = u.ulevel - 9;
|
||||
}
|
||||
}
|
||||
} else { /* u.ulevel <= 9 */
|
||||
if (!(moves % (long) ((MAXULEV + 12) / (u.ulevel + 2) + 1)))
|
||||
heal = 1;
|
||||
}
|
||||
if (Regeneration && !heal)
|
||||
heal = 1;
|
||||
|
||||
if (heal) {
|
||||
context.botl = 1;
|
||||
u.uhp += heal;
|
||||
if (u.uhp > u.uhpmax)
|
||||
u.uhp = u.uhpmax;
|
||||
/* stop voluntary multi-turn activity if now fully healed */
|
||||
reached_full = (u.uhp == u.uhpmax);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (reached_full)
|
||||
interrupt_multi("You are in full health.");
|
||||
}
|
||||
|
||||
void
|
||||
stop_occupation()
|
||||
{
|
||||
@@ -561,7 +586,7 @@ newgame()
|
||||
context.tribute.enabled = TRUE; /* turn on 3.6 tributes */
|
||||
context.tribute.tributesz = sizeof(struct tribute_info);
|
||||
|
||||
for (i = 0; i < NUMMONS; i++)
|
||||
for (i = LOW_PM; i < NUMMONS; i++)
|
||||
mvitals[i].mvflags = mons[i].geno & G_NOCORPSE;
|
||||
|
||||
init_objects(); /* must be before u_init() */
|
||||
|
||||
+24
-8
@@ -445,6 +445,8 @@ struct obj *obj;
|
||||
} else {
|
||||
You(whistle_str, obj->cursed ? "shrill" : "high");
|
||||
wake_nearby();
|
||||
if (obj->cursed)
|
||||
vault_summon_gd();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1564,6 +1566,15 @@ boolean showmsg;
|
||||
|
||||
static int jumping_is_magic;
|
||||
|
||||
boolean
|
||||
get_valid_jump_position(x,y)
|
||||
int x,y;
|
||||
{
|
||||
return (isok(x, y)
|
||||
&& (ACCESSIBLE(levl[x][y].typ) || Passes_walls)
|
||||
&& is_valid_jump_pos(x, y, jumping_is_magic, FALSE));
|
||||
}
|
||||
|
||||
void
|
||||
display_jump_positions(state)
|
||||
int state;
|
||||
@@ -1577,9 +1588,7 @@ int state;
|
||||
for (dy = -4; dy <= 4; dy++) {
|
||||
x = dx + (int) u.ux;
|
||||
y = dy + (int) u.uy;
|
||||
if (isok(x, y)
|
||||
&& (ACCESSIBLE(levl[x][y].typ) || Passes_walls)
|
||||
&& is_valid_jump_pos(x, y, jumping_is_magic, FALSE))
|
||||
if (get_valid_jump_position(x, y))
|
||||
tmp_at(x, y);
|
||||
}
|
||||
} else {
|
||||
@@ -1678,7 +1687,7 @@ int magic; /* 0=Physical, otherwise skill level */
|
||||
cc.x = u.ux;
|
||||
cc.y = u.uy;
|
||||
jumping_is_magic = magic;
|
||||
getpos_sethilite(display_jump_positions);
|
||||
getpos_sethilite(display_jump_positions, get_valid_jump_position);
|
||||
if (getpos(&cc, TRUE, "the desired position") < 0)
|
||||
return 0; /* user pressed ESC */
|
||||
if (!is_valid_jump_pos(cc.x, cc.y, magic, TRUE)) {
|
||||
@@ -2851,6 +2860,15 @@ int min_range, max_range;
|
||||
static int polearm_range_min = -1;
|
||||
static int polearm_range_max = -1;
|
||||
|
||||
boolean
|
||||
get_valid_polearm_position(x,y)
|
||||
int x,y;
|
||||
{
|
||||
return (isok(x, y) && ACCESSIBLE(levl[x][y].typ)
|
||||
&& distu(x, y) >= polearm_range_min
|
||||
&& distu(x, y) <= polearm_range_max);
|
||||
}
|
||||
|
||||
void
|
||||
display_polearm_positions(state)
|
||||
int state;
|
||||
@@ -2864,9 +2882,7 @@ int state;
|
||||
for (dy = -4; dy <= 4; dy++) {
|
||||
x = dx + (int) u.ux;
|
||||
y = dy + (int) u.uy;
|
||||
if (isok(x, y) && ACCESSIBLE(levl[x][y].typ)
|
||||
&& distu(x, y) >= polearm_range_min
|
||||
&& distu(x, y) <= polearm_range_max) {
|
||||
if (get_valid_polearm_position(x, y)) {
|
||||
tmp_at(x, y);
|
||||
}
|
||||
}
|
||||
@@ -2936,7 +2952,7 @@ struct obj *obj;
|
||||
cc.x = hitm->mx;
|
||||
cc.y = hitm->my;
|
||||
}
|
||||
getpos_sethilite(display_polearm_positions);
|
||||
getpos_sethilite(display_polearm_positions, get_valid_polearm_position);
|
||||
if (getpos(&cc, TRUE, "the spot to hit") < 0)
|
||||
return res; /* ESC; uses turn iff polearm became wielded */
|
||||
|
||||
|
||||
+20
-16
@@ -498,7 +498,7 @@ long wp_mask;
|
||||
for (obj = invent; obj; obj = obj->nobj) {
|
||||
if (obj != otmp && obj->oartifact) {
|
||||
art = get_artifact(obj);
|
||||
if (art->cary.adtyp == dtyp) {
|
||||
if (art && art->cary.adtyp == dtyp) {
|
||||
mask = (long *) 0;
|
||||
break;
|
||||
}
|
||||
@@ -519,7 +519,8 @@ long wp_mask;
|
||||
for (obj = invent; obj; obj = obj->nobj)
|
||||
if (obj != otmp && obj->oartifact) {
|
||||
art = get_artifact(obj);
|
||||
spfx &= ~art->cspfx;
|
||||
if (art)
|
||||
spfx &= ~art->cspfx;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -653,16 +654,17 @@ struct monst *mon;
|
||||
return 1;
|
||||
|
||||
yours = (mon == &youmonst);
|
||||
/* all quest artifacts are self-willed; it this ever changes, `badclass'
|
||||
/* all quest artifacts are self-willed; if this ever changes, `badclass'
|
||||
will have to be extended to explicitly include quest artifacts */
|
||||
self_willed = ((oart->spfx & SPFX_INTEL) != 0);
|
||||
if (yours) {
|
||||
badclass = self_willed
|
||||
&& ((oart->role != NON_PM && !Role_if(oart->role))
|
||||
|| (oart->race != NON_PM && !Race_if(oart->race)));
|
||||
badalign =
|
||||
(oart->spfx & SPFX_RESTR) && oart->alignment != A_NONE
|
||||
&& (oart->alignment != u.ualign.type || u.ualign.record < 0);
|
||||
badalign = ((oart->spfx & SPFX_RESTR) != 0
|
||||
&& oart->alignment != A_NONE
|
||||
&& (oart->alignment != u.ualign.type
|
||||
|| u.ualign.record < 0));
|
||||
} else if (!is_covetous(mon->data) && !is_mplayer(mon->data)) {
|
||||
badclass = self_willed && oart->role != NON_PM
|
||||
&& oart != &artilist[ART_EXCALIBUR];
|
||||
@@ -1493,8 +1495,8 @@ struct obj *obj;
|
||||
obj->age = 0;
|
||||
return 0;
|
||||
}
|
||||
b_effect =
|
||||
obj->blessed && (Role_switch == oart->role || !oart->role);
|
||||
b_effect = (obj->blessed
|
||||
&& (Role_switch == oart->role || !oart->role));
|
||||
recharge(otmp, b_effect ? 1 : obj->cursed ? -1 : 0);
|
||||
update_inventory();
|
||||
break;
|
||||
@@ -1583,9 +1585,8 @@ struct obj *obj;
|
||||
} else
|
||||
otmp->quan += rnd(5);
|
||||
otmp->owt = weight(otmp);
|
||||
otmp =
|
||||
hold_another_object(otmp, "Suddenly %s out.",
|
||||
aobjnam(otmp, "fall"), (const char *) 0);
|
||||
otmp = hold_another_object(otmp, "Suddenly %s out.",
|
||||
aobjnam(otmp, "fall"), (char *) 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1883,12 +1884,11 @@ boolean loseit; /* whether to drop it if hero can longer touch it */
|
||||
if (touch_artifact(obj, &youmonst)) {
|
||||
char buf[BUFSZ];
|
||||
int dmg = 0, tmp;
|
||||
boolean ag =
|
||||
(objects[obj->otyp].oc_material == SILVER && Hate_silver),
|
||||
boolean ag = (objects[obj->otyp].oc_material == SILVER && Hate_silver),
|
||||
bane = bane_applies(get_artifact(obj), &youmonst);
|
||||
|
||||
/* nothing else to do if hero can successfully handle this object */
|
||||
if (!ag && !bane && !touch_blasted)
|
||||
if (!ag && !bane)
|
||||
return 1;
|
||||
|
||||
/* hero can't handle this object, but didn't get touch_artifact()'s
|
||||
@@ -2008,11 +2008,15 @@ int dropflag; /* 0==don't drop, 1==drop all, 2==drop weapon */
|
||||
|
||||
dropit = (dropflag > 0); /* drop all or drop weapon */
|
||||
/* check secondary weapon first, before possibly unwielding primary */
|
||||
if (u.twoweap)
|
||||
if (u.twoweap) {
|
||||
bypass_obj(uswapwep); /* so loop below won't process it again */
|
||||
(void) untouchable(uswapwep, dropit);
|
||||
}
|
||||
/* check primary weapon next so that they're handled together */
|
||||
if (uwep)
|
||||
if (uwep) {
|
||||
bypass_obj(uwep); /* so loop below won't process it again */
|
||||
(void) untouchable(uwep, dropit);
|
||||
}
|
||||
|
||||
/* in case someone is daft enough to add artifact or silver saddle */
|
||||
if (u.usteed && (obj = which_armor(u.usteed, W_SADDLE)) != 0) {
|
||||
|
||||
+3
-7
@@ -48,14 +48,10 @@ STATIC_OVL void
|
||||
goodfruit(id)
|
||||
int id;
|
||||
{
|
||||
register struct fruit *f;
|
||||
struct fruit *f = fruit_from_indx(-id);
|
||||
|
||||
for (f = ffruit; f; f = f->nextf) {
|
||||
if (f->fid == -id) {
|
||||
f->fid = id;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (f)
|
||||
f->fid = id;
|
||||
}
|
||||
|
||||
STATIC_OVL void
|
||||
|
||||
+23
-21
@@ -13,6 +13,25 @@ const char *const enc_stat[] = { "", "Burdened", "Stressed",
|
||||
STATIC_OVL NEARDATA int mrank_sz = 0; /* loaded by max_rank_sz (from u_init) */
|
||||
STATIC_DCL const char *NDECL(rank);
|
||||
|
||||
static char *
|
||||
get_strength_str()
|
||||
{
|
||||
static char buf[32];
|
||||
int st = ACURR(A_STR);
|
||||
|
||||
if (st > 18) {
|
||||
if (st > STR18(100))
|
||||
Sprintf(buf, "%2d", st - 100);
|
||||
else if (st < STR18(100))
|
||||
Sprintf(buf, "18/%02d", st - 18);
|
||||
else
|
||||
Sprintf(buf, "18/**");
|
||||
} else
|
||||
Sprintf(buf, "%-1d", st);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
#if !defined(STATUS_VIA_WINDOWPORT) || defined(DUMPLOG)
|
||||
|
||||
char *
|
||||
@@ -48,16 +67,9 @@ do_statusline1()
|
||||
j = (int) ((nb + 2) - newbot1); /* strlen(newbot1) but less computation */
|
||||
if ((i - j) > 0)
|
||||
Sprintf(nb = eos(nb), "%*s", i - j, " "); /* pad with spaces */
|
||||
if (ACURR(A_STR) > 18) {
|
||||
if (ACURR(A_STR) > STR18(100))
|
||||
Sprintf(nb = eos(nb), "St:%2d ", ACURR(A_STR) - 100);
|
||||
else if (ACURR(A_STR) < STR18(100))
|
||||
Sprintf(nb = eos(nb), "St:18/%02d ", ACURR(A_STR) - 18);
|
||||
else
|
||||
Sprintf(nb = eos(nb), "St:18/** ");
|
||||
} else
|
||||
Sprintf(nb = eos(nb), "St:%-1d ", ACURR(A_STR));
|
||||
Sprintf(nb = eos(nb), "Dx:%-1d Co:%-1d In:%-1d Wi:%-1d Ch:%-1d",
|
||||
|
||||
Sprintf(nb = eos(nb), "St:%s Dx:%-1d Co:%-1d In:%-1d Wi:%-1d Ch:%-1d",
|
||||
get_strength_str(),
|
||||
ACURR(A_DEX), ACURR(A_CON), ACURR(A_INT), ACURR(A_WIS),
|
||||
ACURR(A_CHA));
|
||||
Sprintf(nb = eos(nb),
|
||||
@@ -470,18 +482,8 @@ bot()
|
||||
valset[BL_TITLE] = TRUE; /* indicate val already set */
|
||||
|
||||
/* Strength */
|
||||
buf[0] = '\0';
|
||||
blstats[idx][BL_STR].a.a_int = ACURR(A_STR);
|
||||
if (ACURR(A_STR) > 18) {
|
||||
if (ACURR(A_STR) > STR18(100))
|
||||
Sprintf(buf, "%2d", ACURR(A_STR) - 100);
|
||||
else if (ACURR(A_STR) < STR18(100))
|
||||
Sprintf(buf, "18/%02d", ACURR(A_STR) - 18);
|
||||
else
|
||||
Sprintf(buf, "18/**");
|
||||
} else
|
||||
Sprintf(buf, "%-1d", ACURR(A_STR));
|
||||
Strcpy(blstats[idx][BL_STR].val, buf);
|
||||
Strcpy(blstats[idx][BL_STR].val, get_strength_str());
|
||||
valset[BL_STR] = TRUE; /* indicate val already set */
|
||||
|
||||
/* Dexterity, constitution, intelligence, wisdom, charisma. */
|
||||
|
||||
@@ -135,6 +135,7 @@ STATIC_PTR int NDECL(wiz_level_change);
|
||||
STATIC_PTR int NDECL(wiz_show_seenv);
|
||||
STATIC_PTR int NDECL(wiz_show_vision);
|
||||
STATIC_PTR int NDECL(wiz_smell);
|
||||
STATIC_PTR int NDECL(wiz_intrinsic);
|
||||
STATIC_PTR int NDECL(wiz_mon_polycontrol);
|
||||
STATIC_PTR int NDECL(wiz_show_wmodes);
|
||||
STATIC_DCL void NDECL(wiz_map_levltyp);
|
||||
@@ -1157,38 +1158,52 @@ STATIC_PTR int
|
||||
wiz_intrinsic(VOID_ARGS)
|
||||
{
|
||||
if (wizard) {
|
||||
extern const char *const propertynames[]; /* timeout.c */
|
||||
extern const struct propname {
|
||||
int prop_num;
|
||||
const char *prop_name;
|
||||
} propertynames[]; /* timeout.c */
|
||||
static const char wizintrinsic[] = "#wizintrinsic";
|
||||
static const char fmt[] = "You are%s %s.";
|
||||
winid win;
|
||||
anything any;
|
||||
char buf[BUFSZ];
|
||||
int i, n, p, amt, typ;
|
||||
int i, j, n, p, amt, typ;
|
||||
long oldtimeout, newtimeout;
|
||||
const char *propname;
|
||||
menu_item *pick_list = (menu_item *) 0;
|
||||
|
||||
any = zeroany;
|
||||
win = create_nhwindow(NHW_MENU);
|
||||
start_menu(win);
|
||||
|
||||
for (i = 1; (propname = propertynames[i]) != 0; ++i) {
|
||||
if (i == HALLUC_RES) {
|
||||
for (i = 0; (propname = propertynames[i].prop_name) != 0; ++i) {
|
||||
p = propertynames[i].prop_num;
|
||||
if (p == HALLUC_RES) {
|
||||
/* Grayswandir vs hallucination; ought to be redone to
|
||||
use u.uprops[HALLUC].blocked instead of being treated
|
||||
as a separate property; letting in be manually toggled
|
||||
even only in wizard mode would be asking for trouble... */
|
||||
continue;
|
||||
}
|
||||
any.a_int = i;
|
||||
add_menu(win, NO_GLYPH, &any, 0, 0, ATR_NONE, propname, FALSE);
|
||||
if (p == FIRE_RES) {
|
||||
any.a_int = 0;
|
||||
add_menu(win, NO_GLYPH, &any, 0, 0, ATR_NONE, "--", FALSE);
|
||||
}
|
||||
any.a_int = i + 1; /* +1: avoid 0 */
|
||||
oldtimeout = u.uprops[p].intrinsic & TIMEOUT;
|
||||
if (oldtimeout)
|
||||
Sprintf(buf, "%-27s [%li]", propname, oldtimeout);
|
||||
else
|
||||
Sprintf(buf, "%s", propname);
|
||||
add_menu(win, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
|
||||
}
|
||||
end_menu(win, "Which intrinsics?");
|
||||
n = select_menu(win, PICK_ANY, &pick_list);
|
||||
destroy_nhwindow(win);
|
||||
|
||||
amt = 30; /* TODO: prompt for duration */
|
||||
for (i = 0; i < n; ++i) {
|
||||
p = pick_list[i].item.a_int;
|
||||
for (j = 0; j < n; ++j) {
|
||||
i = pick_list[j].item.a_int - 1; /* -1: reverse +1 above */
|
||||
p = propertynames[i].prop_num;
|
||||
oldtimeout = u.uprops[p].intrinsic & TIMEOUT;
|
||||
newtimeout = oldtimeout + (long) amt;
|
||||
switch (p) {
|
||||
@@ -1204,9 +1219,12 @@ wiz_intrinsic(VOID_ARGS)
|
||||
case BLINDED:
|
||||
make_blinded(newtimeout, TRUE);
|
||||
break;
|
||||
#if 0 /* make_confused() only gives feedback when confusion is
|
||||
* ending so use the 'default' case for it instead */
|
||||
case CONFUSION:
|
||||
make_confused(newtimeout, TRUE);
|
||||
break;
|
||||
#endif /*0*/
|
||||
case DEAF:
|
||||
make_deaf(newtimeout, TRUE);
|
||||
break;
|
||||
@@ -1236,7 +1254,7 @@ wiz_intrinsic(VOID_ARGS)
|
||||
pline1(buf);
|
||||
break;
|
||||
default:
|
||||
pline("Timeout for %s %s %d.", propertynames[p],
|
||||
pline("Timeout for %s %s %d.", propertynames[i].prop_name,
|
||||
oldtimeout ? "increased by" : "set to", amt);
|
||||
incr_itimeout(&u.uprops[p].intrinsic, amt);
|
||||
break;
|
||||
@@ -2458,14 +2476,15 @@ int final;
|
||||
/* named fruit debugging (doesn't really belong here...); to enable,
|
||||
include 'fruit' in DEBUGFILES list (even though it isn't a file...) */
|
||||
if (wizard && explicitdebug("fruit")) {
|
||||
int fcount = 0;
|
||||
struct fruit *f;
|
||||
char buf2[BUFSZ];
|
||||
|
||||
reorder_fruit(TRUE); /* sort by fruit index, from low to high;
|
||||
* this modifies the ffruit chain, so could
|
||||
* possibly mask or even introduce a problem,
|
||||
* but it does useful sanity checking */
|
||||
for (f = ffruit; f; f = f->nextf) {
|
||||
Sprintf(buf, "Fruit %d ", ++fcount);
|
||||
Sprintf(buf2, "%s (id %d)", f->fname, f->fid);
|
||||
enl_msg(buf, "is ", "was ", buf2, "");
|
||||
Sprintf(buf, "Fruit #%d ", f->fid);
|
||||
enl_msg(buf, "is ", "was ", f->fname, "");
|
||||
}
|
||||
enl_msg("The current fruit ", "is ", "was ", pl_fruit, "");
|
||||
Sprintf(buf, "%d", flags.made_fruit);
|
||||
@@ -3724,10 +3743,13 @@ struct {
|
||||
{ NHKF_GETPOS_DOOR_PREV, 'D', "getpos.door.prev" },
|
||||
{ NHKF_GETPOS_UNEX_NEXT, 'x', "getpos.unexplored.next" },
|
||||
{ NHKF_GETPOS_UNEX_PREV, 'X', "getpos.unexplored.prev" },
|
||||
{ NHKF_GETPOS_VALID_NEXT, 'z', "getpos.valid.next" },
|
||||
{ NHKF_GETPOS_VALID_PREV, 'Z', "getpos.valid.prev" },
|
||||
{ NHKF_GETPOS_INTERESTING_NEXT, 'a', "getpos.all.next" },
|
||||
{ NHKF_GETPOS_INTERESTING_PREV, 'A', "getpos.all.prev" },
|
||||
{ NHKF_GETPOS_HELP, '?', "getpos.help" },
|
||||
{ NHKF_GETPOS_LIMITVIEW, '"', "getpos.inview" },
|
||||
{ NHKF_GETPOS_LIMITVIEW, '"', "getpos.filter" },
|
||||
{ NHKF_GETPOS_MOVESKIP, '*', "getpos.moveskip" },
|
||||
{ NHKF_GETPOS_MENU, '!', "getpos.menu" }
|
||||
};
|
||||
|
||||
@@ -5016,10 +5038,14 @@ dotravel(VOID_ARGS)
|
||||
}
|
||||
iflags.getloc_travelmode = TRUE;
|
||||
if (iflags.menu_requested) {
|
||||
if (!getpos_menu(&cc, TRUE, GLOC_INTERESTING)) {
|
||||
int gf = iflags.getloc_filter;
|
||||
iflags.getloc_filter = GFILTER_VIEW;
|
||||
if (!getpos_menu(&cc, GLOC_INTERESTING)) {
|
||||
iflags.getloc_filter = gf;
|
||||
iflags.getloc_travelmode = FALSE;
|
||||
return 0;
|
||||
}
|
||||
iflags.getloc_filter = gf;
|
||||
} else {
|
||||
pline("Where do you want to travel to?");
|
||||
if (getpos(&cc, TRUE, "the desired destination") < 0) {
|
||||
|
||||
+178
-20
@@ -36,12 +36,15 @@ nextmbuf()
|
||||
* parameter value 0 = initialize, 1 = highlight, 2 = done
|
||||
*/
|
||||
static void FDECL((*getpos_hilitefunc), (int)) = (void FDECL((*), (int))) 0;
|
||||
static boolean FDECL((*getpos_getvalid), (int,int)) = (boolean FDECL((*), (int,int))) 0;
|
||||
|
||||
void
|
||||
getpos_sethilite(f)
|
||||
getpos_sethilite(f, d)
|
||||
void FDECL((*f), (int));
|
||||
boolean FDECL((*d), (int,int));
|
||||
{
|
||||
getpos_hilitefunc = f;
|
||||
getpos_getvalid = d;
|
||||
}
|
||||
|
||||
const char *const gloc_descr[NUM_GLOCS][4] = {
|
||||
@@ -54,6 +57,11 @@ const char *const gloc_descr[NUM_GLOCS][4] = {
|
||||
"anything interesting" }
|
||||
};
|
||||
|
||||
const char *const gloc_filtertxt[NUM_GFILTER] = {
|
||||
"",
|
||||
" in view",
|
||||
" in this area"
|
||||
};
|
||||
|
||||
void
|
||||
getpos_help_keyxhelp(tmpwin, k1, k2, gloc)
|
||||
@@ -69,7 +77,7 @@ int gloc;
|
||||
iflags.getloc_usemenu ? "get a menu of "
|
||||
: "move the cursor to ",
|
||||
gloc_descr[gloc][2 + iflags.getloc_usemenu],
|
||||
iflags.getloc_limitview ? " in view" : "");
|
||||
gloc_filtertxt[iflags.getloc_filter]);
|
||||
putstr(tmpwin, 0, sbuf);
|
||||
}
|
||||
|
||||
@@ -82,13 +90,17 @@ const char *goal;
|
||||
char sbuf[BUFSZ];
|
||||
boolean doing_what_is;
|
||||
winid tmpwin = create_nhwindow(NHW_MENU);
|
||||
const char *const fastmovemode[2] = { "8 units at a time",
|
||||
"skipping same glyphs" };
|
||||
|
||||
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 'H', 'J', 'K', 'L' to move the cursor 8 units at a time.");
|
||||
Sprintf(sbuf,
|
||||
"Use 'H', 'J', 'K', 'L' to fast-move the cursor, %s.",
|
||||
fastmovemode[iflags.getloc_moveskip]);
|
||||
putstr(tmpwin, 0, sbuf);
|
||||
putstr(tmpwin, 0, "Or enter a background symbol (ex. '<').");
|
||||
Sprintf(sbuf, "Use '%s' to move the cursor on yourself.",
|
||||
visctrl(Cmd.spkeys[NHKF_GETPOS_SELF]));
|
||||
@@ -121,15 +133,26 @@ const char *goal;
|
||||
visctrl(Cmd.spkeys[NHKF_GETPOS_INTERESTING_PREV]),
|
||||
GLOC_INTERESTING);
|
||||
}
|
||||
Sprintf(sbuf, "Use '%s' to change fast-move mode to %s.",
|
||||
visctrl(Cmd.spkeys[NHKF_GETPOS_MOVESKIP]),
|
||||
fastmovemode[!iflags.getloc_moveskip]);
|
||||
putstr(tmpwin, 0, sbuf);
|
||||
|
||||
Sprintf(sbuf, "Use '%s' to toggle menu listing for possible targets.",
|
||||
visctrl(Cmd.spkeys[NHKF_GETPOS_MENU]));
|
||||
putstr(tmpwin, 0, sbuf);
|
||||
Sprintf(sbuf,
|
||||
"Use '%s' to toggle limiting possible targets to in view only.",
|
||||
"Use '%s' to change the mode of limiting possible targets.",
|
||||
visctrl(Cmd.spkeys[NHKF_GETPOS_LIMITVIEW]));
|
||||
putstr(tmpwin, 0, sbuf);
|
||||
if (!iflags.terrainmode) {
|
||||
char kbuf[BUFSZ];
|
||||
if (getpos_getvalid) {
|
||||
Sprintf(sbuf, "Use '%s' or '%s' to move to valid locations.",
|
||||
visctrl(Cmd.spkeys[NHKF_GETPOS_VALID_NEXT]),
|
||||
visctrl(Cmd.spkeys[NHKF_GETPOS_VALID_PREV]));
|
||||
putstr(tmpwin, 0, sbuf);
|
||||
}
|
||||
if (getpos_hilitefunc) {
|
||||
Sprintf(sbuf, "Use '%s' to display valid locations.",
|
||||
visctrl(Cmd.spkeys[NHKF_GETPOS_SHOWVALID]));
|
||||
@@ -214,6 +237,99 @@ const void *b;
|
||||
&& glyph_to_cmap(levl[(x)][(y)].glyph) == S_stone \
|
||||
&& !levl[(x)][(y)].seenv)
|
||||
|
||||
static struct opvar *gloc_filter_map = (struct opvar *) 0;
|
||||
|
||||
#define GLOC_SAME_AREA(x,y) \
|
||||
(isok((x), (y)) \
|
||||
&& (selection_getpoint((x),(y), gloc_filter_map)))
|
||||
|
||||
static int gloc_filter_floodfill_match_glyph;
|
||||
|
||||
int
|
||||
gloc_filter_classify_glyph(glyph)
|
||||
int glyph;
|
||||
{
|
||||
int c;
|
||||
|
||||
if (!glyph_is_cmap(glyph))
|
||||
return 0;
|
||||
|
||||
c = glyph_to_cmap(glyph);
|
||||
|
||||
if (is_cmap_room(c) || is_cmap_furniture(c))
|
||||
return 1;
|
||||
else if (is_cmap_wall(c) || c == S_tree)
|
||||
return 2;
|
||||
else if (is_cmap_corr(c))
|
||||
return 3;
|
||||
else if (is_cmap_water(c))
|
||||
return 4;
|
||||
else if (is_cmap_lava(c))
|
||||
return 5;
|
||||
return 0;
|
||||
}
|
||||
|
||||
STATIC_OVL int
|
||||
gloc_filter_floodfill_matcharea(x,y)
|
||||
int x,y;
|
||||
{
|
||||
int glyph = back_to_glyph(x, y);
|
||||
|
||||
if (!levl[x][y].seenv)
|
||||
return FALSE;
|
||||
|
||||
if (glyph == gloc_filter_floodfill_match_glyph)
|
||||
return TRUE;
|
||||
|
||||
if (gloc_filter_classify_glyph(glyph) == gloc_filter_classify_glyph(gloc_filter_floodfill_match_glyph))
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
gloc_filter_floodfill(x,y)
|
||||
int x,y;
|
||||
{
|
||||
gloc_filter_floodfill_match_glyph = back_to_glyph(x,y);
|
||||
|
||||
set_selection_floodfillchk(gloc_filter_floodfill_matcharea);
|
||||
selection_floodfill(gloc_filter_map, x,y, FALSE);
|
||||
}
|
||||
|
||||
void
|
||||
gloc_filter_init()
|
||||
{
|
||||
if (iflags.getloc_filter == GFILTER_AREA) {
|
||||
if (!gloc_filter_map) {
|
||||
gloc_filter_map = selection_opvar(NULL);
|
||||
}
|
||||
/* special case: if we're in a doorway, try to figure out which
|
||||
direction we're moving, and use that side of the doorway */
|
||||
if (IS_DOOR(levl[u.ux][u.uy].typ)) {
|
||||
if (u.dx || u.dy) {
|
||||
gloc_filter_floodfill(u.ux + u.dx, u.uy + u.dy);
|
||||
} else {
|
||||
/* TODO: maybe add both sides of the doorway? */
|
||||
}
|
||||
} else {
|
||||
gloc_filter_floodfill(u.ux, u.uy);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gloc_filter_done()
|
||||
{
|
||||
if (gloc_filter_map) {
|
||||
opvar_free_x(gloc_filter_map);
|
||||
gloc_filter_map = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
STATIC_OVL boolean
|
||||
gather_locs_interesting(x,y, gloc)
|
||||
int x,y, gloc;
|
||||
@@ -223,7 +339,13 @@ int x,y, gloc;
|
||||
*/
|
||||
int glyph = glyph_at(x, y);
|
||||
|
||||
if (iflags.getloc_limitview && !cansee(x,y))
|
||||
if (iflags.getloc_filter == GFILTER_VIEW && !cansee(x,y))
|
||||
return FALSE;
|
||||
if (iflags.getloc_filter == GFILTER_AREA && !GLOC_SAME_AREA(x,y)
|
||||
&& !GLOC_SAME_AREA(x-1,y)
|
||||
&& !GLOC_SAME_AREA(x,y-1)
|
||||
&& !GLOC_SAME_AREA(x+1,y)
|
||||
&& !GLOC_SAME_AREA(x,y+1))
|
||||
return FALSE;
|
||||
|
||||
switch (gloc) {
|
||||
@@ -272,6 +394,8 @@ int x,y, gloc;
|
||||
|| glyph_to_cmap(glyph) == S_darkroom
|
||||
|| glyph_to_cmap(glyph) == S_corr
|
||||
|| glyph_to_cmap(glyph) == S_litcorr));
|
||||
case GLOC_VALID:
|
||||
return (getpos_getvalid && getpos_getvalid(x,y));
|
||||
}
|
||||
/*NOTREACHED*/
|
||||
return FALSE;
|
||||
@@ -297,6 +421,9 @@ int gloc;
|
||||
* Hero's spot will always sort to array[0] because it will always
|
||||
* be the shortest distance (namely, 0 units) away from <u.ux,u.uy>.
|
||||
*/
|
||||
|
||||
gloc_filter_init();
|
||||
|
||||
*cnt_p = idx = 0;
|
||||
for (pass = 0; pass < 2; pass++) {
|
||||
for (x = 1; x < COLNO; x++)
|
||||
@@ -318,6 +445,8 @@ int gloc;
|
||||
else /* end of second pass */
|
||||
qsort(*arr_p, *cnt_p, sizeof (coord), cmp_coord_distu);
|
||||
} /* pass */
|
||||
|
||||
gloc_filter_done();
|
||||
}
|
||||
|
||||
char *
|
||||
@@ -413,7 +542,9 @@ int cx, cy;
|
||||
if (do_screen_description(cc, TRUE, sym, tmpbuf, &firstmatch)) {
|
||||
(void) coord_desc(cx, cy, tmpbuf, iflags.getpos_coords);
|
||||
custompline(SUPPRESS_HISTORY,
|
||||
"%s%s%s%s", firstmatch, *tmpbuf ? " " : "", tmpbuf,
|
||||
"%s%s%s%s%s", firstmatch, *tmpbuf ? " " : "", tmpbuf,
|
||||
(iflags.autodescribe && getpos_getvalid && !getpos_getvalid(cx,cy))
|
||||
? " (illegal)" : "",
|
||||
(iflags.getloc_travelmode && !is_valid_travelpt(cx, cy))
|
||||
? " (no travel path)" : "");
|
||||
curs(WIN_MAP, cx, cy);
|
||||
@@ -422,9 +553,8 @@ int cx, cy;
|
||||
}
|
||||
|
||||
boolean
|
||||
getpos_menu(ccp, fovonly, gloc)
|
||||
getpos_menu(ccp, gloc)
|
||||
coord *ccp;
|
||||
boolean fovonly;
|
||||
int gloc;
|
||||
{
|
||||
coord *garr = DUMMY;
|
||||
@@ -440,7 +570,8 @@ int gloc;
|
||||
if (gcount < 2) { /* gcount always includes the hero */
|
||||
free((genericptr_t) garr);
|
||||
You("cannot %s %s.",
|
||||
fovonly ? "see" : "detect", gloc_descr[gloc][0]);
|
||||
iflags.getloc_filter == GFILTER_VIEW ? "see" : "detect",
|
||||
gloc_descr[gloc][0]);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -466,7 +597,8 @@ int gloc;
|
||||
}
|
||||
|
||||
Sprintf(tmpbuf, "Pick a target %s%s%s",
|
||||
gloc_descr[gloc][1], fovonly ? " in view" : "",
|
||||
gloc_descr[gloc][1],
|
||||
gloc_filtertxt[iflags.getloc_filter],
|
||||
iflags.getloc_travelmode ? " for travel" : "");
|
||||
end_menu(tmpwin, tmpbuf);
|
||||
pick_cnt = select_menu(tmpwin, PICK_ONE, &picks);
|
||||
@@ -505,10 +637,12 @@ const char *goal;
|
||||
NHKF_GETPOS_UNEX_NEXT,
|
||||
NHKF_GETPOS_UNEX_PREV,
|
||||
NHKF_GETPOS_INTERESTING_NEXT,
|
||||
NHKF_GETPOS_INTERESTING_PREV
|
||||
NHKF_GETPOS_INTERESTING_PREV,
|
||||
NHKF_GETPOS_VALID_NEXT,
|
||||
NHKF_GETPOS_VALID_PREV
|
||||
};
|
||||
char pick_chars[6];
|
||||
char mMoOdDxX[11];
|
||||
char mMoOdDxX[13];
|
||||
int result = 0;
|
||||
int cx, cy, i, c;
|
||||
int sidx, tx, ty;
|
||||
@@ -595,8 +729,23 @@ const char *goal;
|
||||
} else if (Cmd.alphadirchars[i] == lowc((char) c)
|
||||
|| (Cmd.num_pad && Cmd.dirchars[i] == (c & 0177))) {
|
||||
/* a shifted movement letter or Meta-digit */
|
||||
dx = 8 * xdir[i];
|
||||
dy = 8 * ydir[i];
|
||||
if (iflags.getloc_moveskip) {
|
||||
/* skip same glyphs */
|
||||
int glyph = glyph_at(cx, cy);
|
||||
|
||||
dx = xdir[i];
|
||||
dy = ydir[i];
|
||||
while (isok(cx + dx, cy + dy)
|
||||
&& glyph == glyph_at(cx + dx, cy + dy)
|
||||
&& isok(cx + dx+xdir[i], cy+dy+ydir[i])
|
||||
&& glyph == glyph_at(cx + dx+xdir[i], cy + dy+ydir[i])) {
|
||||
dx += xdir[i];
|
||||
dy += ydir[i];
|
||||
}
|
||||
} else {
|
||||
dx = 8 * xdir[i];
|
||||
dy = 8 * ydir[i];
|
||||
}
|
||||
} else
|
||||
continue;
|
||||
|
||||
@@ -646,7 +795,12 @@ const char *goal;
|
||||
msg_given = TRUE;
|
||||
goto nxtc;
|
||||
} else if (c == Cmd.spkeys[NHKF_GETPOS_LIMITVIEW]) {
|
||||
iflags.getloc_limitview = !iflags.getloc_limitview;
|
||||
const char *const view_filters[NUM_GFILTER] = {
|
||||
"Not limiting targets",
|
||||
"Limiting targets to in sight",
|
||||
"Limiting targets to in same area"
|
||||
};
|
||||
iflags.getloc_filter = (iflags.getloc_filter + 1) % NUM_GFILTER;
|
||||
for (i = 0; i < NUM_GLOCS; i++) {
|
||||
if (garr[i]) {
|
||||
free((genericptr_t) garr[i]);
|
||||
@@ -654,8 +808,7 @@ const char *goal;
|
||||
}
|
||||
gidx[i] = gcount[i] = 0;
|
||||
}
|
||||
pline("%s possible targets to those in sight only.",
|
||||
iflags.getloc_limitview ? "Limiting" : "Not limiting");
|
||||
pline("%s.", view_filters[iflags.getloc_filter]);
|
||||
msg_given = TRUE;
|
||||
goto nxtc;
|
||||
} else if (c == Cmd.spkeys[NHKF_GETPOS_MENU]) {
|
||||
@@ -672,6 +825,10 @@ const char *goal;
|
||||
cx = u.ux;
|
||||
cy = u.uy;
|
||||
goto nxtc;
|
||||
} else if (c == Cmd.spkeys[NHKF_GETPOS_MOVESKIP]) {
|
||||
iflags.getloc_moveskip = !iflags.getloc_moveskip;
|
||||
pline("%skipping over similar terrain when fastmoving the cursor.",
|
||||
iflags.getloc_moveskip ? "S" : "Not s");
|
||||
} else if ((cp = index(mMoOdDxX, c)) != 0) { /* 'm|M', 'o|O', &c */
|
||||
/* nearest or farthest monster or object or door or unexplored */
|
||||
int gtmp = (int) (cp - mMoOdDxX), /* 0..7 */
|
||||
@@ -679,7 +836,7 @@ const char *goal;
|
||||
|
||||
if (iflags.getloc_usemenu) {
|
||||
coord tmpcrd;
|
||||
if (getpos_menu(&tmpcrd, iflags.getloc_limitview, gloc)) {
|
||||
if (getpos_menu(&tmpcrd, gloc)) {
|
||||
cx = tmpcrd.x;
|
||||
cy = tmpcrd.y;
|
||||
}
|
||||
@@ -808,6 +965,7 @@ const char *goal;
|
||||
if (garr[i])
|
||||
free((genericptr_t) garr[i]);
|
||||
getpos_hilitefunc = (void FDECL((*), (int))) 0;
|
||||
getpos_getvalid = (boolean FDECL((*), (int,int))) 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -1880,7 +2038,7 @@ static const char *const sir_Terry_novels[] = {
|
||||
"Lords and Ladies", "Men at Arms", "Soul Music", "Interesting Times",
|
||||
"Maskerade", "Feet of Clay", "Hogfather", "Jingo", "The Last Continent",
|
||||
"Carpe Jugulum", "The Fifth Elephant", "The Truth", "Thief of Time",
|
||||
"The Last Hero", "The Amazing Maurice and his Educated Rodents",
|
||||
"The Last Hero", "The Amazing Maurice and His Educated Rodents",
|
||||
"Night Watch", "The Wee Free Men", "Monstrous Regiment",
|
||||
"A Hat Full of Sky", "Going Postal", "Thud!", "Wintersmith",
|
||||
"Making Money", "Unseen Academicals", "I Shall Wear Midnight", "Snuff",
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 dog.c $NHDT-Date: 1446808440 2015/11/06 11:14:00 $ $NHDT-Branch: master $:$NHDT-Revision: 1.52 $ */
|
||||
/* NetHack 3.6 dog.c $NHDT-Date: 1502753406 2017/08/14 23:30:06 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.60 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
@@ -736,7 +736,8 @@ struct monst *mon;
|
||||
register struct obj *obj;
|
||||
{
|
||||
struct permonst *mptr = mon->data, *fptr = 0;
|
||||
boolean carni = carnivorous(mptr), herbi = herbivorous(mptr), starving;
|
||||
boolean carni = carnivorous(mptr), herbi = herbivorous(mptr),
|
||||
starving, mblind;
|
||||
|
||||
if (is_quest_artifact(obj) || obj_resists(obj, 0, 95))
|
||||
return obj->cursed ? TABU : APPORT;
|
||||
@@ -755,8 +756,10 @@ register struct obj *obj;
|
||||
return obj->cursed ? UNDEF : APPORT;
|
||||
|
||||
/* a starving pet will eat almost anything */
|
||||
starving =
|
||||
(mon->mtame && !mon->isminion && EDOG(mon)->mhpmax_penalty);
|
||||
starving = (mon->mtame && !mon->isminion
|
||||
&& EDOG(mon)->mhpmax_penalty);
|
||||
/* even carnivores will eat carrots if they're temporarily blind */
|
||||
mblind = (!mon->mcansee && haseyes(mon->data));
|
||||
|
||||
/* ghouls prefer old corpses and unhatchable eggs, yum!
|
||||
they'll eat fresh non-veggy corpses and hatchable eggs
|
||||
@@ -813,8 +816,9 @@ register struct obj *obj;
|
||||
case TIN:
|
||||
return metallivorous(mptr) ? ACCFOOD : MANFOOD;
|
||||
case APPLE:
|
||||
case CARROT:
|
||||
return herbi ? DOGFOOD : starving ? ACCFOOD : MANFOOD;
|
||||
case CARROT:
|
||||
return (herbi || mblind) ? DOGFOOD : starving ? ACCFOOD : MANFOOD;
|
||||
case BANANA:
|
||||
return (mptr->mlet == S_YETI && herbi)
|
||||
? DOGFOOD /* for monkey and ape (tameable), sasquatch */
|
||||
|
||||
+5
-2
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 dogmove.c $NHDT-Date: 1463704424 2016/05/20 00:33:44 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.60 $ */
|
||||
/* NetHack 3.6 dogmove.c $NHDT-Date: 1502753407 2017/08/14 23:30:07 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.63 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
@@ -209,7 +209,7 @@ int x, y; /* dog's starting location, might be different from current */
|
||||
boolean devour;
|
||||
{
|
||||
register struct edog *edog = EDOG(mtmp);
|
||||
boolean poly, grow, heal, slimer, deadmimic;
|
||||
boolean poly, grow, heal, eyes, slimer, deadmimic;
|
||||
int nutrit;
|
||||
long oprice;
|
||||
char objnambuf[BUFSZ];
|
||||
@@ -226,6 +226,7 @@ boolean devour;
|
||||
poly = polyfodder(obj);
|
||||
grow = mlevelgain(obj);
|
||||
heal = mhealup(obj);
|
||||
eyes = (obj->otyp == CARROT);
|
||||
|
||||
if (devour) {
|
||||
if (mtmp->meating > 1)
|
||||
@@ -343,6 +344,8 @@ boolean devour;
|
||||
}
|
||||
if (heal)
|
||||
mtmp->mhp = mtmp->mhpmax;
|
||||
if ((eyes || heal) && !mtmp->mcansee)
|
||||
mcureblindness(mtmp, canseemon(mtmp));
|
||||
if (deadmimic)
|
||||
quickmimic(mtmp);
|
||||
return 1;
|
||||
|
||||
+23
-7
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 dothrow.c $NHDT-Date: 1455140444 2016/02/10 21:40:44 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.118 $ */
|
||||
/* NetHack 3.6 dothrow.c $NHDT-Date: 1502243899 2017/08/09 01:58:19 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.125 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
@@ -448,7 +448,22 @@ genericptr_t arg;
|
||||
int x, y, dx, dy, x_change, y_change, err, i, prev_x, prev_y;
|
||||
boolean keep_going = TRUE;
|
||||
|
||||
/* Use Bresenham's Line Algorithm to walk from src to dest */
|
||||
/* Use Bresenham's Line Algorithm to walk from src to dest.
|
||||
*
|
||||
* This should be replaced with a more versatile algorithm
|
||||
* since it handles slanted moves in a suboptimal way.
|
||||
* Going from 'x' to 'y' needs to pass through 'z', and will
|
||||
* fail if there's an obstable there, but it could choose to
|
||||
* pass through 'Z' instead if that way imposes no obstacle.
|
||||
* ..y .Zy
|
||||
* xz. vs x..
|
||||
* Perhaps we should check both paths and accept whichever
|
||||
* one isn't blocked. But then multiple zigs and zags could
|
||||
* potentially produce a meandering path rather than the best
|
||||
* attempt at a straight line. And (*check_proc)() would
|
||||
* need to work more like 'travel', distinguishing between
|
||||
* testing a possible move and actually attempting that move.
|
||||
*/
|
||||
dx = dest_cc->x - src_cc->x;
|
||||
dy = dest_cc->y - src_cc->y;
|
||||
prev_x = x = src_cc->x;
|
||||
@@ -640,9 +655,11 @@ int x, y;
|
||||
vision_recalc(1); /* update for new position */
|
||||
flush_screen(1);
|
||||
|
||||
if (levl[x][y].typ == WATER && Is_waterlevel(&u.uz)) {
|
||||
multi = 0;
|
||||
drown();
|
||||
if (is_pool(x, y) && !u.uinwater
|
||||
&& ((Is_waterlevel(&u.uz) && levl[x][y].typ == WATER)
|
||||
|| !(Levitation || Flying || Wwalking))) {
|
||||
multi = 0; /* can move, so drown() allows crawling out of water */
|
||||
(void) drown();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -768,8 +785,7 @@ boolean verbose;
|
||||
(void) walk_path(&uc, &cc, hurtle_step, (genericptr_t) &range);
|
||||
}
|
||||
|
||||
/* Move a monster through the air for a few squares.
|
||||
*/
|
||||
/* Move a monster through the air for a few squares. */
|
||||
void
|
||||
mhurtle(mon, dx, dy, range)
|
||||
struct monst *mon;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 eat.c $NHDT-Date: 1470272344 2016/08/04 00:59:04 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.172 $ */
|
||||
/* NetHack 3.6 eat.c $NHDT-Date: 1502754159 2017/08/14 23:42:39 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.179 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
STATIC_PTR int NDECL(eatmdone);
|
||||
STATIC_PTR int NDECL(eatfood);
|
||||
STATIC_PTR void FDECL(costly_tin, (int));
|
||||
STATIC_PTR struct obj *FDECL(costly_tin, (int));
|
||||
STATIC_PTR int NDECL(opentin);
|
||||
STATIC_PTR int NDECL(unfaint);
|
||||
|
||||
@@ -979,6 +979,7 @@ register int pm;
|
||||
u.mh = u.mhmax;
|
||||
else
|
||||
u.uhp = u.uhpmax;
|
||||
make_blinded(0L, !u.ucreamed);
|
||||
context.botl = 1;
|
||||
break;
|
||||
case PM_STALKER:
|
||||
@@ -1152,7 +1153,7 @@ violated_vegetarian()
|
||||
|
||||
/* common code to check and possibly charge for 1 context.tin.tin,
|
||||
* will split() context.tin.tin if necessary */
|
||||
STATIC_PTR void
|
||||
STATIC_PTR struct obj *
|
||||
costly_tin(alter_type)
|
||||
int alter_type; /* COST_xxx */
|
||||
{
|
||||
@@ -1166,6 +1167,7 @@ int alter_type; /* COST_xxx */
|
||||
}
|
||||
costly_alteration(tin, alter_type);
|
||||
}
|
||||
return tin;
|
||||
}
|
||||
|
||||
int
|
||||
@@ -1293,7 +1295,7 @@ const char *mesg;
|
||||
r = tin_variety(tin, FALSE);
|
||||
if (tin->otrapped || (tin->cursed && r != HOMEMADE_TIN && !rn2(8))) {
|
||||
b_trapped("tin", 0);
|
||||
costly_tin(COST_DSTROY);
|
||||
tin = costly_tin(COST_DSTROY);
|
||||
goto use_up_tin;
|
||||
}
|
||||
|
||||
@@ -1304,7 +1306,7 @@ const char *mesg;
|
||||
if (mnum == NON_PM) {
|
||||
pline("It turns out to be empty.");
|
||||
tin->dknown = tin->known = 1;
|
||||
costly_tin(COST_OPEN);
|
||||
tin = costly_tin(COST_OPEN);
|
||||
goto use_up_tin;
|
||||
}
|
||||
|
||||
@@ -1333,7 +1335,7 @@ const char *mesg;
|
||||
You("discard the open tin.");
|
||||
if (!Hallucination)
|
||||
tin->dknown = tin->known = 1;
|
||||
costly_tin(COST_OPEN);
|
||||
tin = costly_tin(COST_OPEN);
|
||||
goto use_up_tin;
|
||||
}
|
||||
|
||||
@@ -1352,7 +1354,7 @@ const char *mesg;
|
||||
cpostfx(mnum);
|
||||
|
||||
/* charge for one at pre-eating cost */
|
||||
costly_tin(COST_OPEN);
|
||||
tin = costly_tin(COST_OPEN);
|
||||
|
||||
if (tintxts[r].nut < 0) /* rotten */
|
||||
make_vomiting((long) rn1(15, 10), FALSE);
|
||||
@@ -1378,7 +1380,7 @@ const char *mesg;
|
||||
if (yn("Eat it?") == 'n') {
|
||||
if (flags.verbose)
|
||||
You("discard the open tin.");
|
||||
costly_tin(COST_OPEN);
|
||||
tin = costly_tin(COST_OPEN);
|
||||
goto use_up_tin;
|
||||
}
|
||||
|
||||
@@ -1386,14 +1388,13 @@ const char *mesg;
|
||||
* Same order as with non-spinach above:
|
||||
* conduct update, side-effects, shop handling, and nutrition.
|
||||
*/
|
||||
u.uconduct
|
||||
.food++; /* don't need vegan/vegetarian checks for spinach */
|
||||
u.uconduct.food++; /* don't need vegetarian checks for spinach */
|
||||
if (!tin->cursed)
|
||||
pline("This makes you feel like %s!",
|
||||
Hallucination ? "Swee'pea" : "Popeye");
|
||||
gainstr(tin, 0, FALSE);
|
||||
|
||||
costly_tin(COST_OPEN);
|
||||
tin = costly_tin(COST_OPEN);
|
||||
|
||||
lesshungry(tin->blessed
|
||||
? 600 /* blessed */
|
||||
|
||||
+25
-15
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 files.c $NHDT-Date: 1459987580 2016/04/07 00:06:20 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.205 $ */
|
||||
/* NetHack 3.6 files.c $NHDT-Date: 1502581476 2017/08/12 23:44:36 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.211 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
@@ -617,6 +617,7 @@ const char *name;
|
||||
int lev, oflag;
|
||||
{
|
||||
int reslt, fd;
|
||||
|
||||
if (!lftrack.init) {
|
||||
lftrack.init = 1;
|
||||
lftrack.fd = -1;
|
||||
@@ -671,7 +672,7 @@ int fd;
|
||||
}
|
||||
return close(fd);
|
||||
}
|
||||
#else
|
||||
#else /* !HOLD_LOCKFILE_OPEN */
|
||||
|
||||
int
|
||||
nhclose(fd)
|
||||
@@ -679,7 +680,7 @@ int fd;
|
||||
{
|
||||
return close(fd);
|
||||
}
|
||||
#endif
|
||||
#endif /* ?HOLD_LOCKFILE_OPEN */
|
||||
|
||||
/* ---------- END LEVEL FILE HANDLING ----------- */
|
||||
|
||||
@@ -3065,8 +3066,8 @@ const char *dir UNUSED_if_not_OS2_CODEVIEW;
|
||||
#ifdef VMS /* must be stream-lf to use UPDATE_RECORD_IN_PLACE */
|
||||
if (!file_is_stmlf(fd)) {
|
||||
raw_printf(
|
||||
"Warning: scoreboard file %s is not in stream_lf format",
|
||||
fq_record);
|
||||
"Warning: scoreboard file '%s' is not in stream_lf format",
|
||||
fq_record);
|
||||
wait_synch();
|
||||
}
|
||||
#endif
|
||||
@@ -3078,7 +3079,7 @@ const char *dir UNUSED_if_not_OS2_CODEVIEW;
|
||||
(void) chmod(fq_record, FCMASK | 007);
|
||||
#endif /* VMS && !SECURE */
|
||||
} else {
|
||||
raw_printf("Warning: cannot write scoreboard file %s", fq_record);
|
||||
raw_printf("Warning: cannot write scoreboard file '%s'", fq_record);
|
||||
wait_synch();
|
||||
}
|
||||
#endif /* !UNIX && !VMS */
|
||||
@@ -3101,22 +3102,25 @@ const char *dir UNUSED_if_not_OS2_CODEVIEW;
|
||||
#endif
|
||||
|
||||
if ((fd = open(fq_record, O_RDWR)) < 0) {
|
||||
/* try to create empty record */
|
||||
/* try to create empty 'record' */
|
||||
#if defined(AZTEC_C) || defined(_DCC) \
|
||||
|| (defined(__GNUC__) && defined(__AMIGA__))
|
||||
/* Aztec doesn't use the third argument */
|
||||
/* DICE doesn't like it */
|
||||
if ((fd = open(fq_record, O_CREAT | O_RDWR)) < 0) {
|
||||
fd = open(fq_record, O_CREAT | O_RDWR);
|
||||
#else
|
||||
if ((fd = open(fq_record, O_CREAT | O_RDWR, S_IREAD | S_IWRITE))
|
||||
< 0) {
|
||||
fd = open(fq_record, O_CREAT | O_RDWR, S_IREAD | S_IWRITE);
|
||||
#endif
|
||||
raw_printf("Warning: cannot write record %s", tmp);
|
||||
if (fd = < 0) {
|
||||
raw_printf("Warning: cannot write record '%s'", tmp);
|
||||
wait_synch();
|
||||
} else
|
||||
} else {
|
||||
(void) nhclose(fd);
|
||||
} else /* open succeeded */
|
||||
}
|
||||
} else {
|
||||
/* open succeeded => 'record' exists */
|
||||
(void) nhclose(fd);
|
||||
}
|
||||
#else /* MICRO || WIN32*/
|
||||
|
||||
#ifdef MAC
|
||||
@@ -3260,6 +3264,7 @@ recover_savefile()
|
||||
raw_printf("\nError writing %s; recovery failed.", SAVEF);
|
||||
(void) nhclose(gfd);
|
||||
(void) nhclose(sfd);
|
||||
(void) nhclose(lfd);
|
||||
delete_savefile();
|
||||
return FALSE;
|
||||
}
|
||||
@@ -3269,6 +3274,7 @@ recover_savefile()
|
||||
SAVEF);
|
||||
(void) nhclose(gfd);
|
||||
(void) nhclose(sfd);
|
||||
(void) nhclose(lfd);
|
||||
delete_savefile();
|
||||
return FALSE;
|
||||
}
|
||||
@@ -3279,6 +3285,7 @@ recover_savefile()
|
||||
SAVEF);
|
||||
(void) nhclose(gfd);
|
||||
(void) nhclose(sfd);
|
||||
(void) nhclose(lfd);
|
||||
delete_savefile();
|
||||
return FALSE;
|
||||
}
|
||||
@@ -3288,13 +3295,15 @@ recover_savefile()
|
||||
SAVEF);
|
||||
(void) nhclose(gfd);
|
||||
(void) nhclose(sfd);
|
||||
(void) nhclose(lfd);
|
||||
delete_savefile();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!copy_bytes(lfd, sfd)) {
|
||||
(void) nhclose(lfd);
|
||||
(void) nhclose(gfd);
|
||||
(void) nhclose(sfd);
|
||||
(void) nhclose(lfd);
|
||||
delete_savefile();
|
||||
return FALSE;
|
||||
}
|
||||
@@ -3302,7 +3311,7 @@ recover_savefile()
|
||||
processed[savelev] = 1;
|
||||
|
||||
if (!copy_bytes(gfd, sfd)) {
|
||||
(void) nhclose(lfd);
|
||||
(void) nhclose(gfd);
|
||||
(void) nhclose(sfd);
|
||||
delete_savefile();
|
||||
return FALSE;
|
||||
@@ -3343,6 +3352,7 @@ recover_savefile()
|
||||
for (lev = 0; lev < 256; lev++) {
|
||||
if (processed[lev]) {
|
||||
const char *fq_lock;
|
||||
|
||||
set_levelfile_name(lock, lev);
|
||||
fq_lock = fqname(lock, LEVELPREFIX, 3);
|
||||
(void) unlink(fq_lock);
|
||||
|
||||
+2
-1
@@ -1747,7 +1747,8 @@ int FDECL((*fn), (OBJ_P)), FDECL((*ckfn), (OBJ_P));
|
||||
nodot = (!strcmp(word, "nodot") || !strcmp(word, "drop") || ident
|
||||
|| takeoff || take_out || put_in);
|
||||
ininv = (*objchn == invent);
|
||||
bycat = (menu_class_present('B') || menu_class_present('U')
|
||||
bycat = (menu_class_present('u')
|
||||
|| menu_class_present('B') || menu_class_present('U')
|
||||
|| menu_class_present('C') || menu_class_present('X'));
|
||||
|
||||
/* someday maybe we'll sort by 'olets' too (temporarily replace
|
||||
|
||||
+32
-1
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 mkobj.c $NHDT-Date: 1462067745 2016/05/01 01:55:45 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.122 $ */
|
||||
/* NetHack 3.6 mkobj.c $NHDT-Date: 1501725405 2017/08/03 01:56:45 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.124 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
@@ -2720,4 +2720,35 @@ struct obj **obj1, **obj2;
|
||||
return (struct obj *) 0;
|
||||
}
|
||||
|
||||
/* give a message if hero notices two globs merging [used to be in pline.c] */
|
||||
void
|
||||
pudding_merge_message(otmp, otmp2)
|
||||
struct obj *otmp;
|
||||
struct obj *otmp2;
|
||||
{
|
||||
boolean visible = (cansee(otmp->ox, otmp->oy)
|
||||
|| cansee(otmp2->ox, otmp2->oy)),
|
||||
onfloor = (otmp->where == OBJ_FLOOR || otmp2->where == OBJ_FLOOR),
|
||||
inpack = (carried(otmp) || carried(otmp2));
|
||||
|
||||
/* the player will know something happened inside his own inventory */
|
||||
if ((!Blind && visible) || inpack) {
|
||||
if (Hallucination) {
|
||||
if (onfloor) {
|
||||
You_see("parts of the floor melting!");
|
||||
} else if (inpack) {
|
||||
Your("pack reaches out and grabs something!");
|
||||
}
|
||||
/* even though we can see where they should be,
|
||||
* they'll be out of our view (minvent or container)
|
||||
* so don't actually show anything */
|
||||
} else if (onfloor || inpack) {
|
||||
pline("The %s coalesce%s.", makeplural(obj_typename(otmp->otyp)),
|
||||
inpack ? " inside your pack" : "");
|
||||
}
|
||||
} else {
|
||||
You_hear("a faint sloshing sound.");
|
||||
}
|
||||
}
|
||||
|
||||
/*mkobj.c*/
|
||||
|
||||
+21
-1
@@ -239,6 +239,26 @@ int type;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
mk_zoo_thronemon(x,y)
|
||||
int x,y;
|
||||
{
|
||||
int i = rnd(level_difficulty());
|
||||
int pm = (i > 9) ? PM_OGRE_KING
|
||||
: (i > 5) ? PM_ELVENKING
|
||||
: (i > 2) ? PM_DWARF_KING
|
||||
: PM_GNOME_KING;
|
||||
struct monst *mon = makemon(&mons[pm], x, y, NO_MM_FLAGS);
|
||||
|
||||
if (mon) {
|
||||
mon->msleeping = 1;
|
||||
mon->mpeaceful = 0;
|
||||
set_malign(mon);
|
||||
/* Give him a sceptre to pound in judgment */
|
||||
(void) mongets(mon, MACE);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
fill_zoo(sroom)
|
||||
struct mkroom *sroom;
|
||||
@@ -265,7 +285,7 @@ struct mkroom *sroom;
|
||||
ty = mm.y;
|
||||
} while (occupied((xchar) tx, (xchar) ty) && --i > 0);
|
||||
throne_placed:
|
||||
/* TODO: try to ensure the enthroned monster is an M2_PRINCE */
|
||||
mk_zoo_thronemon(tx, ty);
|
||||
break;
|
||||
case BEEHIVE:
|
||||
tx = sroom->lx + (sroom->hx - sroom->lx + 1) / 2;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 mon.c $NHDT-Date: 1496531114 2017/06/03 23:05:14 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.240 $ */
|
||||
/* NetHack 3.6 mon.c $NHDT-Date: 1502753408 2017/08/14 23:30:08 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.242 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
@@ -886,9 +886,9 @@ int
|
||||
meatobj(mtmp) /* for gelatinous cubes */
|
||||
struct monst *mtmp;
|
||||
{
|
||||
register struct obj *otmp, *otmp2;
|
||||
struct obj *otmp, *otmp2;
|
||||
struct permonst *ptr, *original_ptr = mtmp->data;
|
||||
int poly, grow, heal, count = 0, ecount = 0;
|
||||
int poly, grow, heal, eyes, count = 0, ecount = 0;
|
||||
char buf[BUFSZ];
|
||||
|
||||
buf[0] = '\0';
|
||||
@@ -986,6 +986,7 @@ struct monst *mtmp;
|
||||
poly = polyfodder(otmp);
|
||||
grow = mlevelgain(otmp);
|
||||
heal = mhealup(otmp);
|
||||
eyes = (otmp->otyp == CARROT);
|
||||
delobj(otmp); /* munch */
|
||||
ptr = mtmp->data;
|
||||
if (poly) {
|
||||
@@ -996,6 +997,8 @@ struct monst *mtmp;
|
||||
} else if (heal) {
|
||||
mtmp->mhp = mtmp->mhpmax;
|
||||
}
|
||||
if ((eyes || heal) && !mtmp->mcansee)
|
||||
mcureblindness(mtmp, canseemon(mtmp));
|
||||
/* in case it polymorphed or died */
|
||||
if (ptr != original_ptr)
|
||||
return !ptr ? 2 : 1;
|
||||
|
||||
+23
-24
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 muse.c $NHDT-Date: 1469840918 2016/07/30 01:08:38 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.78 $ */
|
||||
/* NetHack 3.6 muse.c $NHDT-Date: 1502753408 2017/08/14 23:30:08 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.79 $ */
|
||||
/* Copyright (C) 1990 by Ken Arromdee */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
@@ -603,7 +603,7 @@ struct monst *mtmp;
|
||||
int i, fleetim, how = 0;
|
||||
struct obj *otmp = m.defensive;
|
||||
boolean vis, vismon, oseen;
|
||||
const char *Mnam, *mcsa = "%s can see again.";
|
||||
const char *Mnam;
|
||||
|
||||
if ((i = precheck(mtmp, otmp)) != 0)
|
||||
return i;
|
||||
@@ -628,10 +628,7 @@ struct monst *mtmp;
|
||||
pline_The("tip of %s's horn glows!", mon_nam(mtmp));
|
||||
}
|
||||
if (!mtmp->mcansee) {
|
||||
mtmp->mcansee = 1;
|
||||
mtmp->mblinded = 0;
|
||||
if (vismon)
|
||||
pline(mcsa, Monnam(mtmp));
|
||||
mcureblindness(mtmp, vismon);
|
||||
} else if (mtmp->mconf || mtmp->mstun) {
|
||||
mtmp->mconf = mtmp->mstun = 0;
|
||||
if (vismon)
|
||||
@@ -939,12 +936,8 @@ struct monst *mtmp;
|
||||
mtmp->mhp += i;
|
||||
if (mtmp->mhp > mtmp->mhpmax)
|
||||
mtmp->mhp = ++mtmp->mhpmax;
|
||||
if (!otmp->cursed && !mtmp->mcansee) {
|
||||
mtmp->mcansee = 1;
|
||||
mtmp->mblinded = 0;
|
||||
if (vismon)
|
||||
pline(mcsa, Monnam(mtmp));
|
||||
}
|
||||
if (!otmp->cursed && !mtmp->mcansee)
|
||||
mcureblindness(mtmp, vismon);
|
||||
if (vismon)
|
||||
pline("%s looks better.", Monnam(mtmp));
|
||||
if (oseen)
|
||||
@@ -957,12 +950,8 @@ struct monst *mtmp;
|
||||
mtmp->mhp += i;
|
||||
if (mtmp->mhp > mtmp->mhpmax)
|
||||
mtmp->mhp = (mtmp->mhpmax += (otmp->blessed ? 5 : 2));
|
||||
if (!mtmp->mcansee) {
|
||||
mtmp->mcansee = 1;
|
||||
mtmp->mblinded = 0;
|
||||
if (vismon)
|
||||
pline(mcsa, Monnam(mtmp));
|
||||
}
|
||||
if (!mtmp->mcansee)
|
||||
mcureblindness(mtmp, vismon);
|
||||
if (vismon)
|
||||
pline("%s looks much better.", Monnam(mtmp));
|
||||
if (oseen)
|
||||
@@ -974,12 +963,8 @@ struct monst *mtmp;
|
||||
if (otmp->otyp == POT_SICKNESS)
|
||||
unbless(otmp); /* Pestilence */
|
||||
mtmp->mhp = (mtmp->mhpmax += (otmp->blessed ? 8 : 4));
|
||||
if (!mtmp->mcansee && otmp->otyp != POT_SICKNESS) {
|
||||
mtmp->mcansee = 1;
|
||||
mtmp->mblinded = 0;
|
||||
if (vismon)
|
||||
pline(mcsa, Monnam(mtmp));
|
||||
}
|
||||
if (!mtmp->mcansee && otmp->otyp != POT_SICKNESS)
|
||||
mcureblindness(mtmp, vismon);
|
||||
if (vismon)
|
||||
pline("%s looks completely healed.", Monnam(mtmp));
|
||||
if (oseen)
|
||||
@@ -2175,6 +2160,20 @@ const char *fmt, *str;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* cure mon's blindness (use_defensive, dog_eat, meatobj) */
|
||||
void
|
||||
mcureblindness(mon, verbos)
|
||||
struct monst *mon;
|
||||
boolean verbos;
|
||||
{
|
||||
if (!mon->mcansee) {
|
||||
mon->mcansee = 1;
|
||||
mon->mblinded = 0;
|
||||
if (verbos && haseyes(mon->data))
|
||||
pline("%s can see again.", Monnam(mon));
|
||||
}
|
||||
}
|
||||
|
||||
/* TRUE if the monster ate something */
|
||||
boolean
|
||||
munstone(mon, by_you)
|
||||
|
||||
+211
-61
@@ -90,8 +90,12 @@ releaseobuf(bufp)
|
||||
char *bufp;
|
||||
{
|
||||
/* caller may not know whether bufp is the most recently allocated
|
||||
buffer; if it isn't, do nothing */
|
||||
if (bufp == obufs[obufidx])
|
||||
buffer; if it isn't, do nothing; note that because of the somewhat
|
||||
obscure PREFIX handling for object name formatting by xname(),
|
||||
the pointer our caller has and is passing to us might be into the
|
||||
middle of an obuf rather than the address returned by nextobuf() */
|
||||
if (bufp >= obufs[obufidx]
|
||||
&& bufp < obufs[obufidx] + sizeof obufs[obufidx]) /* obufs[][BUFSZ] */
|
||||
obufidx = (obufidx - 1 + NUMOBUF) % NUMOBUF;
|
||||
}
|
||||
|
||||
@@ -100,11 +104,11 @@ obj_typename(otyp)
|
||||
register int otyp;
|
||||
{
|
||||
char *buf = nextobuf();
|
||||
register struct objclass *ocl = &objects[otyp];
|
||||
register const char *actualn = OBJ_NAME(*ocl);
|
||||
register const char *dn = OBJ_DESCR(*ocl);
|
||||
register const char *un = ocl->oc_uname;
|
||||
register int nn = ocl->oc_name_known;
|
||||
struct objclass *ocl = &objects[otyp];
|
||||
const char *actualn = OBJ_NAME(*ocl);
|
||||
const char *dn = OBJ_DESCR(*ocl);
|
||||
const char *un = ocl->oc_uname;
|
||||
int nn = ocl->oc_name_known;
|
||||
|
||||
if (Role_if(PM_SAMURAI) && Japanese_item_name(otyp))
|
||||
actualn = Japanese_item_name(otyp);
|
||||
@@ -251,6 +255,135 @@ boolean juice; /* whether or not to append " juice" to the name */
|
||||
return buf;
|
||||
}
|
||||
|
||||
/* look up a named fruit by index (1..127) */
|
||||
struct fruit *
|
||||
fruit_from_indx(indx)
|
||||
int indx;
|
||||
{
|
||||
struct fruit *f;
|
||||
|
||||
for (f = ffruit; f; f = f->nextf)
|
||||
if (f->fid == indx)
|
||||
break;
|
||||
return f;
|
||||
}
|
||||
|
||||
/* look up a named fruit by name */
|
||||
struct fruit *
|
||||
fruit_from_name(fname, exact, highest_fid)
|
||||
const char *fname;
|
||||
boolean exact; /* False => prefix or exact match, True = exact match only */
|
||||
int *highest_fid; /* optional output; only valid if 'fname' isn't found */
|
||||
{
|
||||
struct fruit *f, *tentativef;
|
||||
char *altfname;
|
||||
unsigned k;
|
||||
/*
|
||||
* note: named fruits are case-senstive...
|
||||
*/
|
||||
|
||||
if (highest_fid)
|
||||
*highest_fid = 0;
|
||||
/* first try for an exact match */
|
||||
for (f = ffruit; f; f = f->nextf)
|
||||
if (!strcmp(f->fname, fname))
|
||||
return f;
|
||||
else if (highest_fid && f->fid > *highest_fid)
|
||||
*highest_fid = f->fid;
|
||||
|
||||
/* didn't match as-is; if caller is willing to accept a prefix
|
||||
match, try to find one; we want to find the longest prefix that
|
||||
matches, not the first */
|
||||
if (!exact) {
|
||||
tentativef = 0;
|
||||
for (f = ffruit; f; f = f->nextf) {
|
||||
k = strlen(f->fname);
|
||||
if (!strncmp(f->fname, fname, k)
|
||||
&& (!fname[k] || fname[k] == ' ')
|
||||
&& (!tentativef || k > strlen(tentativef->fname)))
|
||||
tentativef = f;
|
||||
}
|
||||
f = tentativef;
|
||||
}
|
||||
/* if we still don't have a match, try singularizing the target;
|
||||
for exact match, that's trivial, but for prefix, it's hard */
|
||||
if (!f) {
|
||||
altfname = makesingular(fname);
|
||||
for (f = ffruit; f; f = f->nextf) {
|
||||
if (!strcmp(f->fname, altfname))
|
||||
break;
|
||||
}
|
||||
releaseobuf(altfname);
|
||||
}
|
||||
if (!f && !exact) {
|
||||
char fnamebuf[BUFSZ], *p;
|
||||
unsigned fname_k = strlen(fname); /* length of assumed plural fname */
|
||||
|
||||
tentativef = 0;
|
||||
for (f = ffruit; f; f = f->nextf) {
|
||||
k = strlen(f->fname);
|
||||
/* reload fnamebuf[] each iteration in case it gets modified;
|
||||
there's no need to recalculate fname_k */
|
||||
Strcpy(fnamebuf, fname);
|
||||
/* bug? if singular of fname is longer than plural,
|
||||
failing the 'fname_k > k' test could skip a viable
|
||||
candidate; unfortunately, we can't singularize until
|
||||
after stripping off trailing stuff and we can't get
|
||||
accurate fname_k until fname has been singularized;
|
||||
compromise and use 'fname_k >= k' instead of '>',
|
||||
accepting 1 char length discrepancy without risking
|
||||
false match (I hope...) */
|
||||
if (fname_k >= k && (p = index(&fnamebuf[k], ' ')) != 0) {
|
||||
*p = '\0'; /* truncate at 1st space past length of f->fname */
|
||||
altfname = makesingular(fnamebuf);
|
||||
k = strlen(altfname); /* actually revised 'fname_k' */
|
||||
if (!strcmp(f->fname, altfname)
|
||||
&& (!tentativef || k > strlen(tentativef->fname)))
|
||||
tentativef = f;
|
||||
releaseobuf(altfname); /* avoid churning through all obufs */
|
||||
}
|
||||
}
|
||||
f = tentativef;
|
||||
}
|
||||
return f;
|
||||
}
|
||||
|
||||
/* sort the named-fruit linked list by fruit index number */
|
||||
void
|
||||
reorder_fruit(forward)
|
||||
boolean forward;
|
||||
{
|
||||
struct fruit *f, *allfr[1 + 127];
|
||||
int i, j, k = SIZE(allfr);
|
||||
|
||||
for (i = 0; i < k; ++i)
|
||||
allfr[i] = (struct fruit *) 0;
|
||||
for (f = ffruit; f; f = f->nextf) {
|
||||
/* without sanity checking, this would reduce to 'allfr[f->fid]=f' */
|
||||
j = f->fid;
|
||||
if (j < 1 || j >= k) {
|
||||
impossible("reorder_fruit: fruit index (%d) out of range", j);
|
||||
return; /* don't sort after all; should never happen... */
|
||||
} else if (allfr[j]) {
|
||||
impossible("reorder_fruit: duplicate fruit index (%d)", j);
|
||||
return;
|
||||
}
|
||||
allfr[j] = f;
|
||||
}
|
||||
ffruit = 0; /* reset linked list; we're rebuilding it from scratch */
|
||||
/* slot [0] will always be empty; must start 'i' at 1 to avoid
|
||||
[k - i] being out of bounds during first iteration */
|
||||
for (i = 1; i < k; ++i) {
|
||||
/* for forward ordering, go through indices from high to low;
|
||||
for backward ordering, go from low to high */
|
||||
j = forward ? (k - i) : i;
|
||||
if (allfr[j]) {
|
||||
allfr[j]->nextf = ffruit;
|
||||
ffruit = allfr[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
char *
|
||||
xname(obj)
|
||||
struct obj *obj;
|
||||
@@ -388,23 +521,20 @@ unsigned cxn_flags; /* bitmask of CXN_xxx values */
|
||||
break;
|
||||
case FOOD_CLASS:
|
||||
if (typ == SLIME_MOLD) {
|
||||
register struct fruit *f;
|
||||
struct fruit *f = fruit_from_indx(obj->spe);
|
||||
|
||||
for (f = ffruit; f; f = f->nextf) {
|
||||
if (f->fid == obj->spe) {
|
||||
Strcpy(buf, f->fname);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!f) {
|
||||
impossible("Bad fruit #%d?", obj->spe);
|
||||
Strcpy(buf, "fruit");
|
||||
} else if (pluralize) {
|
||||
/* ick; already pluralized fruit names
|
||||
are allowed--we want to try to avoid
|
||||
adding a redundant plural suffix */
|
||||
Strcpy(buf, makeplural(makesingular(buf)));
|
||||
pluralize = FALSE;
|
||||
} else {
|
||||
Strcpy(buf, f->fname);
|
||||
if (pluralize) {
|
||||
/* ick; already pluralized fruit names
|
||||
are allowed--we want to try to avoid
|
||||
adding a redundant plural suffix */
|
||||
Strcpy(buf, makeplural(makesingular(buf)));
|
||||
pluralize = FALSE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1493,7 +1623,10 @@ const char *str;
|
||||
buf[0] = lowc(*str);
|
||||
Strcpy(&buf[1], str + 1);
|
||||
return buf;
|
||||
} else if (*str < 'A' || *str > 'Z') {
|
||||
} else if (*str < 'A' || *str > 'Z'
|
||||
/* treat named fruit as not a proper name, even if player
|
||||
has assigned a capitalized proper name as his/her fruit */
|
||||
|| fruit_from_name(str, TRUE, (int *) 0)) {
|
||||
/* not a proper name, needs an article */
|
||||
insert_the = TRUE;
|
||||
} else {
|
||||
@@ -2010,10 +2143,14 @@ char *str;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Plural routine; chiefly used for user-defined fruits. We have to try to
|
||||
* account for everything reasonable the player has; something unreasonable
|
||||
* can still break the code. However, it's still a lot more accurate than
|
||||
* "just add an s at the end", which Rogue uses...
|
||||
/* Plural routine; once upon a time it may have been chiefly used for
|
||||
* user-defined fruits, but it is now used extensively throughout the
|
||||
* program.
|
||||
*
|
||||
* For fruit, we have to try to account for everything reasonable the
|
||||
* player has; something unreasonable can still break the code.
|
||||
* However, it's still a lot more accurate than "just add an 's' at the
|
||||
* end", which Rogue uses...
|
||||
*
|
||||
* Also used for plural monster names ("Wiped out all homunculi." or the
|
||||
* vanquished monsters list) and body parts. A lot of unique monsters have
|
||||
@@ -2847,9 +2984,14 @@ struct obj *no_wish;
|
||||
if (!strstri(bp, "wand ") && !strstri(bp, "spellbook ")
|
||||
&& !strstri(bp, "finger ")) {
|
||||
if ((p = strstri(bp, "tin of ")) != 0) {
|
||||
tmp = tin_variety_txt(p + 7, &tinv);
|
||||
tvariety = tinv;
|
||||
mntmp = name_to_mon(p + 7 + tmp);
|
||||
if (!strcmpi(p + 7, "spinach")) {
|
||||
contents = SPINACH;
|
||||
mntmp = NON_PM;
|
||||
} else {
|
||||
tmp = tin_variety_txt(p + 7, &tinv);
|
||||
tvariety = tinv;
|
||||
mntmp = name_to_mon(p + 7 + tmp);
|
||||
}
|
||||
typ = TIN;
|
||||
goto typfnd;
|
||||
} else if ((p = strstri(bp, " of ")) != 0
|
||||
@@ -2858,35 +3000,32 @@ struct obj *no_wish;
|
||||
}
|
||||
}
|
||||
/* Find corpse type w/o "of" (red dragon scale mail, yeti corpse) */
|
||||
if (strncmpi(bp, "samurai sword", 13)) /* not the "samurai" monster! */
|
||||
if (strncmpi(bp, "wizard lock", 11)) /* not the "wizard" monster! */
|
||||
if (strncmpi(bp, "ninja-to", 8)) /* not the "ninja" rank */
|
||||
if (strncmpi(bp, "master key",
|
||||
10)) /* not the "master" rank */
|
||||
if (strncmpi(bp, "magenta", 7)) /* not the "mage" rank */
|
||||
if (mntmp < LOW_PM && strlen(bp) > 2
|
||||
&& (mntmp = name_to_mon(bp)) >= LOW_PM) {
|
||||
int mntmptoo,
|
||||
mntmplen; /* double check for rank title */
|
||||
char *obp = bp;
|
||||
mntmptoo = title_to_mon(bp, (int *) 0, &mntmplen);
|
||||
bp += mntmp != mntmptoo
|
||||
? (int) strlen(mons[mntmp].mname)
|
||||
if (strncmpi(bp, "samurai sword", 13) /* not the "samurai" monster! */
|
||||
&& strncmpi(bp, "wizard lock", 11) /* not the "wizard" monster! */
|
||||
&& strncmpi(bp, "ninja-to", 8) /* not the "ninja" rank */
|
||||
&& strncmpi(bp, "master key", 10) /* not the "master" rank */
|
||||
&& strncmpi(bp, "magenta", 7)) { /* not the "mage" rank */
|
||||
if (mntmp < LOW_PM && strlen(bp) > 2
|
||||
&& (mntmp = name_to_mon(bp)) >= LOW_PM) {
|
||||
int mntmptoo, mntmplen; /* double check for rank title */
|
||||
char *obp = bp;
|
||||
|
||||
mntmptoo = title_to_mon(bp, (int *) 0, &mntmplen);
|
||||
bp += (mntmp != mntmptoo) ? (int) strlen(mons[mntmp].mname)
|
||||
: mntmplen;
|
||||
if (*bp == ' ')
|
||||
bp++;
|
||||
else if (!strncmpi(bp, "s ", 2))
|
||||
bp += 2;
|
||||
else if (!strncmpi(bp, "es ", 3))
|
||||
bp += 3;
|
||||
else if (!*bp && !actualn && !dn && !un
|
||||
&& !oclass) {
|
||||
/* no referent; they don't really mean a
|
||||
* monster type */
|
||||
bp = obp;
|
||||
mntmp = NON_PM;
|
||||
}
|
||||
}
|
||||
if (*bp == ' ') {
|
||||
bp++;
|
||||
} else if (!strncmpi(bp, "s ", 2)) {
|
||||
bp += 2;
|
||||
} else if (!strncmpi(bp, "es ", 3)) {
|
||||
bp += 3;
|
||||
} else if (!*bp && !actualn && !dn && !un && !oclass) {
|
||||
/* no referent; they don't really mean a monster type */
|
||||
bp = obp;
|
||||
mntmp = NON_PM;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* first change to singular if necessary */
|
||||
if (*bp) {
|
||||
@@ -2952,7 +3091,8 @@ struct obj *no_wish;
|
||||
* gold/money concept. Maybe we want to add other monetary units as
|
||||
* well in the future. (TH)
|
||||
*/
|
||||
if (!BSTRCMPI(bp, p - 10, "gold piece") || !BSTRCMPI(bp, p - 7, "zorkmid")
|
||||
if (!BSTRCMPI(bp, p - 10, "gold piece")
|
||||
|| !BSTRCMPI(bp, p - 7, "zorkmid")
|
||||
|| !strcmpi(bp, "gold") || !strcmpi(bp, "money")
|
||||
|| !strcmpi(bp, "coin") || *bp == GOLD_SYM) {
|
||||
if (cnt > 5000 && !wizard)
|
||||
@@ -2975,15 +3115,19 @@ struct obj *no_wish;
|
||||
|
||||
/* Search for class names: XXXXX potion, scroll of XXXXX. Avoid */
|
||||
/* false hits on, e.g., rings for "ring mail". */
|
||||
if (strncmpi(bp, "enchant ", 8) && strncmpi(bp, "destroy ", 8)
|
||||
if (strncmpi(bp, "enchant ", 8)
|
||||
&& strncmpi(bp, "destroy ", 8)
|
||||
&& strncmpi(bp, "detect food", 11)
|
||||
&& strncmpi(bp, "food detection", 14) && strncmpi(bp, "ring mail", 9)
|
||||
&& strncmpi(bp, "food detection", 14)
|
||||
&& strncmpi(bp, "ring mail", 9)
|
||||
&& strncmpi(bp, "studded leather armor", 21)
|
||||
&& strncmpi(bp, "leather armor", 13)
|
||||
&& strncmpi(bp, "tooled horn", 11) && strncmpi(bp, "food ration", 11)
|
||||
&& strncmpi(bp, "tooled horn", 11)
|
||||
&& strncmpi(bp, "food ration", 11)
|
||||
&& strncmpi(bp, "meat ring", 9))
|
||||
for (i = 0; i < (int) (sizeof wrpsym); i++) {
|
||||
register int j = strlen(wrp[i]);
|
||||
|
||||
if (!strncmpi(bp, wrp[i], j)) {
|
||||
oclass = wrpsym[i];
|
||||
if (oclass != AMULET_CLASS) {
|
||||
@@ -3099,11 +3243,17 @@ srch:
|
||||
for (i = bases[GEM_CLASS]; i <= LAST_GEM; i++) {
|
||||
register const char *zn;
|
||||
|
||||
if ((zn = OBJ_NAME(objects[i])) && !strcmpi(actualn, zn)) {
|
||||
if ((zn = OBJ_NAME(objects[i])) != 0 && !strcmpi(actualn, zn)) {
|
||||
typ = i;
|
||||
goto typfnd;
|
||||
}
|
||||
}
|
||||
/* "tin of foo" would be caught above, but plain "tin" has
|
||||
a random chance of yielding "tin wand" unless we do this */
|
||||
if (!strcmpi(actualn, "tin")) {
|
||||
typ = TIN;
|
||||
goto typfnd;
|
||||
}
|
||||
}
|
||||
|
||||
if (((typ = rnd_otyp_by_namedesc(actualn, oclass)) != STRANGE_OBJECT)
|
||||
|
||||
+103
-42
@@ -233,7 +233,7 @@ static struct Bool_Opt {
|
||||
{ "vt_tiledata", (boolean *) 0, FALSE, SET_IN_FILE },
|
||||
#endif
|
||||
{ "whatis_menu", &iflags.getloc_usemenu, FALSE, SET_IN_GAME },
|
||||
{ "whatis_inview", &iflags.getloc_limitview, FALSE, SET_IN_GAME },
|
||||
{ "whatis_moveskip", &iflags.getloc_moveskip, FALSE, SET_IN_GAME },
|
||||
{ "wizweight", &iflags.wizweight, FALSE, SET_IN_WIZGAME },
|
||||
{ "wraptext", &iflags.wc2_wraptext, FALSE, SET_IN_GAME },
|
||||
#ifdef ZEROCOMP
|
||||
@@ -403,6 +403,8 @@ static struct Comp_Opt {
|
||||
#endif
|
||||
{ "whatis_coord", "show coordinates when auto-describing cursor position",
|
||||
1, SET_IN_GAME },
|
||||
{ "whatis_filter", "filter coordinate locations when targeting next or previous",
|
||||
1, SET_IN_GAME },
|
||||
{ "windowcolors", "the foreground/background colors of windows", /*WC*/
|
||||
80, DISP_IN_GAME },
|
||||
{ "windowtype", "windowing system to use", WINTYPELEN, DISP_IN_GAME },
|
||||
@@ -2341,32 +2343,32 @@ boolean tinitial, tfrom_file;
|
||||
return;
|
||||
if (!initial) {
|
||||
struct fruit *f;
|
||||
int fnum = 0;
|
||||
|
||||
num = 0;
|
||||
for (f = ffruit; f; f = f->nextf) {
|
||||
if (!strcmp(op, f->fname))
|
||||
break;
|
||||
num++;
|
||||
}
|
||||
if (!flags.made_fruit) {
|
||||
for (forig = ffruit; forig; forig = forig->nextf) {
|
||||
if (!strcmp(pl_fruit, forig->fname)) {
|
||||
break;
|
||||
}
|
||||
/* count number of named fruits; if 'op' is found among them,
|
||||
then the count doesn't matter because we won't be adding it */
|
||||
f = fruit_from_name(op, FALSE, &fnum);
|
||||
if (!f) {
|
||||
if (!flags.made_fruit)
|
||||
forig = fruit_from_name(pl_fruit, FALSE, (int *) 0);
|
||||
|
||||
if (!forig && fnum >= 100) {
|
||||
pline("Doing that so many times isn't very fruitful.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!forig && num >= 100) {
|
||||
pline("Doing that so many times isn't very fruitful.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
goodfruit:
|
||||
nmcpy(pl_fruit, op, PL_FSIZ);
|
||||
sanitize_name(pl_fruit);
|
||||
/* OBJ_NAME(objects[SLIME_MOLD]) won't work after initialization */
|
||||
/* OBJ_NAME(objects[SLIME_MOLD]) won't work for this after
|
||||
initialization; it gets changed to generic "fruit" */
|
||||
if (!*pl_fruit)
|
||||
nmcpy(pl_fruit, "slime mold", PL_FSIZ);
|
||||
if (!initial) {
|
||||
/* if 'forig' is nonNull, we replace it rather than add
|
||||
a new fruit; it can only be nonNull if no fruits have
|
||||
been created since the previous name was put in place */
|
||||
(void) fruitadd(pl_fruit, forig);
|
||||
pline("Fruit is now \"%s\".", pl_fruit);
|
||||
}
|
||||
@@ -2379,7 +2381,7 @@ boolean tinitial, tfrom_file;
|
||||
}
|
||||
|
||||
fullname = "whatis_coord";
|
||||
if (match_optname(opts, fullname, 6, TRUE)) {
|
||||
if (match_optname(opts, fullname, 8, TRUE)) {
|
||||
if (duplicate)
|
||||
complain_about_duplicate(opts, 1);
|
||||
if (negated) {
|
||||
@@ -2399,6 +2401,33 @@ boolean tinitial, tfrom_file;
|
||||
return;
|
||||
}
|
||||
|
||||
fullname = "whatis_filter";
|
||||
if (match_optname(opts, fullname, 8, TRUE)) {
|
||||
if (duplicate)
|
||||
complain_about_duplicate(opts, 1);
|
||||
if (negated) {
|
||||
iflags.getloc_filter = GFILTER_NONE;
|
||||
return;
|
||||
} else if ((op = string_for_env_opt(fullname, opts, FALSE)) != 0) {
|
||||
char c = lowc(*op);
|
||||
|
||||
switch (c) {
|
||||
case 'n':
|
||||
iflags.getloc_filter = GFILTER_NONE;
|
||||
break;
|
||||
case 'v':
|
||||
iflags.getloc_filter = GFILTER_VIEW;
|
||||
break;
|
||||
case 'a':
|
||||
iflags.getloc_filter = GFILTER_AREA;
|
||||
break;
|
||||
default:
|
||||
badoption(opts);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
fullname = "warnings";
|
||||
if (match_optname(opts, fullname, 5, TRUE)) {
|
||||
if (duplicate)
|
||||
@@ -4283,6 +4312,37 @@ boolean setinitial, setfromfile;
|
||||
free((genericptr_t) window_pick);
|
||||
}
|
||||
destroy_nhwindow(tmpwin);
|
||||
} else if (!strcmp("whatis_filter", optname)) {
|
||||
menu_item *window_pick = (menu_item *) 0;
|
||||
int pick_cnt;
|
||||
char gf = iflags.getloc_filter;
|
||||
|
||||
tmpwin = create_nhwindow(NHW_MENU);
|
||||
start_menu(tmpwin);
|
||||
any = zeroany;
|
||||
any.a_char = (GFILTER_NONE + 1);
|
||||
add_menu(tmpwin, NO_GLYPH, &any, 'n',
|
||||
0, ATR_NONE, "no filtering",
|
||||
(gf == GFILTER_NONE) ? MENU_SELECTED : MENU_UNSELECTED);
|
||||
any.a_char = (GFILTER_VIEW + 1);
|
||||
add_menu(tmpwin, NO_GLYPH, &any, 'v',
|
||||
0, ATR_NONE, "in view only",
|
||||
(gf == GFILTER_VIEW) ? MENU_SELECTED : MENU_UNSELECTED);
|
||||
any.a_char = (GFILTER_AREA + 1);
|
||||
add_menu(tmpwin, NO_GLYPH, &any, 'a',
|
||||
0, ATR_NONE, "in same area",
|
||||
(gf == GFILTER_AREA) ? MENU_SELECTED : MENU_UNSELECTED);
|
||||
end_menu(tmpwin,
|
||||
"Select location filtering when going for next/previous map position:");
|
||||
if ((pick_cnt = select_menu(tmpwin, PICK_ONE, &window_pick)) > 0) {
|
||||
iflags.getloc_filter = (window_pick[0].item.a_char - 1);
|
||||
/* PICK_ONE doesn't unselect preselected entry when
|
||||
selecting another one */
|
||||
if (pick_cnt > 1 && iflags.getloc_filter == gf)
|
||||
iflags.getloc_filter = (window_pick[1].item.a_char - 1);
|
||||
free((genericptr_t) window_pick);
|
||||
}
|
||||
destroy_nhwindow(tmpwin);
|
||||
} else if (!strcmp("msg_window", optname)) {
|
||||
#ifdef TTY_GRAPHICS
|
||||
/* by Christian W. Cooper */
|
||||
@@ -5057,6 +5117,11 @@ char *buf;
|
||||
: (iflags.getpos_coords == GPCOORDS_COMFULL) ? "full compass"
|
||||
: (iflags.getpos_coords == GPCOORDS_SCREEN) ? "screen"
|
||||
: "none");
|
||||
} else if (!strcmp(optname, "whatis_filter")) {
|
||||
Sprintf(buf, "%s",
|
||||
(iflags.getloc_filter == GFILTER_VIEW) ? "view"
|
||||
: (iflags.getloc_filter == GFILTER_AREA) ? "area"
|
||||
: "none");
|
||||
} else if (!strcmp(optname, "scores")) {
|
||||
Sprintf(buf, "%d top/%d around%s", flags.end_top, flags.end_around,
|
||||
flags.end_own ? "/own" : "");
|
||||
@@ -5574,7 +5639,6 @@ struct fruit *replace_fruit;
|
||||
/* disallow naming after other foods (since it'd be impossible
|
||||
* to tell the difference)
|
||||
*/
|
||||
|
||||
for (i = bases[FOOD_CLASS]; objects[i].oc_class == FOOD_CLASS; i++) {
|
||||
if (!strcmp(OBJ_NAME(objects[i]), pl_fruit)) {
|
||||
found = TRUE;
|
||||
@@ -5584,15 +5648,15 @@ struct fruit *replace_fruit;
|
||||
{
|
||||
char *c;
|
||||
|
||||
c = pl_fruit;
|
||||
|
||||
for (c = pl_fruit; *c >= '0' && *c <= '9'; c++)
|
||||
;
|
||||
continue;
|
||||
if (isspace((uchar) *c) || *c == 0)
|
||||
numeric = TRUE;
|
||||
}
|
||||
if (found || numeric || !strncmp(str, "cursed ", 7)
|
||||
|| !strncmp(str, "uncursed ", 9) || !strncmp(str, "blessed ", 8)
|
||||
if (found || numeric
|
||||
|| !strncmp(str, "cursed ", 7)
|
||||
|| !strncmp(str, "uncursed ", 9)
|
||||
|| !strncmp(str, "blessed ", 8)
|
||||
|| !strncmp(str, "partly eaten ", 13)
|
||||
|| (!strncmp(str, "tin of ", 7)
|
||||
&& (!strcmp(str + 7, "spinach")
|
||||
@@ -5615,42 +5679,39 @@ struct fruit *replace_fruit;
|
||||
*/
|
||||
flags.made_fruit = FALSE;
|
||||
if (replace_fruit) {
|
||||
for (f = ffruit; f; f = f->nextf) {
|
||||
if (f == replace_fruit) {
|
||||
copynchars(f->fname, str, PL_FSIZ - 1);
|
||||
goto nonew;
|
||||
}
|
||||
}
|
||||
/* replace_fruit is already part of the fruit chain;
|
||||
update it in place rather than looking it up again */
|
||||
f = replace_fruit;
|
||||
copynchars(f->fname, str, PL_FSIZ - 1);
|
||||
goto nonew;
|
||||
}
|
||||
} else {
|
||||
/* not user_supplied, so assumed to be from bones */
|
||||
copynchars(altname, str, PL_FSIZ - 1);
|
||||
sanitize_name(altname);
|
||||
flags.made_fruit = TRUE; /* for safety. Any fruit name added from a
|
||||
bones level should exist anyway. */
|
||||
* bones level should exist anyway. */
|
||||
}
|
||||
for (f = ffruit; f; f = f->nextf) {
|
||||
if (f->fid > highest_fruit_id)
|
||||
highest_fruit_id = f->fid;
|
||||
if (!strncmp(str, f->fname, PL_FSIZ - 1)
|
||||
|| (*altname && !strcmp(altname, f->fname)))
|
||||
goto nonew;
|
||||
}
|
||||
/* if adding another fruit would overflow spe, use a random
|
||||
fruit instead... we've got a lot to choose from.
|
||||
f = fruit_from_name(*altname ? altname : str, FALSE, &highest_fruit_id);
|
||||
if (f)
|
||||
goto nonew;
|
||||
|
||||
/* Maximum number of named fruits is 127, even if obj->spe can
|
||||
handle bigger values. If adding another fruit would overflow,
|
||||
use a random fruit instead... we've got a lot to choose from.
|
||||
current_fruit remains as is. */
|
||||
if (highest_fruit_id >= 127)
|
||||
return rnd(127);
|
||||
|
||||
f = newfruit();
|
||||
(void) memset((genericptr_t)f, 0, sizeof(struct fruit));
|
||||
(void) memset((genericptr_t) f, 0, sizeof (struct fruit));
|
||||
copynchars(f->fname, *altname ? altname : str, PL_FSIZ - 1);
|
||||
f->fid = ++highest_fruit_id;
|
||||
/* we used to go out of our way to add it at the end of the list,
|
||||
but the order is arbitrary so use simpler insertion at start */
|
||||
f->nextf = ffruit;
|
||||
ffruit = f;
|
||||
nonew:
|
||||
nonew:
|
||||
if (user_specified)
|
||||
context.current_fruit = f->fid;
|
||||
return f->fid;
|
||||
|
||||
+5
-3
@@ -177,6 +177,8 @@ int *menu_on_demand;
|
||||
}
|
||||
if (itemcount && menu_on_demand)
|
||||
ilets[iletct++] = 'm';
|
||||
if (count_unpaid(objs))
|
||||
ilets[iletct++] = 'u';
|
||||
|
||||
tally_BUCX(objs, here, &bcnt, &ucnt, &ccnt, &xcnt, &ocnt);
|
||||
if (bcnt)
|
||||
@@ -222,8 +224,8 @@ int *menu_on_demand;
|
||||
goto ask_again;
|
||||
} else if (sym == 'm') {
|
||||
m_seen = TRUE;
|
||||
} else if (index("BUCX", sym)) {
|
||||
add_valid_menu_class(sym); /* 'B','U','C',or 'X' */
|
||||
} else if (index("uBUCX", sym)) {
|
||||
add_valid_menu_class(sym); /* 'u' or 'B','U','C',or 'X' */
|
||||
filtered = TRUE;
|
||||
} else {
|
||||
oc_of_sym = def_char_to_objclass(sym);
|
||||
@@ -2666,7 +2668,7 @@ boolean put_in;
|
||||
} else if (flags.menu_style == MENU_FULL) {
|
||||
all_categories = FALSE;
|
||||
Sprintf(buf, "%s what type of objects?", action);
|
||||
mflags = (ALL_TYPES | BUCX_TYPES);
|
||||
mflags = (ALL_TYPES | UNPAID_TYPES | BUCX_TYPES);
|
||||
if (put_in)
|
||||
mflags |= CHOOSE_ALL;
|
||||
n = query_category(buf, put_in ? invent : current_container->cobj,
|
||||
|
||||
+6
-270
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 pline.c $NHDT-Date: 1490908465 2017/03/30 21:14:25 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.58 $ */
|
||||
/* NetHack 3.6 pline.c $NHDT-Date: 1501803108 2017/08/03 23:31:48 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.61 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
@@ -435,276 +435,12 @@ VA_DECL(const char *, s)
|
||||
Vsprintf(pbuf, s, VA_ARGS);
|
||||
pbuf[BUFSZ - 1] = '\0'; /* sanity */
|
||||
paniclog("impossible", pbuf);
|
||||
pline("%s", pbuf);
|
||||
pline("Program in disorder - perhaps you'd better #quit.");
|
||||
pline("%s", VA_PASS1(pbuf));
|
||||
pline("%s", VA_PASS1("Program in disorder - perhaps you'd better #quit."));
|
||||
program_state.in_impossible = 0;
|
||||
VA_END();
|
||||
}
|
||||
|
||||
const char *
|
||||
align_str(alignment)
|
||||
aligntyp alignment;
|
||||
{
|
||||
switch ((int) alignment) {
|
||||
case A_CHAOTIC:
|
||||
return "chaotic";
|
||||
case A_NEUTRAL:
|
||||
return "neutral";
|
||||
case A_LAWFUL:
|
||||
return "lawful";
|
||||
case A_NONE:
|
||||
return "unaligned";
|
||||
}
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
void
|
||||
mstatusline(mtmp)
|
||||
register struct monst *mtmp;
|
||||
{
|
||||
aligntyp alignment = mon_aligntyp(mtmp);
|
||||
char info[BUFSZ], monnambuf[BUFSZ];
|
||||
|
||||
info[0] = 0;
|
||||
if (mtmp->mtame) {
|
||||
Strcat(info, ", tame");
|
||||
if (wizard) {
|
||||
Sprintf(eos(info), " (%d", mtmp->mtame);
|
||||
if (!mtmp->isminion)
|
||||
Sprintf(eos(info), "; hungry %ld; apport %d",
|
||||
EDOG(mtmp)->hungrytime, EDOG(mtmp)->apport);
|
||||
Strcat(info, ")");
|
||||
}
|
||||
} else if (mtmp->mpeaceful)
|
||||
Strcat(info, ", peaceful");
|
||||
|
||||
if (mtmp->data == &mons[PM_LONG_WORM]) {
|
||||
int segndx, nsegs = count_wsegs(mtmp);
|
||||
|
||||
/* the worm code internals don't consider the head of be one of
|
||||
the worm's segments, but we count it as such when presenting
|
||||
worm feedback to the player */
|
||||
if (!nsegs) {
|
||||
Strcat(info, ", single segment");
|
||||
} else {
|
||||
++nsegs; /* include head in the segment count */
|
||||
segndx = wseg_at(mtmp, bhitpos.x, bhitpos.y);
|
||||
Sprintf(eos(info), ", %d%s of %d segments",
|
||||
segndx, ordin(segndx), nsegs);
|
||||
}
|
||||
}
|
||||
if (mtmp->cham >= LOW_PM && mtmp->data != &mons[mtmp->cham])
|
||||
/* don't reveal the innate form (chameleon, vampire, &c),
|
||||
just expose the fact that this current form isn't it */
|
||||
Strcat(info, ", shapechanger");
|
||||
/* pets eating mimic corpses mimic while eating, so this comes first */
|
||||
if (mtmp->meating)
|
||||
Strcat(info, ", eating");
|
||||
/* a stethoscope exposes mimic before getting here so this
|
||||
won't be relevant for it, but wand of probing doesn't */
|
||||
if (mtmp->mundetected || mtmp->m_ap_type)
|
||||
mhidden_description(mtmp, TRUE, eos(info));
|
||||
if (mtmp->mcan)
|
||||
Strcat(info, ", cancelled");
|
||||
if (mtmp->mconf)
|
||||
Strcat(info, ", confused");
|
||||
if (mtmp->mblinded || !mtmp->mcansee)
|
||||
Strcat(info, ", blind");
|
||||
if (mtmp->mstun)
|
||||
Strcat(info, ", stunned");
|
||||
if (mtmp->msleeping)
|
||||
Strcat(info, ", asleep");
|
||||
#if 0 /* unfortunately mfrozen covers temporary sleep and being busy \
|
||||
(donning armor, for instance) as well as paralysis */
|
||||
else if (mtmp->mfrozen)
|
||||
Strcat(info, ", paralyzed");
|
||||
#else
|
||||
else if (mtmp->mfrozen || !mtmp->mcanmove)
|
||||
Strcat(info, ", can't move");
|
||||
#endif
|
||||
/* [arbitrary reason why it isn't moving] */
|
||||
else if (mtmp->mstrategy & STRAT_WAITMASK)
|
||||
Strcat(info, ", meditating");
|
||||
if (mtmp->mflee)
|
||||
Strcat(info, ", scared");
|
||||
if (mtmp->mtrapped)
|
||||
Strcat(info, ", trapped");
|
||||
if (mtmp->mspeed)
|
||||
Strcat(info, mtmp->mspeed == MFAST ? ", fast" : mtmp->mspeed == MSLOW
|
||||
? ", slow"
|
||||
: ", ???? speed");
|
||||
if (mtmp->minvis)
|
||||
Strcat(info, ", invisible");
|
||||
if (mtmp == u.ustuck)
|
||||
Strcat(info, sticks(youmonst.data)
|
||||
? ", held by you"
|
||||
: !u.uswallow ? ", holding you"
|
||||
: attacktype_fordmg(u.ustuck->data,
|
||||
AT_ENGL, AD_DGST)
|
||||
? ", digesting you"
|
||||
: is_animal(u.ustuck->data)
|
||||
? ", swallowing you"
|
||||
: ", engulfing you");
|
||||
if (mtmp == u.usteed)
|
||||
Strcat(info, ", carrying you");
|
||||
|
||||
/* avoid "Status of the invisible newt ..., invisible" */
|
||||
/* and unlike a normal mon_nam, use "saddled" even if it has a name */
|
||||
Strcpy(monnambuf, x_monnam(mtmp, ARTICLE_THE, (char *) 0,
|
||||
(SUPPRESS_IT | SUPPRESS_INVISIBLE), FALSE));
|
||||
|
||||
pline("Status of %s (%s): Level %d HP %d(%d) AC %d%s.", monnambuf,
|
||||
align_str(alignment), mtmp->m_lev, mtmp->mhp, mtmp->mhpmax,
|
||||
find_mac(mtmp), info);
|
||||
}
|
||||
|
||||
void
|
||||
ustatusline()
|
||||
{
|
||||
char info[BUFSZ];
|
||||
|
||||
info[0] = '\0';
|
||||
if (Sick) {
|
||||
Strcat(info, ", dying from");
|
||||
if (u.usick_type & SICK_VOMITABLE)
|
||||
Strcat(info, " food poisoning");
|
||||
if (u.usick_type & SICK_NONVOMITABLE) {
|
||||
if (u.usick_type & SICK_VOMITABLE)
|
||||
Strcat(info, " and");
|
||||
Strcat(info, " illness");
|
||||
}
|
||||
}
|
||||
if (Stoned)
|
||||
Strcat(info, ", solidifying");
|
||||
if (Slimed)
|
||||
Strcat(info, ", becoming slimy");
|
||||
if (Strangled)
|
||||
Strcat(info, ", being strangled");
|
||||
if (Vomiting)
|
||||
Strcat(info, ", nauseated"); /* !"nauseous" */
|
||||
if (Confusion)
|
||||
Strcat(info, ", confused");
|
||||
if (Blind) {
|
||||
Strcat(info, ", blind");
|
||||
if (u.ucreamed) {
|
||||
if ((long) u.ucreamed < Blinded || Blindfolded
|
||||
|| !haseyes(youmonst.data))
|
||||
Strcat(info, ", cover");
|
||||
Strcat(info, "ed by sticky goop");
|
||||
} /* note: "goop" == "glop"; variation is intentional */
|
||||
}
|
||||
if (Stunned)
|
||||
Strcat(info, ", stunned");
|
||||
if (!u.usteed && Wounded_legs) {
|
||||
const char *what = body_part(LEG);
|
||||
if ((Wounded_legs & BOTH_SIDES) == BOTH_SIDES)
|
||||
what = makeplural(what);
|
||||
Sprintf(eos(info), ", injured %s", what);
|
||||
}
|
||||
if (Glib)
|
||||
Sprintf(eos(info), ", slippery %s", makeplural(body_part(HAND)));
|
||||
if (u.utrap)
|
||||
Strcat(info, ", trapped");
|
||||
if (Fast)
|
||||
Strcat(info, Very_fast ? ", very fast" : ", fast");
|
||||
if (u.uundetected)
|
||||
Strcat(info, ", concealed");
|
||||
if (Invis)
|
||||
Strcat(info, ", invisible");
|
||||
if (u.ustuck) {
|
||||
if (sticks(youmonst.data))
|
||||
Strcat(info, ", holding ");
|
||||
else
|
||||
Strcat(info, ", held by ");
|
||||
Strcat(info, mon_nam(u.ustuck));
|
||||
}
|
||||
|
||||
pline("Status of %s (%s): Level %d HP %d(%d) AC %d%s.", plname,
|
||||
piousness(FALSE, align_str(u.ualign.type)),
|
||||
Upolyd ? mons[u.umonnum].mlevel : u.ulevel, Upolyd ? u.mh : u.uhp,
|
||||
Upolyd ? u.mhmax : u.uhpmax, u.uac, info);
|
||||
}
|
||||
|
||||
void
|
||||
self_invis_message()
|
||||
{
|
||||
pline("%s %s.",
|
||||
Hallucination ? "Far out, man! You" : "Gee! All of a sudden, you",
|
||||
See_invisible ? "can see right through yourself"
|
||||
: "can't see yourself");
|
||||
}
|
||||
|
||||
char *
|
||||
piousness(showneg, suffix)
|
||||
boolean showneg;
|
||||
const char *suffix;
|
||||
{
|
||||
static char buf[32]; /* bigger than "insufficiently neutral" */
|
||||
const char *pio;
|
||||
|
||||
/* note: piousness 20 matches MIN_QUEST_ALIGN (quest.h) */
|
||||
if (u.ualign.record >= 20)
|
||||
pio = "piously";
|
||||
else if (u.ualign.record > 13)
|
||||
pio = "devoutly";
|
||||
else if (u.ualign.record > 8)
|
||||
pio = "fervently";
|
||||
else if (u.ualign.record > 3)
|
||||
pio = "stridently";
|
||||
else if (u.ualign.record == 3)
|
||||
pio = "";
|
||||
else if (u.ualign.record > 0)
|
||||
pio = "haltingly";
|
||||
else if (u.ualign.record == 0)
|
||||
pio = "nominally";
|
||||
else if (!showneg)
|
||||
pio = "insufficiently";
|
||||
else if (u.ualign.record >= -3)
|
||||
pio = "strayed";
|
||||
else if (u.ualign.record >= -8)
|
||||
pio = "sinned";
|
||||
else
|
||||
pio = "transgressed";
|
||||
|
||||
Sprintf(buf, "%s", pio);
|
||||
if (suffix && (!showneg || u.ualign.record >= 0)) {
|
||||
if (u.ualign.record != 3)
|
||||
Strcat(buf, " ");
|
||||
Strcat(buf, suffix);
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
void
|
||||
pudding_merge_message(otmp, otmp2)
|
||||
struct obj *otmp;
|
||||
struct obj *otmp2;
|
||||
{
|
||||
boolean visible =
|
||||
cansee(otmp->ox, otmp->oy) || cansee(otmp2->ox, otmp2->oy);
|
||||
boolean onfloor = otmp->where == OBJ_FLOOR || otmp2->where == OBJ_FLOOR;
|
||||
boolean inpack = carried(otmp) || carried(otmp2);
|
||||
|
||||
/* the player will know something happened inside his own inventory */
|
||||
if ((!Blind && visible) || inpack) {
|
||||
if (Hallucination) {
|
||||
if (onfloor) {
|
||||
You_see("parts of the floor melting!");
|
||||
} else if (inpack) {
|
||||
Your("pack reaches out and grabs something!");
|
||||
}
|
||||
/* even though we can see where they should be,
|
||||
* they'll be out of our view (minvent or container)
|
||||
* so don't actually show anything */
|
||||
} else if (onfloor || inpack) {
|
||||
pline("The %s coalesce%s.", makeplural(obj_typename(otmp->otyp)),
|
||||
inpack ? " inside your pack" : "");
|
||||
}
|
||||
} else {
|
||||
You_hear("a faint sloshing sound.");
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(MSGHANDLER) && (defined(POSIX_TYPES) || defined(__GNUC__))
|
||||
static boolean use_pline_handler = TRUE;
|
||||
static void
|
||||
@@ -732,16 +468,16 @@ const char *line;
|
||||
(void) setuid(getuid());
|
||||
(void) execv(args[0], (char *const *) args);
|
||||
perror((char *) 0);
|
||||
(void) fprintf(stderr, "Exec to message handler %s failed.\n",
|
||||
env);
|
||||
(void) fprintf(stderr, "Exec to message handler %s failed.\n", env);
|
||||
terminate(EXIT_FAILURE);
|
||||
} else if (f > 0) {
|
||||
int status;
|
||||
|
||||
waitpid(f, &status, 0);
|
||||
} else if (f == -1) {
|
||||
perror((char *) 0);
|
||||
use_pline_handler = FALSE;
|
||||
pline("Fork to message handler failed.");
|
||||
pline("%s", VA_PASS1("Fork to message handler failed."));
|
||||
}
|
||||
}
|
||||
#endif /* defined(POSIX_TYPES) || defined(__GNUC__) */
|
||||
|
||||
+34
-7
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 potion.c $NHDT-Date: 1455407631 2016/02/13 23:53:51 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.129 $ */
|
||||
/* NetHack 3.6 potion.c $NHDT-Date: 1502753790 2017/08/14 23:36:30 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.138 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
@@ -408,6 +408,16 @@ boolean talk;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
self_invis_message()
|
||||
{
|
||||
pline("%s %s.",
|
||||
Hallucination ? "Far out, man! You"
|
||||
: "Gee! All of a sudden, you",
|
||||
See_invisible ? "can see right through yourself"
|
||||
: "can't see yourself");
|
||||
}
|
||||
|
||||
STATIC_OVL void
|
||||
ghost_from_bottle()
|
||||
{
|
||||
@@ -1333,15 +1343,22 @@ boolean your_fault;
|
||||
if (useeit && !affected)
|
||||
pline("%s %s wet.", buf, aobjnam(saddle, "get"));
|
||||
} else {
|
||||
boolean angermon = your_fault;
|
||||
boolean angermon = your_fault, cureblind = FALSE;
|
||||
|
||||
switch (obj->otyp) {
|
||||
case POT_HEALING:
|
||||
case POT_EXTRA_HEALING:
|
||||
case POT_FULL_HEALING:
|
||||
cureblind = TRUE;
|
||||
/*FALLTHRU*/
|
||||
case POT_EXTRA_HEALING:
|
||||
if (!obj->cursed)
|
||||
cureblind = TRUE;
|
||||
/*FALLTHRU*/
|
||||
case POT_HEALING:
|
||||
if (obj->blessed)
|
||||
cureblind = TRUE;
|
||||
if (mon->data == &mons[PM_PESTILENCE])
|
||||
goto do_illness;
|
||||
/*FALLTHRU*/
|
||||
/*FALLTHRU*/
|
||||
case POT_RESTORE_ABILITY:
|
||||
case POT_GAIN_ABILITY:
|
||||
do_healing:
|
||||
@@ -1351,6 +1368,8 @@ boolean your_fault;
|
||||
if (canseemon(mon))
|
||||
pline("%s looks sound and hale again.", Monnam(mon));
|
||||
}
|
||||
if (cureblind)
|
||||
mcureblindness(mon, canseemon(mon));
|
||||
break;
|
||||
case POT_SICKNESS:
|
||||
if (mon->data == &mons[PM_PESTILENCE])
|
||||
@@ -1409,7 +1428,7 @@ boolean your_fault;
|
||||
break;
|
||||
case POT_BLINDNESS:
|
||||
if (haseyes(mon->data)) {
|
||||
register int btmp = 64 + rn2(32)
|
||||
int btmp = 64 + rn2(32)
|
||||
+ rn2(32) * !resist(mon, POTION_CLASS, 0, NOTELL);
|
||||
|
||||
btmp += mon->mblinded;
|
||||
@@ -1524,7 +1543,8 @@ void
|
||||
potionbreathe(obj)
|
||||
register struct obj *obj;
|
||||
{
|
||||
register int i, ii, isdone, kn = 0;
|
||||
int i, ii, isdone, kn = 0;
|
||||
boolean cureblind = FALSE;
|
||||
|
||||
switch (obj->otyp) {
|
||||
case POT_RESTORE_ABILITY:
|
||||
@@ -1559,18 +1579,25 @@ register struct obj *obj;
|
||||
u.mh++, context.botl = 1;
|
||||
if (u.uhp < u.uhpmax)
|
||||
u.uhp++, context.botl = 1;
|
||||
cureblind = TRUE;
|
||||
/*FALLTHRU*/
|
||||
case POT_EXTRA_HEALING:
|
||||
if (Upolyd && u.mh < u.mhmax)
|
||||
u.mh++, context.botl = 1;
|
||||
if (u.uhp < u.uhpmax)
|
||||
u.uhp++, context.botl = 1;
|
||||
if (!obj->cursed)
|
||||
cureblind = TRUE;
|
||||
/*FALLTHRU*/
|
||||
case POT_HEALING:
|
||||
if (Upolyd && u.mh < u.mhmax)
|
||||
u.mh++, context.botl = 1;
|
||||
if (u.uhp < u.uhpmax)
|
||||
u.uhp++, context.botl = 1;
|
||||
if (obj->blessed)
|
||||
cureblind = TRUE;
|
||||
if (cureblind)
|
||||
make_blinded(0L, !u.ucreamed);
|
||||
exercise(A_CON, TRUE);
|
||||
break;
|
||||
case POT_SICKNESS:
|
||||
|
||||
+239
-1
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 priest.c $NHDT-Date: 1446892452 2015/11/07 10:34:12 $ $NHDT-Branch: master $:$NHDT-Revision: 1.41 $ */
|
||||
/* NetHack 3.6 priest.c $NHDT-Date: 1501725407 2017/08/03 01:56:47 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.44 $ */
|
||||
/* Copyright (c) Izchak Miller, Steve Linhart, 1989. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
@@ -852,4 +852,242 @@ boolean ghostly;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* align_str(), piousness(), mstatusline() and ustatusline() used to be
|
||||
* in pline.c, presumeably because the latter two generate one line of
|
||||
* output. The USE_OLDARGS config gets warnings from 2016ish-vintage
|
||||
* gcc (for -Wint-to-pointer-cast, activated by -Wall or -W) when they
|
||||
* follow pline() itself. Fixing up the variadic calls like is done for
|
||||
* lev_comp would be needlessly messy there.
|
||||
*
|
||||
* They don't belong here. If/when enlightenment ever gets split off
|
||||
* from cmd.c (which definitely doesn't belong there), they should go
|
||||
* with it.
|
||||
*/
|
||||
|
||||
const char *
|
||||
align_str(alignment)
|
||||
aligntyp alignment;
|
||||
{
|
||||
switch ((int) alignment) {
|
||||
case A_CHAOTIC:
|
||||
return "chaotic";
|
||||
case A_NEUTRAL:
|
||||
return "neutral";
|
||||
case A_LAWFUL:
|
||||
return "lawful";
|
||||
case A_NONE:
|
||||
return "unaligned";
|
||||
}
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
/* used for self-probing */
|
||||
char *
|
||||
piousness(showneg, suffix)
|
||||
boolean showneg;
|
||||
const char *suffix;
|
||||
{
|
||||
static char buf[32]; /* bigger than "insufficiently neutral" */
|
||||
const char *pio;
|
||||
|
||||
/* note: piousness 20 matches MIN_QUEST_ALIGN (quest.h) */
|
||||
if (u.ualign.record >= 20)
|
||||
pio = "piously";
|
||||
else if (u.ualign.record > 13)
|
||||
pio = "devoutly";
|
||||
else if (u.ualign.record > 8)
|
||||
pio = "fervently";
|
||||
else if (u.ualign.record > 3)
|
||||
pio = "stridently";
|
||||
else if (u.ualign.record == 3)
|
||||
pio = "";
|
||||
else if (u.ualign.record > 0)
|
||||
pio = "haltingly";
|
||||
else if (u.ualign.record == 0)
|
||||
pio = "nominally";
|
||||
else if (!showneg)
|
||||
pio = "insufficiently";
|
||||
else if (u.ualign.record >= -3)
|
||||
pio = "strayed";
|
||||
else if (u.ualign.record >= -8)
|
||||
pio = "sinned";
|
||||
else
|
||||
pio = "transgressed";
|
||||
|
||||
Sprintf(buf, "%s", pio);
|
||||
if (suffix && (!showneg || u.ualign.record >= 0)) {
|
||||
if (u.ualign.record != 3)
|
||||
Strcat(buf, " ");
|
||||
Strcat(buf, suffix);
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
/* stethoscope or probing applied to monster -- one-line feedback */
|
||||
void
|
||||
mstatusline(mtmp)
|
||||
struct monst *mtmp;
|
||||
{
|
||||
aligntyp alignment = mon_aligntyp(mtmp);
|
||||
char info[BUFSZ], monnambuf[BUFSZ];
|
||||
|
||||
info[0] = 0;
|
||||
if (mtmp->mtame) {
|
||||
Strcat(info, ", tame");
|
||||
if (wizard) {
|
||||
Sprintf(eos(info), " (%d", mtmp->mtame);
|
||||
if (!mtmp->isminion)
|
||||
Sprintf(eos(info), "; hungry %ld; apport %d",
|
||||
EDOG(mtmp)->hungrytime, EDOG(mtmp)->apport);
|
||||
Strcat(info, ")");
|
||||
}
|
||||
} else if (mtmp->mpeaceful)
|
||||
Strcat(info, ", peaceful");
|
||||
|
||||
if (mtmp->data == &mons[PM_LONG_WORM]) {
|
||||
int segndx, nsegs = count_wsegs(mtmp);
|
||||
|
||||
/* the worm code internals don't consider the head of be one of
|
||||
the worm's segments, but we count it as such when presenting
|
||||
worm feedback to the player */
|
||||
if (!nsegs) {
|
||||
Strcat(info, ", single segment");
|
||||
} else {
|
||||
++nsegs; /* include head in the segment count */
|
||||
segndx = wseg_at(mtmp, bhitpos.x, bhitpos.y);
|
||||
Sprintf(eos(info), ", %d%s of %d segments",
|
||||
segndx, ordin(segndx), nsegs);
|
||||
}
|
||||
}
|
||||
if (mtmp->cham >= LOW_PM && mtmp->data != &mons[mtmp->cham])
|
||||
/* don't reveal the innate form (chameleon, vampire, &c),
|
||||
just expose the fact that this current form isn't it */
|
||||
Strcat(info, ", shapechanger");
|
||||
/* pets eating mimic corpses mimic while eating, so this comes first */
|
||||
if (mtmp->meating)
|
||||
Strcat(info, ", eating");
|
||||
/* a stethoscope exposes mimic before getting here so this
|
||||
won't be relevant for it, but wand of probing doesn't */
|
||||
if (mtmp->mundetected || mtmp->m_ap_type)
|
||||
mhidden_description(mtmp, TRUE, eos(info));
|
||||
if (mtmp->mcan)
|
||||
Strcat(info, ", cancelled");
|
||||
if (mtmp->mconf)
|
||||
Strcat(info, ", confused");
|
||||
if (mtmp->mblinded || !mtmp->mcansee)
|
||||
Strcat(info, ", blind");
|
||||
if (mtmp->mstun)
|
||||
Strcat(info, ", stunned");
|
||||
if (mtmp->msleeping)
|
||||
Strcat(info, ", asleep");
|
||||
#if 0 /* unfortunately mfrozen covers temporary sleep and being busy \
|
||||
(donning armor, for instance) as well as paralysis */
|
||||
else if (mtmp->mfrozen)
|
||||
Strcat(info, ", paralyzed");
|
||||
#else
|
||||
else if (mtmp->mfrozen || !mtmp->mcanmove)
|
||||
Strcat(info, ", can't move");
|
||||
#endif
|
||||
/* [arbitrary reason why it isn't moving] */
|
||||
else if (mtmp->mstrategy & STRAT_WAITMASK)
|
||||
Strcat(info, ", meditating");
|
||||
if (mtmp->mflee)
|
||||
Strcat(info, ", scared");
|
||||
if (mtmp->mtrapped)
|
||||
Strcat(info, ", trapped");
|
||||
if (mtmp->mspeed)
|
||||
Strcat(info, (mtmp->mspeed == MFAST) ? ", fast"
|
||||
: (mtmp->mspeed == MSLOW) ? ", slow"
|
||||
: ", [? speed]");
|
||||
if (mtmp->minvis)
|
||||
Strcat(info, ", invisible");
|
||||
if (mtmp == u.ustuck)
|
||||
Strcat(info, sticks(youmonst.data) ? ", held by you"
|
||||
: !u.uswallow ? ", holding you"
|
||||
: attacktype_fordmg(u.ustuck->data, AT_ENGL, AD_DGST)
|
||||
? ", digesting you"
|
||||
: is_animal(u.ustuck->data) ? ", swallowing you"
|
||||
: ", engulfing you");
|
||||
if (mtmp == u.usteed)
|
||||
Strcat(info, ", carrying you");
|
||||
|
||||
/* avoid "Status of the invisible newt ..., invisible" */
|
||||
/* and unlike a normal mon_nam, use "saddled" even if it has a name */
|
||||
Strcpy(monnambuf, x_monnam(mtmp, ARTICLE_THE, (char *) 0,
|
||||
(SUPPRESS_IT | SUPPRESS_INVISIBLE), FALSE));
|
||||
|
||||
pline("Status of %s (%s): Level %d HP %d(%d) AC %d%s.", monnambuf,
|
||||
align_str(alignment), mtmp->m_lev, mtmp->mhp, mtmp->mhpmax,
|
||||
find_mac(mtmp), info);
|
||||
}
|
||||
|
||||
/* stethoscope or probing applied to hero -- one-line feedback */
|
||||
void
|
||||
ustatusline()
|
||||
{
|
||||
char info[BUFSZ];
|
||||
|
||||
info[0] = '\0';
|
||||
if (Sick) {
|
||||
Strcat(info, ", dying from");
|
||||
if (u.usick_type & SICK_VOMITABLE)
|
||||
Strcat(info, " food poisoning");
|
||||
if (u.usick_type & SICK_NONVOMITABLE) {
|
||||
if (u.usick_type & SICK_VOMITABLE)
|
||||
Strcat(info, " and");
|
||||
Strcat(info, " illness");
|
||||
}
|
||||
}
|
||||
if (Stoned)
|
||||
Strcat(info, ", solidifying");
|
||||
if (Slimed)
|
||||
Strcat(info, ", becoming slimy");
|
||||
if (Strangled)
|
||||
Strcat(info, ", being strangled");
|
||||
if (Vomiting)
|
||||
Strcat(info, ", nauseated"); /* !"nauseous" */
|
||||
if (Confusion)
|
||||
Strcat(info, ", confused");
|
||||
if (Blind) {
|
||||
Strcat(info, ", blind");
|
||||
if (u.ucreamed) {
|
||||
if ((long) u.ucreamed < Blinded || Blindfolded
|
||||
|| !haseyes(youmonst.data))
|
||||
Strcat(info, ", cover");
|
||||
Strcat(info, "ed by sticky goop");
|
||||
} /* note: "goop" == "glop"; variation is intentional */
|
||||
}
|
||||
if (Stunned)
|
||||
Strcat(info, ", stunned");
|
||||
if (!u.usteed && Wounded_legs) {
|
||||
const char *what = body_part(LEG);
|
||||
if ((Wounded_legs & BOTH_SIDES) == BOTH_SIDES)
|
||||
what = makeplural(what);
|
||||
Sprintf(eos(info), ", injured %s", what);
|
||||
}
|
||||
if (Glib)
|
||||
Sprintf(eos(info), ", slippery %s", makeplural(body_part(HAND)));
|
||||
if (u.utrap)
|
||||
Strcat(info, ", trapped");
|
||||
if (Fast)
|
||||
Strcat(info, Very_fast ? ", very fast" : ", fast");
|
||||
if (u.uundetected)
|
||||
Strcat(info, ", concealed");
|
||||
if (Invis)
|
||||
Strcat(info, ", invisible");
|
||||
if (u.ustuck) {
|
||||
if (sticks(youmonst.data))
|
||||
Strcat(info, ", holding ");
|
||||
else
|
||||
Strcat(info, ", held by ");
|
||||
Strcat(info, mon_nam(u.ustuck));
|
||||
}
|
||||
|
||||
pline("Status of %s (%s): Level %d HP %d(%d) AC %d%s.", plname,
|
||||
piousness(FALSE, align_str(u.ualign.type)),
|
||||
Upolyd ? mons[u.umonnum].mlevel : u.ulevel, Upolyd ? u.mh : u.uhp,
|
||||
Upolyd ? u.mhmax : u.uhpmax, u.uac, info);
|
||||
}
|
||||
|
||||
/*priest.c*/
|
||||
|
||||
+12
-3
@@ -915,12 +915,21 @@ struct obj *sobj;
|
||||
return 0;
|
||||
}
|
||||
|
||||
boolean
|
||||
get_valid_stinking_cloud_pos(x,y)
|
||||
int x,y;
|
||||
{
|
||||
return (!(!isok(x,y) || !cansee(x, y)
|
||||
|| !ACCESSIBLE(levl[x][y].typ)
|
||||
|| distu(x, y) >= 32));
|
||||
}
|
||||
|
||||
boolean
|
||||
is_valid_stinking_cloud_pos(x, y, showmsg)
|
||||
int x, y;
|
||||
boolean showmsg;
|
||||
{
|
||||
if (!cansee(x, y) || !ACCESSIBLE(levl[x][y].typ) || distu(x, y) >= 32) {
|
||||
if (get_valid_stinking_cloud_pos(x,y)) {
|
||||
if (showmsg)
|
||||
You("smell rotten eggs.");
|
||||
return FALSE;
|
||||
@@ -942,7 +951,7 @@ int state;
|
||||
for (dy = -dist; dy <= dist; dy++) {
|
||||
x = u.ux + dx;
|
||||
y = u.uy + dy;
|
||||
if (isok(x, y) && is_valid_stinking_cloud_pos(x, y, FALSE))
|
||||
if (get_valid_stinking_cloud_pos(x,y))
|
||||
tmp_at(x, y);
|
||||
}
|
||||
} else {
|
||||
@@ -1633,7 +1642,7 @@ struct obj *sobj; /* scroll, or fake spellbook object for scroll-like spell */
|
||||
already_known ? "stinking " : "");
|
||||
cc.x = u.ux;
|
||||
cc.y = u.uy;
|
||||
getpos_sethilite(display_stinking_cloud_positions);
|
||||
getpos_sethilite(display_stinking_cloud_positions, get_valid_stinking_cloud_pos);
|
||||
if (getpos(&cc, TRUE, "the desired position") < 0) {
|
||||
pline1(Never_mind);
|
||||
break;
|
||||
|
||||
+5
-9
@@ -36,7 +36,6 @@ STATIC_DCL struct opvar *FDECL(opvar_new_coord, (int, int));
|
||||
#if 0
|
||||
STATIC_DCL struct opvar * FDECL(opvar_new_region, (int,int, int,int));
|
||||
#endif /*0*/
|
||||
STATIC_DCL void FDECL(opvar_free_x, (struct opvar *));
|
||||
STATIC_DCL struct opvar *FDECL(opvar_clone, (struct opvar *));
|
||||
STATIC_DCL struct opvar *FDECL(opvar_var_conversion, (struct sp_coder *,
|
||||
struct opvar *));
|
||||
@@ -114,8 +113,6 @@ STATIC_DCL void FDECL(spo_altar, (struct sp_coder *));
|
||||
STATIC_DCL void FDECL(spo_trap, (struct sp_coder *));
|
||||
STATIC_DCL void FDECL(spo_gold, (struct sp_coder *));
|
||||
STATIC_DCL void FDECL(spo_corridor, (struct sp_coder *));
|
||||
STATIC_DCL struct opvar *FDECL(selection_opvar, (char *));
|
||||
STATIC_DCL xchar FDECL(selection_getpoint, (int, int, struct opvar *));
|
||||
STATIC_DCL void FDECL(selection_setpoint, (int, int, struct opvar *, XCHAR_P));
|
||||
STATIC_DCL struct opvar *FDECL(selection_not, (struct opvar *));
|
||||
STATIC_DCL struct opvar *FDECL(selection_logical_oper, (struct opvar *,
|
||||
@@ -126,11 +123,8 @@ STATIC_DCL void FDECL(selection_filter_percent, (struct opvar *, int));
|
||||
STATIC_DCL int FDECL(selection_rndcoord, (struct opvar *, schar *, schar *,
|
||||
BOOLEAN_P));
|
||||
STATIC_DCL void FDECL(selection_do_grow, (struct opvar *, int));
|
||||
STATIC_DCL void FDECL(set_selection_floodfillchk, (int FDECL((*), (int,int))));
|
||||
STATIC_DCL int FDECL(floodfillchk_match_under, (int, int));
|
||||
STATIC_DCL int FDECL(floodfillchk_match_accessible, (int, int));
|
||||
STATIC_DCL void FDECL(selection_floodfill, (struct opvar *, int, int,
|
||||
BOOLEAN_P));
|
||||
STATIC_DCL void FDECL(selection_do_ellipse, (struct opvar *, int, int,
|
||||
int, int, int));
|
||||
STATIC_DCL long FDECL(line_dist_coord, (long, long, long, long, long, long));
|
||||
@@ -3052,6 +3046,7 @@ struct sp_coder *coder;
|
||||
while ((nparams++ < (SP_O_V_END + 1)) && (OV_typ(varparam) == SPOVAR_INT)
|
||||
&& (OV_i(varparam) >= 0) && (OV_i(varparam) < SP_O_V_END)) {
|
||||
struct opvar *parm;
|
||||
|
||||
OV_pop(parm);
|
||||
switch (OV_i(varparam)) {
|
||||
case SP_O_V_NAME:
|
||||
@@ -3063,11 +3058,12 @@ struct sp_coder *coder;
|
||||
char monclass = SP_MONST_CLASS(OV_i(parm));
|
||||
int monid = SP_MONST_PM(OV_i(parm));
|
||||
|
||||
if (monid >= 0 && monid < NUMMONS) {
|
||||
if (monid >= LOW_PM && monid < NUMMONS) {
|
||||
tmpobj.corpsenm = monid;
|
||||
break; /* we're done! */
|
||||
} else {
|
||||
struct permonst *pm = (struct permonst *) 0;
|
||||
|
||||
if (def_char_to_monclass(monclass) != MAXMCLASSES) {
|
||||
pm = mkclass(def_char_to_monclass(monclass), G_NOGEN);
|
||||
} else {
|
||||
@@ -3780,7 +3776,7 @@ int dir;
|
||||
STATIC_VAR int FDECL((*selection_flood_check_func), (int, int));
|
||||
STATIC_VAR schar floodfillchk_match_under_typ;
|
||||
|
||||
STATIC_OVL void
|
||||
void
|
||||
set_selection_floodfillchk(f)
|
||||
int FDECL((*f), (int, int));
|
||||
{
|
||||
@@ -3803,7 +3799,7 @@ int x, y;
|
||||
|| levl[x][y].typ == SCORR);
|
||||
}
|
||||
|
||||
STATIC_OVL void
|
||||
void
|
||||
selection_floodfill(ov, x, y, diagonals)
|
||||
struct opvar *ov;
|
||||
int x, y;
|
||||
|
||||
+90
-42
@@ -15,43 +15,83 @@ STATIC_DCL void FDECL(see_lamp_flicker, (struct obj *, const char *));
|
||||
STATIC_DCL void FDECL(lantern_message, (struct obj *));
|
||||
STATIC_DCL void FDECL(cleanup_burn, (ANY_P *, long));
|
||||
|
||||
/* the order of these must match their numerical sequence in prop.h
|
||||
because the property number is inferred from the array index;
|
||||
used by wizard mode #timeout and #wizintrinsic */
|
||||
const char *const propertynames[] = {
|
||||
"0: not used",
|
||||
/* Resistances */
|
||||
/* 1..2 */ "fire resistance", "cold resistance",
|
||||
/* 3..4 */ "sleep resistance", "disintegration resistance",
|
||||
/* 5..6 */ "shock resistance", "poison resistance",
|
||||
/* 7..8 */ "acid resistance", "stoning resistance",
|
||||
/* 9..10 */ "drain resistance", "sickness resistance",
|
||||
/* 11..12 */ "invulnerable", "magic resistance",
|
||||
/* Troubles */
|
||||
/* 13..16 */ "stunned", "confused", "blinded", "deafness",
|
||||
/* 17..20 */ "fatally sick", "petrifying", "strangling", "vomiting",
|
||||
/* 21..22 */ "slippery fingers", "becoming slime",
|
||||
/* 23..24 */ "hallucinating", "halluicination resistance",
|
||||
/* 25..28 */ "fumbling", "wounded legs", "sleepy", "voracious hunger",
|
||||
/* Vision and senses */
|
||||
/* 29..30 */ "see invisible", "telepathic",
|
||||
/* 31..33 */ "warning", "warn:monster", "warn:undead",
|
||||
/* 34..37 */ "searching", "clairvoyant", "infravision", "monster detection",
|
||||
/* Appearance and behavior */
|
||||
/* 38..41 */ "adorned (+/-Cha)", "invisible", "displaced", "stealthy",
|
||||
/* 42..43 */ "monster aggrevation", "conflict",
|
||||
/* Transportation */
|
||||
/* 44..46 */ "jumping", "teleporting", "teleport control",
|
||||
/* 47..49 */ "levitating", "flying", "water walking",
|
||||
/* 50..52 */ "swimming", "magical breathing", "pass thru walls",
|
||||
/* Physical attributes */
|
||||
/* 53..55 */ "slow digestion", "half spell damage", "half physical damage",
|
||||
/* 56..58 */ "HP regeneration", "energy regeneration", "extra protection",
|
||||
/* 59 */ "protection from shape changers",
|
||||
/* 60..62 */ "polymorphing", "polymorph control", "unchanging",
|
||||
/* 63..66 */ "fast", "reflecting", "free action", "fixed abilites",
|
||||
/* 67 */ "life will be saved",
|
||||
0 /* sentinel */
|
||||
/* used by wizard mode #timeout and #wizintrinsic; order by 'interest'
|
||||
for timeout countdown, where most won't occur in normal play */
|
||||
const struct propname {
|
||||
int prop_num;
|
||||
const char *prop_name;
|
||||
} propertynames[] = {
|
||||
{ INVULNERABLE, "invulnerable" },
|
||||
{ STONED, "petrifying" },
|
||||
{ SLIMED, "becoming slime" },
|
||||
{ STRANGLED, "strangling" },
|
||||
{ SICK, "fatally sick" },
|
||||
{ STUNNED, "stunned" },
|
||||
{ CONFUSION, "confused" },
|
||||
{ HALLUC, "hallucinating" },
|
||||
{ BLINDED, "blinded" },
|
||||
{ DEAF, "deafness" },
|
||||
{ VOMITING, "vomiting" },
|
||||
{ GLIB, "slippery fingers" },
|
||||
{ WOUNDED_LEGS, "wounded legs" },
|
||||
{ SLEEPY, "sleepy" },
|
||||
{ TELEPORT, "teleporting" },
|
||||
{ POLYMORPH, "polymorphing" },
|
||||
{ LEVITATION, "levitating" },
|
||||
{ FAST, "very fast" }, /* timed 'FAST' is very fast */
|
||||
{ CLAIRVOYANT, "clairvoyant" },
|
||||
{ DETECT_MONSTERS, "monster detection" },
|
||||
{ SEE_INVIS, "see invisible" },
|
||||
{ INVIS, "invisible" },
|
||||
/* properties beyond here don't have timed values during normal play,
|
||||
so there's no much point in trying to order them sensibly;
|
||||
they're either on or off based on equipment, role, actions, &c */
|
||||
{ FIRE_RES, "fire resistance" },
|
||||
{ COLD_RES, "cold resistance" },
|
||||
{ SLEEP_RES, "sleep resistance" },
|
||||
{ DISINT_RES, "disintegration resistance" },
|
||||
{ SHOCK_RES, "shock resistance" },
|
||||
{ POISON_RES, "poison resistance" },
|
||||
{ ACID_RES, "acid resistance" },
|
||||
{ STONE_RES, "stoning resistance" },
|
||||
{ DRAIN_RES, "drain resistance" },
|
||||
{ SICK_RES, "sickness resistance" },
|
||||
{ ANTIMAGIC, "magic resistance" },
|
||||
{ HALLUC_RES, "hallucination resistance" },
|
||||
{ FUMBLING, "fumbling" },
|
||||
{ HUNGER, "voracious hunger" },
|
||||
{ TELEPAT, "telepathic" },
|
||||
{ WARNING, "warning" },
|
||||
{ WARN_OF_MON, "warn: monster type or class" },
|
||||
{ WARN_UNDEAD, "warn: undead" },
|
||||
{ SEARCHING, "searching" },
|
||||
{ INFRAVISION, "infravision" },
|
||||
{ ADORNED, "adorned (+/- Cha)" },
|
||||
{ DISPLACED, "displaced" },
|
||||
{ STEALTH, "stealthy" },
|
||||
{ AGGRAVATE_MONSTER, "monster aggravation" },
|
||||
{ CONFLICT, "conflict" },
|
||||
{ JUMPING, "jumping" },
|
||||
{ TELEPORT_CONTROL, "teleport control" },
|
||||
{ FLYING, "flying" },
|
||||
{ WWALKING, "water walking" },
|
||||
{ SWIMMING, "swimming" },
|
||||
{ MAGICAL_BREATHING, "magical breathing" },
|
||||
{ PASSES_WALLS, "pass thru walls" },
|
||||
{ SLOW_DIGESTION, "slow digestion" },
|
||||
{ HALF_SPDAM, "half spell damage" },
|
||||
{ HALF_PHDAM, "half physical damage" },
|
||||
{ REGENERATION, "HP regeneration" },
|
||||
{ ENERGY_REGENERATION, "energy regeneration" },
|
||||
{ PROTECTION, "extra protection" },
|
||||
{ PROT_FROM_SHAPE_CHANGERS, "protection from shape changers" },
|
||||
{ POLYMORPH_CONTROL, "polymorph control" },
|
||||
{ UNCHANGING, "unchanging" },
|
||||
{ REFLECTING, "reflecting" },
|
||||
{ FREE_ACTION, "free action" },
|
||||
{ FIXED_ABIL, "fixed abilites" },
|
||||
{ LIFESAVED, "life will be saved" },
|
||||
{ 0, 0 },
|
||||
};
|
||||
|
||||
/* He is being petrified - dialogue by inmet!tower */
|
||||
@@ -1544,7 +1584,7 @@ wiz_timeout_queue()
|
||||
char buf[BUFSZ];
|
||||
const char *propname;
|
||||
long intrinsic;
|
||||
int i, count, longestlen, ln;
|
||||
int i, p, count, longestlen, ln, specindx = 0;
|
||||
|
||||
win = create_nhwindow(NHW_MENU); /* corner text window */
|
||||
if (win == WIN_ERR)
|
||||
@@ -1562,13 +1602,16 @@ wiz_timeout_queue()
|
||||
* normal play but those can be forced via the #wizintrinsic command.
|
||||
*/
|
||||
count = longestlen = 0;
|
||||
for (i = 1; (propname = propertynames[i]) != 0; ++i) { /* [0] not used */
|
||||
intrinsic = u.uprops[i].intrinsic;
|
||||
for (i = 0; (propname = propertynames[i].prop_name) != 0; ++i) {
|
||||
p = propertynames[i].prop_num;
|
||||
intrinsic = u.uprops[p].intrinsic;
|
||||
if (intrinsic & TIMEOUT) {
|
||||
++count;
|
||||
if ((ln = (int) strlen(propname)) > longestlen)
|
||||
longestlen = ln;
|
||||
}
|
||||
if (specindx == 0 && p == FIRE_RES)
|
||||
specindx = i;
|
||||
}
|
||||
putstr(win, 0, "");
|
||||
if (!count) {
|
||||
@@ -1576,9 +1619,14 @@ wiz_timeout_queue()
|
||||
} else {
|
||||
putstr(win, 0, "Timed properties:");
|
||||
putstr(win, 0, "");
|
||||
for (i = 1; (propname = propertynames[i]) != 0; ++i) {
|
||||
intrinsic = u.uprops[i].intrinsic;
|
||||
for (i = 0; (propname = propertynames[i].prop_name) != 0; ++i) {
|
||||
p = propertynames[i].prop_num;
|
||||
intrinsic = u.uprops[p].intrinsic;
|
||||
if (intrinsic & TIMEOUT) {
|
||||
if (specindx > 0 && i >= specindx) {
|
||||
putstr(win, 0, " -- settable via #wizinstrinc only --");
|
||||
specindx = 0;
|
||||
}
|
||||
/* timeout value can be up to 16777215 (0x00ffffff) but
|
||||
width of 4 digits should result in values lining up
|
||||
almost all the time (if/when they don't, it won't
|
||||
|
||||
+9
-1
@@ -191,6 +191,13 @@ findgd()
|
||||
return (struct monst *) 0;
|
||||
}
|
||||
|
||||
void
|
||||
vault_summon_gd()
|
||||
{
|
||||
if (vault_occupied(u.urooms) && !findgd())
|
||||
u.uinvault = (VAULT_GUARD_TIME - 1);
|
||||
}
|
||||
|
||||
char
|
||||
vault_occupied(array)
|
||||
char *array;
|
||||
@@ -221,7 +228,8 @@ invault()
|
||||
vaultroom -= ROOMOFFSET;
|
||||
|
||||
guard = findgd();
|
||||
if (++u.uinvault % 30 == 0 && !guard) { /* if time ok and no guard now. */
|
||||
if (++u.uinvault % VAULT_GUARD_TIME == 0 && !guard) {
|
||||
/* if time ok and no guard now. */
|
||||
char buf[BUFSZ];
|
||||
register int x, y, dd, gx, gy;
|
||||
int lx = 0, ly = 0;
|
||||
|
||||
Reference in New Issue
Block a user