Merge remote-tracking branch 'origin/NetHack-3.6.0'
This commit is contained in:
@@ -3445,11 +3445,20 @@ boolean initial;
|
||||
Cmd.move_SW = Cmd.dirchars[7];
|
||||
}
|
||||
|
||||
/* non-movement commands which accept 'm' prefix to request menu operation */
|
||||
STATIC_OVL boolean
|
||||
accept_menu_prefix(cmd_func)
|
||||
int NDECL((*cmd_func));
|
||||
{
|
||||
if (cmd_func == dopickup || cmd_func == dotip
|
||||
/* eat, #offer, and apply tinning-kit all use floorfood() to pick
|
||||
an item on floor or in invent; 'm' skips picking from floor
|
||||
(ie, inventory only) rather than request use of menu operation */
|
||||
|| cmd_func == doeat || cmd_func == dosacrifice || cmd_func == doapply
|
||||
/* 'm' for removing saddle from adjacent monster without checking
|
||||
for containers at <u.ux,u.uy> */
|
||||
|| cmd_func == doloot
|
||||
/* 'm' prefix allowed for some extended commands */
|
||||
|| cmd_func == doextcmd || cmd_func == doextlist)
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
|
||||
@@ -814,8 +814,8 @@ register struct obj *obj;
|
||||
case CARROT:
|
||||
return herbi ? DOGFOOD : starving ? ACCFOOD : MANFOOD;
|
||||
case BANANA:
|
||||
return (mptr->mlet == S_YETI)
|
||||
? DOGFOOD
|
||||
return (mptr->mlet == S_YETI && herbi)
|
||||
? DOGFOOD /* for monkey and ape (tameable), sasquatch */
|
||||
: (herbi || starving)
|
||||
? ACCFOOD
|
||||
: MANFOOD;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 eat.c $NHDT-Date: 1466289475 2016/06/18 22:37:55 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.169 $ */
|
||||
/* NetHack 3.6 eat.c $NHDT-Date: 1467028559 2016/06/27 11:55:59 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.171 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
@@ -13,6 +13,7 @@ STATIC_PTR int NDECL(unfaint);
|
||||
STATIC_DCL const char *FDECL(food_xname, (struct obj *, BOOLEAN_P));
|
||||
STATIC_DCL void FDECL(choke, (struct obj *));
|
||||
STATIC_DCL void NDECL(recalc_wt);
|
||||
STATIC_DCL unsigned FDECL(obj_nutrition, (struct obj *));
|
||||
STATIC_DCL struct obj *FDECL(touchfood, (struct obj *));
|
||||
STATIC_DCL void NDECL(do_reset_eat);
|
||||
STATIC_DCL void FDECL(done_eating, (BOOLEAN_P));
|
||||
@@ -296,6 +297,32 @@ reset_eat()
|
||||
return;
|
||||
}
|
||||
|
||||
/* base nutrition of a food-class object */
|
||||
STATIC_OVL unsigned
|
||||
obj_nutrition(otmp)
|
||||
struct obj *otmp;
|
||||
{
|
||||
unsigned nut = (otmp->otyp == CORPSE) ? mons[otmp->corpsenm].cnutrit
|
||||
: otmp->globby ? otmp->owt
|
||||
: (unsigned) objects[otmp->otyp].oc_nutrition;
|
||||
|
||||
if (otmp->otyp == LEMBAS_WAFER) {
|
||||
if (maybe_polyd(is_elf(youmonst.data), Race_if(PM_ELF)))
|
||||
nut += nut / 4; /* 800 -> 1000 */
|
||||
else if (maybe_polyd(is_orc(youmonst.data), Race_if(PM_ORC)))
|
||||
nut -= nut / 4; /* 800 -> 600 */
|
||||
/* prevent polymorph making a partly eaten wafer
|
||||
become more nutritious than an untouched one */
|
||||
if (otmp->oeaten >= nut)
|
||||
otmp->oeaten = (otmp->oeaten < objects[LEMBAS_WAFER].oc_nutrition)
|
||||
? (nut - 1) : nut;
|
||||
} else if (otmp->otyp == CRAM_RATION) {
|
||||
if (maybe_polyd(is_dwarf(youmonst.data), Race_if(PM_DWARF)))
|
||||
nut += nut / 6; /* 600 -> 700 */
|
||||
}
|
||||
return nut;
|
||||
}
|
||||
|
||||
STATIC_OVL struct obj *
|
||||
touchfood(otmp)
|
||||
struct obj *otmp;
|
||||
@@ -310,9 +337,7 @@ struct obj *otmp;
|
||||
|
||||
if (!otmp->oeaten) {
|
||||
costly_alteration(otmp, COST_BITE);
|
||||
otmp->oeaten = (otmp->otyp == CORPSE) ? mons[otmp->corpsenm].cnutrit
|
||||
: otmp->globby ? otmp->owt
|
||||
: (unsigned) objects[otmp->otyp].oc_nutrition;
|
||||
otmp->oeaten = obj_nutrition(otmp);
|
||||
}
|
||||
|
||||
if (carried(otmp)) {
|
||||
@@ -1741,6 +1766,15 @@ struct obj *otmp;
|
||||
make_vomiting((long) rn1(context.victual.reqtime, 14), FALSE);
|
||||
}
|
||||
break;
|
||||
case LEMBAS_WAFER:
|
||||
if (maybe_polyd(is_orc(youmonst.data), Race_if(PM_ORC))) {
|
||||
pline("%s", "!#?&* elf kibble!");
|
||||
break;
|
||||
} else if (maybe_polyd(is_elf(youmonst.data), Race_if(PM_ELF))) {
|
||||
pline("A little goes a long way.");
|
||||
break;
|
||||
}
|
||||
goto give_feedback;
|
||||
case MEATBALL:
|
||||
case MEAT_STICK:
|
||||
case HUGE_CHUNK_OF_MEAT:
|
||||
@@ -2368,6 +2402,7 @@ doeat()
|
||||
|
||||
if (u.uedibility) {
|
||||
int res = edibility_prompts(otmp);
|
||||
|
||||
if (res) {
|
||||
Your(
|
||||
"%s stops tingling and your sense of smell returns to normal.",
|
||||
@@ -2577,9 +2612,7 @@ doeat()
|
||||
}
|
||||
|
||||
/* re-calc the nutrition */
|
||||
basenutrit = (otmp->otyp == CORPSE) ? mons[otmp->corpsenm].cnutrit
|
||||
: otmp->globby ? otmp->owt
|
||||
: (unsigned) objects[otmp->otyp].oc_nutrition;
|
||||
basenutrit = (int) obj_nutrition(otmp);
|
||||
|
||||
debugpline3(
|
||||
"before rounddiv: victual.reqtime == %d, oeaten == %d, basenutrit == %d",
|
||||
@@ -2974,7 +3007,8 @@ int corpsecheck; /* 0, no check, 1, corpses, 2, tinnable corpses */
|
||||
offering = !strcmp(verb, "sacrifice"); /* corpsecheck==1 */
|
||||
|
||||
/* if we can't touch floor objects then use invent food only */
|
||||
if (!can_reach_floor(TRUE) || (feeding && u.usteed)
|
||||
if (iflags.menu_requested /* command was preceded by 'm' prefix */
|
||||
|| !can_reach_floor(TRUE) || (feeding && u.usteed)
|
||||
|| (is_pool_or_lava(u.ux, u.uy)
|
||||
&& (Wwalking || is_clinger(youmonst.data)
|
||||
|| (Flying && !Breathless))))
|
||||
@@ -3085,10 +3119,9 @@ struct obj *obj;
|
||||
{
|
||||
long uneaten_amt, full_amount;
|
||||
|
||||
/* get full_amount first; obj_nutrition() might modify obj->oeaten */
|
||||
full_amount = (long) obj_nutrition(obj);
|
||||
uneaten_amt = (long) obj->oeaten;
|
||||
full_amount = (long) ((obj->otyp == CORPSE) ? mons[obj->corpsenm].cnutrit
|
||||
: obj->globby ? obj->owt
|
||||
: (unsigned) objects[obj->otyp].oc_nutrition);
|
||||
if (uneaten_amt > full_amount) {
|
||||
impossible(
|
||||
"partly eaten food (%ld) more nutritious than untouched food (%ld)",
|
||||
|
||||
+10
-4
@@ -979,15 +979,21 @@ not_special:
|
||||
* mpickstuff() as well.
|
||||
*/
|
||||
if (xx >= lmx && xx <= oomx && yy >= lmy && yy <= oomy) {
|
||||
/* don't get stuck circling around an object that's
|
||||
underneath
|
||||
an immobile or hidden monster; paralysis victims
|
||||
excluded */
|
||||
/* don't get stuck circling around object that's
|
||||
underneath an immobile or hidden monster;
|
||||
paralysis victims excluded */
|
||||
if ((mtoo = m_at(xx, yy)) != 0
|
||||
&& (mtoo->msleeping || mtoo->mundetected
|
||||
|| (mtoo->mappearance && !mtoo->iswiz)
|
||||
|| !mtoo->data->mmove))
|
||||
continue;
|
||||
/* the mfndpos() test for whether to allow a move to a
|
||||
water location accepts flyers, but they can't reach
|
||||
underwater objects, so being able to move to a spot
|
||||
is insufficient for deciding whether to do so */
|
||||
if ((is_pool(xx, yy) && !is_swimmer(ptr))
|
||||
|| (is_lava(xx, yy) && !likes_lava(ptr)))
|
||||
continue;
|
||||
|
||||
if (((likegold && otmp->oclass == COIN_CLASS)
|
||||
|| (likeobjs && index(practical, otmp->oclass)
|
||||
|
||||
+4
-2
@@ -1923,16 +1923,18 @@ struct permonst _mons2[] = {
|
||||
/*
|
||||
* Apelike beasts
|
||||
*/
|
||||
/* tameable via banana; does not grow up into ape...
|
||||
not flagged as domestic, so no guilt penalty for eating non-pet one */
|
||||
MON("monkey", S_YETI, LVL(2, 12, 6, 0, 0), (G_GENO | 1),
|
||||
A(ATTK(AT_CLAW, AD_SITM, 0, 0), ATTK(AT_BITE, AD_PHYS, 1, 3), NO_ATTK,
|
||||
NO_ATTK, NO_ATTK, NO_ATTK),
|
||||
SIZ(100, 50, MS_GROWL, MZ_SMALL), 0, 0,
|
||||
M1_ANIMAL | M1_HUMANOID | M1_CARNIVORE, 0, M3_INFRAVISIBLE, CLR_GRAY),
|
||||
M1_ANIMAL | M1_HUMANOID | M1_OMNIVORE, 0, M3_INFRAVISIBLE, CLR_GRAY),
|
||||
MON("ape", S_YETI, LVL(4, 12, 6, 0, 0), (G_GENO | G_SGROUP | 2),
|
||||
A(ATTK(AT_CLAW, AD_PHYS, 1, 3), ATTK(AT_CLAW, AD_PHYS, 1, 3),
|
||||
ATTK(AT_BITE, AD_PHYS, 1, 6), NO_ATTK, NO_ATTK, NO_ATTK),
|
||||
SIZ(1100, 500, MS_GROWL, MZ_LARGE), 0, 0,
|
||||
M1_ANIMAL | M1_HUMANOID | M1_CARNIVORE, M2_STRONG, M3_INFRAVISIBLE,
|
||||
M1_ANIMAL | M1_HUMANOID | M1_OMNIVORE, M2_STRONG, M3_INFRAVISIBLE,
|
||||
CLR_BROWN),
|
||||
MON("owlbear", S_YETI, LVL(5, 12, 5, 0, 0), (G_GENO | 3),
|
||||
A(ATTK(AT_CLAW, AD_PHYS, 1, 6), ATTK(AT_CLAW, AD_PHYS, 1, 6),
|
||||
|
||||
+22
-25
@@ -414,6 +414,24 @@ boolean verbose; /* give message(s) even when you can't see what happened */
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define MT_FLIGHTCHECK(pre) \
|
||||
(/* missile hits edge of screen */ \
|
||||
!isok(bhitpos.x + dx, bhitpos.y + dy) \
|
||||
/* missile hits the wall */ \
|
||||
|| IS_ROCK(levl[bhitpos.x + dx][bhitpos.y + dy].typ) \
|
||||
/* missile hit closed door */ \
|
||||
|| closed_door(bhitpos.x + dx, bhitpos.y + dy) \
|
||||
/* missile might hit iron bars */ \
|
||||
/* the random chance for small objects hitting bars is */ \
|
||||
/* skipped when reaching them at point blank range */ \
|
||||
|| (levl[bhitpos.x + dx][bhitpos.y + dy].typ == IRONBARS \
|
||||
&& hits_bars(&singleobj, \
|
||||
bhitpos.x, bhitpos.y, \
|
||||
bhitpos.x + dx, bhitpos.y + dy, \
|
||||
((pre) ? 0 : !rn2(5)), 0)) \
|
||||
/* Thrown objects "sink" */ \
|
||||
|| (!(pre) && IS_SINK(levl[bhitpos.x][bhitpos.y].typ)))
|
||||
|
||||
void
|
||||
m_throw(mon, x, y, dx, dy, range, obj)
|
||||
struct monst *mon; /* launching monster */
|
||||
@@ -471,17 +489,7 @@ struct obj *obj; /* missile (or stack providing it) */
|
||||
}
|
||||
}
|
||||
|
||||
/* pre-check for doors, walls and boundaries.
|
||||
Also need to pre-check for bars regardless of direction;
|
||||
the random chance for small objects hitting bars is
|
||||
skipped when reaching them at point blank range */
|
||||
if (!isok(bhitpos.x + dx, bhitpos.y + dy)
|
||||
|| IS_ROCK(levl[bhitpos.x + dx][bhitpos.y + dy].typ)
|
||||
|| closed_door(bhitpos.x + dx, bhitpos.y + dy)
|
||||
|| (levl[bhitpos.x + dx][bhitpos.y + dy].typ == IRONBARS
|
||||
&& hits_bars(&singleobj,
|
||||
bhitpos.x, bhitpos.y,
|
||||
bhitpos.x + dx, bhitpos.y + dy, 0, 0))) {
|
||||
if (MT_FLIGHTCHECK(TRUE)) {
|
||||
(void) drop_throw(singleobj, 0, bhitpos.x, bhitpos.y);
|
||||
return;
|
||||
}
|
||||
@@ -611,20 +619,7 @@ struct obj *obj; /* missile (or stack providing it) */
|
||||
}
|
||||
}
|
||||
if (!range /* reached end of path */
|
||||
/* missile hits edge of screen */
|
||||
|| !isok(bhitpos.x + dx, bhitpos.y + dy)
|
||||
/* missile hits the wall */
|
||||
|| IS_ROCK(levl[bhitpos.x + dx][bhitpos.y + dy].typ)
|
||||
/* missile hit closed door */
|
||||
|| closed_door(bhitpos.x + dx, bhitpos.y + dy)
|
||||
/* missile might hit iron bars */
|
||||
|| (levl[bhitpos.x + dx][bhitpos.y + dy].typ == IRONBARS
|
||||
&& hits_bars(&singleobj,
|
||||
bhitpos.x, bhitpos.y,
|
||||
bhitpos.x + dx, bhitpos.y + dy,
|
||||
!rn2(5), 0))
|
||||
/* Thrown objects "sink" */
|
||||
|| IS_SINK(levl[bhitpos.x][bhitpos.y].typ)) {
|
||||
|| MT_FLIGHTCHECK(FALSE)) {
|
||||
if (singleobj) { /* hits_bars might have destroyed it */
|
||||
if (m_shot.n > 1 && (cansee(bhitpos.x, bhitpos.y)
|
||||
|| (archer && canseemon(archer))))
|
||||
@@ -648,6 +643,8 @@ struct obj *obj; /* missile (or stack providing it) */
|
||||
}
|
||||
}
|
||||
|
||||
#undef MT_FLIGHTCHECK
|
||||
|
||||
/* Monster throws item at another monster */
|
||||
int
|
||||
thrwmm(mtmp, mtarg)
|
||||
|
||||
+30
-1
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 pager.c $NHDT-Date: 1465114189 2016/06/05 08:09:49 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.107 $ */
|
||||
/* NetHack 3.6 pager.c $NHDT-Date: 1466638086 2016/06/22 23:28:06 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.111 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
@@ -1307,6 +1307,35 @@ doidtrap()
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
Implements a rudimentary if/elif/else/endif interpretor and use
|
||||
conditionals in dat/cmdhelp to describe what command each keystroke
|
||||
currently invokes, so that there isn't a lot of "(debug mode only)"
|
||||
and "(if number_pad is off)" cluttering the feedback that the user
|
||||
sees. (The conditionals add quite a bit of clutter to the raw data
|
||||
but users don't see that. number_pad produces a lot of conditional
|
||||
commands: basic letters vs digits, 'g' vs 'G' for '5', phone
|
||||
keypad vs normal layout of digits, and QWERTZ keyboard swap between
|
||||
y/Y/^Y/M-y/M-Y/M-^Y and z/Z/^Z/M-z/M-Z/M-^Z.)
|
||||
|
||||
The interpretor understands
|
||||
'&#' for comment,
|
||||
'&? option' for 'if' (also '&? !option'
|
||||
or '&? option=value[,value2,...]'
|
||||
or '&? !option=value[,value2,...]'),
|
||||
'&: option' for 'elif' (with argument variations same as 'if';
|
||||
any number of instances for each 'if'),
|
||||
'&:' for 'else' (also '&: #comment';
|
||||
0 or 1 instance for a given 'if'), and
|
||||
'&.' for 'endif' (also '&. #comment'; required for each 'if').
|
||||
|
||||
The option handling is a bit of a mess, with no generality for
|
||||
which options to deal with and only a comma separated list of
|
||||
integer values for the '=value' part. number_pad is the only
|
||||
supported option that has a value; the few others (wizard/debug,
|
||||
rest_on_space, #if SHELL, #if SUSPEND) are booleans.
|
||||
*/
|
||||
|
||||
STATIC_DCL void
|
||||
whatdoes_help()
|
||||
{
|
||||
|
||||
+59
-22
@@ -1630,7 +1630,7 @@ doloot()
|
||||
char qbuf[BUFSZ];
|
||||
int prev_inquiry = 0;
|
||||
boolean prev_loot = FALSE;
|
||||
int num_conts;
|
||||
int num_conts = 0;
|
||||
|
||||
abort_looting = FALSE;
|
||||
|
||||
@@ -1653,13 +1653,30 @@ doloot()
|
||||
cc.x = u.ux;
|
||||
cc.y = u.uy;
|
||||
|
||||
lootcont:
|
||||
if (iflags.menu_requested)
|
||||
goto lootmon;
|
||||
|
||||
lootcont:
|
||||
if ((num_conts = container_at(cc.x, cc.y, TRUE)) > 0) {
|
||||
boolean anyfound = FALSE;
|
||||
|
||||
if (!able_to_loot(cc.x, cc.y, TRUE))
|
||||
return 0;
|
||||
|
||||
if (Blind && !uarmg) {
|
||||
/* if blind and without gloves, attempting to #loot at the
|
||||
location of a cockatrice corpse is fatal before asking
|
||||
whether to manipulate any containers */
|
||||
for (nobj = sobj_at(CORPSE, cc.x, cc.y); nobj;
|
||||
nobj = nxtobj(nobj, CORPSE, TRUE))
|
||||
if (will_feel_cockatrice(nobj, FALSE)) {
|
||||
feel_cockatrice(nobj, FALSE);
|
||||
/* if life-saved (or poly'd into stone golem),
|
||||
terminate attempt to loot */
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (num_conts > 1) {
|
||||
/* use a menu to loot many containers */
|
||||
int n, i;
|
||||
@@ -1722,9 +1739,11 @@ lootcont:
|
||||
} else if (IS_GRAVE(levl[cc.x][cc.y].typ)) {
|
||||
You("need to dig up the grave to effectively loot it...");
|
||||
}
|
||||
|
||||
/*
|
||||
* 3.3.1 introduced directional looting for some things.
|
||||
*/
|
||||
lootmon:
|
||||
if (c != 'y' && mon_beside(u.ux, u.uy)) {
|
||||
if (!get_adjacent_loc("Loot in what direction?",
|
||||
"Invalid loot location", u.ux, u.uy, &cc))
|
||||
@@ -2883,20 +2902,27 @@ tipcontainer(box)
|
||||
struct obj *box; /* or bag */
|
||||
{
|
||||
xchar ox = u.ux, oy = u.uy; /* #tip only works at hero's location */
|
||||
boolean empty_it = FALSE,
|
||||
/* Shop handling: can't rely on the container's own unpaid
|
||||
or no_charge status because contents might differ with it.
|
||||
A carried container's contents will be flagged as unpaid
|
||||
or not, as appropriate, and need no special handling here.
|
||||
Items owned by the hero get sold to the shop without
|
||||
confirmation as with other uncontrolled drops. A floor
|
||||
container's contents will be marked no_charge if owned by
|
||||
hero, otherwise they're owned by the shop. By passing
|
||||
the contents through shop billing, they end up getting
|
||||
treated the same as in the carried case. We do so one
|
||||
item at a time instead of doing whole container at once
|
||||
to reduce the chance of exhausting shk's billing capacity. */
|
||||
maybeshopgoods = !carried(box) && costly_spot(ox, oy);
|
||||
boolean empty_it = FALSE, maybeshopgoods;
|
||||
|
||||
/* box is either held or on floor at hero's spot; no need to check for
|
||||
nesting; when held, we need to update its location to match hero's;
|
||||
for floor, the coordinate updating is redundant */
|
||||
if (get_obj_location(box, &ox, &oy, 0))
|
||||
box->ox = ox, box->oy = oy;
|
||||
|
||||
/* Shop handling: can't rely on the container's own unpaid
|
||||
or no_charge status because contents might differ with it.
|
||||
A carried container's contents will be flagged as unpaid
|
||||
or not, as appropriate, and need no special handling here.
|
||||
Items owned by the hero get sold to the shop without
|
||||
confirmation as with other uncontrolled drops. A floor
|
||||
container's contents will be marked no_charge if owned by
|
||||
hero, otherwise they're owned by the shop. By passing
|
||||
the contents through shop billing, they end up getting
|
||||
treated the same as in the carried case. We do so one
|
||||
item at a time instead of doing whole container at once
|
||||
to reduce the chance of exhausting shk's billing capacity. */
|
||||
maybeshopgoods = !carried(box) && costly_spot(box->ox, box->oy);
|
||||
|
||||
/* caveat: this assumes that cknown, lknown, olocked, and otrapped
|
||||
fields haven't been overloaded to mean something special for the
|
||||
@@ -2959,7 +2985,7 @@ struct obj *box; /* or bag */
|
||||
|
||||
if (empty_it) {
|
||||
struct obj *otmp, *nobj;
|
||||
boolean verbose = FALSE, highdrop = !can_reach_floor(TRUE),
|
||||
boolean terse, highdrop = !can_reach_floor(TRUE),
|
||||
altarizing = IS_ALTAR(levl[ox][oy].typ),
|
||||
cursed_mbag = (Is_mbag(box) && box->cursed);
|
||||
int held = carried(box);
|
||||
@@ -2967,20 +2993,27 @@ struct obj *box; /* or bag */
|
||||
|
||||
if (u.uswallow)
|
||||
highdrop = altarizing = FALSE;
|
||||
terse = !(highdrop || altarizing || costly_spot(box->ox, box->oy));
|
||||
box->cknown = 1;
|
||||
/* Terse formatting is
|
||||
* "Objects spill out: obj1, obj2, obj3, ..., objN."
|
||||
* If any other messages intervene between objects, we revert to
|
||||
* "ObjK drops to the floor.", "ObjL drops to the floor.", &c.
|
||||
*/
|
||||
pline("%s out%c",
|
||||
box->cobj->nobj ? "Objects spill" : "An object spills",
|
||||
!(highdrop || altarizing) ? ':' : '.');
|
||||
terse ? ':' : '.');
|
||||
for (otmp = box->cobj; otmp; otmp = nobj) {
|
||||
nobj = otmp->nobj;
|
||||
obj_extract_self(otmp);
|
||||
otmp->ox = box->ox, otmp->oy = box->oy;
|
||||
|
||||
if (box->otyp == ICE_BOX) {
|
||||
removed_from_icebox(otmp); /* resume rotting for corpse */
|
||||
} else if (cursed_mbag && !rn2(13)) {
|
||||
loss += mbag_item_gone(held, otmp);
|
||||
/* abbreviated drop format is no longer appropriate */
|
||||
verbose = TRUE;
|
||||
terse = FALSE;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -2993,14 +3026,18 @@ struct obj *box; /* or bag */
|
||||
/* might break or fall down stairs; handles altars itself */
|
||||
hitfloor(otmp);
|
||||
} else {
|
||||
if (altarizing)
|
||||
if (altarizing) {
|
||||
doaltarobj(otmp);
|
||||
else if (verbose)
|
||||
} else if (!terse) {
|
||||
pline("%s %s to the %s.", Doname2(otmp),
|
||||
otense(otmp, "drop"), surface(ox, oy));
|
||||
else
|
||||
} else {
|
||||
pline("%s%c", doname(otmp), nobj ? ',' : '.');
|
||||
iflags.last_msg = PLNMSG_OBJNAM_ONLY;
|
||||
}
|
||||
dropy(otmp);
|
||||
if (iflags.last_msg != PLNMSG_OBJNAM_ONLY)
|
||||
terse = FALSE; /* terse formatting has been interrupted */
|
||||
}
|
||||
if (maybeshopgoods)
|
||||
iflags.suppress_price--; /* reset */
|
||||
|
||||
@@ -2130,9 +2130,10 @@ boolean unpaid_only;
|
||||
return price;
|
||||
}
|
||||
|
||||
/* count amount of gold inside container 'obj' and any nested containers */
|
||||
long
|
||||
contained_gold(obj)
|
||||
register struct obj *obj;
|
||||
struct obj *obj;
|
||||
{
|
||||
register struct obj *otmp;
|
||||
register long value = 0L;
|
||||
@@ -2867,12 +2868,12 @@ xchar x, y;
|
||||
boolean isgold = (obj->oclass == COIN_CLASS);
|
||||
boolean only_partially_your_contents = FALSE;
|
||||
|
||||
if (!*u.ushops) /* do cheapest exclusion test first */
|
||||
return;
|
||||
if (!(shkp = shop_keeper(*in_rooms(x, y, SHOPBASE))) || !inhishop(shkp))
|
||||
return;
|
||||
if (!costly_spot(x, y))
|
||||
return;
|
||||
if (!*u.ushops)
|
||||
return;
|
||||
|
||||
if (obj->unpaid && !container && !isgold) {
|
||||
sub_one_frombill(obj, shkp);
|
||||
|
||||
+7
-5
@@ -43,7 +43,7 @@ STATIC_DCL int NDECL(throwspell);
|
||||
STATIC_DCL void NDECL(cast_protection);
|
||||
STATIC_DCL void FDECL(spell_backfire, (int));
|
||||
STATIC_DCL const char *FDECL(spelltypemnemonic, (int));
|
||||
STATIC_DCL boolean FDECL(spell_hurtle_step, (genericptr_t, int, int));
|
||||
STATIC_DCL boolean FDECL(spell_aim_step, (genericptr_t, int, int));
|
||||
|
||||
/* The roles[] table lists the role-specific values for tuning
|
||||
* percent_success().
|
||||
@@ -1181,12 +1181,14 @@ boolean atme;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
STATIC_OVL boolean
|
||||
spell_hurtle_step(arg, x, y)
|
||||
genericptr_t arg;
|
||||
spell_aim_step(arg, x, y)
|
||||
genericptr_t arg UNUSED;
|
||||
int x, y;
|
||||
{
|
||||
if (!isok(x,y)) return FALSE;
|
||||
if (!isok(x,y))
|
||||
return FALSE;
|
||||
if (!ZAP_POS(levl[x][y].typ)
|
||||
&& !(IS_DOOR(levl[x][y].typ) && (levl[x][y].doormask & D_ISOPEN)))
|
||||
return FALSE;
|
||||
@@ -1233,7 +1235,7 @@ throwspell()
|
||||
uc.x = u.ux;
|
||||
uc.y = u.uy;
|
||||
|
||||
walk_path(&uc, &cc, spell_hurtle_step, NULL);
|
||||
walk_path(&uc, &cc, spell_aim_step, (genericptr_t) 0);
|
||||
|
||||
u.dx = cc.x;
|
||||
u.dy = cc.y;
|
||||
|
||||
Reference in New Issue
Block a user