Merge branch 'master' into derek-farming

* master: (41 commits)
  Add more explicit helpless reasons
  add data.base suggestion for whistle
  Use existing function to count containers
  ...

Conflicts:
	src/do.c
	src/hack.c
	src/invent.c
	src/mon.c
	src/objnam.c
This commit is contained in:
Derek S. Ray
2015-03-29 17:32:12 -04:00
56 changed files with 3316 additions and 2131 deletions
+82 -13
View File
@@ -27,6 +27,7 @@ STATIC_DCL void FDECL(use_trap, (struct obj *));
STATIC_DCL void FDECL(use_stone, (struct obj *));
STATIC_PTR int NDECL(set_trap); /* occupation callback */
STATIC_DCL int FDECL(use_whip, (struct obj *));
STATIC_PTR void FDECL(display_polearm_positions, (int));
STATIC_DCL int FDECL(use_pole, (struct obj *));
STATIC_DCL int FDECL(use_cream_pie, (struct obj *));
STATIC_DCL int FDECL(use_grapple, (struct obj *));
@@ -736,8 +737,10 @@ struct obj *obj;
pline("Yow! The %s stares back!", mirror);
else
pline("Yikes! You've frozen yourself!");
if (!Hallucination || !rn2(4))
if (!Hallucination || !rn2(4)) {
nomul(-rnd(MAXULEV + 6 - u.ulevel));
multi_reason = "gazing into a mirror";
}
nomovemsg = 0; /* default, "you can move again" */
}
} else if (youmonst.data->mlet == S_VAMPIRE)
@@ -915,6 +918,7 @@ struct obj **optr;
break;
case 2: /* no explanation; it just happens... */
nomovemsg = "";
multi_reason = NULL;
nomul(-rnd(2));
break;
}
@@ -1508,6 +1512,7 @@ int magic; /* 0=Physical, otherwise skill level */
teleds(cc.x, cc.y, TRUE);
sokoban_guilt();
nomul(-1);
multi_reason = "jumping around";
nomovemsg = "";
morehungry(rnd(25));
return 1;
@@ -2531,6 +2536,54 @@ static const char
cant_see_spot[] = "won't hit anything if you can't see that spot.",
cant_reach[] = "can't reach that spot from here.";
/* find pos of monster in range, if only one monster */
boolean
find_poleable_mon(pos, min_range, max_range)
coord *pos;
int min_range, max_range;
{
struct monst *mtmp;
struct monst *selmon = NULL;
for (mtmp = fmon; mtmp; mtmp = mtmp->nmon)
if (mtmp && !DEADMONSTER(mtmp) && !mtmp->mtame &&
cansee(mtmp->mx, mtmp->my) &&
distu(mtmp->mx, mtmp->my) <= max_range &&
distu(mtmp->mx, mtmp->my) >= min_range) {
if (selmon) return FALSE;
selmon = mtmp;
}
if (!selmon) return FALSE;
pos->x = selmon->mx;
pos->y = selmon->my;
return TRUE;
}
int polearm_range_min = -1;
int polearm_range_max = -1;
void
display_polearm_positions(state)
int state;
{
if (state == 0) {
tmp_at(DISP_BEAM, cmap_to_glyph(S_flashbeam));
} else if (state == 1) {
int x,y, dx,dy;
for (dx = -4; dx <= 4; dx++)
for (dy = -4; dy <= 4; dy++) {
x = dx + (int)u.ux;
y = dy + (int)u.uy;
if (isok(x, y) &&
distu(x, y) >= polearm_range_min &&
distu(x, y) <= polearm_range_max) {
tmp_at(x, y);
}
}
} else {
tmp_at(DISP_END, 0);
}
}
/* Distance attacks by pole-weapons */
STATIC_OVL int
use_pole(obj)
@@ -2539,6 +2592,7 @@ use_pole(obj)
int res = 0, typ, max_range, min_range, glyph;
coord cc;
struct monst *mtmp;
struct monst *hitm = context.polearm.hitmon;
/* Are you allowed to use the pole? */
if (u.uswallow) {
@@ -2551,15 +2605,7 @@ use_pole(obj)
}
/* assert(obj == uwep); */
/* Prompt for a location */
pline(where_to_hit);
cc.x = u.ux;
cc.y = u.uy;
if (getpos(&cc, TRUE, "the spot to hit") < 0)
return res; /* ESC; uses turn iff polearm became wielded */
glyph = glyph_at(cc.x, cc.y);
/*
/*
* Calculate allowable range (pole's reach is always 2 steps):
* unskilled and basic: orthogonal direction, 4..4;
* skilled: as basic, plus knight's jump position, 4..5;
@@ -2579,6 +2625,26 @@ use_pole(obj)
if (typ == P_NONE || P_SKILL(typ) <= P_BASIC) max_range = 4;
else if (P_SKILL(typ) == P_SKILLED) max_range = 5;
else max_range = 8; /* (P_SKILL(typ) >= P_EXPERT) */
polearm_range_min = min_range;
polearm_range_max = max_range;
/* Prompt for a location */
pline(where_to_hit);
cc.x = u.ux;
cc.y = u.uy;
if (!find_poleable_mon(&cc, min_range, max_range) &&
hitm && !DEADMONSTER(hitm) && cansee(hitm->mx, hitm->my) &&
distu(hitm->mx,hitm->my) <= max_range &&
distu(hitm->mx,hitm->my) >= min_range) {
cc.x = hitm->mx;
cc.y = hitm->my;
}
getpos_sethilite(display_polearm_positions);
if (getpos(&cc, TRUE, "the spot to hit") < 0)
return res; /* ESC; uses turn iff polearm became wielded */
glyph = glyph_at(cc.x, cc.y);
if (distu(cc.x, cc.y) > max_range) {
pline("Too far!");
return (res);
@@ -2596,11 +2662,13 @@ use_pole(obj)
return res;
}
context.polearm.hitmon = NULL;
/* Attack the monster there */
bhitpos = cc;
if ((mtmp = m_at(bhitpos.x, bhitpos.y)) != (struct monst *)0) {
if (attack_checks(mtmp, uwep)) return res;
if (overexertion()) return 1; /* burn nutrition; maybe pass out */
context.polearm.hitmon = mtmp;
check_caitiff(mtmp);
notonhead = (bhitpos.x != mtmp->mx || bhitpos.y != mtmp->my);
(void) thitmonst(mtmp, uwep);
@@ -2828,6 +2896,7 @@ do_break_wand(obj)
boolean fillmsg = FALSE;
int expltype = EXPL_MAGICAL;
char confirm[QBUFSZ], buf[BUFSZ];
boolean is_fragile = (!strcmp(OBJ_DESCR(objects[obj->otyp]), "balsa"));
if (yn(safe_qbuf(confirm, "Are you really sure you want to break ", "?",
obj, yname, ysimple_name, "the wand")) == 'n')
@@ -2836,7 +2905,7 @@ do_break_wand(obj)
if (nohands(youmonst.data)) {
You_cant("break %s without hands!", yname(obj));
return 0;
} else if (ACURR(A_STR) < 10) {
} else if (ACURR(A_STR) < (is_fragile ? 5 : 10)) {
You("don't have the strength to break %s!", yname(obj));
return 0;
}
@@ -2974,7 +3043,7 @@ do_break_wand(obj)
/* if (context.botl) bot(); */
}
if (affects_objects && level.objects[x][y]) {
(void) bhitpile(obj, bhito, x, y);
(void) bhitpile(obj, bhito, x, y, 0);
if (context.botl) bot(); /* potion effects */
}
} else {
@@ -2991,7 +3060,7 @@ do_break_wand(obj)
* since it's also used by retouch_equipment() for polyself.)
*/
if (affects_objects && level.objects[x][y]) {
(void) bhitpile(obj, bhito, x, y);
(void) bhitpile(obj, bhito, x, y, 0);
if (context.botl) bot(); /* potion effects */
}
damage = zapyourself(obj, FALSE);
+1
View File
@@ -983,6 +983,7 @@ char *hittee; /* target's name: "you" or mon_nam(mdef) */
resisted = TRUE;
} else {
nomul(-3);
multi_reason = "being scared stiff";
nomovemsg = "";
if (magr && magr == u.ustuck && sticks(youmonst.data)) {
u.ustuck = (struct monst *)0;
+1
View File
@@ -21,6 +21,7 @@ char *catmore = 0; /* default pager */
NEARDATA int bases[MAXOCLASSES] = DUMMY;
NEARDATA int multi = 0;
const char *multi_reason = NULL;
NEARDATA int nroom = 0;
NEARDATA int nsubroom = 0;
NEARDATA int occtime = 0;
+1
View File
@@ -890,6 +890,7 @@ struct obj *obj;
}
You("peer into %s...", the(xname(obj)));
nomul(-rnd(10));
multi_reason = "gazing into a crystal ball";
nomovemsg = "";
if (obj->spe <= 0)
pline_The("vision is unclear.");
+1
View File
@@ -1023,6 +1023,7 @@ struct obj *obj;
/* you ought to be able to let go; tough luck */
/* (maybe `move_into_trap()' would be better) */
nomul(-d(2,2));
multi_reason = "stuck in a spider web";
nomovemsg = "You pull free.";
} else if (lev->typ == IRONBARS) {
pline("Clang!");
+1
View File
@@ -1410,6 +1410,7 @@ boolean at_stairs, falling, portal;
/* assume this will always return TRUE when changing level */
(void) in_out_region(u.ux, u.uy);
(void) pickup(1);
context.polearm.hitmon = NULL;
}
STATIC_OVL void
+30 -1
View File
@@ -25,6 +25,17 @@ nextmbuf()
return bufs[bufidx];
}
/* function for getpos() to highlight desired map locations.
* parameter value 0 = initialize, 1 = highlight, 2 = done
*/
void (*getpos_hilitefunc)(int) = NULL;
void
getpos_sethilite(f)
void (*f)(int);
{
getpos_hilitefunc = f;
}
/* the response for '?' help request in getpos() */
STATIC_OVL void
getpos_help(force, goal)
@@ -41,6 +52,8 @@ const char *goal;
putstr(tmpwin, 0, "Use [HJKL] to move the cursor 8 units at a time.");
putstr(tmpwin, 0, "Or enter a background symbol (ex. <).");
putstr(tmpwin, 0, "Use @ to move the cursor on yourself.");
if (getpos_hilitefunc != NULL)
putstr(tmpwin, 0, "Use $ to display valid locations.");
putstr(tmpwin, 0, "Use # to toggle automatic description.");
/* disgusting hack; the alternate selection characters work for any
getpos call, but they only matter for dowhatis (and doquickwhatis) */
@@ -69,6 +82,7 @@ const char *goal;
boolean show_goal_msg = FALSE;
static const char pick_chars[] = ".,;:";
const char *cp;
boolean hilite_state = FALSE;
if (!goal) goal = "desired location";
if (flags.verbose) {
@@ -92,7 +106,7 @@ const char *goal;
curs(WIN_MAP, cx, cy);
flush_screen(0);
show_goal_msg = FALSE;
} else if (auto_msg && !msg_given) {
} else if (auto_msg && !msg_given && !hilite_state) {
coord cc;
int sym = 0;
char tmpbuf[BUFSZ];
@@ -110,6 +124,13 @@ const char *goal;
c = nh_poskey(&tx, &ty, &sidx);
if (hilite_state) {
(*getpos_hilitefunc)(2);
hilite_state = FALSE;
curs(WIN_MAP, cx, cy);
flush_screen(0);
}
if (auto_msg)
msg_given = FALSE;
@@ -174,6 +195,13 @@ const char *goal;
/* update message window to reflect that we're still targetting */
show_goal_msg = TRUE;
msg_given = TRUE;
} else if ((c == '$') && (getpos_hilitefunc != NULL)) {
if (!hilite_state) {
(*getpos_hilitefunc)(0);
(*getpos_hilitefunc)(1);
hilite_state = TRUE;
}
goto nxtc;
} else if (c == '#') {
auto_msg = !auto_msg;
pline("Automatic description %sis %s.",
@@ -269,6 +297,7 @@ const char *goal;
if (msg_given) clear_nhwindow(WIN_MESSAGE);
ccp->x = cx;
ccp->y = cy;
getpos_hilitefunc = NULL;
return result;
}
+2
View File
@@ -1407,6 +1407,7 @@ register struct obj *otmp;
if(cursed(otmp)) return(0);
if(delay) {
nomul(delay);
multi_reason = "disrobing";
if (is_helmet(otmp)) {
/* ick... */
nomovemsg = !strcmp(helm_simple_name(otmp), "hat") ?
@@ -1664,6 +1665,7 @@ dowear()
delay = -objects[otmp->otyp].oc_delay;
if(delay){
nomul(delay);
multi_reason = "dressing up";
if(is_boots(otmp)) afternmv = Boots_on;
if(is_helmet(otmp)) afternmv = Helmet_on;
if(is_gloves(otmp)) afternmv = Gloves_on;
+1
View File
@@ -685,6 +685,7 @@ migrate_to_level(mtmp, tolev, xyloc, cc)
mtmp->mux = new_lev.dnum;
mtmp->muy = new_lev.dlevel;
mtmp->mx = mtmp->my = 0; /* this implies migration */
if (mtmp == context.polearm.hitmon) context.polearm.hitmon = NULL;
}
/* return quality of food; the lower the better */
+22 -1
View File
@@ -991,7 +991,28 @@ dokick()
exercise(A_DEX, TRUE);
return(1);
}
if(IS_GRAVE(maploc->typ) || maploc->typ == IRONBARS)
if (IS_GRAVE(maploc->typ)) {
if(Levitation) goto dumb;
if (rn2(4)) goto ouch;
exercise(A_WIS, FALSE);
if (Role_if(PM_ARCHEOLOGIST) ||
Role_if(PM_SAMURAI) ||
((u.ualign.type == A_LAWFUL) && (u.ualign.record > -10))) {
adjalign(-sgn(u.ualign.type));
}
maploc->typ = ROOM;
maploc->doormask = 0;
(void) mksobj_at(ROCK, x,y, TRUE, FALSE);
del_engr_at(x,y);
if (Blind)
pline("Crack! %s broke!", Something);
else {
pline_The("headstone topples over and breaks!");
newsym(x,y);
}
return 1;
}
if(maploc->typ == IRONBARS)
goto ouch;
if(IS_TREE(maploc->typ)) {
struct obj *treefruit;
+1
View File
@@ -693,6 +693,7 @@ hurtle(dx, dy, range, verbose)
if(!range || (!dx && !dy) || u.ustuck) return; /* paranoia */
nomul(-range);
multi_reason = "moving through the air";
nomovemsg = ""; /* it just happens */
if (verbose)
You("%s in the opposite direction.", range > 1 ? "hurtle" : "float");
+4
View File
@@ -962,6 +962,7 @@ register int pm;
/* A pile of gold can't ride. */
if (u.usteed) dismount_steed(DISMOUNT_FELL);
nomul(-tmp);
multi_reason = "pretending to be a pile of gold";
Sprintf(buf, Hallucination ?
"You suddenly dread being peeled and mimic %s again!" :
"You now prefer mimicking %s again.",
@@ -1479,6 +1480,7 @@ struct obj *obj;
pline_The("world spins and %s %s.", what, where);
incr_itimeout(&HDeaf, duration);
nomul(-duration);
multi_reason = "unconscious from rotten food";
nomovemsg = "You are conscious again.";
afternmv = Hear_again;
return(1);
@@ -2677,6 +2679,7 @@ boolean incr;
if (!Levitation) selftouch("Falling, you");
incr_itimeout(&HDeaf, duration);
nomul(-duration);
multi_reason = "fainted from lack of food";
nomovemsg = "You regain consciousness.";
afternmv = unfaint;
newhs = FAINTED;
@@ -2853,6 +2856,7 @@ vomit() /* A good idea from David Neves */
else
make_sick(0L, (char *)0, TRUE, SICK_VOMITABLE);
nomul(-2);
multi_reason = "vomiting";
nomovemsg = You_can_move_again;
}
+6 -1
View File
@@ -465,7 +465,12 @@ int how;
Sprintf(eos(buf), " called %s", MNAME(mtmp));
}
if (multi) Strcat(buf, ", while helpless");
if (multi) {
if (multi_reason)
Sprintf(eos(buf), ", while %s", multi_reason);
else
Strcat(buf, ", while helpless");
}
Strcpy(killer.name, buf);
if (mptr->mlet == S_WRAITH)
u.ugrave_arise = PM_WRAITH;
+16 -1
View File
@@ -1568,6 +1568,7 @@ domove()
/* must come after we finished picking up, in spoteffects() */
if (cause_delay) {
nomul(-2);
multi_reason = "dragging an iron ball";
nomovemsg = "";
}
@@ -2207,7 +2208,19 @@ dopickup()
}
}
if (!OBJ_AT(u.ux, u.uy)) {
There("is nothing here to pick up.");
register struct rm *lev = &levl[u.ux][u.uy];
if (IS_THRONE(lev->typ))
pline("It must weigh%s a ton!",
lev->looted ? " almost" : "");
else if (IS_SINK(lev->typ))
pline_The("plumbing connects it to the floor.");
else if (IS_GRAVE(lev->typ))
You("don't need a gravestone. Yet.");
else if (IS_FOUNTAIN(lev->typ))
You("could drink the water...");
else if (IS_DOOR(lev->typ) && (lev->doormask & D_ISOPEN))
pline("It won't come off the hinges.");
else There("is nothing here to pick up.");
return 0;
}
if (!can_reach_floor(TRUE)) {
@@ -2422,6 +2435,7 @@ nomul(nval)
u.uinvulnerable = FALSE; /* Kludge to avoid ctrl-C bug -dlc */
u.usleep = 0;
multi = nval;
if (nval == 0) multi_reason = NULL;
context.travel = context.travel1 = context.mv = context.run = 0;
}
@@ -2436,6 +2450,7 @@ const char *msg_override;
if (*nomovemsg) pline1(nomovemsg);
nomovemsg = 0;
u.usleep = 0;
multi_reason = NULL;
if (afternmv) (*afternmv)();
afternmv = 0;
}
+2 -2
View File
@@ -927,8 +927,8 @@ register const char *let,*word;
/* "ugly check" for reading fortune cookies, part 2 */
if ((!strcmp(word, "read")
&& (otmp->otyp == FORTUNE_COOKIE || otmp->otyp == T_SHIRT)))
allowall = TRUE;
&& is_readable(otmp)))
allowall = usegold = TRUE;
}
}
bp[foo] = 0;
+1 -5
View File
@@ -1,4 +1,4 @@
/* NetHack 3.5 makemon.c $NHDT-Date: 1426465436 2015/03/16 00:23:56 $ $NHDT-Branch: debug $:$NHDT-Revision: 1.74 $ */
/* NetHack 3.5 makemon.c $NHDT-Date: 1427440865 2015/03/27 07:21:05 $ $NHDT-Branch: master $:$NHDT-Revision: 1.75 $ */
/* NetHack 3.5 makemon.c $Date: 2012/01/29 00:34:33 $ $Revision: 1.69 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -1884,10 +1884,6 @@ int *seencount; /* secondary output */
} while (--creatcnt > 0);
if (seecount) {
if (seencount) *seencount += seecount;
/* don't set contents-known flag if we just used last charge
(such suppression doesn't actually gain us much since
player can now deduce that the bag has become empty) */
if (bag->spe > 0) bag->cknown = 1;
if (bag->dknown) makeknown(BAG_OF_TRICKS);
} else if (!tipping) {
pline1(!moncount ? nothing_happens : "Nothing seems to happen.");
+2
View File
@@ -634,12 +634,14 @@ int spellnum;
if (multi >= 0)
You("stiffen briefly.");
nomul(-1);
multi_reason = "paralyzed by a monster";
} else {
if (multi >= 0)
You("are frozen in place!");
dmg = 4 + (int)mtmp->m_lev;
if (Half_spell_damage) dmg = (dmg + 1) / 2;
nomul(-dmg);
multi_reason = "paralyzed by a monster";
}
nomovemsg = 0;
dmg = 0;
+1
View File
@@ -1053,6 +1053,7 @@ dopois:
else You("are frozen by %s!", mon_nam(mtmp));
nomovemsg = You_can_move_again;
nomul(-rnd(10));
multi_reason = "paralyzed by a monster";
exercise(A_DEX, FALSE);
}
}
+7 -4
View File
@@ -634,7 +634,10 @@ meatmetal(mtmp)
/* Eats topmost metal object if it is there */
for (otmp = level.objects[mtmp->mx][mtmp->my];
otmp; otmp = otmp->nexthere) {
if (mtmp->data == &mons[PM_RUST_MONSTER] && !is_rustprone(otmp))
/* Don't eat indigestible/choking/inappropriate objects */
if ((mtmp->data == &mons[PM_RUST_MONSTER] && !is_rustprone(otmp)) ||
(otmp->otyp == AMULET_OF_STRANGULATION) ||
(otmp->otyp == RIN_SLOW_DIGESTION))
continue;
if (is_metallic(otmp) && !obj_resists(otmp, 5, 95) &&
touch_artifact(otmp,mtmp)) {
@@ -651,9 +654,7 @@ meatmetal(mtmp)
pline("%s spits %s out in disgust!",
Monnam(mtmp), distant_name(otmp,doname));
}
/* KMH -- Don't eat indigestible/choking objects */
} else if (otmp->otyp != AMULET_OF_STRANGULATION &&
otmp->otyp != RIN_SLOW_DIGESTION) {
} else {
if (cansee(mtmp->mx,mtmp->my) && flags.verbose)
pline("%s eats %s!", Monnam(mtmp),
distant_name(otmp,doname));
@@ -1256,6 +1257,8 @@ dmonsfree()
for (mtmp = &fmon; *mtmp;) {
freetmp = *mtmp;
if (freetmp->mhp <= 0 && !freetmp->isgd) {
if (freetmp == context.polearm.hitmon)
context.polearm.hitmon = NULL;
*mtmp = freetmp->nmon;
dealloc_monst(freetmp);
count++;
+17 -3
View File
@@ -497,6 +497,11 @@ register struct obj *obj;
}
if (pluralize) Strcpy(buf, makeplural(buf));
if (obj->otyp == T_SHIRT && program_state.gameover) {
char tmpbuf[BUFSZ];
Sprintf(eos(buf), " with text \"%s\"", tshirt_text(obj, tmpbuf));
}
if (has_oname(obj) && dknown) {
Strcat(buf, " named ");
nameit:
@@ -659,8 +664,9 @@ register struct obj *obj;
*/
register char *bp = xname(obj);
if (iflags.override_ID) known = cknown = bknown = lknown = TRUE;
else {
if (iflags.override_ID) {
known = cknown = bknown = lknown = TRUE;
} else {
known = obj->known;
cknown = obj->cknown;
bknown = obj->bknown;
@@ -693,7 +699,15 @@ register struct obj *obj;
/* "empty" goes at the beginning, but item count goes at the end */
if (cknown &&
(Is_container(obj) || obj->otyp == STATUE) && !Has_contents(obj))
/* bag of tricks: include "empty" prefix if it's known to
be empty but its precise number of charges isn't known
(when that is known, suffix of "(n:0)" will be appended,
making the prefix be redundant; note that 'known' flag
isn't set when emptiness gets discovered because then
charging magic would yield known number of new charges) */
(obj->otyp == BAG_OF_TRICKS ? (obj->spe == 0 && !obj->known) :
/* not bag of tricks: empty if container which has no contents */
(Is_container(obj) || obj->otyp == STATUE) && !Has_contents(obj)))
Strcat(prefix, "empty ");
if (bknown &&
+2
View File
@@ -201,6 +201,7 @@ static struct Bool_Opt
{"tombstone",&flags.tombstone, TRUE, SET_IN_GAME},
{"toptenwin",&iflags.toptenwin, FALSE, SET_IN_GAME},
{"travel", &flags.travelcmd, TRUE, SET_IN_GAME},
{"use_darkgray", &iflags.wc2_darkgray, TRUE, SET_IN_FILE},
#ifdef WIN32CON
{"use_inverse", &iflags.wc_inverse, TRUE, SET_IN_GAME}, /*WC*/
#else
@@ -4398,6 +4399,7 @@ struct wc_Opt wc2_options[] = {
{"fullscreen", WC2_FULLSCREEN},
{"softkeyboard", WC2_SOFTKEYBOARD},
{"wraptext", WC2_WRAPTEXT},
{"use_darkgray", WC2_DARKGRAY},
#ifdef STATUS_VIA_WINDOWPORT
{"hilite_status", WC2_HILITE_STATUS},
#endif
+2 -1
View File
@@ -447,7 +447,8 @@ const char **firstmatch;
{
boolean need_to_look = FALSE;
int glyph;
char look_buf[BUFSZ], prefix[BUFSZ];
static char look_buf[BUFSZ];
char prefix[BUFSZ];
int found = 0; /* count of matching syms found */
int i;
int skipped_venom = 0;
+4 -5
View File
@@ -1498,6 +1498,7 @@ doloot() /* loot a container on the floor or loot saddle from mon. */
char qbuf[BUFSZ];
int prev_inquiry = 0;
boolean prev_loot = FALSE;
int num_conts;
if (check_capacity((char *)0)) {
/* "Can't do that while carrying so much stuff." */
@@ -1518,15 +1519,11 @@ doloot() /* loot a container on the floor or loot saddle from mon. */
lootcont:
if (container_at(cc.x, cc.y, FALSE)) {
if ((num_conts = container_at(cc.x, cc.y, TRUE)) > 0) {
boolean anyfound = FALSE;
int num_conts = 0;
if (!able_to_loot(cc.x, cc.y, TRUE)) return 0;
for (cobj = level.objects[cc.x][cc.y]; cobj; cobj = cobj->nexthere)
if (Is_container(cobj)) num_conts++;
if (num_conts > 1) {
/* use a menu to loot many containers */
int n, i;
@@ -2124,6 +2121,7 @@ int held;
/* even if the trap fails, you've used up this turn */
if (multi >= 0) { /* in case we didn't become paralyzed */
nomul(-1);
multi_reason = "opening a container";
nomovemsg = "";
}
return 1;
@@ -2633,6 +2631,7 @@ struct obj *box; /* or bag */
/* even if the trap fails, you've used up this turn */
if (multi >= 0) { /* in case we didn't become paralyzed */
nomul(-1);
multi_reason = "tipping a container";
nomovemsg = "";
}
} else if (box->otyp == BAG_OF_TRICKS || box->otyp == HORN_OF_PLENTY) {
+1
View File
@@ -1285,6 +1285,7 @@ dogaze()
-d((int)mtmp->m_lev+1,
(int)mtmp->data->mattk[0].damd)
: -200);
multi_reason = "frozen by a monster's gaze";
nomovemsg = 0;
return 1;
} else
+4
View File
@@ -375,6 +375,7 @@ ghost_from_bottle()
if(flags.verbose)
You("are frightened to death, and unable to move.");
nomul(-3);
multi_reason = "being frightened to death";
nomovemsg = "You regain your composure.";
}
@@ -678,6 +679,7 @@ peffects(otmp)
Your("%s are frozen to the %s!",
makeplural(body_part(FOOT)), surface(u.ux, u.uy));
nomul(-(rn1(10, 25 - 12*bcsign(otmp))));
multi_reason = "frozen by a potion";
nomovemsg = You_can_move_again;
exercise(A_DEX, FALSE);
}
@@ -1467,6 +1469,7 @@ register struct obj *obj;
if (!Free_action) {
pline("%s seems to be holding you.", Something);
nomul(-rnd(5));
multi_reason = "frozen by a potion";
nomovemsg = You_can_move_again;
exercise(A_DEX, FALSE);
} else You("stiffen momentarily.");
@@ -1476,6 +1479,7 @@ register struct obj *obj;
if (!Free_action && !Sleep_resistance) {
You_feel("rather tired.");
nomul(-rnd(5));
multi_reason = "sleeping off a magical draught";
nomovemsg = You_can_move_again;
exercise(A_DEX, FALSE);
} else You("yawn.");
+3
View File
@@ -1269,6 +1269,7 @@ dosacrifice()
dmon->mpeaceful = TRUE;
You("are terrified, and unable to move.");
nomul(-3);
multi_reason = "being terrified of a demon";
nomovemsg = 0;
} else pline_The("%s.", demonless_msg);
}
@@ -1655,6 +1656,7 @@ dopray()
}
}
nomul(-3);
multi_reason = "praying";
nomovemsg = "You finish your prayer.";
afternmv = prayer_done;
@@ -1817,6 +1819,7 @@ doturn()
}
}
nomul(-5);
multi_reason = "trying to turn the monsters";
nomovemsg = You_can_move_again;
return(1);
}
+1
View File
@@ -475,6 +475,7 @@ int roomno;
if (flags.verbose)
You("are frightened to death, and unable to move.");
nomul(-3);
multi_reason = "being terrified of a demon";
nomovemsg = "You regain your composure.";
}
}
+147 -29
View File
@@ -53,6 +53,66 @@ struct obj *sobj;
(void) learnscrolltyp(sobj->otyp);
}
char *
erode_obj_text(otmp, buf)
struct obj *otmp;
char *buf;
{
int erosion = greatest_erosion(otmp);
if (erosion)
wipeout_text(buf,
(int)(strlen(buf) * erosion / (2*MAX_ERODE)),
otmp->o_id ^ (unsigned)ubirthday);
return buf;
}
char *
tshirt_text(tshirt, buf)
struct obj *tshirt;
char *buf;
{
static const char *shirt_msgs[] = { /* Scott Bigham */
"I explored the Dungeons of Doom and all I got was this lousy T-shirt!",
"Is that Mjollnir in your pocket or are you just happy to see me?",
"It's not the size of your sword, it's how #enhance'd you are with it.",
"Madame Elvira's House O' Succubi Lifetime Customer",
"Madame Elvira's House O' Succubi Employee of the Month",
"Ludios Vault Guards Do It In Small, Dark Rooms",
"Yendor Military Soldiers Do It In Large Groups",
"I survived Yendor Military Boot Camp",
"Ludios Accounting School Intra-Mural Lacrosse Team",
"Oracle(TM) Fountains 10th Annual Wet T-Shirt Contest",
"Hey, black dragon! Disintegrate THIS!",
"I'm With Stupid -->",
"Don't blame me, I voted for Izchak!",
"Don't Panic", /* HHGTTG */
"Furinkan High School Athletic Dept.", /* Ranma 1/2 */
"Hel-LOOO, Nurse!", /* Animaniacs */
};
Strcpy(buf, shirt_msgs[tshirt->o_id % SIZE(shirt_msgs)]);
return erode_obj_text(tshirt, buf);
}
char *
apron_text(apron, buf)
struct obj *apron;
char *buf;
{
static const char *apron_msgs[] = {
"Kiss the cook",
"I'm making SCIENCE!",
"Don't mess with the chef",
"Don't make me poison you",
"Gehennom's Kitchen",
"Rat: The other white meat",
"If you can't stand the heat, get out of Gehennom!",
"If we weren't meant to eat animals, why are they made out of meat?",
"If you don't like the food, I'll stab you",
};
Strcpy(buf, apron_msgs[apron->o_id % SIZE(apron_msgs)]);
return erode_obj_text(apron, buf);
}
int
doread()
{
@@ -72,34 +132,15 @@ doread()
if (!Blind) u.uconduct.literate++;
useup(scroll);
return(1);
} else if (scroll->otyp == T_SHIRT) {
static const char *shirt_msgs[] = { /* Scott Bigham */
"I explored the Dungeons of Doom and all I got was this lousy T-shirt!",
"Is that Mjollnir in your pocket or are you just happy to see me?",
"It's not the size of your sword, it's how #enhance'd you are with it.",
"Madame Elvira's House O' Succubi Lifetime Customer",
"Madame Elvira's House O' Succubi Employee of the Month",
"Ludios Vault Guards Do It In Small, Dark Rooms",
"Yendor Military Soldiers Do It In Large Groups",
"I survived Yendor Military Boot Camp",
"Ludios Accounting School Intra-Mural Lacrosse Team",
"Oracle(TM) Fountains 10th Annual Wet T-Shirt Contest",
"Hey, black dragon! Disintegrate THIS!",
"I'm With Stupid -->",
"Don't blame me, I voted for Izchak!",
"Don't Panic", /* HHGTTG */
"Furinkan High School Athletic Dept.", /* Ranma 1/2 */
"Hel-LOOO, Nurse!", /* Animaniacs */
};
} else if (scroll->otyp == T_SHIRT ||
scroll->otyp == ALCHEMY_SMOCK) {
char buf[BUFSZ];
int erosion;
if (Blind) {
You_cant("feel any Braille writing.");
return 0;
}
/* can't read shirt worn under suit (under cloak is ok though) */
if (uarm && scroll == uarmu) {
if (scroll->otyp == T_SHIRT && uarm && scroll == uarmu) {
pline("%s shirt is obscured by %s%s.",
scroll->unpaid ? "That" : "Your",
shk_your(buf, uarm), suit_simple_name(uarm));
@@ -108,13 +149,90 @@ doread()
u.uconduct.literate++;
if(flags.verbose)
pline("It reads:");
Strcpy(buf, shirt_msgs[scroll->o_id % SIZE(shirt_msgs)]);
erosion = greatest_erosion(scroll);
if (erosion)
wipeout_text(buf,
(int)(strlen(buf) * erosion / (2*MAX_ERODE)),
scroll->o_id ^ (unsigned)ubirthday);
pline("\"%s\"", buf);
pline("\"%s\"", (scroll->otyp == T_SHIRT)
? tshirt_text(scroll, buf)
: apron_text(scroll, buf));
return 1;
} else if (scroll->otyp == CREDIT_CARD) {
static const char *card_msgs[] = {
"Leprechaun Gold Tru$t - Shamrock Card",
"Magic Memory Vault Charge Card",
"Larn National Bank", /* Larn */
"First Bank of Omega", /* Omega */
"Bank of Zork - Frobozz Magic Card", /* Zork */
"Ankh-Morpork Merchant's Guild Barter Card",
"Ankh-Morpork Thieves' Guild Unlimited Transaction Card",
"Ransmannsby Moneylenders Association",
"Bank of Gehennom - 99% Interest Card",
"Yendorian Express - Copper Card",
"Yendorian Express - Silver Card",
"Yendorian Express - Gold Card",
"Yendorian Express - Mithril Card",
"Yendorian Express - Platinum Card", /* must be last */
};
if (Blind) {
You("feel the embossed numbers:");
} else {
if(flags.verbose)
pline("It reads:");
pline("\"%s\"", scroll->oartifact ? card_msgs[SIZE(card_msgs)-1]
: card_msgs[scroll->o_id % (SIZE(card_msgs)-1)]);
}
/* Make a credit card number */
pline("\"%d0%d %d%d1 0%d%d0\"", ((scroll->o_id % 89)+10), (scroll->o_id % 4),
(((scroll->o_id * 499) % 899999) + 100000), (scroll->o_id % 10),
(!(scroll->o_id % 3)), ((scroll->o_id * 7) % 10));
u.uconduct.literate++;
return 1;
} else if (scroll->otyp == CAN_OF_GREASE) {
pline("This %s has no label.", singular(scroll, xname));
return 0;
} else if (scroll->otyp == MAGIC_MARKER) {
if (Blind) {
You_cant("feel any Braille writing.");
return 0;
}
if (flags.verbose)
pline("It reads:");
pline("\"Magic Marker(TM) Red Ink Marker Pen. Water Soluble.\"");
u.uconduct.literate++;
return 1;
} else if (scroll->oclass == COIN_CLASS) {
if (Blind)
You("feel the embossed words:");
else if (flags.verbose)
You("read:");
pline("\"1 Zorkmid. 857 GUE. In Frobs We Trust.\"");
u.uconduct.literate++;
return 1;
} else if (scroll->oartifact == ART_ORB_OF_FATE) {
if (Blind)
You("feel the engraved signature:");
else pline("It is signed:");
pline("\"Odin.\"");
u.uconduct.literate++;
return 1;
} else if (scroll->otyp == CANDY_BAR) {
static const char *wrapper_msgs[] = {
"Apollo", /* Lost */
"Moon Crunchy", /* South Park */
"Snacky Cake",
"Chocolate Nuggie",
"The Small Bar",
"Crispy Yum Yum",
"Nilla Crunchie",
"Berry Bar",
"Choco Nummer",
"Om-nom", /* Cat Macro */
"Fruity Oaty", /* Serenity */
"Wonka Bar" /* Charlie and the Chocolate Factory */
};
if (Blind) {
You_cant("feel any Braille writing.");
return 0;
}
pline("The wrapper reads: \"%s\"", wrapper_msgs[scroll->o_id % SIZE(wrapper_msgs)]);
u.uconduct.literate++;
return 1;
} else if (scroll->oclass != SCROLL_CLASS
&& scroll->oclass != SPBOOK_CLASS) {
+4
View File
@@ -446,6 +446,10 @@ boolean ghostly;
if (mtmp->isshk) restshk(mtmp, ghostly);
if (mtmp->ispriest) restpriest(mtmp, ghostly);
if (!ghostly) {
if (mtmp->m_id == context.polearm.m_id)
context.polearm.hitmon = mtmp;
}
mtmp2 = mtmp;
}
if(first && mtmp2->nmon){
+6 -1
View File
@@ -1124,8 +1124,13 @@ register struct monst *mtmp;
}
if (mtmp->minvent)
saveobjchn(fd,mtmp->minvent,mode);
if (release_data(mode))
if (release_data(mode)) {
if (mtmp == context.polearm.hitmon) {
context.polearm.m_id = mtmp->m_id;
context.polearm.hitmon = NULL;
}
dealloc_monst(mtmp);
}
mtmp = mtmp2;
}
if (perform_bwrite(mode))
+1
View File
@@ -710,6 +710,7 @@ register struct monst *mtmp;
pline("%s rattles noisily.", Monnam(mtmp));
You("freeze for a moment.");
nomul(-2);
multi_reason = "scared by rattling";
nomovemsg = 0;
break;
case MS_LAUGH:
+3
View File
@@ -329,6 +329,7 @@ learn(VOID_ARGS)
context.spbook.book = 0; /* no longer studying */
context.spbook.o_id = 0;
nomul(context.spbook.delay); /* remaining delay is uninterrupted */
multi_reason = "reading a book";
nomovemsg = 0;
context.spbook.delay = 0;
return(0);
@@ -506,6 +507,7 @@ register struct obj *spellbook;
boolean gone = cursed_book(spellbook);
nomul(context.spbook.delay); /* study time */
multi_reason = "reading a book";
nomovemsg = 0;
context.spbook.delay = 0;
if(gone || !rn2(3)) {
@@ -522,6 +524,7 @@ register struct obj *spellbook;
spellbook->in_use = FALSE;
}
nomul(context.spbook.delay);
multi_reason = "reading a book";
nomovemsg = 0;
context.spbook.delay = 0;
return(1);
+1
View File
@@ -361,6 +361,7 @@ gotobj:
named++;
/* the following is to set multi for later on */
nomul(-armordelay);
multi_reason = "taking off clothes";
nomovemsg = 0;
remove_worn_item(otmp, TRUE);
otmp->cursed = curssv;
+4
View File
@@ -51,6 +51,7 @@ stoned_dialogue()
case 3: /* limbs turned to stone */
stop_occupation();
nomul(-3); /* can't move anymore */
multi_reason = "getting stoned";
nomovemsg = You_can_move_again; /* not unconscious */
break;
default:
@@ -377,6 +378,7 @@ nh_timeout()
if (u.umoved && !Levitation) {
slip_or_trip();
nomul(-2);
multi_reason = "fumbling";
nomovemsg = "";
/* The more you are carrying the more likely you
* are to make noise when you fumble. Adjustments
@@ -409,6 +411,7 @@ boolean wakeup_msg;
{
stop_occupation();
nomul(how_long);
multi_reason = "sleeping";
/* generally don't notice sounds while sleeping */
if (wakeup_msg && multi == how_long) {
/* caller can follow with a direct call to Hear_again() if
@@ -1271,6 +1274,7 @@ do_storms()
if(!u.uinvulnerable) {
stop_occupation();
nomul(-3);
multi_reason = "hiding from thunderstorm";
nomovemsg = 0;
}
} else
+14
View File
@@ -66,6 +66,7 @@ STATIC_DCL void FDECL(discardexcess, (FILE *));
STATIC_DCL void FDECL(readentry, (FILE *,struct toptenentry *));
STATIC_DCL void FDECL(writeentry, (FILE *,struct toptenentry *));
STATIC_DCL void FDECL(writexlentry, (FILE*, struct toptenentry *));
STATIC_DCL long NDECL(encodexlogflags);
STATIC_DCL long NDECL(encodeconduct);
STATIC_DCL long NDECL(encodeachieve);
STATIC_DCL void FDECL(free_ttlist, (struct toptenentry *));
@@ -341,10 +342,23 @@ struct toptenentry *tt;
Fprintf(rfile, "%cgender0=%s%calign0=%s",
XLOG_SEP, genders[flags.initgend].filecode,
XLOG_SEP, aligns[1 - u.ualignbase[A_ORIGINAL]].filecode);
Fprintf(rfile, "%cflags=0x%lx",
XLOG_SEP, encodexlogflags());
Fprintf(rfile, "\n");
#undef XLOG_SEP
}
STATIC_OVL long
encodexlogflags()
{
long e = 0L;
if (wizard) e |= 1L << 0;
if (discover) e |= 1L << 1;
return e;
}
STATIC_OVL long
encodeconduct()
{
+11 -6
View File
@@ -1,4 +1,4 @@
/* NetHack 3.5 trap.c $NHDT-Date: 1426805491 2015/03/19 22:51:31 $ $NHDT-Branch: water_damage $:$NHDT-Revision: 1.198 $ */
/* NetHack 3.5 trap.c $NHDT-Date: 1427331767 2015/03/26 01:02:47 $ $NHDT-Branch: master $:$NHDT-Revision: 1.199 $ */
/* NetHack 3.5 trap.c $Date: 2013/03/14 01:58:21 $ $Revision: 1.179 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -3118,13 +3118,17 @@ acid_damage(obj)
struct obj *obj;
{
/* Scrolls but not spellbooks can be erased by acid. */
struct monst *victim =
carried(obj) ? &youmonst : mcarried(obj) ? obj->ocarry : NULL;
boolean vismon = victim && (victim != &youmonst) && canseemon(victim);
struct monst *victim;
boolean vismon;
if (obj->greased)
if (!obj) return;
victim = carried(obj) ? &youmonst : mcarried(obj) ? obj->ocarry : NULL;
vismon = victim && (victim != &youmonst) && canseemon(victim);
if (obj->greased) {
grease_protect(obj, NULL, victim);
else if (obj->oclass == SCROLL_CLASS && obj->otyp != SCR_BLANK_PAPER) {
} else if (obj->oclass == SCROLL_CLASS && obj->otyp != SCR_BLANK_PAPER) {
if (obj->otyp != SCR_BLANK_PAPER
#ifdef MAIL
&& obj->otyp != SCR_MAIL
@@ -4443,6 +4447,7 @@ boolean disarm;
if (!Free_action) {
pline("Suddenly you are frozen in place!");
nomul(-d(5, 6));
multi_reason = "frozen by a trap";
exercise(A_DEX, FALSE);
nomovemsg = You_can_move_again;
} else You("momentarily stiffen.");
+3
View File
@@ -1871,6 +1871,7 @@ register struct attack *mattk;
You("digest %s.", mon_nam(mdef));
if (Slow_digestion) tmp *= 2;
nomul(-tmp);
multi_reason = "digesting something";
nomovemsg = msgbuf;
} else pline1(msgbuf);
if (pd == &mons[PM_GREEN_SLIME]) {
@@ -2353,6 +2354,7 @@ boolean wep_was_destroyed;
You("are frozen by %s gaze!",
s_suffix(mon_nam(mon)));
nomul((ACURR(A_WIS) > 12 || rn2(4)) ? -tmp : -127);
multi_reason = "frozen by a monster's gaze";
nomovemsg = 0;
}
} else {
@@ -2366,6 +2368,7 @@ boolean wep_was_destroyed;
You("are frozen by %s!", mon_nam(mon));
nomovemsg = You_can_move_again;
nomul(-tmp);
multi_reason = "frozen by a monster";
exercise(A_DEX, FALSE);
}
break;
+1 -3
View File
@@ -1,4 +1,4 @@
/* NetHack 3.5 worn.c $NHDT-Date$ $NHDT-Branch$:$NHDT-Revision$ */
/* NetHack 3.5 worn.c $NHDT-Date: 1427580338 2015/03/28 22:05:38 $ $NHDT-Branch: master $:$NHDT-Revision: 1.35 $ */
/* NetHack 3.5 worn.c $Date: 2013/11/05 00:57:56 $ $Revision: 1.32 $ */
/* SCCS Id: @(#)worn.c 3.5 2009/02/28 */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
@@ -591,9 +591,7 @@ long flag;
case W_ARMS: return uarms;
case W_ARMG: return uarmg;
case W_ARMF: return uarmf;
#ifdef TOURIST
case W_ARMU: return uarmu;
#endif
default:
impossible("bad flag in which_armor");
return 0;
+35 -9
View File
@@ -1750,9 +1750,9 @@ struct obj *obj, *otmp;
if (Is_box(obj)) (void) boxlock(obj, otmp);
if (obj_shudders(obj)) {
boolean cover = ((obj->ox == u.ux && obj->oy == u.uy) &&
u.uundetected &&
hides_under(youmonst.data));
boolean cover = ((obj == level.objects[u.ux][u.uy]) &&
u.uundetected &&
hides_under(youmonst.data));
if (cansee(obj->ox, obj->oy)) learn_it = TRUE;
do_osshock(obj);
@@ -1892,10 +1892,11 @@ struct obj *obj, *otmp;
/* returns nonzero if something was hit */
int
bhitpile(obj,fhito,tx,ty)
bhitpile(obj,fhito,tx,ty,zdir)
struct obj *obj;
int FDECL((*fhito), (OBJ_P,OBJ_P));
int tx, ty;
schar zdir;
{
int hitanything = 0;
register struct obj *otmp, *next_obj;
@@ -1917,7 +1918,14 @@ bhitpile(obj,fhito,tx,ty)
for(otmp = level.objects[tx][ty]; otmp; otmp = next_obj) {
/* Fix for polymorph bug, Tim Wright */
next_obj = otmp->nexthere;
hitanything += (*fhito)(otmp, obj);
/*
* game flavor: if you are hiding under something,
* a zap downwards shouldn't hit that obj, so honor that.
*/
if (!(u.uundetected && (zdir > 0) &&
(otmp == level.objects[u.ux][u.uy]) &&
hides_under(youmonst.data)))
hitanything += (*fhito)(otmp, obj);
}
if(poly_zapped >= 0)
create_polymon(level.objects[tx][ty], poly_zapped);
@@ -2568,7 +2576,7 @@ struct obj *obj; /* wand or spell */
if (u.dz < 0) {
You("probe towards the %s.", ceiling(x,y));
} else {
ptmp += bhitpile(obj, bhito, x, y);
ptmp += bhitpile(obj, bhito, x, y, u.dz);
You("probe beneath the %s.", surface(x,y));
ptmp += display_binventory(x, y, TRUE);
}
@@ -2688,7 +2696,7 @@ struct obj *obj; /* wand or spell */
if (u.dz > 0) {
/* zapping downward */
(void) bhitpile(obj, bhito, x, y);
(void) bhitpile(obj, bhito, x, y, u.dz);
/* subset of engraving effects; none sets `disclose' */
if ((e = engr_at(x, y)) != 0 && e->engr_type != HEADSTONE) {
@@ -2724,6 +2732,22 @@ struct obj *obj; /* wand or spell */
break;
}
}
} else if (u.dz < 0) {
/* zapping upward */
/* game flavor: if you're hiding under "something"
* a zap upward should hit that "something".
*/
if (u.uundetected && hides_under(youmonst.data)) {
int hitit = 0;
otmp = level.objects[u.ux][u.uy];
if (otmp) hitit = bhito(otmp, obj);
if (hitit) {
(void) hideunder(&youmonst);
disclose = TRUE;
}
}
}
return disclose;
@@ -3095,7 +3119,7 @@ struct obj **pobj; /* object tossed/used, set to NULL
}
}
if(fhito) {
if(bhitpile(obj,fhito,bhitpos.x,bhitpos.y))
if(bhitpile(obj,fhito,bhitpos.x,bhitpos.y,0))
range--;
} else {
if(weapon == KICKED_WEAPON &&
@@ -3259,8 +3283,10 @@ int dx, dy;
}
tmp_at(bhitpos.x, bhitpos.y);
delay_output();
if(IS_SINK(levl[bhitpos.x][bhitpos.y].typ))
if(IS_SINK(levl[bhitpos.x][bhitpos.y].typ)) {
if (!Deaf) pline("Klonk!");
break; /* boomerang falls on sink */
}
/* ct==0, initial position, we want next delta to be same;
ct==5, opposite position, repeat delta undoes first one */
if (ct % 5 != 0) i += (counterclockwise ? -1 : 1);