-NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.332 $ $NHDT-Date: 1602958104 2020/10/17 18:08:24 $
+NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.337 $ $NHDT-Date: 1603507384 2020/10/24 02:43:04 $
General Fixes and Modified Features
-----------------------------------
pre-populate teleport destination prompt with travel destination
ghosts cannot be renamed
tossed upwards objects got two times half physical damage reduction
+monster xorns could pass through iron bars but not eat them; monster rock
+ moles could no neither; now they can eat bars when adjacent and will
+ do so if the bars are blocking their path
+hero poly'd into rust monster could implicitly eat bars when adjacent by
+ trying to move there, now when in rock mole form too; in xorn form
+ can explicitly eat them via 'e' after moving onto their spot
Fixes to 3.7.0-x Problems that Were Exposed Via git Repository
-/* NetHack 3.7 extern.h $NHDT-Date: 1602270114 2020/10/09 19:01:54 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.867 $ */
+/* NetHack 3.7 extern.h $NHDT-Date: 1603507384 2020/10/24 02:43:04 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.873 $ */
/* Copyright (c) Steve Creps, 1988. */
/* NetHack may be freely redistributed. See license for details. */
E anything *FDECL(monst_to_any, (struct monst *));
E anything *FDECL(obj_to_any, (struct obj *));
E boolean FDECL(revive_nasty, (int, int, const char *));
+E int FDECL(still_chewing, (XCHAR_P, XCHAR_P));
E void FDECL(movobj, (struct obj *, XCHAR_P, XCHAR_P));
E boolean FDECL(may_dig, (XCHAR_P, XCHAR_P));
E boolean FDECL(may_passwall, (XCHAR_P, XCHAR_P));
-/* NetHack 3.7 eat.c $NHDT-Date: 1599258557 2020/09/04 22:29:17 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.233 $ */
+/* NetHack 3.7 eat.c $NHDT-Date: 1603507384 2020/10/24 02:43:04 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.235 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2012. */
/* NetHack may be freely redistributed. See license for details. */
{
/* perhaps it was stolen (although that should cause interruption) */
if (!carried(g.context.tin.tin)
- && (!obj_here(g.context.tin.tin, u.ux, u.uy) || !can_reach_floor(TRUE)))
+ && (!obj_here(g.context.tin.tin, u.ux, u.uy)
+ || !can_reach_floor(TRUE)))
return 0; /* %% probably we should use tinoid */
if (g.context.tin.usedtime++ >= 50) {
You("give up your attempt to open the tin.");
}
}
+ /* from floorfood(), &zeroobj means iron bars at current spot */
+ if (otmp == &cg.zeroobj) {
+ /* hero in metallivore form is eating [diggable] iron bars
+ at current location so skip the other assorted checks;
+ operates as if digging rather than via the eat occupation */
+ if (still_chewing(u.ux, u.uy) && levl[u.ux][u.uy].typ == IRONBARS) {
+ /* this is verbose, but player will see the hero rather than the
+ bars so wouldn't know that more turns of eating are required */
+ You("pause to swallow.");
+ }
+ return 1;
+ }
/* We have to make non-foods take 1 move to eat, unless we want to
* do ridiculous amounts of coding to deal with partly eaten plate
* mails, players who polymorph back to human in the middle of their
register struct obj *otmp;
char qbuf[QBUFSZ];
char c;
- boolean feeding = !strcmp(verb, "eat"), /* corpsecheck==0 */
- offering = !strcmp(verb, "sacrifice"); /* corpsecheck==1 */
+ struct permonst *uptr = g.youmonst.data;
+ boolean feeding = !strcmp(verb, "eat"), /* corpsecheck==0 */
+ offering = !strcmp(verb, "sacrifice"); /* corpsecheck==1 */
/* if we can't touch floor objects then use invent food only */
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(g.youmonst.data)
- || (Flying && !Breathless))))
+ && (Wwalking || is_clinger(uptr) || (Flying && !Breathless))))
goto skipfloor;
- if (feeding && metallivorous(g.youmonst.data)) {
+ if (feeding && metallivorous(uptr)) {
struct obj *gold;
struct trap *ttmp = t_at(u.ux, u.uy);
return (struct obj *) 0;
}
}
+ if (levl[u.ux][u.uy].typ == IRONBARS) {
+ /* already verified that hero is metallivorous above */
+ boolean nodig = (levl[u.ux][u.uy].wall_info & W_NONDIGGABLE) != 0;
- if (g.youmonst.data != &mons[PM_RUST_MONSTER]
+ c = 'n';
+ Strcpy(qbuf, "There are iron bars here");
+ if (nodig || u.uhunger > 1500) {
+ pline("%s but you %s eat them.", qbuf,
+ nodig ? "cannot" : "are too full to");
+ } else {
+ Strcat(qbuf, ((!g.context.digging.chew
+ || g.context.digging.pos.x != u.ux
+ || g.context.digging.pos.y != u.uy
+ || !on_level(&g.context.digging.level, &u.uz))
+ ? "; eat them?"
+ : "; resume eating them?"));
+ c = yn_function(qbuf, ynqchars, 'n');
+ }
+ if (c == 'y')
+ return (struct obj *) &cg.zeroobj; /* csst away 'const' */
+ else if (c == 'q')
+ return (struct obj *) 0;
+ }
+ if (uptr != &mons[PM_RUST_MONSTER]
&& (gold = g_at(u.ux, u.uy)) != 0) {
if (gold->quan == 1L)
Sprintf(qbuf, "There is 1 gold piece here; eat it?");
-/* NetHack 3.7 hack.c $NHDT-Date: 1600469617 2020/09/18 22:53:37 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.268 $ */
+/* NetHack 3.7 hack.c $NHDT-Date: 1603507385 2020/10/24 02:43:05 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.269 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Derek S. Ray, 2015. */
/* NetHack may be freely redistributed. See license for details. */
static void NDECL(maybe_wail);
static int NDECL(moverock);
-static int FDECL(still_chewing, (XCHAR_P, XCHAR_P));
static void NDECL(dosinkfall);
static boolean FDECL(findtravelpath, (int));
static boolean FDECL(trapmove, (int, int, struct trap *));
* Chew on a wall, door, or boulder. [What about statues?]
* Returns TRUE if still eating, FALSE when done.
*/
-static int
+int
still_chewing(x, y)
xchar x, y;
{
: "hard stone");
nomul(0);
return 1;
- } else if (g.context.digging.pos.x != x || g.context.digging.pos.y != y
+ } else if (lev->typ == IRONBARS
+ && metallivorous(g.youmonst.data) && u.uhunger > 1500) {
+ /* finishing eating via 'morehungry()' doesn't handle choking */
+ You("are too full to eat the bars.");
+ nomul(0);
+ return 1;
+ } else if (!g.context.digging.chew
+ || g.context.digging.pos.x != x
+ || g.context.digging.pos.y != y
|| !on_level(&g.context.digging.level, &u.uz)) {
g.context.digging.down = FALSE;
g.context.digging.chew = TRUE;
digtxt = "chew through the tree.";
lev->typ = ROOM;
} else if (lev->typ == IRONBARS) {
- digtxt = "eat through the bars.";
+ if (metallivorous(g.youmonst.data)) { /* should always be True here */
+ /* arbitrary amount; unlike proper eating, nutrition is
+ bestowed in a lump sum at the end */
+ int nut = (int) objects[HEAVY_IRON_BALL].oc_weight;
+
+ /* lesshungry() requires that victual be set up, so skip it;
+ morehungry() of a negative amount will increase nutrition
+ without any possibility of choking to death on the meal;
+ updates hunger state and requests status update if changed */
+ morehungry(-nut);
+ }
+ digtxt = (x == u.ux && y == u.uy)
+ ? "devour the iron bars."
+ : "eat through the bars.";
dissolve_bars(x, y);
} else if (lev->typ == SDOOR) {
if (lev->doormask & D_TRAPPED) {
pline("There is an obstacle there.");
return FALSE;
} else if (tmpr->typ == IRONBARS) {
- if ((dmgtype(g.youmonst.data, AD_RUST)
- || dmgtype(g.youmonst.data, AD_CORR)) && mode == DO_MOVE
+ if (mode == DO_MOVE
+ && (dmgtype(g.youmonst.data, AD_RUST)
+ || dmgtype(g.youmonst.data, AD_CORR)
+ || metallivorous(g.youmonst.data))
&& still_chewing(x, y)) {
return FALSE;
}
-/* NetHack 3.7 mondata.c $NHDT-Date: 1596498186 2020/08/03 23:43:06 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.83 $ */
+/* NetHack 3.7 mondata.c $NHDT-Date: 1603507386 2020/10/24 02:43:06 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.86 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2011. */
/* NetHack may be freely redistributed. See license for details. */
{
return (boolean) (passes_walls(mptr) || amorphous(mptr) || unsolid(mptr)
|| is_whirly(mptr) || verysmall(mptr)
- || dmgtype(mptr, AD_CORR) || dmgtype(mptr, AD_RUST)
+ /* rust monsters and some puddings can destroy bars */
+ || dmgtype(mptr, AD_RUST) || dmgtype(mptr, AD_CORR)
+ /* rock moles can eat bars */
+ || metallivorous(mptr)
|| (slithy(mptr) && !bigmonst(mptr)));
}
-/* NetHack 3.7 monmove.c $NHDT-Date: 1600469618 2020/09/18 22:53:38 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.143 $ */
+/* NetHack 3.7 monmove.c $NHDT-Date: 1603507386 2020/10/24 02:43:06 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.146 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Michael Allison, 2006. */
/* NetHack may be freely redistributed. See license for details. */
add_damage(mtmp->mx, mtmp->my, 0L);
}
} else if (levl[mtmp->mx][mtmp->my].typ == IRONBARS) {
- /* 3.6.2: was using may_dig() but it doesn't handle bars */
+ /* 3.6.2: was using may_dig() but that doesn't handle bars;
+ AD_RUST catches rust monsters but metallivorous() is
+ needed for xorns and rock moles */
if (!(levl[mtmp->mx][mtmp->my].wall_info & W_NONDIGGABLE)
- && (dmgtype(ptr, AD_RUST) || dmgtype(ptr, AD_CORR))) {
+ && (dmgtype(ptr, AD_RUST) || dmgtype(ptr, AD_CORR)
+ || metallivorous(ptr))) {
if (canseemon(mtmp))
pline("%s eats through the iron bars.", Monnam(mtmp));
dissolve_bars(mtmp->mx, mtmp->my);
levl[x][y].typ = (Is_special(&u.uz) || *in_rooms(x, y, 0)) ? ROOM : CORR;
levl[x][y].flags = 0;
newsym(x, y);
+ if (x == u.ux && y == u.uy)
+ switch_terrain();
}
boolean