STATIC_DCL void FDECL(mkcavearea, (BOOLEAN_P));
STATIC_DCL int FDECL(dig_typ, (struct obj *,XCHAR_P,XCHAR_P));
STATIC_DCL int NDECL(dig);
-STATIC_DCL void NDECL(dig_up_grave);
+STATIC_DCL void FDECL(dig_up_grave, (coord *));
+STATIC_DCL int FDECL(adj_pit_checks, (coord *,char *));
+STATIC_DCL void FDECL(pit_flow, (struct trap *,SCHAR_P));
/* Indices returned by dig_typ() */
#define DIGTYP_UNDIGGABLE 0
if (context.digging.effort > 250 ||
(ttmp && ttmp->ttyp == HOLE)) {
- (void) dighole(FALSE);
+ (void) dighole(FALSE, (coord *)0);
(void) memset((genericptr_t)&context.digging, 0,
sizeof (struct dig_info));
return(0); /* done with digging */
angry_priest();
}
- if (dighole(TRUE)) { /* make pit at <u.ux,u.uy> */
+ if (dighole(TRUE, (coord *)0)) { /* make pit at <u.ux,u.uy> */
context.digging.level.dnum = 0;
context.digging.level.dlevel = -1;
}
/* Return typ of liquid to fill a hole with, or ROOM, if no liquid nearby */
schar
-fillholetyp(x,y)
+fillholetyp(x,y,fill_if_any)
int x, y;
+boolean fill_if_any; /* force filling if it exists at all */
{
register int x1, y1;
int lo_x = max(1,x-1), hi_x = min(x+1,COLNO-1),
(levl[x1][y1].typ == DRAWBRIDGE_UP &&
(levl[x1][y1].drawbridgemask & DB_UNDER) == DB_LAVA))
lava_cnt++;
- pool_cnt /= 3; /* not as much liquid as the others */
+ if (!fill_if_any) pool_cnt /= 3; /* not as much liquid as the others */
- if (lava_cnt > moat_cnt + pool_cnt && rn2(lava_cnt + 1))
+ if ((lava_cnt > moat_cnt + pool_cnt && rn2(lava_cnt + 1)) ||
+ (lava_cnt && fill_if_any))
return LAVAPOOL;
- else if (moat_cnt > 0 && rn2(moat_cnt + 1))
+ else if ((moat_cnt > 0 && rn2(moat_cnt + 1)) ||
+ (moat_cnt && fill_if_any))
return MOAT;
- else if (pool_cnt > 0 && rn2(pool_cnt + 1))
+ else if ((pool_cnt > 0 && rn2(pool_cnt + 1)) ||
+ (pool_cnt && fill_if_any))
return POOL;
else
return ROOM;
if (ttyp == PIT) {
if(madeby_u) {
- You("dig a pit in the %s.", surface_type);
+ if (x != u.ux || y != u.uy)
+ You("dig an adjacent pit.");
+ else
+ You("dig a pit in the %s.", surface_type);
if (shopdoor) pay_for_damage("ruin", FALSE);
} else if (!madeby_obj && canseemon(madeby))
pline("%s digs a pit in the %s.", Monnam(madeby), surface_type);
/* return TRUE if digging succeeded, FALSE otherwise */
boolean
-dighole(pit_only)
+dighole(pit_only, cc)
boolean pit_only;
+coord *cc;
{
- register struct trap *ttmp = t_at(u.ux, u.uy);
- struct rm *lev = &levl[u.ux][u.uy];
+ register struct trap *ttmp;
+ struct rm *lev;
struct obj *boulder_here;
schar typ;
- boolean nohole = (!Can_dig_down(&u.uz) && !lev->candig);
+ xchar dig_x,dig_y;
+ boolean nohole;
+
+ if (!cc) {
+ dig_x = u.ux;
+ dig_y = u.uy;
+ } else {
+ dig_x = cc->x;
+ dig_y = cc->y;
+ if (!isok(dig_x,dig_y)) return FALSE;
+ }
+
+ ttmp = t_at(dig_x, dig_y);
+ lev = &levl[dig_x][dig_y];
+ nohole = (!Can_dig_down(&u.uz) && !lev->candig);
if ((ttmp && (ttmp->ttyp == MAGIC_PORTAL || nohole)) ||
(IS_ROCK(lev->typ) && lev->typ != SDOOR &&
(lev->wall_info & W_NONDIGGABLE) != 0)) {
- pline_The("%s here is too hard to dig in.", surface(u.ux,u.uy));
+ pline_The("%s %shere is too hard to dig in.",
+ surface(dig_x,dig_y),
+ (dig_x != u.ux || dig_y != u.uy) ? "t" : "");
- } else if (is_pool(u.ux, u.uy) || is_lava(u.ux, u.uy)) {
+ } else if (is_pool(dig_x, dig_y) || is_lava(dig_x, dig_y)) {
pline_The("%s sloshes furiously for a moment, then subsides.",
- is_lava(u.ux, u.uy) ? "lava" : "water");
+ is_lava(dig_x, dig_y) ? "lava" : "water");
wake_nearby(); /* splashing */
} else if (lev->typ == DRAWBRIDGE_DOWN ||
- (is_drawbridge_wall(u.ux, u.uy) >= 0)) {
+ (is_drawbridge_wall(dig_x, dig_y) >= 0)) {
/* drawbridge_down is the platform crossing the moat when the
bridge is extended; drawbridge_wall is the open "doorway" or
closed "door" where the portcullis/mechanism is located */
pline_The("drawbridge seems too hard to dig through.");
return FALSE;
} else {
- int x = u.ux, y = u.uy;
+ int x = dig_x, y = dig_y;
/* if under the portcullis, the bridge is adjacent */
(void) find_drawbridge(&x, &y);
destroy_drawbridge(x, y);
return TRUE;
}
- } else if ((boulder_here = sobj_at(BOULDER, u.ux, u.uy)) != 0) {
+ } else if ((boulder_here = sobj_at(BOULDER, dig_x, dig_y)) != 0) {
if (ttmp && (ttmp->ttyp == PIT || ttmp->ttyp == SPIKED_PIT) &&
rn2(2)) {
- pline_The("boulder settles into the pit.");
+ pline_The("boulder settles into the %spit.",
+ (dig_x != u.ux || dig_y != u.uy) ?
+ "adjacent " : "");
ttmp->ttyp = PIT; /* crush spikes */
} else {
/*
return TRUE;
} else if (IS_GRAVE(lev->typ)) {
- digactualhole(u.ux, u.uy, BY_YOU, PIT);
- dig_up_grave();
+ digactualhole(dig_x, dig_y, BY_YOU, PIT);
+ dig_up_grave(cc);
return TRUE;
} else if (lev->typ == DRAWBRIDGE_UP) {
/* must be floor or ice, other cases handled above */
/* dig "pit" and let fluid flow in (if possible) */
- typ = fillholetyp(u.ux,u.uy);
+ typ = fillholetyp(dig_x,dig_y,FALSE);
if (typ == ROOM) {
/*
* We can't dig a hole here since that will destroy
* the drawbridge. The following is a cop-out. --dlc
*/
- pline_The("%s here is too hard to dig in.",
- surface(u.ux, u.uy));
+ pline_The("%s %shere is too hard to dig in.",
+ surface(dig_x, dig_y),
+ (dig_x != u.ux || dig_y != u.uy) ? "t" : "");
return FALSE;
}
lev->drawbridgemask &= ~DB_UNDER;
lev->drawbridgemask |= (typ == LAVAPOOL) ? DB_LAVA : DB_MOAT;
- liquid_flow(u.ux, u.uy, typ, ttmp,
+ liquid_flow(dig_x, dig_y, typ, ttmp,
"As you dig, the hole fills with %s!");
return TRUE;
pline_The("altar is too hard to break apart.");
} else {
- typ = fillholetyp(u.ux,u.uy);
+ typ = fillholetyp(dig_x,dig_y,FALSE);
if (typ != ROOM) {
lev->typ = typ;
- liquid_flow(u.ux, u.uy, typ, ttmp,
+ liquid_flow(dig_x, dig_y, typ, ttmp,
"As you dig, the hole fills with %s!");
return TRUE;
}
/* finally we get to make a hole */
if (nohole || pit_only)
- digactualhole(u.ux, u.uy, BY_YOU, PIT);
+ digactualhole(dig_x, dig_y, BY_YOU, PIT);
else
- digactualhole(u.ux, u.uy, BY_YOU, HOLE);
+ digactualhole(dig_x, dig_y, BY_YOU, HOLE);
return TRUE;
}
}
STATIC_OVL void
-dig_up_grave()
+dig_up_grave(cc)
+coord *cc;
{
struct obj *otmp;
+ xchar dig_x, dig_y;
+
+ if (!cc) {
+ dig_x = u.ux;
+ dig_y = u.uy;
+ } else {
+ dig_x = cc->x;
+ dig_y = cc->y;
+ if (!isok(dig_x,dig_y)) return ;
+ }
+
/* Grave-robbing is frowned upon... */
exercise(A_WIS, FALSE);
case 0:
case 1:
You("unearth a corpse.");
- if (!!(otmp = mk_tt_object(CORPSE, u.ux, u.uy)))
+ if (!!(otmp = mk_tt_object(CORPSE, dig_x, dig_y)))
otmp->age -= 100; /* this is an *OLD* corpse */;
break;
case 2:
if (!Blind) pline(Hallucination ? "Dude! The living dead!" :
"The grave's owner is very upset!");
- (void) makemon(mkclass(S_ZOMBIE,0), u.ux, u.uy, NO_MM_FLAGS);
+ (void) makemon(mkclass(S_ZOMBIE,0), dig_x, dig_y, NO_MM_FLAGS);
break;
case 3:
if (!Blind) pline(Hallucination ? "I want my mummy!" :
"You've disturbed a tomb!");
- (void) makemon(mkclass(S_MUMMY,0), u.ux, u.uy, NO_MM_FLAGS);
+ (void) makemon(mkclass(S_MUMMY,0), dig_x, dig_y, NO_MM_FLAGS);
break;
default:
/* No corpse */
pline_The("grave seems unused. Strange....");
break;
}
- levl[u.ux][u.uy].typ = ROOM;
- del_engr_at(u.ux, u.uy);
- newsym(u.ux,u.uy);
+ levl[dig_x][dig_y].typ = ROOM;
+ del_engr_at(dig_x, dig_y);
+ newsym(dig_x,dig_y);
return;
}
{
register int rx, ry;
register struct rm *lev;
- struct trap *trap;
+ struct trap *trap, *trap_with_u;
int dig_target;
boolean ispick = is_pick(obj);
const char *verbing = ispick ? "digging" : "chopping";
if (vibrate) losehp(Maybe_Half_Phys(2),
"axing a hard object", KILLED_BY);
}
+ else if (u.utrap && u.utraptype == TT_PIT && trap &&
+ (trap_with_u = t_at(u.ux, u.uy)) &&
+ (trap->ttyp == PIT || trap->ttyp == SPIKED_PIT) &&
+ !conjoined_pits(trap, trap_with_u, FALSE)) {
+ int idx;
+ for (idx = 0; idx < 8; idx++) {
+ if (xdir[idx] == u.dx && ydir[idx] == u.dy)
+ break;
+ }
+ /* idx is valid if < 8 */
+ if (idx < 8) {
+ int adjidx = (idx + 4) % 8;
+ trap_with_u->conjoined[idx] = TRUE;
+ trap->conjoined[adjidx] = TRUE;
+ pline(
+ "You clear some debris from between the pits.");
+ }
+ }
+ else if (u.utrap && u.utraptype == TT_PIT &&
+ (trap_with_u = t_at(u.ux, u.uy))) {
+ You("swing %s, but the rubble has no place to go.",
+ yobjnam(obj, (char *)0));
+ }
else
You("swing %s through thin air.",
yobjnam(obj, (char *)0));
struct rm *room;
struct monst *mtmp;
struct obj *otmp;
- int zx, zy, digdepth;
- boolean shopdoor, shopwall, maze_dig;
+ struct trap *trap_with_u = (struct trap *)0;
+ int zx, zy, diridx, digdepth, flow_x, flow_y;
+ boolean shopdoor, shopwall, maze_dig, pitdig = FALSE, pitflow = FALSE;
+
/*
* Original effect (approximately):
* from CORR: dig until we pierce a wall
* an ACCESSIBLE place.
* Currently: dig for digdepth positions;
* also down on request of Lennart Augustsson.
+ * 3.5.0: from a PIT: dig one adjacent pit.
*/
if (u.uswallow) {
newsym(u.ux, u.uy);
} else {
watch_dig((struct monst *)0, u.ux, u.uy, TRUE);
- (void) dighole(FALSE);
+ (void) dighole(FALSE, (coord *)0);
}
}
return;
maze_dig = level.flags.is_maze_lev && !Is_earthlevel(&u.uz);
zx = u.ux + u.dx;
zy = u.uy + u.dy;
+ if(u.utrap && u.utraptype == TT_PIT && (trap_with_u = t_at(u.ux, u.uy))) {
+ pitdig = TRUE;
+ for (diridx = 0; diridx < 8; diridx++) {
+ if (xdir[diridx] == u.dx && ydir[diridx] == u.dy)
+ break;
+ /* diridx is valid if < 8 */
+ }
+ }
digdepth = rn1(18, 8);
tmp_at(DISP_BEAM, cmap_to_glyph(S_digbeam));
while (--digdepth >= 0) {
room = &levl[zx][zy];
tmp_at(zx,zy);
delay_output(); /* wait a little bit */
- if (closed_door(zx, zy) || room->typ == SDOOR) {
+
+ if (pitdig) { /* we are already in a pit if this is true */
+ coord cc;
+ struct trap *adjpit = t_at(zx,zy);
+ if ((diridx < 8) &&
+ !conjoined_pits(adjpit, trap_with_u, FALSE)) {
+ digdepth = 0; /* limited to the adjacent location only */
+ if (!(adjpit && (adjpit->ttyp == PIT ||
+ adjpit->ttyp == SPIKED_PIT))) {
+ char buf[BUFSZ];
+ cc.x = zx; cc.y = zy;
+ if (!adj_pit_checks(&cc, buf)) {
+ if (buf[0]) pline("%s", buf);
+ } else {
+ /* this can also result in a pool at zx,zy */
+ dighole(TRUE, &cc);
+ adjpit = t_at(zx,zy);
+ }
+ }
+ if (adjpit && (adjpit->ttyp == PIT ||
+ adjpit->ttyp == SPIKED_PIT)) {
+ int adjidx = (diridx + 4) % 8;
+ trap_with_u->conjoined[diridx] = TRUE;
+ adjpit->conjoined[adjidx] = TRUE;
+ flow_x = zx;
+ flow_y = zy;
+ pitflow = TRUE;
+ }
+ if (is_pool(zx,zy) || is_lava(zx,zy)) {
+ flow_x = zx - u.dx;
+ flow_y = zy - u.dy;
+ pitflow = TRUE;
+ }
+ break;
+ }
+ } else if (closed_door(zx, zy) || room->typ == SDOOR) {
if (*in_rooms(zx,zy,SHOPBASE)) {
add_damage(zx, zy, 400L);
shopdoor = TRUE;
zy += u.dy;
} /* while */
tmp_at(DISP_END,0); /* closing call */
+
+ if (pitflow) {
+ struct trap *ttmp = t_at(flow_x, flow_y);
+ if (ttmp && (ttmp->ttyp == PIT || ttmp->ttyp == SPIKED_PIT)) {
+ schar filltyp = fillholetyp(ttmp->tx, ttmp->ty, TRUE);
+ if (filltyp != ROOM)
+ pit_flow(ttmp, filltyp);
+ }
+ }
+
if (shopdoor || shopwall)
pay_for_damage(shopdoor ? "destroy" : "dig into", FALSE);
return;
}
+/*
+ * This checks what is on the surface above the
+ * location where an adjacent pit might be created if
+ * you're zapping a wand of digging laterally while
+ * down in the pit.
+ */
+STATIC_OVL int
+adj_pit_checks(cc, msg)
+coord *cc;
+char *msg;
+{
+ int ltyp;
+ struct rm *room;
+ const char *foundation_msg =
+ "The foundation is too hard to dig through from this angle.";
+
+ if (!cc) return FALSE;
+ if (!isok(cc->x,cc->y)) return FALSE;
+ if (msg) *msg = '\0';
+ room = &levl[cc->x][cc->y];
+ ltyp = room->typ;
+
+
+ if (is_pool(cc->x, cc->y) || is_lava(cc->x, cc->y)) {
+ /* this is handled by the caller after we return FALSE */
+ return FALSE;
+ } else if (closed_door(cc->x, cc->y) || room->typ == SDOOR) {
+ /* We reject this here because dighole() isn't
+ prepared to deal with this case */
+ Strcpy(msg, foundation_msg);
+ return FALSE;
+ } else if (IS_WALL(ltyp)) {
+ /* if (room->wall_info & W_NONDIGGABLE) */
+ Strcpy(msg, foundation_msg);
+ return FALSE;
+ } else if (IS_TREE(ltyp)) { /* check trees before stone */
+ /* if (room->wall_info & W_NONDIGGABLE) */
+ Strcpy(msg, "The tree's roots glow then fade.");
+ return FALSE;
+ } else if (ltyp == STONE || ltyp == SCORR) {
+ if (room->wall_info & W_NONDIGGABLE) {
+ Strcpy(msg, "The rock glows then fades.");
+ return FALSE;
+ }
+ } else if (ltyp == IRONBARS) {
+ /* "set of iron bars" */
+ Strcpy(msg, "The bars go much deeper than your pit.");
+#if 0
+ } else if (is_lava(cc->x,cc->y)) {
+ } else if (is_ice(cc->x,cc->y)) {
+ } else if (is_pool(cc->x,cc->y)) {
+ } else if (IS_GRAVE(ltyp)) {
+#endif
+#ifdef SINKS
+ } else if (IS_SINK(ltyp)) {
+ Strcpy(msg, "A tangled mass of plumbing remains below the sink.");
+ return FALSE;
+#endif
+ } else if ((cc->x == xupladder && cc->y == yupladder) || /* "ladder up" */
+ (cc->x == xdnladder && cc->y == ydnladder)) { /* "ladder down" */
+ Strcpy(msg, "The ladder is unaffected.");
+ return FALSE;
+ } else {
+ const char *supporting = (const char *)0;
+ if (IS_FOUNTAIN(ltyp)) supporting = "fountain";
+ else if (IS_THRONE(ltyp)) supporting = "throne";
+ else if (IS_ALTAR(ltyp)) supporting = "altar";
+ else if ((cc->x == xupstair && cc->y == yupstair) ||
+ (cc->x == sstairs.sx && cc->y == sstairs.sy && sstairs.up))
+ /* "staircase up" */
+ supporting = "stairs";
+ else if ((cc->x == xdnstair && cc->y == ydnstair) ||
+ (cc->x == sstairs.sx && cc->y == sstairs.sy && !sstairs.up))
+ /* "staircase down" */
+ supporting = "stairs";
+ else if ((ltyp == DRAWBRIDGE_DOWN) || /* "lowered drawbridge" */
+ (ltyp == DBWALL)) /* "raised drawbridge" */
+ supporting = "drawbridge";
+ if (supporting) {
+ Sprintf(msg,
+ "The %s%ssupporting structures remain intact.",
+ supporting ? s_suffix(supporting) : "",
+ supporting ? " " : "");
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+/*
+ * Ensure that all conjoined pits fill up.
+ */
+STATIC_OVL void
+pit_flow(trap, filltyp)
+struct trap *trap;
+schar filltyp;
+{
+ int idx;
+ if (trap && (filltyp != ROOM) &&
+ (trap->ttyp == PIT || trap->ttyp == SPIKED_PIT)) {
+ struct trap t;
+ t = *trap;
+ levl[trap->tx][trap->ty].typ = filltyp;
+ liquid_flow(trap->tx, trap->ty, filltyp, trap,
+ (trap->tx == u.ux && trap->ty == u.uy) ?
+ "Suddenly %s flows in from the adjacent pit!":
+ (char *)0);
+ for(idx = 0; idx < 8; ++idx) {
+ if (t.conjoined[idx]) {
+ int x, y;
+ struct trap *t2;
+ x = t.tx + xdir[idx];
+ y = t.ty + ydir[idx];
+ t2 = t_at(x,y);
+#if 0
+ /* cannot do this back-check; liquid_flow()
+ * called deltrap() which cleaned up the
+ * conjoined fields on both pits.
+ */
+ if (t2 && t2->conjoined[(idx + 4) % 8])
+#endif
+ /* recursion */
+ pit_flow(t2, filltyp);
+ }
+ }
+ }
+}
+
struct obj *
buried_ball(cc)
coord *cc;
"ooze" : "phase", surface(u.ux, u.uy));
if(tunnels(youmonst.data) && !needspick(youmonst.data))
- good = dighole(TRUE);
+ good = dighole(TRUE, (coord *)0);
else good = TRUE;
if(good) unearth_you();
}
STATIC_DCL int FDECL(mkroll_launch,
(struct trap *,XCHAR_P,XCHAR_P,SHORT_P,long));
STATIC_DCL boolean FDECL(isclearpath,(coord *, int, SCHAR_P, SCHAR_P));
+#if 0
+STATIC_DCL void FDECL(join_adjacent_pits, (struct trap *));
+#endif
+STATIC_DCL void FDECL(clear_conjoined_pits, (struct trap *));
#ifdef STEED
STATIC_OVL int FDECL(steedintrap, (struct trap *, struct obj *));
STATIC_OVL boolean FDECL(keep_saddle_with_steedcorpse,
register struct trap *ttmp;
register struct rm *lev;
register boolean oldplace;
+ int idx;
if ((ttmp = t_at(x,y)) != 0) {
if (ttmp->ttyp == MAGIC_PORTAL) return (struct trap *)0;
case PIT:
case SPIKED_PIT:
case TRAPDOOR:
+ for (idx = 0; idx < 8; ++idx)
+ ttmp->conjoined[idx] = FALSE;
lev = &levl[x][y];
if (*in_rooms(x, y, SHOPBASE) &&
((typ == HOLE || typ == TRAPDOOR) ||
boolean webmsgok = (!(trflags & NOWEBMSG));
boolean forcebungle = (trflags & FORCEBUNGLE);
boolean plunged = (trflags & TOOKPLUNGE);
+ boolean adj_pit = conjoined_pits(trap, t_at(u.ux0,u.uy0), TRUE);
#ifdef STEED
int steed_article = ARTICLE_THE;
#endif
return;
}
if(!Fumbling && ttype != MAGIC_PORTAL &&
- ttype != ANTI_MAGIC && !forcebungle && !plunged &&
+ ttype != ANTI_MAGIC && !forcebungle && !plunged && !adj_pit &&
(!rn2(5) ||
- ((ttype == PIT || ttype == SPIKED_PIT) && is_clinger(youmonst.data)))) {
+ ((ttype == PIT || ttype == SPIKED_PIT) && is_clinger(youmonst.data)))) {
You("escape %s %s.",
(ttype == ARROW_TRAP && !trap->madeby_u) ? "an" :
a_your[trap->madeby_u],
"poor", SUPPRESS_SADDLE, FALSE));
} else
#endif
- Strcpy(verbbuf, plunged ? "plunge" : "fall");
- You("%s into %s pit!", verbbuf, a_your[trap->madeby_u]);
+ if (adj_pit) {
+ You("move into an adjacent pit.");
+ } else {
+ Strcpy(verbbuf, plunged ? "plunge" : "fall");
+ You("%s into %s pit!", verbbuf, a_your[trap->madeby_u]);
+ }
}
/* wumpus reference */
if (Role_if(PM_RANGER) && !trap->madeby_u && !trap->once &&
const char *predicament = "on a set of sharp iron spikes";
#ifdef STEED
if (u.usteed) {
- pline("%s lands %s!",
+ pline("%s %s %s!",
upstart(x_monnam(u.usteed, steed_article,
"poor", SUPPRESS_SADDLE, FALSE)),
+ adj_pit ? "steps" : "lands",
predicament);
} else
#endif
- You("land %s!", predicament);
+ You("%s %s!", adj_pit ? "step" : "land", predicament);
}
u.utrap = rn1(6,2);
u.utraptype = TT_PIT;
if (!steedintrap(trap, (struct obj *)0)) {
#endif
if (ttype == SPIKED_PIT) {
- losehp(Maybe_Half_Phys(rnd(10)),
+ losehp(Maybe_Half_Phys(rnd(adj_pit ? 6 : 10)),
plunged ? "deliberately plunged into a pit of iron spikes" :
+ adj_pit ? "stepped into a pit of iron spikes" :
"fell into a pit of iron spikes",
NO_KILLER_PREFIX);
if (!rn2(6))
- poisoned("spikes", A_STR, "fall onto poison spikes",
+ poisoned("spikes", A_STR,
+ adj_pit ? "stepping on poison spikes" :
+ "fall onto poison spikes",
8, FALSE);
- } else
- losehp(Maybe_Half_Phys(rnd(6)),
- plunged ? "deliberately plunged into a pit" :
- "fell into a pit",
- NO_KILLER_PREFIX);
+ } else {
+ if (!adj_pit)
+ losehp(Maybe_Half_Phys(rnd(6)),
+ plunged ? "deliberately plunged into a pit" :
+ "fell into a pit",
+ NO_KILLER_PREFIX);
+ }
if (Punished && !carried(uball)) {
unplacebc();
ballfall();
placebc();
}
- selftouch("Falling, you");
+ if (!adj_pit) selftouch("Falling, you");
vision_full_recalc = 1; /* vision limits change */
exercise(A_STR, FALSE);
exercise(A_DEX, FALSE);
{
register struct trap *ttmp;
+ clear_conjoined_pits(trap);
if(trap == ftrap)
ftrap = ftrap->ntrap;
else {
dealloc_trap(trap);
}
+boolean
+conjoined_pits(trap2, trap1, u_entering_trap2)
+struct trap *trap2, *trap1;
+boolean u_entering_trap2;
+{
+ int dx, dy, diridx, adjidx;
+ if (!trap1 || !trap2) return FALSE;
+ if (!isok(trap2->tx,trap2->ty) || !isok(trap1->tx,trap1->ty) ||
+ !(trap2->ttyp == PIT || trap2->ttyp == SPIKED_PIT) ||
+ !(trap1->ttyp == PIT || trap1->ttyp == SPIKED_PIT) ||
+ (u_entering_trap2 && !(u.utrap && u.utraptype == TT_PIT)))
+ return FALSE;
+ dx = sgn(trap2->tx - trap1->tx);
+ dy = sgn(trap2->ty - trap1->ty);
+ for (diridx = 0; diridx < 8; diridx++)
+ if (xdir[diridx] == dx && ydir[diridx] == dy)
+ break;
+ /* diridx is valid if < 8 */
+ if (diridx < 8) {
+ adjidx = (diridx + 4) % 8;
+ if (trap1->conjoined[diridx] && trap2->conjoined[adjidx])
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void
+clear_conjoined_pits(trap)
+struct trap *trap;
+{
+ int tmp, adj, x, y;
+ struct trap *t;
+ if (trap && (trap->ttyp == PIT || trap->ttyp == SPIKED_PIT)) {
+ for(tmp = 0; tmp < 8; ++tmp) {
+ if (trap->conjoined[tmp]) {
+ x = trap->tx + xdir[tmp];
+ y = trap->ty + ydir[tmp];
+ t = t_at(x,y);
+ if (isok(x,y) && t &&
+ (t->ttyp == PIT || t->ttyp == SPIKED_PIT)) {
+ adj = (tmp + 4) % 8;
+ t->conjoined[adj] = FALSE;
+ }
+ trap->conjoined[tmp] = FALSE;
+ }
+ }
+ }
+}
+
+#if 0
+/*
+ * Mark all neighboring pits as conjoined pits.
+ * (currently not called from anywhere)
+ */
+STATIC_OVL void
+join_adjacent_pits(trap)
+struct trap *trap;
+{
+ struct trap *t;
+ int tmp, x, y;
+ if (!trap) return;
+ for(tmp = 0; tmp < 8; ++tmp) {
+ x = trap->tx + xdir[tmp];
+ y = trap->ty + ydir[tmp];
+ if (isok(x,y)) {
+ if (((t = t_at(x,y)) != 0) &&
+ (t->ttyp == PIT || t->ttyp == SPIKED_PIT)) {
+ trap->conjoined[tmp] = TRUE;
+ join_adjacent_pits(t);
+ } else trap->conjoined[tmp] = FALSE;
+ }
+ }
+}
+#endif
+
/*
* Returns TRUE if you escaped a pit and are standing on the precipice.
*/