-/* NetHack 3.6 trap.c $NHDT-Date: 1524312044 2018/04/21 12:00:44 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.290 $ */
+/* NetHack 3.6 trap.c $NHDT-Date: 1545259936 2018/12/19 22:52:16 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.313 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2013. */
/* NetHack may be freely redistributed. See license for details. */
extern const char *const destroy_strings[][3]; /* from zap.c */
+STATIC_DCL boolean FDECL(keep_saddle_with_steedcorpse, (unsigned, struct obj *,
+ struct obj *));
+STATIC_DCL struct obj *FDECL(t_missile, (int, struct trap *));
+STATIC_DCL char *FDECL(trapnote, (struct trap *, BOOLEAN_P));
+STATIC_DCL int FDECL(steedintrap, (struct trap *, struct obj *));
+STATIC_DCL void FDECL(launch_drop_spot, (struct obj *, XCHAR_P, XCHAR_P));
+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));
STATIC_DCL void FDECL(dofiretrap, (struct obj *));
STATIC_DCL void NDECL(domagictrap);
STATIC_DCL boolean FDECL(emergency_disrobe, (boolean *));
STATIC_DCL int FDECL(disarm_landmine, (struct trap *));
STATIC_DCL int FDECL(disarm_squeaky_board, (struct trap *));
STATIC_DCL int FDECL(disarm_shooting_trap, (struct trap *, int));
+STATIC_DCL void FDECL(clear_conjoined_pits, (struct trap *));
+STATIC_DCL boolean FDECL(adj_nonconjoined_pit, (struct trap *));
STATIC_DCL int FDECL(try_lift, (struct monst *, struct trap *, int,
BOOLEAN_P));
STATIC_DCL int FDECL(help_monster_out, (struct monst *, struct trap *));
-STATIC_DCL boolean FDECL(thitm, (int, struct monst *, struct obj *, int,
- BOOLEAN_P));
-STATIC_DCL void FDECL(launch_drop_spot, (struct obj *, XCHAR_P, XCHAR_P));
-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));
-STATIC_DCL char *FDECL(trapnote, (struct trap *, BOOLEAN_P));
#if 0
STATIC_DCL void FDECL(join_adjacent_pits, (struct trap *));
#endif
-STATIC_DCL void FDECL(clear_conjoined_pits, (struct trap *));
-STATIC_DCL boolean FDECL(adj_nonconjoined_pit, (struct trap *));
-
-STATIC_DCL int FDECL(steedintrap, (struct trap *, struct obj *));
-STATIC_DCL boolean FDECL(keep_saddle_with_steedcorpse, (unsigned,
- struct obj *,
- struct obj *));
+STATIC_DCL boolean FDECL(thitm, (int, struct monst *, struct obj *, int,
+ BOOLEAN_P));
STATIC_DCL void NDECL(maybe_finish_sokoban);
/* mintrap() should take a flags argument, but for time being we use this */
if (u.utrap && x == u.ux && y == u.uy
&& ((u.utraptype == TT_BEARTRAP && typ != BEAR_TRAP)
|| (u.utraptype == TT_WEB && typ != WEB)
- || (u.utraptype == TT_PIT && typ != PIT
- && typ != SPIKED_PIT)))
+ || (u.utraptype == TT_PIT && !is_pit(typ))))
u.utrap = 0;
/* old <tx,ty> remain valid */
} else if (IS_FURNITURE(lev->typ)
case HOLE:
case TRAPDOOR:
if (*in_rooms(x, y, SHOPBASE)
- && (typ == HOLE || typ == TRAPDOOR
- || IS_DOOR(lev->typ) || IS_WALL(lev->typ)))
+ && (is_hole(typ) || IS_DOOR(lev->typ) || IS_WALL(lev->typ)))
add_damage(x, y, /* schedule repair */
((IS_DOOR(lev->typ) || IS_WALL(lev->typ))
&& !context.mon_moving)
if (use_saved_traits) {
/* restore a petrified monster */
cc.x = x, cc.y = y;
- mon = montraits(statue, &cc);
+ mon = montraits(statue, &cc, (cause == ANIMATE_SPELL));
if (mon && mon->mtame && !mon->isminion)
wary_dog(mon, TRUE);
} else {
if (has_oname(statue) && !unique_corpstat(mon->data))
mon = christen_monst(mon, ONAME(statue));
/* mimic statue becomes seen mimic; other hiders won't be hidden */
- if (mon->m_ap_type)
+ if (M_AP_TYPE(mon))
seemimic(mon);
else
mon->mundetected = FALSE;
{
boolean isyou = (mtmp == &youmonst);
struct permonst *mptr = mtmp->data;
+
if (amorphous(mptr) || is_whirly(mptr) || flaming(mptr)
|| unsolid(mptr) || mptr == &mons[PM_GELATINOUS_CUBE]) {
xchar x = trap->tx;
xchar y = trap->ty;
+
if (flaming(mptr) || acidic(mptr)) {
if (domsg) {
if (isyou)
return TRUE;
}
if (domsg) {
- if (isyou)
+ if (isyou) {
/*JP
You("flow through %s spider web.", a_your[trap->madeby_u]);
*/
You("%s\82\82à\82Ì\91\83\82ð\82·\82é\82è\82Æ\92Ê\82è\94²\82¯\82½\81D", web_you[trap->madeby_u]);
- else {
+ } else {
#if 0 /*JP*/
pline("%s flows through %s spider web.", Monnam(mtmp),
a_your[trap->madeby_u]);
return FALSE;
}
+/* make a single arrow/dart/rock for a trap to shoot or drop */
+STATIC_OVL struct obj *
+t_missile(otyp, trap)
+int otyp;
+struct trap *trap;
+{
+ struct obj *otmp = mksobj(otyp, TRUE, FALSE);
+
+ otmp->quan = 1L;
+ otmp->owt = weight(otmp);
+ otmp->opoisoned = 0;
+ otmp->ox = trap->tx, otmp->oy = trap->ty;
+ return otmp;
+}
+
+void
+set_utrap(tim, typ)
+unsigned tim, typ;
+{
+ u.utrap = tim;
+ /* FIXME:
+ * utraptype==0 is bear trap rather than 'none'; we probably ought
+ * to change that but can't do so until save file compatability is
+ * able to be broken.
+ */
+ u.utraptype = tim ? typ : 0;
+
+ float_vs_flight(); /* maybe block Lev and/or Fly */
+}
+
+void
+reset_utrap(msg)
+boolean msg;
+{
+ boolean was_Lev = (Levitation != 0), was_Fly = (Flying != 0);
+
+ set_utrap(0, 0);
+
+ if (msg) {
+ if (!was_Lev && Levitation)
+ float_up();
+ if (!was_Fly && Flying)
+ You("can fly.");
+ }
+}
+
void
dotrap(trap, trflags)
register struct trap *trap;
register int ttype = trap->ttyp;
struct obj *otmp;
boolean already_seen = trap->tseen,
- forcetrap = (trflags & FORCETRAP) != 0,
+ forcetrap = ((trflags & FORCETRAP) != 0
+ || (trflags & FAILEDUNTRAP) != 0),
webmsgok = (trflags & NOWEBMSG) == 0,
forcebungle = (trflags & FORCEBUNGLE) != 0,
plunged = (trflags & TOOKPLUNGE) != 0,
nomul(0);
/* KMH -- You can't escape the Sokoban level traps */
- if (Sokoban && (ttype == PIT || ttype == SPIKED_PIT
- || ttype == HOLE || ttype == TRAPDOOR)) {
+ if (Sokoban && (is_pit(ttype) || is_hole(ttype))) {
/* The "air currents" message is still appropriate -- even when
* the hero isn't flying or levitating -- because it conveys the
* reason why the player cannot escape the trap with a dexterity
/* then proceed to normal trap effect */
} else if (already_seen && !forcetrap) {
if ((Levitation || (Flying && !plunged))
- && (ttype == PIT || ttype == SPIKED_PIT || ttype == HOLE
- || ttype == BEAR_TRAP)) {
+ && (is_pit(ttype) || ttype == HOLE || ttype == BEAR_TRAP)) {
#if 0 /*JP*/
You("%s over %s %s.", Levitation ? "float" : "fly",
a_your[trap->madeby_u],
if (!Fumbling && ttype != MAGIC_PORTAL && ttype != VIBRATING_SQUARE
&& ttype != ANTI_MAGIC && !forcebungle && !plunged
&& !conj_pit && !adj_pit
- && (!rn2(5) || ((ttype == PIT || ttype == SPIKED_PIT)
+ && (!rn2(5) || (is_pit(ttype)
&& is_clinger(youmonst.data)))) {
#if 0 /*JP*/
You("escape %s %s.", (ttype == ARROW_TRAP && !trap->madeby_u)
pline("An arrow shoots out at you!");
*/
pline("\96î\82ª\94ò\82ñ\82Å\82«\82½\81I");
- otmp = mksobj(ARROW, TRUE, FALSE);
- otmp->quan = 1L;
- otmp->owt = weight(otmp);
- otmp->opoisoned = 0;
- if (u.usteed && !rn2(2) && steedintrap(trap, otmp)) { /* nothing */
- ;
-#if 0 /*JP*/
+ otmp = t_missile(ARROW, trap);
+ if (u.usteed && !rn2(2) && steedintrap(trap, otmp)) {
+ ; /* nothing */
+#if 0 /*JP:T*/
} else if (thitu(8, dmgval(otmp, &youmonst), &otmp, "arrow")) {
#else
} else if (thitu(8, dmgval(otmp, &youmonst), &otmp, "\96î")) {
pline("A little dart shoots out at you!");
*/
pline("\8f¬\82³\82È\93\8a\82°\96î\82ª\94ò\82ñ\82Å\82«\82½\81I");
- otmp = mksobj(DART, TRUE, FALSE);
- otmp->quan = 1L;
- otmp->owt = weight(otmp);
+ otmp = t_missile(DART, trap);
if (!rn2(6))
otmp->opoisoned = 1;
oldumort = u.umortality;
- if (u.usteed && !rn2(2) && steedintrap(trap, otmp)) { /* nothing */
- ;
+ if (u.usteed && !rn2(2) && steedintrap(trap, otmp)) {
+ ; /* nothing */
#if 0 /*JP*/
} else if (thitu(7, dmgval(otmp, &youmonst), &otmp, "little dart")) {
#else
trap->once = 1;
feeltrap(trap);
- otmp = mksobj_at(ROCK, u.ux, u.uy, TRUE, FALSE);
- otmp->quan = 1L;
- otmp->owt = weight(otmp);
+ otmp = t_missile(ROCK, trap);
+ place_object(otmp, u.ux, u.uy);
#if 0 /*JP*/
pline("A trap door in %s opens and %s falls on your %s!",
pline("\97\8e\82µ\94à\82ª%s\82É\8aJ\82«\81C%s\82ª\82 \82È\82½\82Ì%s\82É\97\8e\82¿\82Ä\82«\82½\81I",
ceiling(u.ux,u.uy), xname(otmp), body_part(HEAD));
#endif
-
if (uarmh) {
if (is_metallic(uarmh)) {
/*JP
pline("%s\82Å\82Í\96h\82°\82È\82¢\81D", xname(uarmh));
}
}
-
if (!Blind)
otmp->dknown = 1;
stackobj(otmp);
#endif
break;
}
- u.utrap = rn1(4, 4);
- u.utraptype = TT_BEARTRAP;
+ set_utrap((unsigned) rn1(4, 4), TT_BEARTRAP);
if (u.usteed) {
#if 0 /*JP*/
pline("%s bear trap closes on %s %s!", A_Your[trap->madeby_u],
mon_nam(u.usteed), mbodypart(u.usteed, FOOT));
#endif
if (thitm(0, u.usteed, (struct obj *) 0, dmg, FALSE))
- u.utrap = 0; /* steed died, hero not trapped */
+ reset_utrap(TRUE); /* steed died, hero not trapped */
} else {
#if 0 /*JP*/
pline("%s bear trap closes on your %s!", A_Your[trap->madeby_u],
if (!Sokoban) {
char verbbuf[BUFSZ];
+ *verbbuf = '\0';
if (u.usteed) {
if ((trflags & RECURSIVETRAP) != 0)
/*JP
Strcpy(verbbuf,
!plunged ? "\97\8e\82¿\82½" : (Flying ? "\94ò\82Ñ\8d\9e\82ñ\82¾" : "\93Ë\93ü\82µ\82½"));
#endif
+ }
+ if (*verbbuf)
/*JP
You("%s into %s pit!", verbbuf, a_your[trap->madeby_u]);
*/
You("%s\97\8e\82µ\8c\8a\82É%s!", set_you[trap->madeby_u], verbbuf);
- }
}
/* wumpus reference */
if (Role_if(PM_RANGER) && !trap->madeby_u && !trap->once
*/
You("%s%s\81I", predicament, conj_pit ? "\97\8e\82¿\82½" : "\8d~\82è\82½");
}
- u.utrap = rn1(6, 2);
- u.utraptype = TT_PIT;
+ /* FIXME:
+ * if hero gets killed here, setting u.utrap in advance will
+ * show "you were trapped in a pit" during disclosure's display
+ * of enlightenment, but hero is dying *before* becoming trapped.
+ */
+ set_utrap((unsigned) rn1(6, 2), TT_PIT);
if (!steedintrap(trap, (struct obj *) 0)) {
if (ttype == SPIKED_PIT) {
oldumort = u.umortality;
#if 0 /*JP:T*/
losehp(Maybe_Half_Phys(rnd(conj_pit ? 4 : adj_pit ? 6 : 10)),
+ /* note: these don't need locomotion() handling;
+ if fatal while poly'd and Unchanging, the
+ death reason will be overridden with
+ "killed while stuck in creature form" */
plunged
- ? "deliberately plunged into a pit of iron spikes"
- : conj_pit ? "stepped into a pit of iron spikes"
- : adj_pit ? "stumbled into a pit of iron spikes"
- : "fell into a pit of iron spikes",
+ ? "deliberately plunged into a pit of iron spikes"
+ : conj_pit
+ ? "stepped into a pit of iron spikes"
+ : adj_pit
+ ? "stumbled into a pit of iron spikes"
+ : "fell into a pit of iron spikes",
NO_KILLER_PREFIX);
#else
losehp(Maybe_Half_Phys(rnd(conj_pit ? 4 : adj_pit ? 6 : 10)),
plunged
- ? "\82í\82´\82í\82´\83g\83Q\82¾\82ç\82¯\82Ì\97\8e\82µ\8c\8a\82É\93Ë\93ü\82µ\82Ä"
- : conj_pit ? "\83g\83Q\82¾\82ç\82¯\82Ì\97\8e\82µ\8c\8a\82É\93¥\82Ý\8d\9e\82ñ\82Å"
- : adj_pit ? "\83g\83Q\82¾\82ç\82¯\82Ì\97\8e\82µ\8c\8a\82É\82æ\82ë\82ß\82«\97\8e\82¿\82Ä"
- : "\83g\83Q\82¾\82ç\82¯\82Ì\97\8e\82µ\8c\8a\82É\97\8e\82¿\82Ä",
+ ? "\82í\82´\82í\82´\83g\83Q\82¾\82ç\82¯\82Ì\97\8e\82µ\8c\8a\82É\93Ë\93ü\82µ\82Ä"
+ : conj_pit
+ ? "\83g\83Q\82¾\82ç\82¯\82Ì\97\8e\82µ\8c\8a\82É\93¥\82Ý\8d\9e\82ñ\82Å"
+ : adj_pit
+ ? "\83g\83Q\82¾\82ç\82¯\82Ì\97\8e\82µ\8c\8a\82É\82æ\82ë\82ß\82«\97\8e\82¿\82Ä"
+ : "\83g\83Q\82¾\82ç\82¯\82Ì\97\8e\82µ\8c\8a\82É\97\8e\82¿\82Ä",
KILLED_BY);
#endif
if (!rn2(6))
#if 0 /*JP:T*/
poisoned("spikes", A_STR,
- (conj_pit || adj_pit) ? "stepping on poison spikes"
- : "fall onto poison spikes",
+ (conj_pit || adj_pit)
+ ? "stepping on poison spikes"
+ : "fall onto poison spikes",
/* if damage triggered life-saving,
poison is limited to attrib loss */
(u.umortality > oldumort) ? 0 : 8, FALSE);
#else
poisoned("\83g\83Q", A_STR,
- (conj_pit || adj_pit) ? "\93Å\82Ì\93h\82ç\82ê\82½\83g\83Q\82ð\93¥\82ñ\82Å"
- : "\93Å\82Ì\93h\82ç\82ê\82½\83g\83Q\82Ì\8fã\82É\97\8e\82¿\82Ä",
+ (conj_pit || adj_pit)
+ ? "\93Å\82Ì\93h\82ç\82ê\82½\83g\83Q\82ð\93¥\82ñ\82Å"
+ : "\93Å\82Ì\93h\82ç\82ê\82½\83g\83Q\82Ì\8fã\82É\97\8e\82¿\82Ä",
/* if damage triggered life-saving,
poison is limited to attrib loss */
(u.umortality > oldumort) ? 0 : 8, FALSE);
pline("%s%s\82\82à\82Ì\91\83\82É\82Ð\82Á\82©\82©\82Á\82½\81I", verbbuf, web_you[trap->madeby_u]);
#endif
}
- u.utraptype = TT_WEB;
+
+ /* time will be adjusted below */
+ set_utrap(1, TT_WEB);
/* Time stuck in the web depends on your/steed strength. */
{
- register int str = ACURR(A_STR);
+ int tim, str = ACURR(A_STR);
/* If mounted, the steed gets trapped. Use mintrap
* to do all the work. If mtrapped is set as a result,
if (strongmonst(u.usteed->data))
str = 17;
} else {
+ reset_utrap(FALSE);
break;
}
webmsgok = FALSE; /* mintrap printed the messages */
}
if (str <= 3)
- u.utrap = rn1(6, 6);
+ tim = rn1(6, 6);
else if (str < 6)
- u.utrap = rn1(6, 4);
+ tim = rn1(6, 4);
else if (str < 9)
- u.utrap = rn1(4, 4);
+ tim = rn1(4, 4);
else if (str < 12)
- u.utrap = rn1(4, 2);
+ tim = rn1(4, 2);
else if (str < 15)
- u.utrap = rn1(2, 2);
+ tim = rn1(2, 2);
else if (str < 18)
- u.utrap = rnd(2);
+ tim = rnd(2);
else if (str < 69)
- u.utrap = 1;
+ tim = 1;
else {
- u.utrap = 0;
+ tim = 0;
if (webmsgok)
/*JP
You("tear through %s web!", a_your[trap->madeby_u]);
deltrap(trap);
newsym(u.ux, u.uy); /* get rid of trap symbol */
}
+ set_utrap((unsigned) tim, TT_WEB);
}
break;
feeltrap(trap);
/*JP
- pline("Click! You trigger a rolling boulder trap!");
+ pline("Click! You trigger a rolling boulder trap!");
*/
pline("\83J\83`\83b\81I\82 \82È\82½\82Í\8b\90\8aâ\82Ìã©\82Ì\83X\83C\83b\83`\82ð\93¥\82ñ\82¾\81I");
if (!launch_obj(BOULDER, trap->launch.x, trap->launch.y,
break;
case PIT:
case SPIKED_PIT:
- trapkilled = (steed->mhp <= 0
+ trapkilled = (DEADMONSTER(steed)
|| thitm(0, steed, (struct obj *) 0,
rnd((tt == PIT) ? 6 : 10), FALSE));
steedhit = TRUE;
xchar x, y;
} launchplace;
-static void
+STATIC_OVL void
launch_drop_spot(obj, x, y)
struct obj *obj;
xchar x, y;
delaycnt = 1;
if (!cansee(bhitpos.x, bhitpos.y))
curs_on_u();
- tmp_at(DISP_FLASH, obj_to_glyph(singleobj));
+ tmp_at(DISP_FLASH, obj_to_glyph(singleobj, rn2_on_display_rng));
tmp_at(bhitpos.x, bhitpos.y);
}
/* Mark a spot to place object in bones files to prevent
mtmp->mtrapped = 0; /* perhaps teleported? */
} else if (mtmp->mtrapped) { /* is currently in the trap */
if (!trap->tseen && cansee(mtmp->mx, mtmp->my) && canseemon(mtmp)
- && (trap->ttyp == SPIKED_PIT || trap->ttyp == BEAR_TRAP
- || trap->ttyp == HOLE || trap->ttyp == PIT
+ && (is_pit(trap->ttyp) || trap->ttyp == BEAR_TRAP
+ || trap->ttyp == HOLE
|| trap->ttyp == WEB)) {
/* If you come upon an obviously trapped monster, then
* you must be able to see the trap it's in too.
if (!rn2(40)) {
if (sobj_at(BOULDER, mtmp->mx, mtmp->my)
- && (trap->ttyp == PIT || trap->ttyp == SPIKED_PIT)) {
+ && is_pit(trap->ttyp)) {
if (!rn2(2)) {
mtmp->mtrapped = 0;
if (canseemon(mtmp))
break;
}
trap->once = 1;
- otmp = mksobj(ARROW, TRUE, FALSE);
- otmp->quan = 1L;
- otmp->owt = weight(otmp);
- otmp->opoisoned = 0;
+ otmp = t_missile(ARROW, trap);
if (in_sight)
seetrap(trap);
if (thitm(8, mtmp, otmp, 0, FALSE))
break;
}
trap->once = 1;
- otmp = mksobj(DART, TRUE, FALSE);
- otmp->quan = 1L;
- otmp->owt = weight(otmp);
+ otmp = t_missile(DART, trap);
if (!rn2(6))
otmp->opoisoned = 1;
if (in_sight)
break;
}
trap->once = 1;
- otmp = mksobj(ROCK, TRUE, FALSE);
- otmp->quan = 1L;
- otmp->owt = weight(otmp);
+ otmp = t_missile(ROCK, trap);
if (in_sight)
seetrap(trap);
if (thitm(0, mtmp, otmp, d(2, 6), FALSE))
*/
pline("%s\82æ\81C\88À\82ç\82©\82É\8eK\82Ñ\82ñ\8e\96\82ð\81D", mon_nam(mtmp));
mondied(mtmp);
- if (mtmp->mhp <= 0)
+ if (DEADMONSTER(mtmp))
trapkilled = TRUE;
} else if (mptr == &mons[PM_GREMLIN] && rn2(3)) {
(void) split_mon(mtmp, (struct monst *) 0);
pline("\89\8c\82Ì\93õ\82¢\82ª\82µ\82½\81D");
if (is_ice(mtmp->mx, mtmp->my))
melt_ice(mtmp->mx, mtmp->my, (char *) 0);
- if (see_it)
+ if (see_it && t_at(mtmp->mx, mtmp->my))
seetrap(trap);
break;
case PIT:
mselftouch(mtmp, "Falling, ", FALSE);
*/
mselftouch(mtmp, "\97\8e\89º\92\86\81C", FALSE);
- if (mtmp->mhp <= 0 || thitm(0, mtmp, (struct obj *) 0,
+ if (DEADMONSTER(mtmp) || thitm(0, mtmp, (struct obj *) 0,
rnd((tt == PIT) ? 6 : 10), FALSE))
trapkilled = TRUE;
break;
if (in_sight)
seetrap(trap);
mtmp->mhp -= dmgval2;
- if (mtmp->mhp <= 0)
+ if (DEADMONSTER(mtmp))
monkilled(mtmp,
in_sight
/*JP
? "\94½\96\82\96@\8bó\8aÔ\82Ì\88³\8fk"
: (const char *) 0,
-AD_MAGM);
- if (mtmp->mhp <= 0)
+ if (DEADMONSTER(mtmp))
trapkilled = TRUE;
if (see_it)
newsym(trap->tx, trap->ty);
blow_up_landmine(trap);
/* explosion might have destroyed a drawbridge; don't
dish out more damage if monster is already dead */
- if (mtmp->mhp <= 0
+ if (DEADMONSTER(mtmp)
|| thitm(0, mtmp, (struct obj *) 0, rnd(16), FALSE)) {
trapkilled = TRUE;
} else {
}
/* a boulder may fill the new pit, crushing monster */
fill_pit(trap->tx, trap->ty);
- if (mtmp->mhp <= 0)
+ if (DEADMONSTER(mtmp))
trapkilled = TRUE;
if (unconscious()) {
multi = -1;
newsym(mtmp->mx, mtmp->my);
if (in_sight)
#if 0 /*JP*/
- pline("Click! %s triggers %s.", Monnam(mtmp),
+ pline("Click! %s triggers %s.", Monnam(mtmp),
trap->tseen ? "a rolling boulder trap" : something);
#else
pline("\83J\83`\83b\81I%s\82Í%s\82Ì\83X\83C\83b\83`\82ð\93¥\82ñ\82¾\81I", Monnam(mtmp),
trap->launch2.x, trap->launch2.y, style)) {
if (in_sight)
trap->tseen = TRUE;
- if (mtmp->mhp <= 0)
+ if (DEADMONSTER(mtmp))
trapkilled = TRUE;
} else {
deltrap(trap);
break;
case VIBRATING_SQUARE:
if (see_it && !Blind) {
- if (in_sight)
+ seetrap(trap); /* before messages */
+ if (in_sight) {
#if 0 /*JP*/
- pline("You see a strange vibration beneath %s %s.",
- s_suffix(mon_nam(mtmp)),
- makeplural(mbodypart(mtmp, FOOT)));
+ char buf[BUFSZ], *p, *monnm = mon_nam(mtmp);
+
+ if (nolimbs(mtmp->data)
+ || is_floater(mtmp->data) || is_flyer(mtmp->data)) {
+ /* just "beneath <mon>" */
+ Strcpy(buf, monnm);
+ } else {
+ Strcpy(buf, s_suffix(monnm));
+ p = eos(strcat(buf, " "));
+ Strcpy(p, makeplural(mbodypart(mtmp, FOOT)));
+ /* avoid "beneath 'rear paws'" or 'rear hooves' */
+ (void) strsubst(p, "rear ", "");
+ }
+ You_see("a strange vibration beneath %s.", buf);
+#else /* \91«\82ª\82È\82\82Ä\82à\81u\91«\8c³\81v\82Å\93\9d\88ê */
+ You_see("%s\82Ì\91«\8c³\82ª\95s\8ev\8bc\82É\90U\93®\82µ\82Ä\82¢\82é\82Ì\82ð\8c©\82½\81D",
+ mon_nam(mtmp));
+#endif
+ } else {
+ /* notice something (hearing uses a larger threshold
+ for 'nearby') */
+#if 0 /*JP:T*/
+ You_see("the ground vibrate %s.",
+ (distu(mtmp->mx, mtmp->my) <= 2 * 2)
+ ? "nearby" : "in the distance");
#else
- pline("%s\82Ì%s\82ª\95s\8ev\8bc\82É\90U\93®\82µ\82Ä\82¢\82é\82Ì\82ð\8c©\82½\81D",
- mon_nam(mtmp), mbodypart(mtmp, FOOT));
+ You_see("%s\82\82Å\92n\96Ê\82ª\90U\93®\82µ\82Ä\82¢\82é\82Ì\82ð\8c©\82½\81D",
+ (distu(mtmp->mx, mtmp->my) <= 2 * 2)
+ ? "\8bß" : "\89\93");
#endif
- else
-/*JP
- pline("You see the ground vibrate in the distance.");
-*/
- pline("\89\93\82\82Å\92n\96Ê\82ª\90U\93®\82µ\82Ä\82¢\82é\82Ì\82ð\8c©\82½\81D");
- seetrap(trap);
+ }
}
break;
default:
}
minstapetrify(mon, byplayer);
/* if life-saved, might not be able to continue wielding */
- if (mon->mhp > 0 && !which_armor(mon, W_ARMG) && !resists_ston(mon))
+ if (!DEADMONSTER(mon) && !which_armor(mon, W_ARMG) && !resists_ston(mon))
mwepgone(mon);
}
}
context.botl = TRUE;
if (u.utrap) {
if (u.utraptype == TT_PIT) {
- u.utrap = 0;
+ reset_utrap(FALSE);
/*JP
You("float up, out of the pit!");
*/
You("\95\82\82«\8fã\82ª\82Á\82Ä\81C\97\8e\82µ\8c\8a\82©\82ç\8fo\82½\81I");
vision_full_recalc = 1; /* vision limits change */
fill_pit(u.ux, u.uy);
- } else if (u.utraptype == TT_INFLOOR) {
+ } else if (u.utraptype == TT_LAVA /* molten lava */
+ || u.utraptype == TT_INFLOOR) { /* solidified lava */
/*JP
Your("body pulls upward, but your %s are still stuck.",
*/
Your("\91Ì\82Í\88ø\82«\8fã\82°\82ç\82ê\82½\81D\82µ\82©\82µ%s\82Í\82Ü\82¾\82Í\82Ü\82Á\82Ä\82¢\82é\81D",
makeplural(body_part(LEG)));
- } else {
-/*JP
- You("float up, only your %s is still stuck.", body_part(LEG));
-*/
- You("\95\82\82«\8fo\82½\81D%s\82¾\82¯\82ª\82Í\82Ü\82Á\82Ä\82¢\82é\81D", body_part(LEG));
+ } else if (u.utraptype == TT_BURIEDBALL) { /* tethered */
+ coord cc;
+
+ cc.x = u.ux, cc.y = u.uy;
+ /* caveat: this finds the first buried iron ball within
+ one step of the specified location, not necessarily the
+ buried [former] uball at the original anchor point */
+ (void) buried_ball(&cc);
+ /* being chained to the floor blocks levitation from floating
+ above that floor but not from enhancing carrying capacity */
+ You("feel lighter, but your %s is still chained to the %s.",
+ body_part(LEG),
+ IS_ROOM(levl[cc.x][cc.y].typ) ? "floor" : "ground");
+ } else if (u.utraptype == WEB) {
+ You("float up slightly, but you are still stuck in the web.");
+ } else { /* bear trap */
+/*JP
+ You("float up slightly, but your %s is still stuck.",
+*/
+ You("\8f\82µ\95\82\82«\8fã\82ª\82Á\82½\82ª%s\82Í\82Ü\82¾\82Í\82Ü\82Á\82Ä\82¢\82é\81D",
+ body_part(LEG));
}
+ /* when still trapped, float_vs_flight() below will block levitation */
#if 0
} else if (Is_waterlevel(&u.uz)) {
/*JP
*/
You("\8bó\92\86\82É\95\82\82«\82Í\82¶\82ß\82½\81I");
}
- if (u.usteed && !is_floater(u.usteed->data)
- && !is_flyer(u.usteed->data)) {
+ if (u.usteed && !is_floater(u.usteed->data) && !is_flyer(u.usteed->data)) {
if (Lev_at_will) {
/*JP
pline("%s magically floats up!", Monnam(u.usteed));
You("are no longer able to control your flight.");
*/
You("\8bó\92\86\82Å\82¤\82Ü\82\93®\82¯\82È\82\82È\82Á\82½\81D");
- BFlying |= I_SPECIAL;
+ float_vs_flight(); /* set BFlying, also BLevitation if still trapped */
/* levitation gives maximum carrying capacity, so encumbrance
state might be reduced */
(void) encumber_msg();
struct obj *otmp;
struct trap *t;
- if ((t = t_at(x, y)) && ((t->ttyp == PIT) || (t->ttyp == SPIKED_PIT))
+ if ((t = t_at(x, y)) && is_pit(t->ttyp)
&& (otmp = sobj_at(BOULDER, x, y))) {
obj_extract_self(otmp);
/*JP
if (Levitation)
return 0; /* maybe another ring/potion/boots */
if (BLevitation) {
- /* Levitation is blocked, so hero is not actually floating
- hence shouldn't have float_down effects and feedback */
- float_vs_flight(); /* before nomul() rather than after */
+ /* if blocked by terrain, we haven't actually been levitating so
+ we don't give any end-of-levitation feedback or side-effects,
+ but if blocking is solely due to being trapped in/on floor,
+ do give some feedback but skip other float_down() effects */
+ boolean trapped = (BLevitation == I_SPECIAL);
+
+ float_vs_flight();
+ if (trapped && u.utrap) /* u.utrap => paranoia */
+ You("are no longer trying to float up from the %s.",
+ (u.utraptype == TT_BEARTRAP) ? "trap's jaws"
+ : (u.utraptype == TT_WEB) ? "web"
+ : (u.utraptype == TT_BURIEDBALL) ? "chain"
+ : (u.utraptype == TT_LAVA) ? "lava"
+ : "ground"); /* TT_INFLOOR */
+ (void) encumber_msg(); /* carrying capacity might have changed */
return 0;
}
context.botl = TRUE;
nomul(0); /* stop running or resting */
if (BFlying) {
/* controlled flight no longer overridden by levitation */
- BFlying &= ~I_SPECIAL;
+ float_vs_flight(); /* clears BFlying & I_SPECIAL
+ * unless hero is stuck in floor */
if (Flying) {
/*JP
You("have stopped levitating and are now flying.");
if (Punished && !carried(uball)
&& (is_pool(uball->ox, uball->oy)
|| ((trap = t_at(uball->ox, uball->oy))
- && ((trap->ttyp == PIT) || (trap->ttyp == SPIKED_PIT)
- || (trap->ttyp == TRAPDOOR) || (trap->ttyp == HOLE))))) {
+ && (is_pit(trap->ttyp) || is_hole(trap->ttyp))))) {
u.ux0 = u.ux;
u.uy0 = u.uy;
u.ux = uball->ox;
You("ascend from the pit.");
*/
You("\97\8e\82µ\8c\8a\82ð\8fã\82Á\82Ä\82¢\82Á\82½\81D");
- u.utrap = 0;
+ reset_utrap(FALSE);
fill_pit(u.ux, u.uy);
vision_full_recalc = 1; /* vision limits change */
} else if (!rn2(2) && sobj_at(BOULDER, u.ux, u.uy)) {
You("%s from the pit.", Flying ? "fly" : "climb");
*/
You("\97\8e\82µ\8c\8a\82©\82ç%s\82¢\82Á\82½\81D", Flying ? "\8fã\82Á\82Ä" : "\93o\82Á\82Ä");
- u.utrap = 0;
+ reset_utrap(FALSE);
fill_pit(u.ux, u.uy);
vision_full_recalc = 1; /* vision limits change */
} else if (!(--u.utrap)) {
-#if 0 /*JP*/
+ reset_utrap(FALSE);
+#if 0 /*JP:T*/
You("%s to the edge of the pit.",
(Sokoban && Levitation)
? "struggle against the air currents and float"
*/
Norep("%s\82Í\82Ü\82¾\97\8e\82µ\8c\8a\82Ì\92\86\82É\82¢\82é\81D", y_monnam(u.usteed));
else
-#if 0 /*JP*/
+#if 0 /*JP:T*/
Norep((Hallucination && !rn2(5))
? "You've fallen, and you can't get up."
: "You are still in a pit.");
if (fate < 10) {
/* Most of the time, it creates some monsters. */
- register int cnt = rnd(4);
+ int cnt = rnd(4);
/* blindness effects */
if (!resists_blnd(&youmonst)) {
}
while (cnt--)
(void) makemon((struct permonst *) 0, u.ux, u.uy, NO_MM_FLAGS);
+ /* roar: wake monsters in vicinity, after placing trap-created ones */
+ wake_nearto(u.ux, u.uy, 7 * 7);
+ /* [flash: should probably also hit nearby gremlins with light] */
} else
switch (fate) {
case 10:
You("\8fu\8aÔ\88Ú\93®\82Ì\8eô\95¶\82ð\8f¥\82¦\82Ä\82Ý\82½\81D");
#endif
if (!level.flags.noteleport) {
- (void) dotele();
+ (void) dotele(FALSE);
if (!is_pool(u.ux, u.uy))
return TRUE;
} else
}
newsym(ttmp->tx, ttmp->ty);
if (u.utrap && ttmp->tx == u.ux && ttmp->ty == u.uy)
- u.utrap = 0;
+ reset_utrap(TRUE);
deltrap(ttmp);
}
there are objects covering this trap */
ttmp->tseen = 0; /* hack for check_here() */
/* trigger the trap */
+ iflags.failing_untrap++; /* spoteffects() -> dotrap(,FAILEDUNTRAP) */
spoteffects(TRUE); /* pickup() + dotrap() */
+ iflags.failing_untrap--;
+ /* this should no longer be necessary; before the failing_untrap
+ hack, Flying hero would not trigger an unseen bear trap and
+ setting it not-yet-seen above resulted in leaving it hidden */
+ if ((ttmp = t_at(u.ux, u.uy)) != 0)
+ ttmp->tseen = 1;
exercise(A_WIS, FALSE);
}
}
}
}
/* untrappable traps are located on the ground. */
- if (!can_reach_floor(TRUE)) {
+ if (!can_reach_floor(under_u)) {
if (u.usteed && P_SKILL(P_RIDING) < P_BASIC)
rider_cant_reach();
else
if (mtmp->mtame)
abuse_dog(mtmp);
mtmp->mhp -= rnd(4);
- if (mtmp->mhp <= 0)
+ if (DEADMONSTER(mtmp))
killed(mtmp);
} else if (ttype == WEB) {
if (!webmaker(youmonst.data)) {
if (ttmp2) {
pline_The(
/*JP
- "webbing sticks to you. You're caught too!");
+ "webbing sticks to you. You're caught too!");
*/
"\82\82à\82Ì\91\83\82ª\82 \82È\82½\82É\82©\82ç\82ñ\82Å\82«\82½\81D\82Ü\82·\82Ü\82·\95ß\82Ü\82Á\82Ä\82µ\82Ü\82Á\82½\81I");
dotrap(ttmp2, NOWEBMSG);
pline("%s\82Í\82©\82ç\82Ü\82Á\82½\82Ü\82Ü\82¾\81D", Monnam(mtmp));
}
} else if (under_u) {
- dotrap(ttmp, 0);
+ /* [don't need the iflags.failing_untrap hack here] */
+ dotrap(ttmp, FAILEDUNTRAP);
} else {
move_into_trap(ttmp);
}
if (ttmp) {
Strcpy(the_trap, the(trapdescr));
if (boxcnt) {
- if (ttmp->ttyp == PIT || ttmp->ttyp == SPIKED_PIT) {
-#if 0 /*JP*/
+ if (is_pit(ttmp->ttyp)) {
+#if 0 /*JP:T*/
You_cant("do much about %s%s.", the_trap,
u.utrap ? " that you're stuck in"
: " while standing on the edge of it");
trap_skipped = TRUE;
deal_with_floor_trap = FALSE;
} else {
-#if 0 /*JP*/
+#if 0 /*JP:T*/
Sprintf(
- qbuf, "There %s and %s here. %s %s?",
+ qbuf, "There %s and %s here. %s %s?",
(boxcnt == 1) ? "is a container" : "are containers",
an(trapdescr),
(ttmp->ttyp == WEB) ? "Remove" : "Disarm", the_trap);
return 1;
}
if ((mtmp = m_at(x, y)) != 0
- && (mtmp->m_ap_type == M_AP_FURNITURE
- || mtmp->m_ap_type == M_AP_OBJECT)) {
+ && (M_AP_TYPE(mtmp) == M_AP_FURNITURE
+ || M_AP_TYPE(mtmp) == M_AP_OBJECT)) {
stumble_onto_mimic(mtmp);
return 1;
}
boolean *noticed; /* set to true iff hero notices the effect; */
{ /* otherwise left with its previous value intact */
struct trap *t;
- char buf[BUFSZ];
- const char *trapdescr, *which;
+ char buf[BUFSZ], whichbuf[20];
+ const char *trapdescr = 0, *which = 0;
boolean ishero = (mon == &youmonst);
if (!mon)
return FALSE;
if (mon == u.usteed)
ishero = TRUE;
+
t = t_at(ishero ? u.ux : mon->mx, ishero ? u.uy : mon->my);
- /* if no trap here or it's not a holding trap, we're done */
- if (!t || (t->ttyp != BEAR_TRAP && t->ttyp != WEB))
- return FALSE;
- trapdescr = defsyms[trap_to_defsym(t->ttyp)].explanation;
+ if (ishero && u.utrap) { /* all u.utraptype values are holding traps */
+ which = "";
+ switch (u.utraptype) {
+ case TT_LAVA:
+ trapdescr = "molten lava";
+ break;
+ case TT_INFLOOR:
+ /* solidified lava, so not "floor" even if within a room */
+ trapdescr = "ground";
+ break;
+ case TT_BURIEDBALL:
+ trapdescr = "your anchor";
+ break;
+ case TT_BEARTRAP:
+ case TT_PIT:
+ case TT_WEB:
+ trapdescr = 0; /* use defsyms[].explanation */
+ break;
+ default:
+ /* lint suppression in case 't' is unexpectedly Null
+ or u.utraptype has new value we don't know about yet */
+ trapdescr = "trap";
+ break;
+ }
+ } else {
+ /* if no trap here or it's not a holding trap, we're done */
+ if (!t || (t->ttyp != BEAR_TRAP && t->ttyp != WEB))
+ return FALSE;
+ }
+
+ if (!trapdescr)
+ trapdescr = defsyms[trap_to_defsym(t->ttyp)].explanation;
+ if (!which)
#if 0 /*JP*/
- which = t->tseen ? the_your[t->madeby_u]
- : index(vowels, *trapdescr) ? "an" : "a";
+ which = t->tseen ? the_your[t->madeby_u]
+ : index(vowels, *trapdescr) ? "an" : "a";
#else
- which = t->tseen ? set_you[t->madeby_u] : "";
+ which = t->tseen ? set_you[t->madeby_u] : "";
#endif
+ if (*which)
+ which = strcat(strcpy(whichbuf, which), " ");
if (ishero) {
if (!u.utrap)
return FALSE;
- u.utrap = 0; /* released regardless of type */
*noticed = TRUE;
- /* give message only if trap was the expected type */
- if (u.utraptype == TT_BEARTRAP || u.utraptype == TT_WEB) {
- if (u.usteed)
+ if (u.usteed)
/*JP
Sprintf(buf, "%s is", noit_Monnam(u.usteed));
*/
Strcpy(buf, noit_Monnam(u.usteed));
- else
+ else
/*JP
Strcpy(buf, "You are");
*/
Strcpy(buf, "\82 \82È\82½");
/*JP
- pline("%s released from %s %s.", buf, which, trapdescr);
+ pline("%s released from %s%s.", buf, which, trapdescr);
*/
- pline("%s\82Í%s%s\82©\82ç\89ð\95ú\82³\82ê\82½\81D", buf, which, trapdescr);
- }
+ pline("%s\82Í%s%s\82©\82ç\89ð\95ú\82³\82ê\82½\81D", buf, which, trapdescr);
+ reset_utrap(TRUE);
} else {
if (!mon->mtrapped)
return FALSE;
if (canspotmon(mon)) {
*noticed = TRUE;
#if 0 /*JP*/
- pline("%s is released from %s %s.", Monnam(mon), which,
+ pline("%s is released from %s%s.", Monnam(mon), which,
trapdescr);
#else
pline("%s\82Í%s%s\82©\82ç\89ð\95ú\82³\82ê\82½\81D", Monnam(mon), which,
} else if (cansee(t->tx, t->ty) && t->tseen) {
*noticed = TRUE;
if (t->ttyp == WEB)
-#if 0 /*JP*/
- pline("%s is released from %s %s.", Something, which,
+#if 0 /*JP:T*/
+ pline("%s is released from %s%s.", Something, which,
trapdescr);
#else
pline("\89½\8eÒ\82©\82Í%s%s\82©\82ç\89ð\95ú\82³\82ê\82½\81D", which,
#endif
else /* BEAR_TRAP */
/*JP
- pline("%s %s opens.", upstart(strcpy(buf, which)), trapdescr);
+ pline("%s%s opens.", upstart(strcpy(buf, which)), trapdescr);
*/
pline("%s%s\82Í\8aJ\82¢\82½\81D", which, trapdescr);
}
/* if no trap here or it's not a falling trap, we're done
(note: falling rock traps have a trapdoor in the ceiling) */
if (!t || ((t->ttyp != TRAPDOOR && t->ttyp != ROCKTRAP)
- && (trapdoor_only || (t->ttyp != HOLE && t->ttyp != PIT
- && t->ttyp != SPIKED_PIT))))
+ && (trapdoor_only || (t->ttyp != HOLE && !is_pit(t->ttyp)))))
return FALSE;
if (ishero) {
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)
+ || !is_pit(trap2->ttyp)
+ || !is_pit(trap1->ttyp)
|| (u_entering_trap2 && !(u.utrap && u.utraptype == TT_PIT)))
return FALSE;
dx = sgn(trap2->tx - trap1->tx);
return FALSE;
}
-void
+STATIC_OVL void
clear_conjoined_pits(trap)
struct trap *trap;
{
int diridx, adjidx, x, y;
struct trap *t;
- if (trap && (trap->ttyp == PIT || trap->ttyp == SPIKED_PIT)) {
+ if (trap && is_pit(trap->ttyp)) {
for (diridx = 0; diridx < 8; ++diridx) {
if (trap->conjoined & (1 << diridx)) {
x = trap->tx + xdir[diridx];
y = trap->ty + ydir[diridx];
if (isok(x, y)
&& (t = t_at(x, y)) != 0
- && (t->ttyp == PIT || t->ttyp == SPIKED_PIT)) {
+ && is_pit(t->ttyp)) {
adjidx = (diridx + 4) % 8;
t->conjoined &= ~(1 << adjidx);
}
}
}
-boolean
+STATIC_OVL boolean
adj_nonconjoined_pit(adjtrap)
struct trap *adjtrap;
{
struct trap *trap_with_u = t_at(u.ux0, u.uy0);
- if (trap_with_u && adjtrap && u.utrap && u.utraptype == TT_PIT &&
- (trap_with_u->ttyp == PIT || trap_with_u->ttyp == SPIKED_PIT) &&
- (adjtrap->ttyp == PIT || adjtrap->ttyp == SPIKED_PIT)) {
+ if (trap_with_u && adjtrap && u.utrap && u.utraptype == TT_PIT
+ && is_pit(trap_with_u->ttyp) && is_pit(adjtrap->ttyp)) {
int idx;
+
for (idx = 0; idx < 8; idx++) {
if (xdir[idx] == u.dx && ydir[idx] == u.dy)
return TRUE;
x = trap->tx + xdir[diridx];
y = trap->ty + ydir[diridx];
if (isok(x, y)) {
- if ((t = t_at(x, y)) != 0
- && (t->ttyp == PIT || t->ttyp == SPIKED_PIT)) {
+ if ((t = t_at(x, y)) != 0 && is_pit(t->ttyp)) {
trap->conjoined |= (1 << diridx);
join_adjacent_pits(t);
} else
struct trap *trap;
{
if (trap && trap->tseen && (!u.utrap || u.utraptype != TT_PIT)
- && (trap->ttyp == PIT || trap->ttyp == SPIKED_PIT))
+ && is_pit(trap->ttyp))
return TRUE;
else
return FALSE;
/* some of these are arbitrary -dlc */
if (ttmp && ((ttmp->ttyp == SQKY_BOARD) || (ttmp->ttyp == BEAR_TRAP)
|| (ttmp->ttyp == LANDMINE) || (ttmp->ttyp == FIRE_TRAP)
- || (ttmp->ttyp == PIT) || (ttmp->ttyp == SPIKED_PIT)
- || (ttmp->ttyp == HOLE) || (ttmp->ttyp == TRAPDOOR)
+ || is_pit(ttmp->ttyp)
+ || is_hole(ttmp->ttyp)
|| (ttmp->ttyp == TELEP_TRAP) || (ttmp->ttyp == LEVEL_TELEP)
|| (ttmp->ttyp == WEB) || (ttmp->ttyp == MAGIC_TRAP)
|| (ttmp->ttyp == ANTI_MAGIC))) {
register struct monst *mtmp;
if (ttmp->tx == u.ux && ttmp->ty == u.uy) {
- u.utrap = 0;
- u.utraptype = 0;
+ if (u.utraptype != TT_BURIEDBALL)
+ reset_utrap(TRUE);
} else if ((mtmp = m_at(ttmp->tx, ttmp->ty)) != 0) {
mtmp->mtrapped = 0;
}
dam = 1;
}
mon->mhp -= dam;
- if (mon->mhp <= 0) {
+ if (DEADMONSTER(mon)) {
int xx = mon->mx, yy = mon->my;
monkilled(mon, "", nocorpse ? -AD_RBRE : AD_PHYS);
- if (mon->mhp <= 0) {
+ if (DEADMONSTER(mon)) {
newsym(xx, yy);
trapkilled = TRUE;
}
boil_away = !Fire_resistance;
/* if not fire resistant, sink_into_lava() will quickly be fatal;
hero needs to escape immediately */
- u.utrap = rn1(4, 4) + ((boil_away ? 2 : rn1(4, 12)) << 8);
- u.utraptype = TT_LAVA;
-#if 0 /*JP*/
+ set_utrap((unsigned) (rn1(4, 4) + ((boil_away ? 2 : rn1(4, 12)) << 8)),
+ TT_LAVA);
+#if 0 /*JP:T*/
You("sink into the %s%s!", hliquid("lava"),
- !boil_away
- ? ", but it only burns slightly"
- : " and are about to be immolated");
+ !boil_away ? ", but it only burns slightly"
+ : " and are about to be immolated");
#else
You("%s\82É\92¾\82ñ%s\82¾\81I", hliquid("\97n\8aâ"),
- !boil_away
- ? "\82¾\82ª\81C\82¿\82å\82Á\82Æ\8fÅ\82°\82½\82¾\82¯"
- : "\82Å\8fÄ\82«\8eE\82³\82ê\82»\82¤");
+ !boil_away ? "\82¾\82ª\81C\82¿\82å\82Á\82Æ\8fÅ\82°\82½\82¾\82¯"
+ : "\82Å\8fÄ\82«\8eE\82³\82ê\82»\82¤");
#endif
if (u.uhp > 1)
losehp(!boil_away ? 1 : (u.uhp / 2), lava_killer,
if (!u.utrap || u.utraptype != TT_LAVA) {
; /* do nothing; this shouldn't happen */
} else if (!is_lava(u.ux, u.uy)) {
- u.utrap = 0; /* this shouldn't happen either */
+ reset_utrap(FALSE); /* this shouldn't happen either */
} else if (!u.uinvulnerable) {
/* ordinarily we'd have to be fire resistant to survive long
enough to become stuck in lava, but it can happen without
burn_away_slime(); /* add insult to injury? */
done(DISSOLVED);
/* can only get here via life-saving; try to get away from lava */
- u.utrap = 0;
- (void) safe_teleds(TRUE);
+ reset_utrap(TRUE);
+ /* levitation or flight have become unblocked, otherwise Tport */
+ if (!Levitation && !Flying)
+ (void) safe_teleds(TRUE);
} else if (!u.umoved) {
/* can't fully turn into slime while in lava, but might not
have it be burned away until you've come awfully close */