1 /* 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 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /*-Copyright (c) Robert Patrick Rankin, 2013. */
4 /* NetHack may be freely redistributed. See license for details. */
6 /* JNetHack Copyright */
7 /* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000 */
8 /* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2019 */
9 /* JNetHack may be freely redistributed. See license for details. */
13 extern const char *const destroy_strings[][3]; /* from zap.c */
15 STATIC_DCL boolean FDECL(keep_saddle_with_steedcorpse, (unsigned, struct obj *,
17 STATIC_DCL struct obj *FDECL(t_missile, (int, struct trap *));
18 STATIC_DCL char *FDECL(trapnote, (struct trap *, BOOLEAN_P));
19 STATIC_DCL int FDECL(steedintrap, (struct trap *, struct obj *));
20 STATIC_DCL void FDECL(launch_drop_spot, (struct obj *, XCHAR_P, XCHAR_P));
21 STATIC_DCL int FDECL(mkroll_launch, (struct trap *, XCHAR_P, XCHAR_P,
23 STATIC_DCL boolean FDECL(isclearpath, (coord *, int, SCHAR_P, SCHAR_P));
24 STATIC_DCL void FDECL(dofiretrap, (struct obj *));
25 STATIC_DCL void NDECL(domagictrap);
26 STATIC_DCL boolean FDECL(emergency_disrobe, (boolean *));
27 STATIC_DCL int FDECL(untrap_prob, (struct trap *));
28 STATIC_DCL void FDECL(move_into_trap, (struct trap *));
29 STATIC_DCL int FDECL(try_disarm, (struct trap *, BOOLEAN_P));
30 STATIC_DCL void FDECL(reward_untrap, (struct trap *, struct monst *));
31 STATIC_DCL int FDECL(disarm_holdingtrap, (struct trap *));
32 STATIC_DCL int FDECL(disarm_landmine, (struct trap *));
33 STATIC_DCL int FDECL(disarm_squeaky_board, (struct trap *));
34 STATIC_DCL int FDECL(disarm_shooting_trap, (struct trap *, int));
35 STATIC_DCL void FDECL(clear_conjoined_pits, (struct trap *));
36 STATIC_DCL boolean FDECL(adj_nonconjoined_pit, (struct trap *));
37 STATIC_DCL int FDECL(try_lift, (struct monst *, struct trap *, int,
39 STATIC_DCL int FDECL(help_monster_out, (struct monst *, struct trap *));
41 STATIC_DCL void FDECL(join_adjacent_pits, (struct trap *));
43 STATIC_DCL boolean FDECL(thitm, (int, struct monst *, struct obj *, int,
45 STATIC_DCL void NDECL(maybe_finish_sokoban);
47 /* mintrap() should take a flags argument, but for time being we use this */
48 STATIC_VAR int force_mintrap = 0;
51 STATIC_VAR const char *const a_your[2] = { "a", "your" };
52 STATIC_VAR const char *const A_Your[2] = { "A", "Your" };
53 STATIC_VAR const char tower_of_flame[] = "tower of flame";
54 STATIC_VAR const char *const A_gush_of_water_hits = "A gush of water hits";
57 STATIC_VAR const char *const blindgas[6] = { "humid", "odorless",
58 "pungent", "chilling",
61 STATIC_VAR const char * const blindgas[6] = {
62 "
\82Þ
\82µ
\82Þ
\82µ
\82·
\82é", "
\96³
\8fL
\82Ì",
63 "
\8eh
\8c\83\8fL
\82Ì
\82·
\82é", "
\97â
\82½
\82¢",
64 "
\83c
\83\93\82Æ
\82µ
\82½
\82É
\82¨
\82¢
\82Ì", "
\82Ð
\82è
\82Ð
\82è
\82·
\82é"
68 const char *set_you[2] = { "", "
\82 \82È
\82½
\82Ì
\8ed
\8a|
\82¯
\82½" };
69 STATIC_VAR const char *dig_you[2] = { "", "
\82 \82È
\82½
\82ª
\8c@
\82Á
\82½" };
70 STATIC_VAR const char *web_you[2] = { "", "
\82 \82È
\82½
\82ª
\92£
\82Á
\82½" };
73 /* called when you're hit by fire (dofiretrap,buzz,zapyourself,explode);
74 returns TRUE if hit on torso */
86 hitting_u = (victim == &youmonst);
88 /* burning damage may dry wet towel */
89 item = hitting_u ? carrying(TOWEL) : m_carrying(victim, TOWEL);
91 if (is_wet_towel(item)) {
93 dry_a_towel(item, rn2(oldspe + 1), TRUE);
94 if (item->spe != oldspe)
95 break; /* stop once one towel has been affected */
100 #define burn_dmg(obj, descr) erode_obj(obj, descr, ERODE_BURN, EF_GREASE)
104 item = hitting_u ? uarmh : which_armor(victim, W_ARMH);
106 mat_idx = objects[item->otyp].oc_material;
108 Sprintf(buf, "%s %s", materialnm[mat_idx],
109 helm_simple_name(item));
111 Sprintf(buf, "%s
\82Ì%s", materialnm[mat_idx],
112 helm_simple_name(item));
116 if (!burn_dmg(item, item ? buf : "helmet"))
118 if (!burn_dmg(item, item ? buf : "
\8a\95"))
122 item = hitting_u ? uarmc : which_armor(victim, W_ARMC);
124 (void) burn_dmg(item, cloak_simple_name(item));
127 item = hitting_u ? uarm : which_armor(victim, W_ARM);
129 (void) burn_dmg(item, xname(item));
132 item = hitting_u ? uarmu : which_armor(victim, W_ARMU);
135 (void) burn_dmg(item, "shirt");
137 (void) burn_dmg(item, "
\83V
\83\83\83c");
140 item = hitting_u ? uarms : which_armor(victim, W_ARMS);
142 if (!burn_dmg(item, "wooden shield"))
144 if (!burn_dmg(item, "
\96Ø
\82Ì
\8f\82"))
148 item = hitting_u ? uarmg : which_armor(victim, W_ARMG);
150 if (!burn_dmg(item, "gloves"))
152 if (!burn_dmg(item, "
\8f¬
\8eè"))
156 item = hitting_u ? uarmf : which_armor(victim, W_ARMF);
158 if (!burn_dmg(item, "boots"))
160 if (!burn_dmg(item, "
\8cC"))
164 break; /* Out of while loop */
171 /* Generic erode-item function.
172 * "ostr", if non-null, is an alternate string to print instead of the
174 * "type" is an ERODE_* value for the erosion type
175 * "flags" is an or-ed list of EF_* flags
177 * Returns an erosion return value (ER_*)
180 erode_obj(otmp, ostr, type, ef_flags)
181 register struct obj *otmp;
186 static NEARDATA const char
188 *const action[] = { "smoulder", "rust", "rot", "corrode" },
190 *const action[] = { "
\82
\82·
\82Ô
\82Á
\82½", "
\8eK
\82Ñ
\82½", "
\95\85\82Á
\82½", "
\95\85\90H
\82µ
\82½" },
192 *const msg[] = { "burnt", "rusted", "rotten", "corroded" },
194 *const msg[] = { "
\8fÅ
\82°
\82½", "
\8eK
\82Ñ
\82½", "
\95\85\82Á
\82½", "
\95\85\90H
\82µ
\82½" },
196 *const bythe[] = { "heat", "oxidation", "decay", "corrosion" };
198 *const bythe[] = { "
\94M", "
\8e_
\89»", "
\95\85\94s", "
\95\85\90H" };
199 boolean vulnerable = FALSE, is_primary = TRUE,
200 check_grease = (ef_flags & EF_GREASE) ? TRUE : FALSE,
201 print = (ef_flags & EF_VERBOSE) ? TRUE : FALSE,
202 uvictim, vismon, visobj;
203 int erosion, cost_type;
204 struct monst *victim;
209 victim = carried(otmp) ? &youmonst : mcarried(otmp) ? otmp->ocarry : NULL;
210 uvictim = (victim == &youmonst);
211 vismon = victim && (victim != &youmonst) && canseemon(victim);
212 /* Is bhitpos correct here? Ugh. */
213 visobj = !victim && cansee(bhitpos.x, bhitpos.y);
217 vulnerable = is_flammable(otmp);
218 check_grease = FALSE;
219 cost_type = COST_BURN;
222 vulnerable = is_rustprone(otmp);
223 cost_type = COST_RUST;
226 vulnerable = is_rottable(otmp);
227 check_grease = FALSE;
229 cost_type = COST_ROT;
232 vulnerable = is_corrodeable(otmp);
234 cost_type = COST_CORRODE;
237 impossible("Invalid erosion type in erode_obj");
240 erosion = is_primary ? otmp->oeroded : otmp->oeroded2;
244 /* 'visobj' messages insert "the"; probably ought to switch to the() */
245 if (visobj && !(uvictim || vismon) && !strncmpi(ostr, "the ", 4))
248 if (check_grease && otmp->greased) {
249 grease_protect(otmp, ostr, victim);
251 } else if (!erosion_matters(otmp)) {
253 } else if (!vulnerable || (otmp->oerodeproof && otmp->rknown)) {
254 if (flags.verbose && print && (uvictim || vismon))
256 pline("%s %s %s not affected by %s.",
257 uvictim ? "Your" : s_suffix(Monnam(victim)),
258 ostr, vtense(ostr, "are"), bythe[type]);
260 pline("%s%s
\82Í%s
\82Ì
\89e
\8b¿
\82ð
\8eó
\82¯
\82È
\82©
\82Á
\82½
\81D",
261 uvictim ? "
\82 \82È
\82½
\82Ì" : s_suffix(Monnam(victim)),
265 } else if (otmp->oerodeproof || (otmp->blessed && !rnl(4))) {
266 if (flags.verbose && (print || otmp->oerodeproof)
267 && (uvictim || vismon || visobj))
269 pline("Somehow, %s %s %s not affected by the %s.",
271 : !vismon ? "the" /* visobj */
272 : s_suffix(mon_nam(victim)),
273 ostr, vtense(ostr, "are"), bythe[type]);
275 pline("
\82È
\82º
\82©
\81C%s%s
\82Í%s
\82Ì
\89e
\8b¿
\82ð
\8eó
\82¯
\82È
\82©
\82Á
\82½
\81D",
276 uvictim ? "
\82 \82È
\82½
\82Ì"
277 : !vismon ? "" /* visobj */
278 : s_suffix(mon_nam(victim)),
281 /* We assume here that if the object is protected because it
282 * is blessed, it still shows some minor signs of wear, and
283 * the hero can distinguish this from an object that is
284 * actually proof against damage.
286 if (otmp->oerodeproof) {
288 if (victim == &youmonst)
293 } else if (erosion < MAX_ERODE) {
295 const char *adverb = (erosion + 1 == MAX_ERODE)
297 : erosion ? " further" : "";
299 const char *adverb = (erosion + 1 == MAX_ERODE)
301 : erosion ? "
\82³
\82ç
\82É" : "";
304 if (uvictim || vismon || visobj)
308 : !vismon ? "The" /* visobj */
309 : s_suffix(Monnam(victim)),
310 ostr, vtense(ostr, action[type]), adverb);
312 pline("%s%s
\82Í%s%s!",
313 uvictim ? "
\82 \82È
\82½
\82Ì"
314 : !vismon ? "" /* visobj */
315 : s_suffix(Monnam(victim)),
316 ostr, adverb, action[type]);
319 if (ef_flags & EF_PAY)
320 costly_alteration(otmp, cost_type);
327 if (victim == &youmonst)
331 } else if (ef_flags & EF_DESTROY) {
332 if (uvictim || vismon || visobj)
334 pline("%s %s %s away!",
336 : !vismon ? "The" /* visobj */
337 : s_suffix(Monnam(victim)),
338 ostr, vtense(ostr, action[type]));
340 pline("%s%s
\82Í
\8a®
\91S
\82É%s
\81I",
341 uvictim ? "
\82 \82È
\82½
\82Ì"
342 : !vismon ? "" /* visobj */
343 : s_suffix(Monnam(victim)),
347 if (ef_flags & EF_PAY)
348 costly_alteration(otmp, cost_type);
354 if (flags.verbose && print) {
357 Your("%s %s completely %s.",
358 ostr, vtense(ostr, Blind ? "feel" : "look"), msg[type]);
360 Your("%s
\82Í
\8a®
\91S
\82É%s%s
\81D",
361 ostr, msg[type], Blind ? "
\82æ
\82¤
\82¾" : "");
363 else if (vismon || visobj)
365 pline("%s %s %s completely %s.",
366 !vismon ? "The" : s_suffix(Monnam(victim)),
367 ostr, vtense(ostr, "look"), msg[type]);
369 pline("%s%s
\82Í
\8a®
\91S
\82É%s
\82æ
\82¤
\82¾
\81D",
370 !vismon ? "" : s_suffix(Monnam(victim)),
378 /* Protect an item from erosion with grease. Returns TRUE if the grease
382 grease_protect(otmp, ostr, victim)
383 register struct obj *otmp;
385 struct monst *victim;
388 static const char txt[] = "protected by the layer of grease!";
390 static const char txt[] = "
\96û
\82Ì
\93h
\82è
\82±
\82Ý
\82É
\82æ
\82Á
\82Ä
\8eç
\82ç
\82ê
\82Ä
\82¢
\82é
\81I";
391 boolean vismon = victim && (victim != &youmonst) && canseemon(victim);
394 if (victim == &youmonst)
396 Your("%s %s %s", ostr, vtense(ostr, "are"), txt);
398 Your("%s
\82Í%s", ostr, txt);
401 pline("%s's %s %s %s", Monnam(victim),
402 ostr, vtense(ostr, "are"), txt);
404 pline("%s
\82Ì%s
\82Í%s", Monnam(victim), ostr, txt);
406 } else if (victim == &youmonst || vismon) {
408 pline("%s %s", Yobjnam2(otmp, "are"), txt);
410 Your("%s
\82Í%s",xname(otmp), txt);
416 pline_The("grease dissolves.");
418 pline("
\96û
\82Í
\82Í
\82°
\82Ä
\82µ
\82Ü
\82Á
\82½
\81D");
430 static union vlaunchinfo zero_vl;
433 struct rm *lev = &levl[x][y];
435 if ((ttmp = t_at(x, y)) != 0) {
436 if (ttmp->ttyp == MAGIC_PORTAL || ttmp->ttyp == VIBRATING_SQUARE)
437 return (struct trap *) 0;
439 if (u.utrap && x == u.ux && y == u.uy
440 && ((u.utraptype == TT_BEARTRAP && typ != BEAR_TRAP)
441 || (u.utraptype == TT_WEB && typ != WEB)
442 || (u.utraptype == TT_PIT && !is_pit(typ))))
444 /* old <tx,ty> remain valid */
445 } else if (IS_FURNITURE(lev->typ)
446 && (!IS_GRAVE(lev->typ) || (typ != PIT && typ != HOLE))) {
447 /* no trap on top of furniture (caller usually screens the
448 location to inhibit this, but wizard mode wishing doesn't) */
449 return (struct trap *) 0;
453 (void) memset((genericptr_t)ttmp, 0, sizeof(struct trap));
458 /* [re-]initialize all fields except ntrap (handled below) and <tx,ty> */
460 ttmp->launch.x = ttmp->launch.y = -1; /* force error if used before set */
461 ttmp->dst.dnum = ttmp->dst.dlevel = -1;
464 ttmp->tseen = (typ == HOLE); /* hide non-holes */
469 int tavail[12], tpick[12], tcnt = 0, k;
472 for (k = 0; k < 12; ++k)
473 tavail[k] = tpick[k] = 0;
474 for (t = ftrap; t; t = t->ntrap)
475 if (t->ttyp == SQKY_BOARD && t != ttmp)
476 tavail[t->tnote] = 1;
477 /* now populate tpick[] with the available indices */
478 for (k = 0; k < 12; ++k)
481 /* choose an unused note; if all are in use, pick a random one */
482 ttmp->tnote = (short) ((tcnt > 0) ? tpick[rn2(tcnt)] : rn2(12));
485 case STATUE_TRAP: { /* create a "living" statue */
487 struct obj *otmp, *statue;
488 struct permonst *mptr;
491 do { /* avoid ultimately hostile co-aligned unicorn */
492 mptr = &mons[rndmonnum()];
493 } while (--trycount > 0 && is_unicorn(mptr)
494 && sgn(u.ualign.type) == sgn(mptr->maligntyp));
495 statue = mkcorpstat(STATUE, (struct monst *) 0, mptr, x, y,
497 mtmp = makemon(&mons[statue->corpsenm], 0, 0, MM_NOCOUNTBIRTH);
499 break; /* should never happen */
500 while (mtmp->minvent) {
501 otmp = mtmp->minvent;
503 obj_extract_self(otmp);
504 (void) add_to_container(statue, otmp);
506 statue->owt = weight(statue);
510 case ROLLING_BOULDER_TRAP: /* boulder will roll towards trigger */
511 (void) mkroll_launch(ttmp, x, y, BOULDER, 1L);
519 if (*in_rooms(x, y, SHOPBASE)
520 && (is_hole(typ) || IS_DOOR(lev->typ) || IS_WALL(lev->typ)))
521 add_damage(x, y, /* schedule repair */
522 ((IS_DOOR(lev->typ) || IS_WALL(lev->typ))
523 && !context.mon_moving)
526 lev->doormask = 0; /* subsumes altarmask, icedpool... */
527 if (IS_ROOM(lev->typ)) /* && !IS_AIR(lev->typ) */
530 * some cases which can happen when digging
531 * down while phazing thru solid areas
533 else if (lev->typ == STONE || lev->typ == SCORR)
535 else if (IS_WALL(lev->typ) || lev->typ == SDOOR)
536 lev->typ = level.flags.is_maze_lev
538 : level.flags.is_cavernous_lev ? CORR : DOOR;
549 it shouldn't be possible to override a sokoban pit or hole
550 with some other trap, but we'll check just to be safe */
552 maybe_finish_sokoban();
559 boolean td; /* td == TRUE : trap door or hole */
563 const char *dont_fall = 0;
564 int newlevel, bottom;
566 /* we'll fall even while levitating in Sokoban; otherwise, if we
567 won't fall and won't be told that we aren't falling, give up now */
568 if (Blind && Levitation && !Sokoban)
571 bottom = dunlevs_in_dungeon(&u.uz);
572 /* when in the upper half of the quest, don't fall past the
573 middle "quest locate" level if hero hasn't been there yet */
574 if (In_quest(&u.uz)) {
575 int qlocate_depth = qlocate_level.dlevel;
577 /* deepest reached < qlocate implies current < qlocate */
578 if (dunlev_reached(&u.uz) < qlocate_depth)
579 bottom = qlocate_depth; /* early cut-off */
581 newlevel = dunlev(&u.uz); /* current level */
584 } while (!rn2(4) && newlevel < bottom);
587 struct trap *t = t_at(u.ux, u.uy);
591 if (t->ttyp == TRAPDOOR)
593 pline("A trap door opens up under you!");
595 pline("
\97\8e\82µ
\94à
\82ª
\82 \82È
\82½
\82Ì
\91«
\8c³
\82É
\8aJ
\82¢
\82½
\81I");
598 pline("There's a gaping hole under you!");
600 pline("
\82 \82È
\82½
\82Ì
\91«
\89º
\82É
\82Û
\82Á
\82©
\82è
\82Æ
\8c\8a\82ª
\8aJ
\82¢
\82Ä
\82¢
\82é
\81I");
604 pline_The("%s opens up under you!", surface(u.ux, u.uy));
606 pline("
\91«
\8c³
\82Ì%s
\82É
\8c\8a\82ª
\8aJ
\82¢
\82½
\81I", surface(u.ux,u.uy));
608 if (Sokoban && Can_fall_thru(&u.uz))
609 ; /* KMH -- You can't escape the Sokoban level traps */
610 else if (Levitation || u.ustuck
611 || (!Can_fall_thru(&u.uz) && !levl[u.ux][u.uy].candig) || Flying
612 || is_clinger(youmonst.data)
613 || (Inhell && !u.uevent.invoked && newlevel == bottom)) {
615 dont_fall = "don't fall in.";
617 dont_fall = "
\82µ
\82©
\82µ
\82 \82È
\82½
\82Í
\97\8e\82¿
\82È
\82©
\82Á
\82½
\81D";
618 } else if (youmonst.data->msize >= MZ_HUGE) {
620 dont_fall = "don't fit through.";
622 dont_fall = "
\92Ê
\82è
\94²
\82¯
\82é
\82É
\82Í
\83T
\83C
\83Y
\82ª
\8d\87\82í
\82È
\82¢
\81D";
623 } else if (!next_to_u()) {
625 dont_fall = "are jerked back by your pet!";
627 dont_fall = "
\82 \82È
\82½
\82Í
\83y
\83b
\83g
\82É
\82æ
\82Á
\82Ä
\88ø
\82Á
\82Ï
\82è
\82à
\82Ç
\82³
\82ê
\82½
\81I";
630 #if 0 /*JP*//*
\81u
\82 \82È
\82½
\82Í
\81v
\82Å
\8en
\82Ü
\82ç
\82È
\82¢
\82à
\82Ì
\82à
\82 \82é*/
635 /* hero didn't fall through, but any objects here might */
636 impact_drop((struct obj *) 0, u.ux, u.uy, 0);
638 display_nhwindow(WIN_MESSAGE, FALSE);
640 pline_The("opening under you closes up.");
642 pline_The("
\91«
\89º
\82É
\8aJ
\82¢
\82Ä
\82¢
\82½
\82à
\82Ì
\82Í
\95Â
\82¶
\82½
\81D");
649 if (Is_stronghold(&u.uz)) {
652 int dist = newlevel - dunlev(&u.uz);
653 dtmp.dnum = u.uz.dnum;
654 dtmp.dlevel = newlevel;
657 You("fall down a %s%sshaft!", dist > 3 ? "very " : "",
658 dist > 2 ? "deep " : "");
660 You("%s%s
\8c\8a\82Ì
\92\86\82ð
\97\8e\82¿
\82Ä
\82¢
\82Á
\82½
\81I", dist > 3 ? "
\82Æ
\82Ä
\82à" : "",
661 dist > 2 ? "
\90[
\82¢" : "");
666 Sprintf(msgbuf, "The hole in the %s above you closes up.",
668 Sprintf(msgbuf, "%s
\82É
\8aJ
\82¢
\82½
\8c\8a\82Í
\95Â
\82¶
\82½
\81D",
669 ceiling(u.ux, u.uy));
671 schedule_goto(&dtmp, FALSE, TRUE, 0, (char *) 0,
672 !td ? msgbuf : (char *) 0);
676 * Animate the given statue. May have been via shatter attempt, trap,
677 * or stone to flesh spell. Return a monster if successfully animated.
678 * If the monster is animated, the object is deleted. If fail_reason
679 * is non-null, then fill in the reason for failure (or success).
681 * The cause of animation is:
683 * ANIMATE_NORMAL - hero "finds" the monster
684 * ANIMATE_SHATTER - hero tries to destroy the statue
685 * ANIMATE_SPELL - stone to flesh spell hits the statue
687 * Perhaps x, y is not needed if we can use get_obj_location() to find
688 * the statue's location... ???
690 * Sequencing matters:
691 * create monster; if it fails, give up with statue intact;
692 * give "statue comes to life" message;
693 * if statue belongs to shop, have shk give "you owe" message;
694 * transfer statue contents to monster (after stolen_value());
696 * [This ordering means that if the statue ends up wearing a cloak of
697 * invisibility or a mummy wrapping, the visibility checks might be
698 * wrong, but to avoid that we'd have to clone the statue contents
699 * first in order to give them to the monster before checking their
700 * shop status--it's not worth the hassle.]
703 animate_statue(statue, x, y, cause, fail_reason)
709 int mnum = statue->corpsenm;
710 struct permonst *mptr = &mons[mnum];
711 struct monst *mon = 0, *shkp;
714 boolean historic = (Role_if(PM_ARCHEOLOGIST)
715 && (statue->spe & STATUE_HISTORIC) != 0),
716 golem_xform = FALSE, use_saved_traits;
717 const char *comes_to_life;
718 char statuename[BUFSZ], tmpbuf[BUFSZ];
719 static const char historic_statue_is_gone[] =
721 "that the historic statue is now gone";
723 "
\97ð
\8ej
\93I
\82È
\92¤
\91\9c\82ª
\82È
\82
\82È
\82Á
\82Ä
\82µ
\82Ü
\82Á
\82½
\82±
\82Æ";
725 if (cant_revive(&mnum, TRUE, statue)) {
726 /* mnum has changed; we won't be animating this statue as itself */
727 if (mnum != PM_DOPPELGANGER)
729 use_saved_traits = FALSE;
730 } else if (is_golem(mptr) && cause == ANIMATE_SPELL) {
731 /* statue of any golem hit by stone-to-flesh becomes flesh golem */
732 golem_xform = (mptr != &mons[PM_FLESH_GOLEM]);
733 mnum = PM_FLESH_GOLEM;
734 mptr = &mons[PM_FLESH_GOLEM];
735 use_saved_traits = (has_omonst(statue) && !golem_xform);
737 use_saved_traits = has_omonst(statue);
740 if (use_saved_traits) {
741 /* restore a petrified monster */
743 mon = montraits(statue, &cc, (cause == ANIMATE_SPELL));
744 if (mon && mon->mtame && !mon->isminion)
747 /* statues of unique monsters from bones or wishing end
748 up here (cant_revive() sets mnum to be doppelganger;
749 mptr reflects the original form for use by newcham()) */
750 if ((mnum == PM_DOPPELGANGER && mptr != &mons[PM_DOPPELGANGER])
751 /* block quest guards from other roles */
752 || (mptr->msound == MS_GUARDIAN
753 && quest_info(MS_GUARDIAN) != mnum)) {
754 mon = makemon(&mons[PM_DOPPELGANGER], x, y,
755 NO_MINVENT | MM_NOCOUNTBIRTH | MM_ADJACENTOK);
756 /* if hero has protection from shape changers, cham field will
757 be NON_PM; otherwise, set form to match the statue */
758 if (mon && mon->cham >= LOW_PM)
759 (void) newcham(mon, mptr, FALSE, FALSE);
761 mon = makemon(mptr, x, y, (cause == ANIMATE_SPELL)
762 ? (NO_MINVENT | MM_ADJACENTOK)
768 *fail_reason = unique_corpstat(&mons[statue->corpsenm])
771 return (struct monst *) 0;
774 /* a non-montraits() statue might specify gender */
775 if (statue->spe & STATUE_MALE)
777 else if (statue->spe & STATUE_FEMALE)
779 /* if statue has been named, give same name to the monster */
780 if (has_oname(statue) && !unique_corpstat(mon->data))
781 mon = christen_monst(mon, ONAME(statue));
782 /* mimic statue becomes seen mimic; other hiders won't be hidden */
786 mon->mundetected = FALSE;
788 if (cause == ANIMATE_NORMAL || cause == ANIMATE_SHATTER) {
789 /* trap always releases hostile monster */
790 mon->mtame = 0; /* (might be petrified pet tossed onto trap) */
796 comes_to_life = !canspotmon(mon)
800 : (nonliving(mon->data) || is_vampshifter(mon))
804 comes_to_life = !canspotmon(mon)
807 ? "
\93÷
\91Ì
\82É
\96ß
\82Á"
808 : (nonliving(mon->data) || is_vampshifter(mon))
810 : "
\90¶
\96½
\82ð
\91Ñ
\82Ñ";
812 if ((x == u.ux && y == u.uy) || cause == ANIMATE_SPELL) {
813 /* "the|your|Manlobbi's statue [of a wombat]" */
814 shkp = shop_keeper(*in_rooms(mon->mx, mon->my, SHOPBASE));
816 Sprintf(statuename, "%s%s", shk_your(tmpbuf, statue),
817 (cause == ANIMATE_SPELL
818 /* avoid "of a shopkeeper" if it's Manlobbi himself
819 (if carried, it can't be unpaid--hence won't be
820 described as "Manlobbi's statue"--because there
821 wasn't any living shk when statue was picked up) */
822 && (mon != shkp || carried(statue)))
826 Sprintf(statuename, "%s%s", shk_your(tmpbuf, statue),
827 (cause == ANIMATE_SPELL
828 && (mon != shkp || carried(statue)))
833 pline("%s %s!", upstart(statuename), comes_to_life);
835 pline("%s
\82Í%s
\82½
\81I", upstart(statuename), comes_to_life);
836 } else if (Hallucination) { /* They don't know it's a statue */
838 pline_The("%s suddenly seems more animated.", rndmonnam((char *) 0));
840 pline_The("%s
\82Í
\93Ë
\91R
\82æ
\82è
\8a\88\93®
\93I
\82É
\82È
\82Á
\82½
\81D", rndmonnam((char *) 0));
841 } else if (cause == ANIMATE_SHATTER) {
843 Sprintf(statuename, "%s%s", shk_your(tmpbuf, statue),
847 Strcpy(statuename, "a statue");
849 Strcpy(statuename, "
\92¤
\91\9c");
851 pline("Instead of shattering, %s suddenly %s!", statuename,
854 pline("%s
\82Í
\8dÓ
\82¯
\82¸
\82É%s
\82½
\81I", statuename,
857 } else { /* cause == ANIMATE_NORMAL */
859 You("find %s posing as a statue.",
861 You("%s
\82ª
\92¤
\91\9c\82Ì
\82Ó
\82è
\82ð
\82µ
\82Ä
\82¢
\82é
\82Ì
\82ð
\8c©
\82Â
\82¯
\82½
\81D",
862 canspotmon(mon) ? a_monnam(mon) : something);
863 if (!canspotmon(mon) && Blind)
868 /* if this isn't caused by a monster using a wand of striking,
869 there might be consequences for the hero */
870 if (!context.mon_moving) {
871 /* if statue is owned by a shop, hero will have to pay for it;
872 stolen_value gives a message (about debt or use of credit)
873 which refers to "it" so needs to follow a message describing
874 the object ("the statue comes to life" one above) */
875 if (cause != ANIMATE_NORMAL && costly_spot(x, y)
876 && (carried(statue) ? statue->unpaid : !statue->no_charge)
877 && (shkp = shop_keeper(*in_rooms(x, y, SHOPBASE))) != 0
878 /* avoid charging for Manlobbi's statue of Manlobbi
879 if stone-to-flesh is used on petrified shopkeep */
881 (void) stolen_value(statue, x, y, (boolean) shkp->mpeaceful,
886 You_feel("guilty %s.", historic_statue_is_gone);
888 You_feel("%s
\82É
\8dß
\82ð
\8a´
\82¶
\82½
\81D", historic_statue_is_gone);
892 if (historic && cansee(x, y))
894 You_feel("regret %s.", historic_statue_is_gone);
896 You_feel("%s
\82ð
\8cã
\89÷
\82µ
\82½
\81D", historic_statue_is_gone);
897 /* no alignment penalty */
900 /* transfer any statue contents to monster's inventory */
901 while ((item = statue->cobj) != 0) {
902 obj_extract_self(item);
903 (void) mpickobj(mon, item);
906 /* in case statue is wielded and hero zaps stone-to-flesh at self */
907 if (statue->owornmask)
908 remove_worn_item(statue, TRUE);
909 /* statue no longer exists */
912 /* avoid hiding under nothing */
913 if (x == u.ux && y == u.uy && Upolyd && hides_under(youmonst.data)
918 *fail_reason = AS_OK;
923 * You've either stepped onto a statue trap's location or you've triggered a
924 * statue trap by searching next to it or by trying to break it with a wand
928 activate_statue_trap(trap, x, y, shatter)
933 struct monst *mtmp = (struct monst *) 0;
934 struct obj *otmp = sobj_at(STATUE, x, y);
938 * Try to animate the first valid statue. Stop the loop when we
939 * actually create something or the failure cause is not because
940 * the mon was unique.
944 mtmp = animate_statue(otmp, x, y,
945 shatter ? ANIMATE_SHATTER : ANIMATE_NORMAL,
947 if (mtmp || fail_reason != AS_MON_IS_UNIQUE)
950 otmp = nxtobj(otmp, STATUE, TRUE);
958 keep_saddle_with_steedcorpse(steed_mid, objchn, saddle)
960 struct obj *objchn, *saddle;
965 if (objchn->otyp == CORPSE && has_omonst(objchn)) {
966 struct monst *mtmp = OMONST(objchn);
968 if (mtmp->m_id == steed_mid) {
971 if (get_obj_location(objchn, &x, &y, 0)) {
972 obj_extract_self(saddle);
973 place_object(saddle, x, y);
979 if (Has_contents(objchn)
980 && keep_saddle_with_steedcorpse(steed_mid, objchn->cobj, saddle))
982 objchn = objchn->nobj;
987 /* monster or you go through and possibly destroy a web.
988 return TRUE if could go through. */
990 mu_maybe_destroy_web(mtmp, domsg, trap)
995 boolean isyou = (mtmp == &youmonst);
996 struct permonst *mptr = mtmp->data;
998 if (amorphous(mptr) || is_whirly(mptr) || flaming(mptr)
999 || unsolid(mptr) || mptr == &mons[PM_GELATINOUS_CUBE]) {
1003 if (flaming(mptr) || acidic(mptr)) {
1007 You("%s %s spider web!",
1008 (flaming(mptr)) ? "burn" : "dissolve",
1009 a_your[trap->madeby_u]);
1011 You("%s
\82
\82à
\82Ì
\91\83\82ð%s
\81I",
1012 web_you[trap->madeby_u],
1013 (flaming(mptr)) ? "
\8fÄ
\82¢
\82½" : "
\82±
\82È
\82²
\82È
\82É
\82µ
\82½");
1017 pline("%s %s %s spider web!", Monnam(mtmp),
1018 (flaming(mptr)) ? "burns" : "dissolves",
1019 a_your[trap->madeby_u]);
1021 pline("%s%s
\82
\82à
\82Ì
\91\83\82ð%s
\81I", Monnam(mtmp),
1022 web_you[trap->madeby_u],
1023 (flaming(mptr)) ? "
\8fÄ
\82¢
\82½" : "
\82±
\82È
\82²
\82È
\82É
\82µ
\82½");
1033 You("flow through %s spider web.", a_your[trap->madeby_u]);
1035 You("%s
\82
\82à
\82Ì
\91\83\82ð
\82·
\82é
\82è
\82Æ
\92Ê
\82è
\94²
\82¯
\82½
\81D", web_you[trap->madeby_u]);
1038 pline("%s flows through %s spider web.", Monnam(mtmp),
1039 a_your[trap->madeby_u]);
1041 pline("%s
\82Í%s
\82
\82à
\82Ì
\91\83\82ð
\82·
\82é
\82è
\82Æ
\92Ê
\82è
\94²
\82¯
\82½
\81D", Monnam(mtmp),
1042 web_you[trap->madeby_u]);
1052 /* make a single arrow/dart/rock for a trap to shoot or drop */
1053 STATIC_OVL struct obj *
1054 t_missile(otyp, trap)
1058 struct obj *otmp = mksobj(otyp, TRUE, FALSE);
1061 otmp->owt = weight(otmp);
1062 otmp->opoisoned = 0;
1063 otmp->ox = trap->tx, otmp->oy = trap->ty;
1073 * utraptype==0 is bear trap rather than 'none'; we probably ought
1074 * to change that but can't do so until save file compatability is
1075 * able to be broken.
1077 u.utraptype = tim ? typ : 0;
1079 float_vs_flight(); /* maybe block Lev and/or Fly */
1086 boolean was_Lev = (Levitation != 0), was_Fly = (Flying != 0);
1091 if (!was_Lev && Levitation)
1093 if (!was_Fly && Flying)
1097 You("
\94ò
\82×
\82é
\82æ
\82¤
\82É
\82È
\82Á
\82½
\81D");
1102 dotrap(trap, trflags)
1103 register struct trap *trap;
1106 register int ttype = trap->ttyp;
1108 boolean already_seen = trap->tseen,
1109 forcetrap = ((trflags & FORCETRAP) != 0
1110 || (trflags & FAILEDUNTRAP) != 0),
1111 webmsgok = (trflags & NOWEBMSG) == 0,
1112 forcebungle = (trflags & FORCEBUNGLE) != 0,
1113 plunged = (trflags & TOOKPLUNGE) != 0,
1114 viasitting = (trflags & VIASITTING) != 0,
1115 conj_pit = conjoined_pits(trap, t_at(u.ux0, u.uy0), TRUE),
1116 adj_pit = adj_nonconjoined_pit(trap);
1118 int steed_article = ARTICLE_THE;
1122 /* KMH -- You can't escape the Sokoban level traps */
1123 if (Sokoban && (is_pit(ttype) || is_hole(ttype))) {
1124 /* The "air currents" message is still appropriate -- even when
1125 * the hero isn't flying or levitating -- because it conveys the
1126 * reason why the player cannot escape the trap with a dexterity
1127 * check, clinging to the ceiling, etc.
1130 pline("Air currents pull you down into %s %s!",
1131 a_your[trap->madeby_u],
1132 defsyms[trap_to_defsym(ttype)].explanation);
1134 pline("
\8bó
\8bC
\82Ì
\97¬
\82ê
\82ª
\82 \82È
\82½
\82ð%s
\82É
\88ø
\82«
\96ß
\82µ
\82½
\81I",
1135 defsyms[trap_to_defsym(ttype)].explanation);
1137 /* then proceed to normal trap effect */
1138 } else if (already_seen && !forcetrap) {
1139 if ((Levitation || (Flying && !plunged))
1140 && (is_pit(ttype) || ttype == HOLE || ttype == BEAR_TRAP)) {
1142 You("%s over %s %s.", Levitation ? "float" : "fly",
1143 a_your[trap->madeby_u],
1144 defsyms[trap_to_defsym(ttype)].explanation);
1146 You("%s%s
\82Ì
\8fã%s
\81D",
1147 set_you[trap->madeby_u],
1148 defsyms[trap_to_defsym(ttype)].explanation,
1149 Levitation ? "
\82ð
\8c©
\89º
\82ë
\82µ
\82½" : "
\82ð
\94ò
\82ñ
\82Å
\82¢
\82é");
1153 if (!Fumbling && ttype != MAGIC_PORTAL && ttype != VIBRATING_SQUARE
1154 && ttype != ANTI_MAGIC && !forcebungle && !plunged
1155 && !conj_pit && !adj_pit
1156 && (!rn2(5) || (is_pit(ttype)
1157 && is_clinger(youmonst.data)))) {
1159 You("escape %s %s.", (ttype == ARROW_TRAP && !trap->madeby_u)
1161 : a_your[trap->madeby_u],
1162 defsyms[trap_to_defsym(ttype)].explanation);
1164 You("%s%s
\82ð
\82·
\82é
\82è
\82Æ
\94ð
\82¯
\82½
\81D",
1165 set_you[trap->madeby_u],
1166 defsyms[trap_to_defsym(ttype)].explanation);
1173 u.usteed->mtrapseen |= (1 << (ttype - 1));
1174 /* suppress article in various steed messages when using its
1175 name (which won't occur when hallucinating) */
1176 if (has_mname(u.usteed) && !Hallucination)
1177 steed_article = ARTICLE_NONE;
1182 if (trap->once && trap->tseen && !rn2(15)) {
1184 You_hear("a loud click!");
1186 You_hear("
\83K
\83`
\83\83\83b
\82Æ
\82¢
\82¤
\91å
\82«
\82È
\89¹
\82ð
\95·
\82¢
\82½
\81I");
1194 pline("An arrow shoots out at you!");
1196 pline("
\96î
\82ª
\94ò
\82ñ
\82Å
\82«
\82½
\81I");
1197 otmp = t_missile(ARROW, trap);
1198 if (u.usteed && !rn2(2) && steedintrap(trap, otmp)) {
1201 } else if (thitu(8, dmgval(otmp, &youmonst), &otmp, "arrow")) {
1203 } else if (thitu(8, dmgval(otmp, &youmonst), &otmp, "
\96î")) {
1206 obfree(otmp, (struct obj *) 0);
1208 place_object(otmp, u.ux, u.uy);
1217 if (trap->once && trap->tseen && !rn2(15)) {
1219 You_hear("a soft click.");
1221 You_hear("
\83J
\83`
\83b
\82Æ
\82¢
\82¤
\89¹
\82ð
\95·
\82¢
\82½
\81D");
1229 pline("A little dart shoots out at you!");
1231 pline("
\8f¬
\82³
\82È
\93\8a\82°
\96î
\82ª
\94ò
\82ñ
\82Å
\82«
\82½
\81I");
1232 otmp = t_missile(DART, trap);
1234 otmp->opoisoned = 1;
1235 oldumort = u.umortality;
1236 if (u.usteed && !rn2(2) && steedintrap(trap, otmp)) {
1239 } else if (thitu(7, dmgval(otmp, &youmonst), &otmp, "little dart")) {
1241 } else if (thitu(7, dmgval(otmp, &youmonst), &otmp, "
\93\8a\82°
\96î")) {
1244 if (otmp->opoisoned)
1246 poisoned("dart", A_CON, "little dart",
1247 /* if damage triggered life-saving,
1248 poison is limited to attrib loss */
1249 (u.umortality > oldumort) ? 0 : 10, TRUE);
1251 poisoned("
\93\8a\82°
\96î", A_CON, "
\8f¬
\82³
\82È
\93\8a\82°
\96î",
1252 /* if damage triggered life-saving,
1253 poison is limited to attrib loss */
1254 (u.umortality > oldumort) ? 0 : 10, TRUE);
1256 obfree(otmp, (struct obj *) 0);
1259 place_object(otmp, u.ux, u.uy);
1268 if (trap->once && trap->tseen && !rn2(15)) {
1270 pline("A trap door in %s opens, but nothing falls out!",
1272 pline("
\97\8e\82µ
\94à
\82ª%s
\82É
\8aJ
\82¢
\82½
\82ª
\81C
\89½
\82à
\97\8e\82¿
\82Ä
\82±
\82È
\82©
\82Á
\82½
\81I",
1273 the(ceiling(u.ux, u.uy)));
1277 int dmg = d(2, 6); /* should be std ROCK dmg? */
1281 otmp = t_missile(ROCK, trap);
1282 place_object(otmp, u.ux, u.uy);
1285 pline("A trap door in %s opens and %s falls on your %s!",
1286 the(ceiling(u.ux, u.uy)), an(xname(otmp)), body_part(HEAD));
1288 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",
1289 ceiling(u.ux,u.uy), xname(otmp), body_part(HEAD));
1292 if (is_metallic(uarmh)) {
1294 pline("Fortunately, you are wearing a hard helmet.");
1296 pline("
\8dK
\89^
\82É
\82à
\81C
\82 \82È
\82½
\82Í
\8cÅ
\82¢
\8a\95\82ð
\90g
\82É
\82Â
\82¯
\82Ä
\82¢
\82½
\81D");
1298 } else if (flags.verbose) {
1300 pline("%s does not protect you.", Yname2(uarmh));
1302 pline("%s
\82Å
\82Í
\96h
\82°
\82È
\82¢
\81D", xname(uarmh));
1308 newsym(u.ux, u.uy); /* map the rock */
1311 losehp(Maybe_Half_Phys(dmg), "falling rock", KILLED_BY_AN);
1313 losehp(Maybe_Half_Phys(dmg), "
\97\8e\8aâ
\82Å", KILLED_BY_AN);
1314 exercise(A_STR, FALSE);
1318 case SQKY_BOARD: /* stepped on a squeaky board */
1319 if ((Levitation || Flying) && !forcetrap) {
1324 You("notice a crease in the linoleum.");
1326 You("
\8f°
\82Ì
\8ed
\8fã
\8dÞ
\82Ì
\82µ
\82í
\82É
\8bC
\82ª
\82Â
\82¢
\82½
\81D");
1329 You("notice a loose board below you.");
1331 You("
\91«
\8c³
\82Ì
\8aÉ
\82ñ
\82¾
\94Â
\82É
\8bC
\82ª
\82Â
\82¢
\82½
\81D");
1336 pline("A board beneath you %s%s%s.",
1337 Deaf ? "vibrates" : "squeaks ",
1338 Deaf ? "" : trapnote(trap, 0), Deaf ? "" : " loudly");
1341 pline("
\91«
\8c³
\82Ì
\94Â
\82ª
\82ä
\82ê
\82½
\81D");
1343 pline("
\91«
\8c³
\82Ì
\94Â
\82ª
\91å
\82«
\82%s
\82Ì
\89¹
\82É
\82«
\82µ
\82ñ
\82¾
\81D", trapnote(trap, 0));
1353 if ((Levitation || Flying) && !forcetrap)
1356 if (amorphous(youmonst.data) || is_whirly(youmonst.data)
1357 || unsolid(youmonst.data)) {
1359 pline("%s bear trap closes harmlessly through you.",
1360 A_Your[trap->madeby_u]);
1362 pline("%s
\8cF
\82Ìã©
\82Í
\8a\9a\82Ý
\82Â
\82¢
\82½
\82ª
\81C
\82·
\82é
\82Á
\82Æ
\92Ê
\82è
\94²
\82¯
\82½
\81D",
1363 set_you[trap->madeby_u]);
1367 if (!u.usteed && youmonst.data->msize <= MZ_SMALL) {
1369 pline("%s bear trap closes harmlessly over you.",
1370 A_Your[trap->madeby_u]);
1372 pline("%s
\8cF
\82Ìã©
\82Í
\8a\9a\82Ý
\82Â
\82¢
\82½
\82ª
\81C
\97y
\82©
\8fã
\95û
\82¾
\82Á
\82½
\81D",
1373 set_you[trap->madeby_u]);
1377 set_utrap((unsigned) rn1(4, 4), TT_BEARTRAP);
1380 pline("%s bear trap closes on %s %s!", A_Your[trap->madeby_u],
1381 s_suffix(mon_nam(u.usteed)), mbodypart(u.usteed, FOOT));
1383 pline("%s
\8cF
\82Ìã©
\82Í%s
\82Ì%s
\82É
\8a\9a\82Ý
\82Â
\82¢
\82½
\81I", set_you[trap->madeby_u],
1384 mon_nam(u.usteed), mbodypart(u.usteed, FOOT));
1386 if (thitm(0, u.usteed, (struct obj *) 0, dmg, FALSE))
1387 reset_utrap(TRUE); /* steed died, hero not trapped */
1390 pline("%s bear trap closes on your %s!", A_Your[trap->madeby_u],
1393 pline("%s
\8cF
\82Ìã©
\82ª
\82 \82È
\82½
\82Ì%s
\82É
\8a\9a\82Ý
\82Â
\82¢
\82½
\81I", set_you[trap->madeby_u],
1396 set_wounded_legs(rn2(2) ? RIGHT_SIDE : LEFT_SIDE, rn1(10, 10));
1397 if (u.umonnum == PM_OWLBEAR || u.umonnum == PM_BUGBEAR)
1399 You("howl in anger!");
1401 You("
\93{
\82è
\82Ì
\99ô
\9aK
\82ð
\82 \82°
\82½
\81I");
1403 losehp(Maybe_Half_Phys(dmg), "bear trap", KILLED_BY_AN);
1405 losehp(Maybe_Half_Phys(dmg), "
\8cF
\82Ìã©
\82Å", KILLED_BY_AN);
1407 exercise(A_DEX, FALSE);
1413 if (Sleep_resistance || breathless(youmonst.data)) {
1415 You("are enveloped in a cloud of gas!");
1417 You("
\83K
\83X
\89_
\82É
\82Â
\82Â
\82Ü
\82ê
\82½
\81I");
1420 pline("A cloud of gas puts you to sleep!");
1422 pline("
\82 \82È
\82½
\82Í
\83K
\83X
\89_
\82Å
\96°
\82Á
\82Ä
\82µ
\82Ü
\82Á
\82½
\81I");
1423 fall_asleep(-rnd(25), TRUE);
1425 (void) steedintrap(trap, (struct obj *) 0);
1431 /* Unlike monsters, traps cannot aim their rust attacks at
1432 * you, so instead of looping through and taking either the
1433 * first rustable one or the body, we take whatever we get,
1434 * even if it is not rustable.
1439 pline("%s you on the %s!", A_gush_of_water_hits, body_part(HEAD));
1441 pline("
\90\85\82ª
\95¬
\8fo
\82µ
\82Ä
\82 \82È
\82½
\82Ì%s
\82É
\96½
\92\86\82µ
\82½
\81I", body_part(HEAD));
1442 (void) water_damage(uarmh, helm_simple_name(uarmh), TRUE);
1446 pline("%s your left %s!", A_gush_of_water_hits, body_part(ARM));
1448 pline("
\90\85\82ª
\95¬
\8fo
\82µ
\82Ä
\82 \82È
\82½
\82Ì
\8d¶%s
\82É
\96½
\92\86\82µ
\82½
\81I", body_part(ARM));
1450 if (water_damage(uarms, "shield", TRUE) != ER_NOTHING)
1452 if (water_damage(uarms, "
\8f\82", TRUE) != ER_NOTHING)
1454 if (u.twoweap || (uwep && bimanual(uwep)))
1455 (void) water_damage(u.twoweap ? uswapwep : uwep, 0, TRUE);
1458 (void) water_damage(uarmg, "gauntlets", TRUE);
1460 (void) water_damage(uarmg, "
\8f¬
\8eè", TRUE);
1461 /* Not "metal gauntlets" since it gets called
1462 * even if it's leather for the message
1467 pline("%s your right %s!", A_gush_of_water_hits, body_part(ARM));
1469 pline("
\90\85\82ª
\95¬
\8fo
\82µ
\82Ä
\82 \82È
\82½
\82Ì
\89E%s
\82É
\96½
\92\86\82µ
\82½
\81I", body_part(ARM));
1470 (void) water_damage(uwep, 0, TRUE);
1474 pline("%s you!", A_gush_of_water_hits);
1476 pline("
\90\85\82ª
\95¬
\8fo
\82µ
\82Ä
\82 \82È
\82½
\82É
\96½
\92\86\82µ
\82½
\81I");
1477 for (otmp = invent; otmp; otmp = otmp->nobj)
1478 if (otmp->lamplit && otmp != uwep
1479 && (otmp != uswapwep || !u.twoweap))
1480 (void) snuff_lit(otmp);
1482 (void) water_damage(uarmc, cloak_simple_name(uarmc), TRUE);
1484 (void) water_damage(uarm, suit_simple_name(uarm), TRUE);
1487 (void) water_damage(uarmu, "shirt", TRUE);
1489 (void) water_damage(uarmu, "
\83V
\83\83\83c", TRUE);
1493 if (u.umonnum == PM_IRON_GOLEM) {
1497 You("are covered with rust!");
1499 You("
\8eK
\82É
\95¢
\82í
\82ê
\82½
\81I");
1501 losehp(Maybe_Half_Phys(dam), "rusting away", KILLED_BY);
1503 losehp(Maybe_Half_Phys(dam), "
\8a®
\91S
\82É
\8eK
\82Ñ
\82Ä", KILLED_BY);
1504 } else if (u.umonnum == PM_GREMLIN && rn2(3)) {
1505 (void) split_mon(&youmonst, (struct monst *) 0);
1512 dofiretrap((struct obj *) 0);
1517 /* KMH -- You can't escape the Sokoban level traps */
1518 if (!Sokoban && (Levitation || (Flying && !plunged)))
1521 if (!Sokoban && is_clinger(youmonst.data) && !plunged) {
1524 You_see("%s %spit below you.", a_your[trap->madeby_u],
1525 ttype == SPIKED_PIT ? "spiked " : "");
1527 pline("
\91«
\8c³
\82É%s%s
\97\8e\82µ
\8c\8a\82ð
\94
\8c©
\82µ
\82½
\81D", dig_you[trap->madeby_u],
1528 ttype == SPIKED_PIT ? "
\83g
\83Q
\82¾
\82ç
\82¯
\82Ì" : "");
1532 pline("%s pit %sopens up under you!", A_Your[trap->madeby_u],
1533 ttype == SPIKED_PIT ? "full of spikes " : "");
1535 pline("%s%s
\97\8e\82µ
\8c\8a\82ª
\91«
\8c³
\82É
\8aJ
\82¢
\82½
\81I", dig_you[trap->madeby_u],
1536 ttype == SPIKED_PIT ? "
\83g
\83Q
\82¾
\82ç
\82¯
\82Ì" : "");
1539 You("don't fall in!");
1541 pline("
\82µ
\82©
\82µ
\81C
\82 \82È
\82½
\82Í
\97\8e\82¿
\82È
\82©
\82Á
\82½
\81I");
1546 char verbbuf[BUFSZ];
1550 if ((trflags & RECURSIVETRAP) != 0)
1552 Sprintf(verbbuf, "and %s fall",
1554 Sprintf(verbbuf, "
\82Æ%s",
1555 x_monnam(u.usteed, steed_article, (char *) 0,
1556 SUPPRESS_SADDLE, FALSE));
1559 Sprintf(verbbuf, "lead %s",
1560 x_monnam(u.usteed, steed_article, "poor",
1561 SUPPRESS_SADDLE, FALSE));
1563 Sprintf(verbbuf, "
\82Æ%s",
1564 x_monnam(u.usteed, steed_article, "
\82©
\82í
\82¢
\82»
\82¤
\82È",
1565 SUPPRESS_SADDLE, FALSE));
1567 } else if (conj_pit) {
1569 You("move into an adjacent pit.");
1571 You("
\97×
\82Ì
\97\8e\82µ
\8c\8a\82É
\88Ú
\93®
\82µ
\82½
\81D");
1572 } else if (adj_pit) {
1574 You("stumble over debris%s.",
1575 !rn2(5) ? " between the pits" : "");
1577 You("
\82Í%s
\82ª
\82ç
\82
\82½
\82Å
\82Â
\82Ü
\82Ã
\82¢
\82½
\81D",
1578 !rn2(5) ? "
\97\8e\82µ
\8c\8a\82Ì" : "");
1583 !plunged ? "fall" : (Flying ? "dive" : "plunge"));
1586 !plunged ? "
\97\8e\82¿
\82½" : (Flying ? "
\94ò
\82Ñ
\8d\9e\82ñ
\82¾" : "
\93Ë
\93ü
\82µ
\82½"));
1591 You("%s into %s pit!", verbbuf, a_your[trap->madeby_u]);
1593 You("%s
\97\8e\82µ
\8c\8a\82É%s!", set_you[trap->madeby_u], verbbuf);
1595 /* wumpus reference */
1596 if (Role_if(PM_RANGER) && !trap->madeby_u && !trap->once
1597 && In_quest(&u.uz) && Is_qlocate(&u.uz)) {
1599 pline("Fortunately it has a bottom after all...");
1601 pline("
\8dK
\82¢
\81C
\8c\8b\8bÇ
\82Í
\92ê
\82ª
\82 \82Á
\82½
\81D
\81D
\81D");
1603 } else if (u.umonnum == PM_PIT_VIPER || u.umonnum == PM_PIT_FIEND) {
1605 pline("How pitiful. Isn't that the pits?");
1607 pline("
\82±
\82Ì
\97\8e\82µ
\8c\8a\82Í
\82¢
\82¢
\8ed
\8e\96\82ð
\82µ
\82Ä
\82¢
\82é
\81D");
1609 if (ttype == SPIKED_PIT) {
1611 const char *predicament = "on a set of sharp iron spikes";
1613 const char *predicament = "
\89s
\82¢
\93S
\82Ì
\83g
\83Q
\83g
\83Q
\82Ì
\8fã
\82É";
1618 upstart(x_monnam(u.usteed, steed_article, "poor",
1619 SUPPRESS_SADDLE, FALSE)),
1620 conj_pit ? "steps" : "lands", predicament);
1622 pline("%s
\82Í%s%s
\81I",
1623 upstart(x_monnam(u.usteed, steed_article, "
\82©
\82í
\82¢
\82»
\82¤
\82È",
1624 SUPPRESS_SADDLE, FALSE)),
1625 predicament, conj_pit ? "
\97\8e\82¿
\82½" : "
\8d~
\82è
\82½");
1629 You("%s %s!", conj_pit ? "step" : "land", predicament);
1631 You("%s%s
\81I", predicament, conj_pit ? "
\97\8e\82¿
\82½" : "
\8d~
\82è
\82½");
1634 * if hero gets killed here, setting u.utrap in advance will
1635 * show "you were trapped in a pit" during disclosure's display
1636 * of enlightenment, but hero is dying *before* becoming trapped.
1638 set_utrap((unsigned) rn1(6, 2), TT_PIT);
1639 if (!steedintrap(trap, (struct obj *) 0)) {
1640 if (ttype == SPIKED_PIT) {
1641 oldumort = u.umortality;
1643 losehp(Maybe_Half_Phys(rnd(conj_pit ? 4 : adj_pit ? 6 : 10)),
1644 /* note: these don't need locomotion() handling;
1645 if fatal while poly'd and Unchanging, the
1646 death reason will be overridden with
1647 "killed while stuck in creature form" */
1649 ? "deliberately plunged into a pit of iron spikes"
1651 ? "stepped into a pit of iron spikes"
1653 ? "stumbled into a pit of iron spikes"
1654 : "fell into a pit of iron spikes",
1657 losehp(Maybe_Half_Phys(rnd(conj_pit ? 4 : adj_pit ? 6 : 10)),
1659 ? "
\82í
\82´
\82í
\82´
\83g
\83Q
\82¾
\82ç
\82¯
\82Ì
\97\8e\82µ
\8c\8a\82É
\93Ë
\93ü
\82µ
\82Ä"
1661 ? "
\83g
\83Q
\82¾
\82ç
\82¯
\82Ì
\97\8e\82µ
\8c\8a\82É
\93¥
\82Ý
\8d\9e\82ñ
\82Å"
1663 ? "
\83g
\83Q
\82¾
\82ç
\82¯
\82Ì
\97\8e\82µ
\8c\8a\82É
\82æ
\82ë
\82ß
\82«
\97\8e\82¿
\82Ä"
1664 : "
\83g
\83Q
\82¾
\82ç
\82¯
\82Ì
\97\8e\82µ
\8c\8a\82É
\97\8e\82¿
\82Ä",
1669 poisoned("spikes", A_STR,
1670 (conj_pit || adj_pit)
1671 ? "stepping on poison spikes"
1672 : "fall onto poison spikes",
1673 /* if damage triggered life-saving,
1674 poison is limited to attrib loss */
1675 (u.umortality > oldumort) ? 0 : 8, FALSE);
1677 poisoned("
\83g
\83Q", A_STR,
1678 (conj_pit || adj_pit)
1679 ? "
\93Å
\82Ì
\93h
\82ç
\82ê
\82½
\83g
\83Q
\82ð
\93¥
\82ñ
\82Å"
1680 : "
\93Å
\82Ì
\93h
\82ç
\82ê
\82½
\83g
\83Q
\82Ì
\8fã
\82É
\97\8e\82¿
\82Ä",
1681 /* if damage triggered life-saving,
1682 poison is limited to attrib loss */
1683 (u.umortality > oldumort) ? 0 : 8, FALSE);
1686 /* plunging flyers take spike damage but not pit damage */
1688 && !(plunged && (Flying || is_clinger(youmonst.data))))
1690 losehp(Maybe_Half_Phys(rnd(adj_pit ? 3 : 6)),
1691 plunged ? "deliberately plunged into a pit"
1692 : "fell into a pit",
1695 losehp(Maybe_Half_Phys(rnd(adj_pit ? 3 : 6)),
1696 plunged ? "
\82í
\82´
\82í
\82´
\97\8e\82µ
\8c\8a\82É
\93Ë
\93ü
\82µ
\82Ä"
1697 : "
\97\8e\82µ
\8c\8a\82É
\97\8e\82¿
\82Ä",
1701 if (Punished && !carried(uball)) {
1708 selftouch("Falling, you");
1710 selftouch("
\97\8e\89º
\92\86\81C
\82 \82È
\82½
\82Í");
1711 vision_full_recalc = 1; /* vision limits change */
1712 exercise(A_STR, FALSE);
1713 exercise(A_DEX, FALSE);
1719 if (!Can_fall_thru(&u.uz)) {
1720 seetrap(trap); /* normally done in fall_through */
1721 impossible("dotrap: %ss cannot exist on this level.",
1722 defsyms[trap_to_defsym(ttype)].explanation);
1723 break; /* don't activate it after all */
1735 level_tele_trap(trap, trflags);
1738 case WEB: /* Our luckless player has stumbled into a web. */
1740 if (mu_maybe_destroy_web(&youmonst, webmsgok, trap))
1742 if (webmaker(youmonst.data)) {
1745 pline(trap->madeby_u ? "You take a walk on your web."
1746 : "There is a spider web here.");
1748 pline(trap->madeby_u ? "
\8e©
\95ª
\82Å
\92£
\82Á
\82½
\82
\82à
\82Ì
\91\83\82Ì
\8fã
\82ð
\95à
\82¢
\82½
\81D"
1749 : "
\82±
\82±
\82É
\82Í
\82
\82à
\82Ì
\91\83\82ª
\82 \82é
\81D");
1754 char verbbuf[BUFSZ];
1757 if (forcetrap || viasitting) {
1758 Strcpy(verbbuf, "are caught by");
1759 } else if (u.usteed) {
1760 Sprintf(verbbuf, "lead %s into",
1761 x_monnam(u.usteed, steed_article, "poor",
1762 SUPPRESS_SADDLE, FALSE));
1764 Sprintf(verbbuf, "%s into",
1765 Levitation ? (const char *) "float"
1766 : locomotion(youmonst.data, "stumble"));
1768 You("%s %s spider web!", verbbuf, a_your[trap->madeby_u]);
1771 Strcpy(verbbuf, "
\82 \82È
\82½
\82Í");
1772 } else if (u.usteed) {
1773 Sprintf(verbbuf, "
\82 \82È
\82½
\82Æ%s",
1774 x_monnam(u.usteed, steed_article, "
\82©
\82í
\82¢
\82»
\82¤
\82È",
1775 SUPPRESS_SADDLE, FALSE));
1777 Sprintf(verbbuf, "
\82 \82È
\82½
\82Í%s",
1778 Levitation ? (const char *) "
\95\82\82«
\82È
\82ª
\82ç"
1779 : jconj(locomotion(youmonst.data, "
\82Â
\82Ü
\82¸
\82"), "
\82Ä"));
1781 pline("%s%s
\82
\82à
\82Ì
\91\83\82É
\82Ð
\82Á
\82©
\82©
\82Á
\82½
\81I", verbbuf, web_you[trap->madeby_u]);
1785 /* time will be adjusted below */
1786 set_utrap(1, TT_WEB);
1788 /* Time stuck in the web depends on your/steed strength. */
1790 int tim, str = ACURR(A_STR);
1792 /* If mounted, the steed gets trapped. Use mintrap
1793 * to do all the work. If mtrapped is set as a result,
1794 * unset it and set utrap instead. In the case of a
1795 * strongmonst and mintrap said it's trapped, use a
1796 * short but non-zero trap time. Otherwise, monsters
1797 * have no specific strength, so use player strength.
1798 * This gets skipped for webmsgok, which implies that
1799 * the steed isn't a factor.
1801 if (u.usteed && webmsgok) {
1802 /* mtmp location might not be up to date */
1803 u.usteed->mx = u.ux;
1804 u.usteed->my = u.uy;
1806 /* mintrap currently does not return 2(died) for webs */
1807 if (mintrap(u.usteed)) {
1808 u.usteed->mtrapped = 0;
1809 if (strongmonst(u.usteed->data))
1816 webmsgok = FALSE; /* mintrap printed the messages */
1836 You("tear through %s web!", a_your[trap->madeby_u]);
1838 You("%s
\82
\82à
\82Ì
\91\83\82ð
\90Ø
\82è
\97ô
\82¢
\82½
\81I", web_you[trap->madeby_u]);
1840 newsym(u.ux, u.uy); /* get rid of trap symbol */
1842 set_utrap((unsigned) tim, TT_WEB);
1847 (void) activate_statue_trap(trap, u.ux, u.uy, FALSE);
1850 case MAGIC_TRAP: /* A magic trap. */
1854 newsym(u.ux, u.uy); /* update position */
1856 You("are caught in a magical explosion!");
1858 You("
\96\82\96@
\82Ì
\94\9a\94
\82ð
\97\81\82Ñ
\82½
\81I");
1860 losehp(rnd(10), "magical explosion", KILLED_BY_AN);
1862 losehp(rnd(10), "
\96\82\96@
\82Ì
\94\9a\94
\82ð
\97\81\82Ñ
\82Ä", KILLED_BY_AN);
1864 Your("body absorbs some of the magical energy!");
1866 Your("
\91Ì
\82Í
\96\82\96@
\82Ì
\83G
\83l
\83\8b\83M
\81[
\82ð
\8f
\82µ
\8bz
\82¢
\82Æ
\82Á
\82½
\81I");
1867 u.uen = (u.uenmax += 2);
1872 (void) steedintrap(trap, (struct obj *) 0);
1877 /* hero without magic resistance loses spell energy,
1878 hero with magic resistance takes damage instead;
1879 possibly non-intuitive but useful for play balance */
1881 drain_en(rnd(u.ulevel) + 1);
1883 int dmgval2 = rnd(4), hp = Upolyd ? u.mh : u.uhp;
1885 /* Half_XXX_damage has opposite its usual effect (approx)
1886 but isn't cumulative if hero has more than one */
1887 if (Half_physical_damage || Half_spell_damage)
1889 /* give Magicbane wielder dose of own medicine */
1890 if (uwep && uwep->oartifact == ART_MAGICBANE)
1892 /* having an artifact--other than own quest one--which
1893 confers magic resistance simply by being carried
1894 also increases the effect */
1895 for (otmp = invent; otmp; otmp = otmp->nobj)
1896 if (otmp->oartifact && !is_quest_artifact(otmp)
1897 && defends_when_carried(AD_MAGM, otmp))
1902 dmgval2 = (dmgval2 + 3) / 4;
1905 You_feel((dmgval2 >= hp) ? "unbearably torpid!"
1906 : (dmgval2 >= hp / 4) ? "very lethargic."
1909 You_feel((dmgval2 >= hp) ? "
\91Ï
\82¦
\82ç
\82ê
\82È
\82¢
\82Ù
\82Ç
\96³
\8bC
\97Í
\82É
\82È
\82Á
\82½
\81I"
1910 : (dmgval2 >= hp / 4) ? "
\82Æ
\82Ä
\82à
\8bC
\82¾
\82é
\82
\82È
\82Á
\82½
\81D"
1911 : "
\82à
\82Ì
\82®
\82³
\82È
\8bC
\95ª
\82É
\82È
\82Á
\82½
\81D");
1913 /* opposite of magical explosion */
1915 losehp(dmgval2, "anti-magic implosion", KILLED_BY_AN);
1917 losehp(dmgval2, "
\94½
\96\82\96@
\82Ì
\93à
\95\94\94j
\97ô
\82Å", KILLED_BY_AN);
1922 char verbbuf[BUFSZ];
1927 Strcpy(verbbuf, "trigger"); /* follows "You sit down." */
1929 Strcpy(verbbuf, "
\82ð
\88ø
\82«
\8bN
\82±
\82µ
\82½"); /* follows "You sit down." */
1933 Sprintf(verbbuf, "lead %s onto",
1934 x_monnam(u.usteed, steed_article, (char *) 0,
1935 SUPPRESS_SADDLE, FALSE));
1937 Sprintf(verbbuf, "
\82É%s
\82Æ
\82Æ
\82à
\82É
\94ò
\82Ñ
\8d\9e\82ñ
\82¾",
1938 x_monnam(u.usteed, steed_article, (char *) 0,
1939 SUPPRESS_SADDLE, FALSE));
1943 Sprintf(verbbuf, "%s onto",
1944 Levitation ? (const char *) "float"
1945 : locomotion(youmonst.data, "step"));
1947 Sprintf(verbbuf,"
\82É%s",
1948 jpast(Levitation ? (const char *)"
\95\82\82«
\82È
\82ª
\82ç
\94ò
\82Ñ
\82±
\82Þ"
1949 : locomotion(youmonst.data, "
\93¥
\82Ý
\8d\9e\82Þ")));
1952 You("%s a polymorph trap!", verbbuf);
1954 You("
\95Ï
\89»
\82Ìã©%s
\81I", verbbuf);
1955 if (Antimagic || Unchanging) {
1956 shieldeff(u.ux, u.uy);
1958 You_feel("momentarily different.");
1960 You("
\88ê
\8fu
\88á
\82Á
\82½
\8a´
\82¶
\82ª
\82µ
\82½
\81D");
1961 /* Trap did nothing; don't remove it --KAA */
1963 (void) steedintrap(trap, (struct obj *) 0);
1964 deltrap(trap); /* delete trap before polymorph */
1965 newsym(u.ux, u.uy); /* get rid of trap symbol */
1967 You_feel("a change coming over you.");
1969 You("
\95Ï
\89»
\82ª
\96K
\82ê
\82½
\82æ
\82¤
\82È
\8bC
\82ª
\82µ
\82½
\81D");
1975 unsigned steed_mid = 0;
1976 struct obj *saddle = 0;
1978 if ((Levitation || Flying) && !forcetrap) {
1979 if (!already_seen && rn2(3))
1983 pline("%s %s in a pile of soil below you.",
1984 already_seen ? "There is" : "You discover",
1985 trap->madeby_u ? "the trigger of your mine" : "a trigger");
1988 pline("
\82±
\82±
\82É
\82Í%s
\92n
\97\8b\82Ì
\8bN
\94\9a\83X
\83C
\83b
\83`
\82ª
\82 \82é
\81D",
1989 set_you[trap->madeby_u]);
1991 You("
\91«
\89º
\82Ì
\93y
\82Ì
\8eR
\82É%s
\92n
\97\8b\82Ì
\8bN
\94\9a\83X
\83C
\83b
\83`
\82ð
\82Ý
\82Â
\82¯
\82½
\81D",
1992 set_you[trap->madeby_u]);
1994 if (already_seen && rn2(3))
1997 pline("KAABLAMM!!! %s %s%s off!",
1998 forcebungle ? "Your inept attempt sets"
1999 : "The air currents set",
2000 already_seen ? a_your[trap->madeby_u] : "",
2001 already_seen ? " land mine" : "it");
2003 pline("
\82¿
\82ã
\82Ç
\81[
\82ñ
\81I
\81I%s%s%s
\8bN
\94\9a\83X
\83C
\83b
\83`
\82ª
\94
\93®
\82µ
\82½
\81I",
2004 forcebungle ? "
\95s
\8aí
\97p
\82È
\82¹
\82¢
\82Å"
2005 : "
\8bó
\8bC
\82Ì
\97¬
\82ê
\82Å",
2006 already_seen ? set_you[trap->madeby_u] : "",
2007 already_seen ? "
\92n
\97\8b\82Ì" : "");
2010 /* prevent landmine from killing steed, throwing you to
2011 * the ground, and you being affected again by the same
2012 * mine because it hasn't been deleted yet
2014 static boolean recursive_mine = FALSE;
2020 pline("KAABLAMM!!! You triggered %s land mine!",
2021 a_your[trap->madeby_u]);
2023 pline("
\82¿
\82ã
\82Ç
\81[
\82ñ
\81I
\81I%s
\92n
\97\8b\82Ì
\8bN
\94\9a\83X
\83C
\83b
\83`
\82ð
\93¥
\82ñ
\82¾
\81I",
2024 set_you[trap->madeby_u]);
2027 steed_mid = u.usteed->m_id;
2028 recursive_mine = TRUE;
2029 (void) steedintrap(trap, (struct obj *) 0);
2030 recursive_mine = FALSE;
2031 saddle = sobj_at(SADDLE, u.ux, u.uy);
2032 set_wounded_legs(LEFT_SIDE, rn1(35, 41));
2033 set_wounded_legs(RIGHT_SIDE, rn1(35, 41));
2034 exercise(A_DEX, FALSE);
2036 blow_up_landmine(trap);
2037 if (steed_mid && saddle && !u.usteed)
2038 (void) keep_saddle_with_steedcorpse(steed_mid, fobj, saddle);
2039 newsym(u.ux, u.uy); /* update trap symbol */
2041 losehp(Maybe_Half_Phys(rnd(16)), "land mine", KILLED_BY_AN);
2043 losehp(Maybe_Half_Phys(rnd(16)), "
\92n
\97\8b\82ð
\93¥
\82ñ
\82Å", KILLED_BY_AN);
2044 /* fall recursively into the pit... */
2045 if ((trap = t_at(u.ux, u.uy)) != 0)
2046 dotrap(trap, RECURSIVETRAP);
2047 fill_pit(u.ux, u.uy);
2051 case ROLLING_BOULDER_TRAP: {
2052 int style = ROLL | (trap->tseen ? LAUNCH_KNOWN : 0);
2056 pline("Click! You trigger a rolling boulder trap!");
2058 pline("
\83J
\83`
\83b
\81I
\82 \82È
\82½
\82Í
\8b\90\8aâ
\82Ìã©
\82Ì
\83X
\83C
\83b
\83`
\82ð
\93¥
\82ñ
\82¾
\81I");
2059 if (!launch_obj(BOULDER, trap->launch.x, trap->launch.y,
2060 trap->launch2.x, trap->launch2.y, style)) {
2062 newsym(u.ux, u.uy); /* get rid of trap symbol */
2064 pline("Fortunately for you, no boulder was released.");
2066 pline("
\89^
\82Ì
\82æ
\82¢
\82±
\82Æ
\82É
\8aâ
\82Í
\93]
\82ª
\82Á
\82Ä
\82±
\82È
\82©
\82Á
\82½
\81D");
2073 domagicportal(trap);
2076 case VIBRATING_SQUARE:
2078 /* messages handled elsewhere; the trap symbol is merely to mark the
2079 * square for future reference */
2084 impossible("You hit a trap of type %u", trap->ttyp);
2089 trapnote(trap, noprefix)
2093 static char tnbuf[12];
2096 *tnnames[12] = { "C note", "D flat", "D note", "E flat",
2097 "E note", "F note", "F sharp", "G note",
2098 "G sharp", "A note", "B flat", "B note" };
2100 *tnnames[12] = { "
\83h", "
\83\8c\81ó", "
\83\8c", "
\83~
\81ó",
2101 "
\83~", "
\83t
\83@", "
\83t
\83@
\81ò", "
\83\",
2102 "
\83\
\81ò", "
\83\89", "
\83V
\81ó", "
\83V" };
2106 tn = tnnames[trap->tnote];
2109 Sprintf(tnbuf, "%s ",
2110 (*tn == 'A' || *tn == 'E' || *tn == 'F') ? "an" : "a");
2111 Sprintf(eos(tnbuf), "%s", tn);
2113 Sprintf(tnbuf, "%s
\82Ì
\89¹", tn);
2119 steedintrap(trap, otmp)
2123 struct monst *steed = u.usteed;
2125 boolean trapkilled, steedhit;
2127 if (!steed || !trap)
2132 trapkilled = steedhit = FALSE;
2137 impossible("steed hit by non-existant arrow?");
2140 trapkilled = thitm(8, steed, otmp, 0, FALSE);
2145 impossible("steed hit by non-existant dart?");
2148 trapkilled = thitm(7, steed, otmp, 0, FALSE);
2152 if (!resists_sleep(steed) && !breathless(steed->data)
2153 && !steed->msleeping && steed->mcanmove) {
2154 if (sleep_monst(steed, rnd(25), -1))
2155 /* no in_sight check here; you can feel it even if blind */
2157 pline("%s suddenly falls asleep!", Monnam(steed));
2159 pline("%s
\82Í
\82Æ
\82Â
\82º
\82ñ
\96°
\82Á
\82Ä
\82µ
\82Ü
\82Á
\82½
\81I", Monnam(steed));
2164 trapkilled = thitm(0, steed, (struct obj *) 0, rnd(16), FALSE);
2169 trapkilled = (DEADMONSTER(steed)
2170 || thitm(0, steed, (struct obj *) 0,
2171 rnd((tt == PIT) ? 6 : 10), FALSE));
2175 if (!resists_magm(steed) && !resist(steed, WAND_CLASS, 0, NOTELL)) {
2176 (void) newcham(steed, (struct permonst *) 0, FALSE, FALSE);
2177 if (!can_saddle(steed) || !can_ride(steed))
2178 dismount_steed(DISMOUNT_POLY);
2181 You("have to adjust yourself in the saddle on %s.",
2183 You("%s
\82Ì
\88Æ
\82Ì
\8fã
\82Å
\8dÀ
\82è
\82È
\82¨
\82µ
\82½
\81D",
2184 x_monnam(steed, ARTICLE_A, (char *) 0, SUPPRESS_SADDLE,
2194 dismount_steed(DISMOUNT_POLY);
2197 return steedhit ? 1 : 0;
2200 /* some actions common to both player and monsters for triggered landmine */
2202 blow_up_landmine(trap)
2205 int x = trap->tx, y = trap->ty, dbx, dby;
2206 struct rm *lev = &levl[x][y];
2208 (void) scatter(x, y, 4,
2209 MAY_DESTROY | MAY_HIT | MAY_FRACTURE | VIS_EFFECTS,
2212 wake_nearto(x, y, 400);
2213 if (IS_DOOR(lev->typ))
2214 lev->doormask = D_BROKEN;
2215 /* destroy drawbridge if present */
2216 if (lev->typ == DRAWBRIDGE_DOWN || is_drawbridge_wall(x, y) >= 0) {
2218 /* if under the portcullis, the bridge is adjacent */
2219 if (find_drawbridge(&dbx, &dby))
2220 destroy_drawbridge(dbx, dby);
2221 trap = t_at(x, y); /* expected to be null after destruction */
2223 /* convert landmine into pit */
2225 if (Is_waterlevel(&u.uz) || Is_airlevel(&u.uz)) {
2229 trap->ttyp = PIT; /* explosion creates a pit */
2230 trap->madeby_u = FALSE; /* resulting pit isn't yours */
2231 seetrap(trap); /* and it isn't concealed */
2237 * The following are used to track launched objects to
2238 * prevent them from vanishing if you are killed. They
2239 * will reappear at the launchplace in bones files.
2247 launch_drop_spot(obj, x, y)
2252 launchplace.obj = (struct obj *) 0;
2256 launchplace.obj = obj;
2263 launch_in_progress()
2265 if (launchplace.obj)
2271 force_launch_placement()
2273 if (launchplace.obj) {
2274 launchplace.obj->otrapped = 0;
2275 place_object(launchplace.obj, launchplace.x, launchplace.y);
2280 * Move obj from (x1,y1) to (x2,y2)
2282 * Return 0 if no object was launched.
2283 * 1 if an object was launched and placed somewhere.
2284 * 2 if an object was launched, but used up.
2287 launch_obj(otyp, x1, y1, x2, y2, style)
2289 register int x1, y1, x2, y2;
2292 register struct monst *mtmp;
2293 register struct obj *otmp, *otmp2;
2294 register int dx, dy;
2295 struct obj *singleobj;
2296 boolean used_up = FALSE;
2297 boolean otherside = FALSE;
2302 otmp = sobj_at(otyp, x1, y1);
2303 /* Try the other side too, for rolling boulder traps */
2304 if (!otmp && otyp == BOULDER) {
2306 otmp = sobj_at(otyp, x2, y2);
2310 if (otherside) { /* swap 'em */
2321 if (otmp->quan == 1L) {
2322 obj_extract_self(otmp);
2324 otmp = (struct obj *) 0;
2326 singleobj = splitobj(otmp, 1L);
2327 obj_extract_self(singleobj);
2330 /* in case you're using a pick-axe to chop the boulder that's being
2331 launched (perhaps a monster triggered it), destroy context so that
2332 next dig attempt never thinks you're resuming previous effort */
2333 if ((otyp == BOULDER || otyp == STATUE)
2334 && singleobj->ox == context.digging.pos.x
2335 && singleobj->oy == context.digging.pos.y)
2336 (void) memset((genericptr_t) &context.digging, 0,
2337 sizeof(struct dig_info));
2339 dist = distmin(x1, y1, x2, y2);
2345 case ROLL | LAUNCH_UNSEEN:
2346 if (otyp == BOULDER) {
2348 You_hear(Hallucination ? "someone bowling."
2349 : "rumbling in the distance.");
2351 You_hear(Hallucination ? "
\92N
\82©
\82ª
\83{
\81[
\83\8a\83\93\83O
\82ð
\82µ
\82Ä
\82¢
\82é
\89¹
\82ð
\95·
\82¢
\82½
\81D"
2352 : "
\89\93\82
\82Ì
\83S
\83\8d\83S
\83\8d\82Æ
\82¢
\82¤
\89¹
\82ð
\95·
\82¢
\82½
\81D");
2355 style &= ~LAUNCH_UNSEEN;
2357 case ROLL | LAUNCH_KNOWN:
2358 /* use otrapped as a flag to ohitmon */
2359 singleobj->otrapped = 1;
2360 style &= ~LAUNCH_KNOWN;
2369 if (!cansee(bhitpos.x, bhitpos.y))
2371 tmp_at(DISP_FLASH, obj_to_glyph(singleobj, rn2_on_display_rng));
2372 tmp_at(bhitpos.x, bhitpos.y);
2374 /* Mark a spot to place object in bones files to prevent
2375 * loss of object. Use the starting spot to ensure that
2376 * a rolling boulder will still launch, which it wouldn't
2377 * do if left midstream. Unfortunately we can't use the
2378 * target resting spot, because there are some things/situations
2379 * that would prevent it from ever getting there (bars), and we
2380 * can't tell that yet.
2382 launch_drop_spot(singleobj, bhitpos.x, bhitpos.y);
2384 /* Set the object in motion */
2385 while (dist-- > 0 && !used_up) {
2387 tmp_at(bhitpos.x, bhitpos.y);
2390 /* dstage@u.washington.edu -- Delay only if hero sees it */
2391 if (cansee(bhitpos.x, bhitpos.y))
2397 t = t_at(bhitpos.x, bhitpos.y);
2399 if ((mtmp = m_at(bhitpos.x, bhitpos.y)) != 0) {
2400 if (otyp == BOULDER && throws_rocks(mtmp->data)) {
2402 if (cansee(bhitpos.x, bhitpos.y))
2404 pline("%s snatches the boulder.", Monnam(mtmp));
2406 pline("%s
\82Í
\8aâ
\82ð
\82Â
\82©
\82Ý
\8eæ
\82Á
\82½
\81D", Monnam(mtmp));
2407 singleobj->otrapped = 0;
2408 (void) mpickobj(mtmp, singleobj);
2410 launch_drop_spot((struct obj *) 0, 0, 0);
2414 if (ohitmon(mtmp, singleobj, (style == ROLL) ? -1 : dist,
2417 launch_drop_spot((struct obj *) 0, 0, 0);
2420 } else if (bhitpos.x == u.ux && bhitpos.y == u.uy) {
2423 if (thitu(9 + singleobj->spe, dmgval(singleobj, &youmonst),
2424 &singleobj, (char *) 0))
2427 if (style == ROLL) {
2428 if (down_gate(bhitpos.x, bhitpos.y) != -1) {
2429 if (ship_object(singleobj, bhitpos.x, bhitpos.y, FALSE)) {
2431 launch_drop_spot((struct obj *) 0, 0, 0);
2435 if (t && otyp == BOULDER) {
2442 cansee(bhitpos.x, bhitpos.y)
2443 ? " The rolling boulder triggers a land mine."
2447 "
\82¿
\82ã
\82Ç
\81[
\82ñ
\81I
\81I%s",
2448 cansee(bhitpos.x, bhitpos.y)
2449 ? "
\93]
\82ª
\82Á
\82Ä
\82«
\82½
\8aâ
\82ª
\92n
\97\8b\82Ì
\8bN
\94\9a\83X
\83C
\83b
\83`
\82ð
\93¥
\82ñ
\82¾
\81D"
2453 del_engr_at(bhitpos.x, bhitpos.y);
2454 place_object(singleobj, bhitpos.x, bhitpos.y);
2455 singleobj->otrapped = 0;
2456 fracture_rock(singleobj);
2457 (void) scatter(bhitpos.x, bhitpos.y, 4,
2458 MAY_DESTROY | MAY_HIT | MAY_FRACTURE
2461 if (cansee(bhitpos.x, bhitpos.y))
2462 newsym(bhitpos.x, bhitpos.y);
2464 launch_drop_spot((struct obj *) 0, 0, 0);
2469 if (cansee(bhitpos.x, bhitpos.y))
2471 pline("Suddenly the rolling boulder disappears!");
2473 pline("
\93]
\82ª
\82Á
\82Ä
\82«
\82½
\8aâ
\82ª
\82Æ
\82Â
\82º
\82ñ
\8fÁ
\82¦
\82½
\81I");
2476 You_hear("a rumbling stop abruptly.");
2478 pline("
\83S
\83\8d\83S
\83\8d\82Æ
\82¢
\82¤
\89¹
\82ª
\93Ë
\91R
\8e~
\82Ü
\82Á
\82½
\81D");
2479 singleobj->otrapped = 0;
2480 if (t->ttyp == TELEP_TRAP)
2481 (void) rloco(singleobj);
2483 int newlev = random_teleport_level();
2486 if (newlev == depth(&u.uz) || In_endgame(&u.uz))
2488 add_to_migration(singleobj);
2489 get_level(&dest, newlev);
2490 singleobj->ox = dest.dnum;
2491 singleobj->oy = dest.dlevel;
2492 singleobj->owornmask = (long) MIGR_RANDOM;
2496 launch_drop_spot((struct obj *) 0, 0, 0);
2502 /* the boulder won't be used up if there is a
2503 monster in the trap; stop rolling anyway */
2504 x2 = bhitpos.x, y2 = bhitpos.y; /* stops here */
2506 if (flooreffects(singleobj, x2, y2, "fall")) {
2508 if (flooreffects(singleobj, x2, y2, "
\97\8e\82¿
\82é")) {
2510 launch_drop_spot((struct obj *) 0, 0, 0);
2512 dist = -1; /* stop rolling immediately */
2515 if (used_up || dist == -1)
2519 if (flooreffects(singleobj, bhitpos.x, bhitpos.y, "fall")) {
2521 if (flooreffects(singleobj, bhitpos.x, bhitpos.y, "
\97\8e\82¿
\82é")) {
2523 launch_drop_spot((struct obj *) 0, 0, 0);
2527 && (otmp2 = sobj_at(BOULDER, bhitpos.x, bhitpos.y)) != 0) {
2529 const char *bmsg = " as one boulder sets another in motion";
2531 const char *bmsg = "
\82Ð
\82Æ
\82Â
\82Ì
\8aâ
\82ª
\91¼
\82Ì
\8aâ
\82ð
\93®
\82©
\82µ
\82½
\82©
\82Ì
\82æ
\82¤
\82È
\81C";
2533 if (!isok(bhitpos.x + dx, bhitpos.y + dy) || !dist
2534 || IS_ROCK(levl[bhitpos.x + dx][bhitpos.y + dy].typ))
2536 bmsg = " as one boulder hits another";
2538 bmsg = "
\82Ð
\82Æ
\82Â
\82Ì
\8aâ
\82ª
\91¼
\82Ì
\8aâ
\82É
\93\96\82½
\82Á
\82½
\82æ
\82¤
\82È";
2541 You_hear("a loud crash%s!",
2543 You_hear("%s
\91å
\82«
\82È
\83S
\83\93\82Æ
\82¢
\82¤
\89¹
\82ð
\95·
\82¢
\82½
\81I",
2544 cansee(bhitpos.x, bhitpos.y) ? bmsg : "");
2545 obj_extract_self(otmp2);
2546 /* pass off the otrapped flag to the next boulder */
2547 otmp2->otrapped = singleobj->otrapped;
2548 singleobj->otrapped = 0;
2549 place_object(singleobj, bhitpos.x, bhitpos.y);
2551 otmp2 = (struct obj *) 0;
2552 wake_nearto(bhitpos.x, bhitpos.y, 10 * 10);
2555 if (otyp == BOULDER && closed_door(bhitpos.x, bhitpos.y)) {
2556 if (cansee(bhitpos.x, bhitpos.y))
2558 pline_The("boulder crashes through a door.");
2560 pline("
\8aâ
\82Í
\94à
\82ð
\94j
\89ó
\82µ
\82½
\81D");
2561 levl[bhitpos.x][bhitpos.y].doormask = D_BROKEN;
2563 unblock_point(bhitpos.x, bhitpos.y);
2566 /* if about to hit iron bars, do so now */
2567 if (dist > 0 && isok(bhitpos.x + dx, bhitpos.y + dy)
2568 && levl[bhitpos.x + dx][bhitpos.y + dy].typ == IRONBARS) {
2569 x2 = bhitpos.x, y2 = bhitpos.y; /* object stops here */
2570 if (hits_bars(&singleobj,
2571 x2, y2, x2+dx, y2+dy,
2575 launch_drop_spot((struct obj *) 0, 0, 0);
2581 tmp_at(DISP_END, 0);
2582 launch_drop_spot((struct obj *) 0, 0, 0);
2584 singleobj->otrapped = 0;
2585 place_object(singleobj, x2, y2);
2598 newsym(trap->tx, trap->ty);
2602 /* like seetrap() but overrides vision */
2609 /* in case it's beneath something, redisplay the something */
2610 newsym(trap->tx, trap->ty);
2614 mkroll_launch(ttmp, x, y, otyp, ocount)
2627 boolean success = FALSE;
2630 if (ttmp->ttyp == ROLLING_BOULDER_TRAP)
2632 distance = rn1(5, 4); /* 4..8 away */
2633 tmp = rn2(8); /* randomly pick a direction to try first */
2634 while (distance >= mindist) {
2639 /* Prevent boulder from being placed on water */
2640 if (ttmp->ttyp == ROLLING_BOULDER_TRAP
2641 && is_pool_or_lava(x + distance * dx, y + distance * dy))
2644 success = isclearpath(&cc, distance, dx, dy);
2645 if (ttmp->ttyp == ROLLING_BOULDER_TRAP) {
2646 boolean success_otherway;
2650 success_otherway = isclearpath(&bcc, distance, -(dx), -(dy));
2651 if (!success_otherway)
2658 if ((++trycount % 8) == 0)
2662 /* create the trap without any ammo, launch pt at trap location */
2666 otmp = mksobj(otyp, TRUE, FALSE);
2667 otmp->quan = ocount;
2668 otmp->owt = weight(otmp);
2669 place_object(otmp, cc.x, cc.y);
2672 ttmp->launch.x = cc.x;
2673 ttmp->launch.y = cc.y;
2674 if (ttmp->ttyp == ROLLING_BOULDER_TRAP) {
2675 ttmp->launch2.x = bcc.x;
2676 ttmp->launch2.y = bcc.y;
2678 ttmp->launch_otyp = otyp;
2679 newsym(ttmp->launch.x, ttmp->launch.y);
2684 isclearpath(cc, distance, dx, dy)
2694 while (distance-- > 0) {
2697 typ = levl[x][y].typ;
2698 if (!isok(x, y) || !ZAP_POS(typ) || closed_door(x, y))
2708 register struct monst *mtmp;
2710 register struct trap *trap = t_at(mtmp->mx, mtmp->my);
2711 boolean trapkilled = FALSE;
2712 struct permonst *mptr = mtmp->data;
2716 mtmp->mtrapped = 0; /* perhaps teleported? */
2717 } else if (mtmp->mtrapped) { /* is currently in the trap */
2718 if (!trap->tseen && cansee(mtmp->mx, mtmp->my) && canseemon(mtmp)
2719 && (is_pit(trap->ttyp) || trap->ttyp == BEAR_TRAP
2720 || trap->ttyp == HOLE
2721 || trap->ttyp == WEB)) {
2722 /* If you come upon an obviously trapped monster, then
2723 * you must be able to see the trap it's in too.
2729 if (sobj_at(BOULDER, mtmp->mx, mtmp->my)
2730 && is_pit(trap->ttyp)) {
2733 if (canseemon(mtmp))
2735 pline("%s pulls free...", Monnam(mtmp));
2737 pline("%s
\82Í
\8f\95\82¯
\8fã
\82°
\82ç
\82ê
\82½
\81D", Monnam(mtmp));
2738 fill_pit(mtmp->mx, mtmp->my);
2743 } else if (metallivorous(mptr)) {
2744 if (trap->ttyp == BEAR_TRAP) {
2745 if (canseemon(mtmp))
2747 pline("%s eats a bear trap!", Monnam(mtmp));
2749 pline("%s
\82Í
\8cF
\82Ìã©
\82ð
\90H
\82×
\82½
\81I", Monnam(mtmp));
2753 } else if (trap->ttyp == SPIKED_PIT) {
2754 if (canseemon(mtmp))
2756 pline("%s munches on some spikes!", Monnam(mtmp));
2758 pline("%s
\82Í
\83g
\83Q
\83g
\83Q
\82ð
\90H
\82×
\82½
\81I", Monnam(mtmp));
2764 register int tt = trap->ttyp;
2765 boolean in_sight, tear_web, see_it,
2766 inescapable = force_mintrap || ((tt == HOLE || tt == PIT)
2767 && Sokoban && !trap->madeby_u);
2768 const char *fallverb;
2770 /* true when called from dotrap, inescapable is not an option */
2771 if (mtmp == u.usteed)
2773 if (!inescapable && ((mtmp->mtrapseen & (1 << (tt - 1))) != 0
2774 || (tt == HOLE && !mindless(mptr)))) {
2775 /* it has been in such a trap - perhaps it escapes */
2779 mtmp->mtrapseen |= (1 << (tt - 1));
2781 /* Monster is aggravated by being trapped by you.
2782 Recognizing who made the trap isn't completely
2783 unreasonable; everybody has their own style. */
2784 if (trap->madeby_u && rnl(5))
2785 setmangry(mtmp, TRUE);
2787 in_sight = canseemon(mtmp);
2788 see_it = cansee(mtmp->mx, mtmp->my);
2789 /* assume hero can tell what's going on for the steed */
2790 if (mtmp == u.usteed)
2794 if (trap->once && trap->tseen && !rn2(15)) {
2795 if (in_sight && see_it)
2797 pline("%s triggers a trap but nothing happens.",
2800 pline("%s
\82ª
\82í
\82È
\82ð
\8bN
\93®
\82³
\82¹
\82½
\82ª
\89½
\82à
\8bN
\82±
\82ç
\82È
\82©
\82Á
\82½
\81D",
2804 newsym(mtmp->mx, mtmp->my);
2808 otmp = t_missile(ARROW, trap);
2811 if (thitm(8, mtmp, otmp, 0, FALSE))
2815 if (trap->once && trap->tseen && !rn2(15)) {
2816 if (in_sight && see_it)
2818 pline("%s triggers a trap but nothing happens.",
2821 pline("%s
\82ª
\82í
\82È
\82ð
\8bN
\93®
\82³
\82¹
\82½
\82ª
\89½
\82à
\8bN
\82±
\82ç
\82È
\82©
\82Á
\82½
\81D",
2825 newsym(mtmp->mx, mtmp->my);
2829 otmp = t_missile(DART, trap);
2831 otmp->opoisoned = 1;
2834 if (thitm(7, mtmp, otmp, 0, FALSE))
2838 if (trap->once && trap->tseen && !rn2(15)) {
2839 if (in_sight && see_it)
2842 "A trap door above %s opens, but nothing falls out!",
2844 "%s
\82Ì
\8fã
\82Ì
\94à
\82ª
\8aJ
\82¢
\82½
\82ª
\81C
\89½
\82à
\97\8e\82¿
\82Ä
\82±
\82È
\82©
\82Á
\82½
\81I",
2847 newsym(mtmp->mx, mtmp->my);
2851 otmp = t_missile(ROCK, trap);
2854 if (thitm(0, mtmp, otmp, d(2, 6), FALSE))
2860 /* stepped on a squeaky board */
2864 pline("A board beneath %s squeaks %s loudly.",
2865 mon_nam(mtmp), trapnote(trap, 0));
2867 pline("%s
\82Ì
\91«
\8c³
\82Ì
\94Â
\82ª
\91å
\82«
\82%s
\82É
\82«
\82µ
\82ñ
\82¾
\81D",
2868 mon_nam(mtmp), trapnote(trap, 0));
2873 pline("%s stops momentarily and appears to cringe.",
2875 pline("%s
\82Í
\88ê
\8fu
\8e~
\82Ü
\82Á
\82Ä
\90g
\82ð
\82·
\82
\82ß
\82½
\82æ
\82¤
\82¾
\81D",
2879 /* same near/far threshold as mzapmsg() */
2880 int range = couldsee(mtmp->mx, mtmp->my) /* 9 or 5 */
2881 ? (BOLT_LIM + 1) : (BOLT_LIM - 3);
2884 You_hear("a %s squeak %s.", trapnote(trap, 1),
2885 (distu(mtmp->mx, mtmp->my) <= range * range)
2886 ? "nearby" : "in the distance");
2888 You_hear("%s
\82
\82Å%s
\82ª
\82«
\82µ
\82Þ
\89¹
\82ð
\95·
\82¢
\82½
\81D",
2889 (distu(mtmp->mx, mtmp->my) <= range * range)
2890 ? "
\8bß" : "
\89\93",
2894 /* wake up nearby monsters */
2895 wake_nearto(mtmp->mx, mtmp->my, 40);
2898 if (mptr->msize > MZ_SMALL && !amorphous(mptr) && !is_flyer(mptr)
2899 && !is_whirly(mptr) && !unsolid(mptr)) {
2903 pline("%s is caught in %s bear trap!", Monnam(mtmp),
2904 a_your[trap->madeby_u]);
2906 pline("%s
\82Í%s
\8cF
\82Ìã©
\82É
\82Â
\82©
\82Ü
\82Á
\82½
\81I", Monnam(mtmp),
2907 set_you[trap->madeby_u]);
2911 if (mptr == &mons[PM_OWLBEAR]
2912 || mptr == &mons[PM_BUGBEAR])
2914 You_hear("the roaring of an angry bear!");
2916 You_hear("
\93{
\82è
\82Ì
\99ô
\9aK
\82ð
\95·
\82¢
\82½
\81I");
2918 } else if (force_mintrap) {
2921 pline("%s evades %s bear trap!", Monnam(mtmp),
2922 a_your[trap->madeby_u]);
2924 pline("%s
\82Í%s
\8cF
\82Ìã©
\82ð
\82½
\82
\82Ý
\82É
\94ð
\82¯
\82½
\81I", Monnam(mtmp),
2925 set_you[trap->madeby_u]);
2931 trapkilled = thitm(0, mtmp, (struct obj *) 0, d(2, 4), FALSE);
2934 if (!resists_sleep(mtmp) && !breathless(mptr) && !mtmp->msleeping
2935 && mtmp->mcanmove) {
2936 if (sleep_monst(mtmp, rnd(25), -1) && in_sight) {
2938 pline("%s suddenly falls asleep!", Monnam(mtmp));
2940 pline("%s
\82Í
\93Ë
\91R
\96°
\82è
\82É
\97\8e\82¿
\82½
\81I", Monnam(mtmp));
2954 pline("%s %s on the %s!", A_gush_of_water_hits,
2955 mon_nam(mtmp), mbodypart(mtmp, HEAD));
2957 pline("
\90\85\82ª
\95¬
\8fo
\82µ
\82Ä
\81C%s
\82Ì%s
\82É
\96½
\92\86\82µ
\82½
\81I",
2958 mon_nam(mtmp), mbodypart(mtmp, HEAD));
2960 target = which_armor(mtmp, W_ARMH);
2961 (void) water_damage(target, helm_simple_name(target), TRUE);
2966 pline("%s %s's left %s!", A_gush_of_water_hits,
2967 mon_nam(mtmp), mbodypart(mtmp, ARM));
2969 pline("
\90\85\82ª
\95¬
\8fo
\82µ
\82Ä
\81C%s
\82Ì
\8d¶%s
\82É
\96½
\92\86\82µ
\82½
\81I",
2970 mon_nam(mtmp), mbodypart(mtmp, ARM));
2972 target = which_armor(mtmp, W_ARMS);
2974 if (water_damage(target, "shield", TRUE) != ER_NOTHING)
2976 if (water_damage(target, "
\8f\82", TRUE) != ER_NOTHING)
2978 target = MON_WEP(mtmp);
2979 if (target && bimanual(target))
2980 (void) water_damage(target, 0, TRUE);
2982 target = which_armor(mtmp, W_ARMG);
2984 (void) water_damage(target, "gauntlets", TRUE);
2986 (void) water_damage(target, "
\8f¬
\8eè", TRUE);
2991 pline("%s %s's right %s!", A_gush_of_water_hits,
2992 mon_nam(mtmp), mbodypart(mtmp, ARM));
2994 pline("
\90\85\82ª
\95¬
\8fo
\82µ
\82Ä
\81C%s
\82Ì
\89E%s
\82É
\96½
\92\86\82µ
\82½
\81I",
2995 mon_nam(mtmp), mbodypart(mtmp, ARM));
2997 (void) water_damage(MON_WEP(mtmp), 0, TRUE);
3002 pline("%s %s!", A_gush_of_water_hits, mon_nam(mtmp));
3004 pline("
\90\85\82ª
\95¬
\8fo
\82µ
\82Ä
\81C%s
\82É
\96½
\92\86\82µ
\82½
\81I", mon_nam(mtmp));
3005 for (otmp = mtmp->minvent; otmp; otmp = otmp->nobj)
3007 && (otmp->owornmask & (W_WEP | W_SWAPWEP)) == 0)
3008 (void) snuff_lit(otmp);
3009 if ((target = which_armor(mtmp, W_ARMC)) != 0)
3010 (void) water_damage(target, cloak_simple_name(target),
3012 else if ((target = which_armor(mtmp, W_ARM)) != 0)
3013 (void) water_damage(target, suit_simple_name(target),
3015 else if ((target = which_armor(mtmp, W_ARMU)) != 0)
3017 (void) water_damage(target, "shirt", TRUE);
3019 (void) water_damage(target, "
\83V
\83\83\83c", TRUE);
3022 if (mptr == &mons[PM_IRON_GOLEM]) {
3025 pline("%s falls to pieces!", Monnam(mtmp));
3027 pline("%s
\82Í
\82
\82¾
\82¯
\82¿
\82Á
\82½
\81I", Monnam(mtmp));
3028 else if (mtmp->mtame)
3030 pline("May %s rust in peace.", mon_nam(mtmp));
3032 pline("%s
\82æ
\81C
\88À
\82ç
\82©
\82É
\8eK
\82Ñ
\82ñ
\8e\96\82ð
\81D", mon_nam(mtmp));
3034 if (DEADMONSTER(mtmp))
3036 } else if (mptr == &mons[PM_GREMLIN] && rn2(3)) {
3037 (void) split_mon(mtmp, (struct monst *) 0);
3045 pline("A %s erupts from the %s under %s!", tower_of_flame,
3046 surface(mtmp->mx, mtmp->my), mon_nam(mtmp));
3048 pline("
\89Î
\92\8c\82ª%s
\82Ì
\91«
\8c³
\82Ì%s
\82©
\82ç
\97§
\82¿
\82Ì
\82Ú
\82Á
\82½
\81I",
3049 mon_nam(mtmp), surface(mtmp->mx,mtmp->my));
3051 else if (see_it) /* evidently `mtmp' is invisible */
3053 You_see("a %s erupt from the %s!", tower_of_flame,
3054 surface(mtmp->mx, mtmp->my));
3056 You("
\89Î
\92\8c\82ª%s
\82©
\82ç
\90¶
\82¶
\82é
\82Ì
\82ð
\8c©
\82½
\81I",
3057 surface(mtmp->mx,mtmp->my));
3060 if (resists_fire(mtmp)) {
3062 shieldeff(mtmp->mx, mtmp->my);
3064 pline("%s is uninjured.", Monnam(mtmp));
3066 pline("
\82ª
\81C%s
\82Í
\8f\9d\82Â
\82©
\82È
\82¢
\81D", Monnam(mtmp));
3069 int num = d(2, 4), alt;
3070 boolean immolate = FALSE;
3072 /* paper burns very fast, assume straw is tightly
3073 * packed and burns a bit slower */
3074 switch (monsndx(mptr)) {
3075 case PM_PAPER_GOLEM:
3079 case PM_STRAW_GOLEM:
3080 alt = mtmp->mhpmax / 2;
3083 alt = mtmp->mhpmax / 4;
3085 case PM_LEATHER_GOLEM:
3086 alt = mtmp->mhpmax / 8;
3095 if (thitm(0, mtmp, (struct obj *) 0, num, immolate))
3098 /* we know mhp is at least `num' below mhpmax,
3099 so no (mhp > mhpmax) check is needed here */
3100 mtmp->mhpmax -= rn2(num + 1);
3102 if (burnarmor(mtmp) || rn2(3)) {
3103 (void) destroy_mitem(mtmp, SCROLL_CLASS, AD_FIRE);
3104 (void) destroy_mitem(mtmp, SPBOOK_CLASS, AD_FIRE);
3105 (void) destroy_mitem(mtmp, POTION_CLASS, AD_FIRE);
3107 if (burn_floor_objects(mtmp->mx, mtmp->my, see_it, FALSE)
3108 && !see_it && distu(mtmp->mx, mtmp->my) <= 3 * 3)
3110 You("smell smoke.");
3112 pline("
\89\8c\82Ì
\93õ
\82¢
\82ª
\82µ
\82½
\81D");
3113 if (is_ice(mtmp->mx, mtmp->my))
3114 melt_ice(mtmp->mx, mtmp->my, (char *) 0);
3115 if (see_it && t_at(mtmp->mx, mtmp->my))
3123 fallverb = "
\97\8e\82¿
\82½";
3124 if (is_flyer(mptr) || is_floater(mptr)
3125 || (mtmp->wormno && count_wsegs(mtmp) > 5)
3126 || is_clinger(mptr)) {
3127 if (force_mintrap && !Sokoban) {
3128 /* openfallingtrap; not inescapable here */
3132 pline("%s doesn't fall into the pit.", Monnam(mtmp));
3134 pline("%s
\82Í
\97\8e\82µ
\8c\8a\82É
\97\8e\82¿
\82È
\82©
\82Á
\82½
\81D", Monnam(mtmp));
3136 break; /* inescapable = FALSE; */
3139 break; /* avoids trap */
3141 fallverb = "is dragged"; /* sokoban pit */
3143 fallverb = "
\82¸
\82è
\97\8e\82¿
\82½"; /* sokoban pit */
3146 if (!passes_walls(mptr))
3150 pline("%s %s into %s pit!", Monnam(mtmp), fallverb,
3151 a_your[trap->madeby_u]);
3153 pline("%s
\82Í%s
\97\8e\82µ
\8c\8a\82É%s
\81I", Monnam(mtmp),
3154 set_you[trap->madeby_u], fallverb);
3156 if (mptr == &mons[PM_PIT_VIPER]
3157 || mptr == &mons[PM_PIT_FIEND])
3159 pline("How pitiful. Isn't that the pits?");
3161 pline("
\82±
\82Ì
\97\8e\82µ
\8c\8a\82Í
\82¢
\82¢
\8ed
\8e\96\82ð
\82µ
\82Ä
\82¢
\82é
\81D");
3165 mselftouch(mtmp, "Falling, ", FALSE);
3167 mselftouch(mtmp, "
\97\8e\89º
\92\86\81C", FALSE);
3168 if (DEADMONSTER(mtmp) || thitm(0, mtmp, (struct obj *) 0,
3169 rnd((tt == PIT) ? 6 : 10), FALSE))
3174 if (!Can_fall_thru(&u.uz)) {
3175 impossible("mintrap: %ss cannot exist on this level.",
3176 defsyms[trap_to_defsym(tt)].explanation);
3177 break; /* don't activate it after all */
3179 if (is_flyer(mptr) || is_floater(mptr) || mptr == &mons[PM_WUMPUS]
3180 || (mtmp->wormno && count_wsegs(mtmp) > 5)
3181 || mptr->msize >= MZ_HUGE) {
3182 if (force_mintrap && !Sokoban) {
3183 /* openfallingtrap; not inescapable here */
3189 "A trap door opens, but %s doesn't fall through.",
3191 "
\97\8e\82µ
\94à
\82ª
\8aJ
\82¢
\82½
\82ª
\81C%s
\82Í
\97\8e\82¿
\82È
\82©
\82Á
\82½
\81D",
3193 else /* (tt == HOLE) */
3195 pline("%s doesn't fall through the hole.",
3197 pline("%s
\82Í
\8c\8a\82É
\97\8e\82¿
\82È
\82©
\82Á
\82½
\81D",
3200 break; /* inescapable = FALSE; */
3202 if (inescapable) { /* sokoban hole */
3205 pline("%s seems to be yanked down!", Monnam(mtmp));
3207 pline("%s
\82Í
\88ø
\82«
\97\8e\82³
\82ê
\82½
\82æ
\82¤
\82¾
\81I", Monnam(mtmp));
3208 /* suppress message in mlevel_tele_trap() */
3217 case MAGIC_PORTAL: {
3220 mlev_res = mlevel_tele_trap(mtmp, trap, inescapable, in_sight);
3226 mtele_trap(mtmp, trap, in_sight);
3229 /* Monster in a web. */
3232 if (mu_maybe_destroy_web(mtmp, in_sight, trap))
3235 switch (monsndx(mptr)) {
3236 case PM_OWLBEAR: /* Eric Backus */
3240 You_hear("the roaring of a confused bear!");
3242 You_hear("
\8d¬
\97\90\82Ì
\99ô
\9aK
\82ð
\95·
\82¢
\82½
\81I");
3248 if (mptr->mlet == S_GIANT
3249 /* exclude baby dragons and relatively short worms */
3250 || (mptr->mlet == S_DRAGON && extra_nasty(mptr))
3251 || (mtmp->wormno && count_wsegs(mtmp) > 5)) {
3253 } else if (in_sight) {
3255 pline("%s is caught in %s spider web.", Monnam(mtmp),
3256 a_your[trap->madeby_u]);
3258 pline("%s
\82Í%s
\82
\82à
\82Ì
\91\83\82É
\82Â
\82©
\82Ü
\82Á
\82½
\81D", Monnam(mtmp),
3259 web_you[trap->madeby_u]);
3263 mtmp->mtrapped = tear_web ? 0 : 1;
3265 /* this list is fairly arbitrary; it deliberately
3266 excludes wumpus & giant/ettin zombies/mummies */
3267 case PM_TITANOTHERE:
3268 case PM_BALUCHITHERIUM:
3269 case PM_PURPLE_WORM:
3278 case PM_LORD_SURTUR:
3285 pline("%s tears through %s spider web!", Monnam(mtmp),
3286 a_your[trap->madeby_u]);
3288 pline("%s
\82Í%s
\82
\82à
\82Ì
\91\83\82ð
\88ø
\82«
\97ô
\82¢
\82½
\81I", Monnam(mtmp),
3289 web_you[trap->madeby_u]);
3292 newsym(mtmp->mx, mtmp->my);
3293 } else if (force_mintrap && !mtmp->mtrapped) {
3296 pline("%s avoids %s spider web!", Monnam(mtmp),
3297 a_your[trap->madeby_u]);
3299 pline("%s
\82Í%s
\82
\82à
\82Ì
\91\83\82ð
\94ð
\82¯
\82½
\81I", Monnam(mtmp),
3300 web_you[trap->madeby_u]);
3309 /* A magic trap. Monsters usually immune. */
3314 /* similar to hero's case, more or less */
3315 if (!resists_magm(mtmp)) { /* lose spell energy */
3316 if (!mtmp->mcan && (attacktype(mptr, AT_MAGC)
3317 || attacktype(mptr, AT_BREA))) {
3318 mtmp->mspec_used += d(2, 2);
3322 pline("%s seems lethargic.", Monnam(mtmp));
3324 pline("%s
\88ê
\8fu
\96³
\8bC
\97Í
\8a´
\82ð
\8a´
\82¶
\82½
\81D", Monnam(mtmp));
3327 } else { /* take some damage */
3328 int dmgval2 = rnd(4);
3330 if ((otmp = MON_WEP(mtmp)) != 0
3331 && otmp->oartifact == ART_MAGICBANE)
3333 for (otmp = mtmp->minvent; otmp; otmp = otmp->nobj)
3335 && defends_when_carried(AD_MAGM, otmp))
3339 if (passes_walls(mptr))
3340 dmgval2 = (dmgval2 + 3) / 4;
3344 mtmp->mhp -= dmgval2;
3345 if (DEADMONSTER(mtmp))
3349 ? "compression from an anti-magic field"
3351 ? "
\94½
\96\82\96@
\8bó
\8aÔ
\82Ì
\88³
\8fk"
3354 if (DEADMONSTER(mtmp))
3357 newsym(trap->tx, trap->ty);
3362 break; /* monsters usually don't set it off */
3363 if (is_flyer(mptr)) {
3364 boolean already_seen = trap->tseen;
3366 if (in_sight && !already_seen) {
3368 pline("A trigger appears in a pile of soil below %s.",
3370 pline("%s
\82Ì
\91«
\8c³
\82Ì
\93y
\82Ì
\8eR
\82É
\8bN
\94\9a\83X
\83C
\83b
\83`
\82ª
\8c»
\82í
\82ê
\82½
\81D",
3377 newsym(mtmp->mx, mtmp->my);
3379 pline_The("air currents set %s off!",
3380 already_seen ? "a land mine" : "it");
3382 pline("
\8bó
\8bC
\82Ì
\97¬
\82ê
\82Å
\83X
\83C
\83b
\83`
\82ª
\93ü
\82Á
\82½
\81I");
3385 } else if (in_sight) {
3386 newsym(mtmp->mx, mtmp->my);
3388 pline("%s%s triggers %s land mine!",
3389 !Deaf ? "KAABLAMM!!! " : "", Monnam(mtmp),
3390 a_your[trap->madeby_u]);
3392 pline("%s%s
\82Í%s
\92n
\97\8b\82Ì
\8bN
\94\9a\83X
\83C
\83b
\83`
\82ð
\93¥
\82ñ
\82¾
\81I",
3393 !Deaf ? "
\82¿
\82ã
\82Ç
\81[
\82ñ
\81I
\81I" : "", Monnam(mtmp),
3394 set_you[trap->madeby_u]);
3397 if (!in_sight && !Deaf)
3399 pline("Kaablamm! You hear an explosion in the distance!");
3401 pline("
\82¿
\82ã
\82Ç
\81[
\82ñ
\81I
\82 \82È
\82½
\82Í
\89\93\95û
\82Ì
\94\9a\94
\89¹
\82ð
\95·
\82¢
\82½
\81I");
3402 blow_up_landmine(trap);
3403 /* explosion might have destroyed a drawbridge; don't
3404 dish out more damage if monster is already dead */
3405 if (DEADMONSTER(mtmp)
3406 || thitm(0, mtmp, (struct obj *) 0, rnd(16), FALSE)) {
3409 /* monsters recursively fall into new pit */
3410 if (mintrap(mtmp) == 2)
3413 /* a boulder may fill the new pit, crushing monster */
3414 fill_pit(trap->tx, trap->ty);
3415 if (DEADMONSTER(mtmp))
3417 if (unconscious()) {
3420 nomovemsg = "The explosion awakens you!";
3422 nomovemsg = "
\94\9a\94
\82Å
\82 \82È
\82½
\82Í
\8bN
\82«
\82½
\81I";
3426 if (resists_magm(mtmp)) {
3427 shieldeff(mtmp->mx, mtmp->my);
3428 } else if (!resist(mtmp, WAND_CLASS, 0, NOTELL)) {
3429 if (newcham(mtmp, (struct permonst *) 0, FALSE, FALSE))
3430 /* we're done with mptr but keep it up to date */
3436 case ROLLING_BOULDER_TRAP:
3437 if (!is_flyer(mptr)) {
3438 int style = ROLL | (in_sight ? 0 : LAUNCH_UNSEEN);
3440 newsym(mtmp->mx, mtmp->my);
3443 pline("Click! %s triggers %s.", Monnam(mtmp),
3444 trap->tseen ? "a rolling boulder trap" : something);
3446 pline("
\83J
\83`
\83b
\81I%s
\82Í%s
\82Ì
\83X
\83C
\83b
\83`
\82ð
\93¥
\82ñ
\82¾
\81I", Monnam(mtmp),
3447 trap->tseen ? "
\97\8e\8aâ
\82Ìã©" : "
\89½
\82©");
3449 if (launch_obj(BOULDER, trap->launch.x, trap->launch.y,
3450 trap->launch2.x, trap->launch2.y, style)) {
3453 if (DEADMONSTER(mtmp))
3457 newsym(mtmp->mx, mtmp->my);
3461 case VIBRATING_SQUARE:
3462 if (see_it && !Blind) {
3463 seetrap(trap); /* before messages */
3466 char buf[BUFSZ], *p, *monnm = mon_nam(mtmp);
3468 if (nolimbs(mtmp->data)
3469 || is_floater(mtmp->data) || is_flyer(mtmp->data)) {
3470 /* just "beneath <mon>" */
3473 Strcpy(buf, s_suffix(monnm));
3474 p = eos(strcat(buf, " "));
3475 Strcpy(p, makeplural(mbodypart(mtmp, FOOT)));
3476 /* avoid "beneath 'rear paws'" or 'rear hooves' */
3477 (void) strsubst(p, "rear ", "");
3479 You_see("a strange vibration beneath %s.", buf);
3480 #else /*
\91«
\82ª
\82È
\82
\82Ä
\82à
\81u
\91«
\8c³
\81v
\82Å
\93\9d\88ê */
3481 You_see("%s
\82Ì
\91«
\8c³
\82ª
\95s
\8ev
\8bc
\82É
\90U
\93®
\82µ
\82Ä
\82¢
\82é
\82Ì
\82ð
\8c©
\82½
\81D",
3485 /* notice something (hearing uses a larger threshold
3488 You_see("the ground vibrate %s.",
3489 (distu(mtmp->mx, mtmp->my) <= 2 * 2)
3490 ? "nearby" : "in the distance");
3492 You_see("%s
\82
\82Å
\92n
\96Ê
\82ª
\90U
\93®
\82µ
\82Ä
\82¢
\82é
\82Ì
\82ð
\8c©
\82½
\81D",
3493 (distu(mtmp->mx, mtmp->my) <= 2 * 2)
3494 ? "
\8bß" : "
\89\93");
3500 impossible("Some monster encountered a strange trap of type %d.",
3506 return mtmp->mtrapped;
3509 /* Combine cockatrice checks into single functions to avoid repeating code. */
3514 if (Stone_resistance)
3516 if (poly_when_stoned(youmonst.data) && polymon(PM_STONE_GOLEM))
3519 You("turn to stone...");
3521 You("
\90Î
\82É
\82È
\82Á
\82½
\81D
\81D
\81D");
3522 killer.format = KILLED_BY;
3523 if (str != killer.name)
3524 Strcpy(killer.name, str ? str : "");
3529 minstapetrify(mon, byplayer)
3533 if (resists_ston(mon))
3535 if (poly_when_stoned(mon->data)) {
3539 if (!vamp_stone(mon))
3542 /* give a "<mon> is slowing down" message and also remove
3543 intrinsic speed (comparable to similar effect on the hero) */
3544 mon_adjust_speed(mon, -3, (struct obj *) 0);
3546 if (cansee(mon->mx, mon->my))
3548 pline("%s turns to stone.", Monnam(mon));
3550 pline("%s
\82Í
\90Î
\82É
\82È
\82Á
\82½
\81D", Monnam(mon));
3553 xkilled(mon, XKILL_NOMSG);
3564 if (uwep && uwep->otyp == CORPSE && touch_petrifies(&mons[uwep->corpsenm])
3565 && !Stone_resistance) {
3567 pline("%s touch the %s corpse.", arg, mons[uwep->corpsenm].mname);
3569 pline("%s%s
\82Ì
\8e\80\91Ì
\82É
\90G
\82Á
\82½
\81D", arg, mons[uwep->corpsenm].mname);
3571 Sprintf(kbuf, "%s corpse", an(mons[uwep->corpsenm].mname));
3573 Sprintf(kbuf, "%s
\82Ì
\8e\80\91Ì
\82Å", mons[uwep->corpsenm].mname);
3575 /* life-saved; unwield the corpse if we can't handle it */
3576 if (!uarmg && !Stone_resistance)
3579 /* Or your secondary weapon, if wielded [hypothetical; we don't
3580 allow two-weapon combat when either weapon is a corpse] */
3581 if (u.twoweap && uswapwep && uswapwep->otyp == CORPSE
3582 && touch_petrifies(&mons[uswapwep->corpsenm]) && !Stone_resistance) {
3584 pline("%s touch the %s corpse.", arg, mons[uswapwep->corpsenm].mname);
3586 pline("%s%s
\82Ì
\8e\80\91Ì
\82É
\90G
\82Á
\82½
\81D", arg, mons[uswapwep->corpsenm].mname);
3588 Sprintf(kbuf, "%s corpse", an(mons[uswapwep->corpsenm].mname));
3590 Sprintf(kbuf, "%s
\82Ì
\8e\80\91Ì
\82Å", mons[uswapwep->corpsenm].mname);
3592 /* life-saved; unwield the corpse */
3593 if (!uarmg && !Stone_resistance)
3599 mselftouch(mon, arg, byplayer)
3604 struct obj *mwep = MON_WEP(mon);
3606 if (mwep && mwep->otyp == CORPSE && touch_petrifies(&mons[mwep->corpsenm])
3607 && !resists_ston(mon)) {
3608 if (cansee(mon->mx, mon->my)) {
3610 pline("%s%s touches %s.", arg ? arg : "",
3611 arg ? mon_nam(mon) : Monnam(mon),
3612 corpse_xname(mwep, (const char *) 0, CXN_PFX_THE));
3614 pline("%s%s
\82Í%s
\82Ì
\8e\80\91Ì
\82É
\90G
\82Á
\82½
\81D", arg ? arg : "",
3615 arg ? mon_nam(mon) : Monnam(mon),
3616 corpse_xname(mwep, (const char *) 0, CXN_PFX_THE));
3619 minstapetrify(mon, byplayer);
3620 /* if life-saved, might not be able to continue wielding */
3621 if (!DEADMONSTER(mon) && !which_armor(mon, W_ARMG) && !resists_ston(mon))
3626 /* start levitating */
3630 context.botl = TRUE;
3632 if (u.utraptype == TT_PIT) {
3635 You("float up, out of the pit!");
3637 You("
\95\82\82«
\8fã
\82ª
\82Á
\82Ä
\81C
\97\8e\82µ
\8c\8a\82©
\82ç
\8fo
\82½
\81I");
3638 vision_full_recalc = 1; /* vision limits change */
3639 fill_pit(u.ux, u.uy);
3640 } else if (u.utraptype == TT_LAVA /* molten lava */
3641 || u.utraptype == TT_INFLOOR) { /* solidified lava */
3643 Your("body pulls upward, but your %s are still stuck.",
3645 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",
3646 makeplural(body_part(LEG)));
3647 } else if (u.utraptype == TT_BURIEDBALL) { /* tethered */
3650 cc.x = u.ux, cc.y = u.uy;
3651 /* caveat: this finds the first buried iron ball within
3652 one step of the specified location, not necessarily the
3653 buried [former] uball at the original anchor point */
3654 (void) buried_ball(&cc);
3655 /* being chained to the floor blocks levitation from floating
3656 above that floor but not from enhancing carrying capacity */
3658 You("feel lighter, but your %s is still chained to the %s.",
3660 IS_ROOM(levl[cc.x][cc.y].typ) ? "floor" : "ground");
3662 You("
\82·
\82±
\82µ
\8cy
\82
\82È
\82Á
\82½
\82ª
\81C
\82 \82È
\82½
\82Ì%s
\82Í
\82Ü
\82¾%s
\82É
\82Â
\82È
\82ª
\82Á
\82Ä
\82¢
\82é
\81D",
3664 IS_ROOM(levl[cc.x][cc.y].typ) ? "
\8f°" : "
\92n
\96Ê");
3666 } else if (u.utraptype == WEB) {
3668 You("float up slightly, but you are still stuck in the web.");
3670 You("
\82·
\82±
\82µ
\95\82\82«
\8fã
\82ª
\82Á
\82½
\82ª
\81C
\82Ü
\82¾
\82
\82à
\82Ì
\91\83\82É
\82Â
\82©
\82Ü
\82Á
\82Ä
\82¢
\82é
\81D");
3671 } else { /* bear trap */
3673 You("float up slightly, but your %s is still stuck.",
3675 You("
\8f
\82µ
\95\82\82«
\8fã
\82ª
\82Á
\82½
\82ª%s
\82Í
\82Ü
\82¾
\82Í
\82Ü
\82Á
\82Ä
\82¢
\82é
\81D",
3678 /* when still trapped, float_vs_flight() below will block levitation */
3680 } else if (Is_waterlevel(&u.uz)) {
3682 pline("It feels as though you've lost some weight.");
3684 You("
\82Ü
\82é
\82Å
\91Ì
\8fd
\82ª
\8c¸
\82Á
\82½
\82æ
\82¤
\82É
\8a´
\82¶
\82½
\81D");
3686 } else if (u.uinwater) {
3688 } else if (u.uswallow) {
3690 You(is_animal(u.ustuck->data) ? "float away from the %s."
3691 : "spiral up into %s.",
3692 is_animal(u.ustuck->data) ? surface(u.ux, u.uy)
3693 : mon_nam(u.ustuck));
3695 You(is_animal(u.ustuck->data) ? "%s
\82Ì
\92\86\82Å
\95\82\82¢
\82½
\81D"
3696 : "%s
\82Ì
\92\86\82Å
\82®
\82é
\82®
\82é
\89ñ
\93]
\82µ
\82½
\81D",
3697 is_animal(u.ustuck->data) ? surface(u.ux, u.uy)
3698 : mon_nam(u.ustuck));
3700 } else if (Hallucination) {
3702 pline("Up, up, and awaaaay! You're walking on air!");
3704 pline("
\8fã
\82ê
\81C
\8fã
\82ê
\81C
\8fã
\82ê
\82¥
\82¥
\82¥
\82¥
\81I
\82 \82È
\82½
\82Í
\8bó
\92\86\82ð
\95à
\82¢
\82Ä
\82¢
\82é
\81I");
3705 } else if (Is_airlevel(&u.uz)) {
3707 You("gain control over your movements.");
3709 You("
\82¤
\82Ü
\82
\93®
\82¯
\82é
\82æ
\82¤
\82É
\82È
\82Á
\82½
\81D");
3712 You("start to float in the air!");
3714 You("
\8bó
\92\86\82É
\95\82\82«
\82Í
\82¶
\82ß
\82½
\81I");
3716 if (u.usteed && !is_floater(u.usteed->data) && !is_flyer(u.usteed->data)) {
3719 pline("%s magically floats up!", Monnam(u.usteed));
3721 pline("%s
\82Í
\96\82\96@
\82Ì
\97Í
\82Å
\95\82\82¢
\82½
\81I", Monnam(u.usteed));
3724 You("cannot stay on %s.", mon_nam(u.usteed));
3726 You("%s
\82Ì
\8fã
\82É
\8fæ
\82Á
\82Ä
\82¢
\82ç
\82ê
\82È
\82¢
\81D", mon_nam(u.usteed));
3727 dismount_steed(DISMOUNT_GENERIC);
3732 You("are no longer able to control your flight.");
3734 You("
\8bó
\92\86\82Å
\82¤
\82Ü
\82
\93®
\82¯
\82È
\82
\82È
\82Á
\82½
\81D");
3735 float_vs_flight(); /* set BFlying, also BLevitation if still trapped */
3736 /* levitation gives maximum carrying capacity, so encumbrance
3737 state might be reduced */
3738 (void) encumber_msg();
3749 if ((t = t_at(x, y)) && is_pit(t->ttyp)
3750 && (otmp = sobj_at(BOULDER, x, y))) {
3751 obj_extract_self(otmp);
3753 (void) flooreffects(otmp, x, y, "settle");
3755 (void) flooreffects(otmp, x, y, "
\82Í
\82Ü
\82é");
3759 /* stop levitating */
3761 float_down(hmask, emask)
3762 long hmask, emask; /* might cancel timeout */
3764 register struct trap *trap = (struct trap *) 0;
3765 d_level current_dungeon_level;
3766 boolean no_msg = FALSE;
3768 HLevitation &= ~hmask;
3769 ELevitation &= ~emask;
3771 return 0; /* maybe another ring/potion/boots */
3773 /* if blocked by terrain, we haven't actually been levitating so
3774 we don't give any end-of-levitation feedback or side-effects,
3775 but if blocking is solely due to being trapped in/on floor,
3776 do give some feedback but skip other float_down() effects */
3777 boolean trapped = (BLevitation == I_SPECIAL);
3780 if (trapped && u.utrap) /* u.utrap => paranoia */
3782 You("are no longer trying to float up from the %s.",
3783 (u.utraptype == TT_BEARTRAP) ? "trap's jaws"
3784 : (u.utraptype == TT_WEB) ? "web"
3785 : (u.utraptype == TT_BURIEDBALL) ? "chain"
3786 : (u.utraptype == TT_LAVA) ? "lava"
3787 : "ground"); /* TT_INFLOOR */
3789 You("
\82à
\82Í
\82â%s
\82©
\82ç
\95\82\82«
\8fã
\82ª
\82ë
\82¤
\82Æ
\82µ
\82È
\82
\82È
\82Á
\82½
\81D",
3790 (u.utraptype == TT_BEARTRAP) ? "ã©
\82Ì
\8e\95"
3791 : (u.utraptype == TT_WEB) ? "
\82
\82à
\82Ì
\91\83"
3792 : (u.utraptype == TT_BURIEDBALL) ? "
\8d½"
3793 : (u.utraptype == TT_LAVA) ? "
\97n
\8aâ"
3794 : "
\92n
\96Ê"); /* TT_INFLOOR */
3796 (void) encumber_msg(); /* carrying capacity might have changed */
3799 context.botl = TRUE;
3800 nomul(0); /* stop running or resting */
3802 /* controlled flight no longer overridden by levitation */
3803 float_vs_flight(); /* clears BFlying & I_SPECIAL
3804 * unless hero is stuck in floor */
3807 You("have stopped levitating and are now flying.");
3809 You("
\8bó
\92\86\95\82\97V
\82ð
\8e~
\82ß
\82Ä
\8bó
\82ð
\94ò
\82Ñ
\82Í
\82¶
\82ß
\82½
\81D");
3810 (void) encumber_msg(); /* carrying capacity might have changed */
3816 You("float down, but you are still %s.",
3817 is_animal(u.ustuck->data) ? "swallowed" : "engulfed");
3819 You("
\92\85\92n
\82µ
\82½
\82ª
\81C
\82Ü
\82¾
\88ù
\82Ý
\8d\9e\82Ü
\82ê
\82½
\82Ü
\82Ü
\82¾
\81D");
3821 (void) encumber_msg();
3825 if (Punished && !carried(uball)
3826 && (is_pool(uball->ox, uball->oy)
3827 || ((trap = t_at(uball->ox, uball->oy))
3828 && (is_pit(trap->ttyp) || is_hole(trap->ttyp))))) {
3833 movobj(uchain, uball->ox, uball->oy);
3834 newsym(u.ux0, u.uy0);
3835 vision_full_recalc = 1; /* in case the hero moved. */
3837 /* check for falling into pool - added by GAN 10/20/86 */
3839 if (!u.uswallow && u.ustuck) {
3840 if (sticks(youmonst.data))
3842 You("aren't able to maintain your hold on %s.",
3845 You("%s
\82ð
\82Â
\82©
\82Ü
\82¦
\91±
\82¯
\82Ä
\82¢
\82ç
\82ê
\82È
\82
\82È
\82Á
\82½
\81D",
3850 pline("Startled, %s can no longer hold you!",
3853 pline("%s
\82Í
\8bÁ
\82¢
\82Ä
\82 \82È
\82½
\82ð
\95ú
\82µ
\82Ä
\82µ
\82Ü
\82Á
\82½
\81I",
3859 * drown() and lava_effects() print various messages almost
3860 * every time they're called which conflict with the "fall
3861 * into" message below. Thus, we want to avoid printing
3862 * confusing, duplicate or out-of-order messages.
3863 * Use knowledge of the two routines as a hack -- this
3864 * should really be handled differently -dlc
3866 if (is_pool(u.ux, u.uy) && !Wwalking && !Swimming && !u.uinwater)
3869 if (is_lava(u.ux, u.uy)) {
3870 (void) lava_effects();
3875 trap = t_at(u.ux, u.uy);
3876 if (Is_airlevel(&u.uz)) {
3878 You("begin to tumble in place.");
3880 You("
\82»
\82Ì
\8fê
\82Å
\82Ð
\82Á
\82
\82è
\95Ô
\82è
\82Í
\82¶
\82ß
\82½
\81D");
3881 } else if (Is_waterlevel(&u.uz) && !no_msg) {
3883 You_feel("heavier.");
3885 You("
\8fd
\82
\82È
\82Á
\82½
\82æ
\82¤
\82È
\8bC
\82ª
\82µ
\82½
\81D");
3886 /* u.uinwater msgs already in spoteffects()/drown() */
3887 } else if (!u.uinwater && !no_msg) {
3888 if (!(emask & W_SADDLE)) {
3889 if (Sokoban && trap) {
3890 /* Justification elsewhere for Sokoban traps is based
3891 * on air currents. This is consistent with that.
3892 * The unexpected additional force of the air currents
3893 * once levitation ceases knocks you off your feet.
3897 pline("Bummer! You've crashed.");
3899 pline("
\82â
\82ß
\82Ä
\82¥
\81I
\82 \82È
\82½
\82Í
\92@
\82«
\82Â
\82¯
\82ç
\82ê
\82½
\81D");
3904 You("
\82Â
\82Ü
\82Ã
\82¢
\82½
\81D");
3906 losehp(rnd(2), "dangerous winds", KILLED_BY);
3908 losehp(rnd(2), "
\8aë
\8c¯
\82È
\95\97\82Å", KILLED_BY);
3910 dismount_steed(DISMOUNT_FELL);
3912 selftouch("As you fall, you");
3914 selftouch("
\97\8e\82¿
\82È
\82ª
\82ç
\81C
\82 \82È
\82½
\82Í");
3915 } else if (u.usteed && (is_floater(u.usteed->data)
3916 || is_flyer(u.usteed->data))) {
3918 You("settle more firmly in the saddle.");
3920 You("
\82æ
\82è
\82µ
\82Á
\82©
\82è
\82Æ
\88Æ
\82É
\94[
\82Ü
\82Á
\82½
\81D");
3921 } else if (Hallucination) {
3923 pline("Bummer! You've %s.",
3926 : "hit the ground");
3928 pline("
\82â
\82ß
\82Ä
\82¥
\81I
\82 \82È
\82½
\82Í%s
\82É
\92@
\82«
\82Â
\82¯
\82ç
\82ê
\82½
\81D",
3935 You("float gently to the %s.", surface(u.ux, u.uy));
3937 You("
\90Ã
\82©
\82É%s
\82Ü
\82Å
\92H
\82è
\82Â
\82¢
\82½
\81D", surface(u.ux, u.uy));
3943 /* levitation gives maximum carrying capacity, so having it end
3944 potentially triggers greater encumbrance; do this after
3945 'come down' messages, before trap activation or autopickup */
3946 (void) encumber_msg();
3948 /* can't rely on u.uz0 for detecting trap door-induced level change;
3949 it gets changed to reflect the new level before we can check it */
3950 assign_level(¤t_dungeon_level, &u.uz);
3952 switch (trap->ttyp) {
3957 if (!Can_fall_thru(&u.uz) || u.ustuck)
3961 if (!u.utrap) /* not already in the trap */
3965 if (!Is_airlevel(&u.uz) && !Is_waterlevel(&u.uz) && !u.uswallow
3966 /* falling through trap door calls goto_level,
3967 and goto_level does its own pickup() call */
3968 && on_level(&u.uz, ¤t_dungeon_level))
3973 /* shared code for climbing out of a pit */
3977 if (!u.utrap || u.utraptype != TT_PIT)
3981 /* marked as trapped so they can pick things up */
3983 You("ascend from the pit.");
3985 You("
\97\8e\82µ
\8c\8a\82ð
\8fã
\82Á
\82Ä
\82¢
\82Á
\82½
\81D");
3987 fill_pit(u.ux, u.uy);
3988 vision_full_recalc = 1; /* vision limits change */
3989 } else if (!rn2(2) && sobj_at(BOULDER, u.ux, u.uy)) {
3991 Your("%s gets stuck in a crevice.", body_part(LEG));
3993 Your("%s
\82Í
\8a\84\82ê
\96Ú
\82É
\82Í
\82Ü
\82Á
\82½
\81D", body_part(LEG));
3994 display_nhwindow(WIN_MESSAGE, FALSE);
3995 clear_nhwindow(WIN_MESSAGE);
3997 You("free your %s.", body_part(LEG));
3999 Your("%s
\82Í
\8e©
\97R
\82É
\82È
\82Á
\82½
\81D", body_part(LEG));
4000 } else if ((Flying || is_clinger(youmonst.data)) && !Sokoban) {
4001 /* eg fell in pit, then poly'd to a flying monster;
4002 or used '>' to deliberately enter it */
4004 You("%s from the pit.", Flying ? "fly" : "climb");
4006 You("
\97\8e\82µ
\8c\8a\82©
\82ç%s
\82¢
\82Á
\82½
\81D", Flying ? "
\8fã
\82Á
\82Ä" : "
\93o
\82Á
\82Ä");
4008 fill_pit(u.ux, u.uy);
4009 vision_full_recalc = 1; /* vision limits change */
4010 } else if (!(--u.utrap)) {
4013 You("%s to the edge of the pit.",
4014 (Sokoban && Levitation)
4015 ? "struggle against the air currents and float"
4016 : u.usteed ? "ride" : "crawl");
4018 You("%s
\97\8e\82µ
\8c\8a\82Ì
\92[
\82É
\82½
\82Ç
\82è
\92\85\82¢
\82½
\81D",
4019 (Sokoban && Levitation)
4020 ? "
\8bó
\8bC
\82Ì
\97¬
\82ê
\82Ì
\92\86\82Å
\82à
\82ª
\82«
\82È
\82ª
\82ç" : "");
4022 fill_pit(u.ux, u.uy);
4023 vision_full_recalc = 1; /* vision limits change */
4024 } else if (u.dz || flags.verbose) {
4027 Norep("%s is still in a pit.", upstart(y_monnam(u.usteed)));
4029 Norep("%s
\82Í
\82Ü
\82¾
\97\8e\82µ
\8c\8a\82Ì
\92\86\82É
\82¢
\82é
\81D", y_monnam(u.usteed));
4032 Norep((Hallucination && !rn2(5))
4033 ? "You've fallen, and you can't get up."
4034 : "You are still in a pit.");
4036 Norep((Hallucination && !rn2(5))
4037 ? "
\82 \82È
\82½
\82Í
\97\8e\82¿
\81C
\8fã
\82ª
\82ê
\82È
\82¢
\81D"
4038 : "
\82 \82È
\82½
\82Í
\82Ü
\82¾
\97\8e\82µ
\8c\8a\82Ì
\92\86\82É
\82¢
\82é
\81D");
4045 struct obj *box; /* null for floor trap */
4047 boolean see_it = !Blind;
4050 /* Bug: for box case, the equivalent of burn_floor_objects() ought
4051 * to be done upon its contents.
4054 if ((box && !carried(box)) ? is_pool(box->ox, box->oy) : Underwater) {
4056 pline("A cascade of steamy bubbles erupts from %s!",
4058 pline("
\8fö
\8bC
\82Ì
\96A
\82ª%s
\82©
\82ç
\82µ
\82ã
\81[
\82Á
\82Æ
\94
\90¶
\82µ
\82½
\81I",
4059 the(box ? xname(box) : surface(u.ux, u.uy)));
4060 if (Fire_resistance)
4062 You("are uninjured.");
4064 You("
\8f\9d\82Â
\82©
\82È
\82¢
\81D");
4067 losehp(rnd(3), "boiling water", KILLED_BY);
4069 losehp(rnd(3), "
\95¦
\93«
\82µ
\82½
\90\85\82Å", KILLED_BY);
4073 pline("A %s %s from %s!", tower_of_flame, box ? "bursts" : "erupts",
4074 the(box ? xname(box) : surface(u.ux, u.uy)));
4076 pline("
\89Î
\92\8c\82ª%s
\82©
\82ç%s
\81I", box ? xname(box) : surface(u.ux,u.uy),
4077 box ? "
\90\81\82«
\8fo
\82µ
\82½" : "
\97§
\82¿
\82Ì
\82Ú
\82Á
\82½");
4079 if (Fire_resistance) {
4080 shieldeff(u.ux, u.uy);
4082 } else if (Upolyd) {
4084 switch (u.umonnum) {
4085 case PM_PAPER_GOLEM:
4088 case PM_STRAW_GOLEM:
4094 case PM_LEATHER_GOLEM:
4103 if (u.mhmax > mons[u.umonnum].mlevel)
4104 u.mhmax -= rn2(min(u.mhmax, num + 1)), context.botl = 1;
4107 if (u.uhpmax > u.ulevel)
4108 u.uhpmax -= rn2(min(u.uhpmax, num + 1)), context.botl = 1;
4112 You("are uninjured.");
4114 You("
\8f\9d\82Â
\82©
\82È
\82¢
\81D");
4117 losehp(num, tower_of_flame, KILLED_BY_AN); /* fire damage */
4119 losehp(num, "
\89Î
\92\8c\82Å", KILLED_BY_AN); /* fire damage */
4123 if (burnarmor(&youmonst) || rn2(3)) {
4124 destroy_item(SCROLL_CLASS, AD_FIRE);
4125 destroy_item(SPBOOK_CLASS, AD_FIRE);
4126 destroy_item(POTION_CLASS, AD_FIRE);
4128 if (!box && burn_floor_objects(u.ux, u.uy, see_it, TRUE) && !see_it)
4130 You("smell paper burning.");
4132 You("
\8e\86\82Ì
\82±
\82°
\82é
\93õ
\82¢
\82ª
\82µ
\82½
\81D");
4133 if (is_ice(u.ux, u.uy))
4134 melt_ice(u.ux, u.uy, (char *) 0);
4140 register int fate = rnd(20);
4142 /* What happened to the poor sucker? */
4145 /* Most of the time, it creates some monsters. */
4148 /* blindness effects */
4149 if (!resists_blnd(&youmonst)) {
4151 You("are momentarily blinded by a flash of light!");
4153 You("
\82Ü
\82Î
\82ä
\82¢
\8cõ
\82Å
\88ê
\8fu
\96Ú
\82ª
\82
\82ç
\82ñ
\82¾
\81I");
4154 make_blinded((long) rn1(5, 10), FALSE);
4156 Your1(vision_clears);
4157 } else if (!Blind) {
4159 You_see("a flash of light!");
4161 You("
\82Ü
\82Î
\82ä
\82¢
\8cõ
\82ð
\97\81\82Ñ
\82½
\81I");
4164 /* deafness effects */
4167 You_hear("a deafening roar!");
4169 You_hear("
\8e¨
\82ð
\82Â
\82ñ
\82´
\82
\82æ
\82¤
\82È
\99ô
\9aK
\82ð
\95·
\82¢
\82½
\81I");
4170 incr_itimeout(&HDeaf, rn1(20, 30));
4171 context.botl = TRUE;
4173 /* magic vibrations still hit you */
4175 You_feel("rankled.");
4177 You_feel("
\82¢
\82ç
\82¢
\82ç
\82µ
\82½
\81D");
4178 incr_itimeout(&HDeaf, rn1(5, 15));
4179 context.botl = TRUE;
4182 (void) makemon((struct permonst *) 0, u.ux, u.uy, NO_MM_FLAGS);
4183 /* roar: wake monsters in vicinity, after placing trap-created ones */
4184 wake_nearto(u.ux, u.uy, 7 * 7);
4185 /* [flash: should probably also hit nearby gremlins with light] */
4190 /* sometimes nothing happens */
4192 case 12: /* a flash of fire */
4193 dofiretrap((struct obj *) 0);
4199 pline("A shiver runs up and down your %s!", body_part(SPINE));
4201 pline("
\90k
\82¦
\82ª
\82 \82È
\82½
\82Ì%s
\82ð
\91\96\82Á
\82½
\81I", body_part(SPINE));
4205 You_hear(Hallucination ? "the moon howling at you."
4206 : "distant howling.");
4208 You_hear(Hallucination ? "
\8c\8e\82ª
\96i
\82¦
\82Ä
\82¢
\82é
\82Ì
\82ð
\95·
\82¢
\82½
\81D"
4209 : "
\89\93\95û
\82Ì
\89\93\96i
\82ð
\95·
\82¢
\82½
\81D");
4213 if (on_level(&u.uz, &qstart_level))
4216 "%slike the prodigal son.",
4217 (flags.female || (Upolyd && is_neuter(youmonst.data)))
4220 #else /*JP
\90¹
\8f\91\82Ì
\83\8b\83J
\93`
\82æ
\82è */
4221 You("%s
\95ú
\93 \91§
\8eq
\82Ì
\82æ
\82¤
\82É
\82È
\82Á
\82½
\82æ
\82¤
\82È
\8bC
\82ª
\82µ
\82½
\81D",
4222 (flags.female || (Upolyd && is_neuter(youmonst.data)))
4228 You("suddenly yearn for %s.",
4231 : (In_quest(&u.uz) || at_dgn_entrance("The Quest"))
4232 ? "your nearby homeland"
4233 : "your distant homeland");
4235 You("
\93Ë
\91R%s
\82ª
\97ö
\82µ
\82
\82È
\82Á
\82½
\81D",
4236 Hallucination ? "
\90Â
\90X"
4237 : (In_quest(&u.uz) || at_dgn_entrance("
\83N
\83G
\83X
\83g"))
4238 ? "
\82·
\82®
\82»
\82±
\82É
\82 \82é
\8cÌ
\8b½"
4239 : "
\82Í
\82é
\82©
\82©
\82È
\82½
\82Ì
\8cÌ
\8b½");
4244 Your("pack shakes violently!");
4246 Your("
\91Ü
\82Í
\8c\83\82µ
\82
\97h
\82ê
\82½
\81I");
4250 You(Hallucination ? "smell hamburgers." : "smell charred flesh.");
4252 You(Hallucination ? "
\83n
\83\93\83o
\81[
\83K
\81[
\82Ì
\93õ
\82¢
\82ª
\82µ
\82½
\81D" : "
\8d\95\8fÅ
\82°
\82Ì
\93÷
\82Ì
\93õ
\82¢
\82ª
\82µ
\82½
\81D");
4258 You("
\94æ
\82ê
\82ð
\8a´
\82¶
\82½
\81D");
4261 /* very occasionally something nice happens. */
4262 case 19: { /* tame nearby monsters */
4266 (void) adjattrib(A_CHA, 1, FALSE);
4267 for (i = -1; i <= 1; i++)
4268 for (j = -1; j <= 1; j++) {
4269 if (!isok(u.ux + i, u.uy + j))
4271 mtmp = m_at(u.ux + i, u.uy + j);
4273 (void) tamedog(mtmp, (struct obj *) 0);
4277 case 20: { /* uncurse stuff */
4279 long save_conf = HConfusion;
4281 pseudo = zeroobj; /* neither cursed nor blessed,
4282 and zero out oextra */
4283 pseudo.otyp = SCR_REMOVE_CURSE;
4285 (void) seffects(&pseudo);
4286 HConfusion = save_conf;
4294 /* Set an item on fire.
4295 * "force" means not to roll a luck-based protection check for the
4297 * "x" and "y" are the coordinates to dump the contents of a
4298 * container, if it burns up.
4300 * Return whether the object was destroyed.
4303 fire_damage(obj, force, x, y)
4309 struct obj *otmp, *ncobj;
4310 int in_sight = !Blind && couldsee(x, y); /* Don't care if it's lit */
4313 /* object might light in a controlled manner */
4317 if (Is_container(obj)) {
4318 switch (obj->otyp) {
4320 return FALSE; /* Immune */
4331 if ((!force && (Luck + 5) > rn2(chance))
4332 || (is_flammable(obj) && obj->oerodeproof))
4334 /* Container is burnt up - dump contents out */
4337 pline("%s catches fire and burns.", Yname2(obj));
4339 pline("%s
\82Í
\89Î
\82ª
\82Â
\82¢
\82Ä
\94R
\82¦
\82½
\81D", Yname2(obj));
4340 if (Has_contents(obj)) {
4343 pline("Its contents fall out.");
4345 pline("
\92\86\90g
\82ª
\8fo
\82Ä
\82«
\82½
\81D");
4346 for (otmp = obj->cobj; otmp; otmp = ncobj) {
4348 obj_extract_self(otmp);
4349 if (!flooreffects(otmp, x, y, ""))
4350 place_object(otmp, x, y);
4356 } else if (!force && (Luck + 5) > rn2(20)) {
4357 /* chance per item of sustaining damage:
4358 * max luck (Luck==13): 10%
4359 * avg luck (Luck==0): 75%
4360 * awful luck (Luck<-4): 100%
4363 } else if (obj->oclass == SCROLL_CLASS || obj->oclass == SPBOOK_CLASS) {
4364 if (obj->otyp == SCR_FIRE || obj->otyp == SPE_FIREBALL)
4366 if (obj->otyp == SPE_BOOK_OF_THE_DEAD) {
4369 pline("Smoke rises from %s.", the(xname(obj)));
4371 pline("%s
\82©
\82ç
\89\8c\82ª
\82 \82ª
\82Á
\82½
\81D", the(xname(obj)));
4374 dindx = (obj->oclass == SCROLL_CLASS) ? 3 : 4;
4377 pline("%s %s.", Yname2(obj),
4378 destroy_strings[dindx][(obj->quan > 1L)]);
4380 pline("%s
\82Í%s
\81D", Yname2(obj),
4381 destroy_strings[dindx][(obj->quan > 1L)]);
4386 } else if (obj->oclass == POTION_CLASS) {
4387 dindx = (obj->otyp != POT_OIL) ? 1 : 2;
4390 pline("%s %s.", Yname2(obj),
4391 destroy_strings[dindx][(obj->quan > 1L)]);
4393 pline("%s
\82Í%s
\81D", Yname2(obj),
4394 destroy_strings[dindx][(obj->quan > 1L)]);
4399 } else if (erode_obj(obj, (char *) 0, ERODE_BURN, EF_DESTROY)
4407 * Apply fire_damage() to an entire chain.
4409 * Return number of objects destroyed. --ALI
4412 fire_damage_chain(chain, force, here, x, y)
4414 boolean force, here;
4417 struct obj *obj, *nobj;
4420 for (obj = chain; obj; obj = nobj) {
4421 nobj = here ? obj->nexthere : obj->nobj;
4422 if (fire_damage(obj, force, x, y))
4426 if (num && (Blind && !couldsee(x, y)))
4428 You("smell smoke.");
4430 You("
\89\8c\82Ì
\82É
\82¨
\82¢
\82ª
\82µ
\82½
\81D");
4434 /* obj has been thrown or dropped into lava; damage is worse than mere fire */
4436 lava_damage(obj, x, y)
4440 int otyp = obj->otyp, ocls = obj->oclass;
4442 /* the Amulet, invocation items, and Rider corpses are never destroyed
4443 (let Book of the Dead fall through to fire_damage() to get feedback) */
4444 if (obj_resists(obj, 0, 0) && otyp != SPE_BOOK_OF_THE_DEAD)
4446 /* destroy liquid (venom), wax, veggy, flesh, paper (except for scrolls
4447 and books--let fire damage deal with them), cloth, leather, wood, bone
4448 unless it's inherently or explicitly fireproof or contains something;
4449 note: potions are glass so fall through to fire_damage() and boil */
4450 if (objects[otyp].oc_material < DRAGON_HIDE
4451 && ocls != SCROLL_CLASS && ocls != SPBOOK_CLASS
4452 && objects[otyp].oc_oprop != FIRE_RES
4453 && otyp != WAN_FIRE && otyp != FIRE_HORN
4454 /* assumes oerodeproof isn't overloaded for some other purpose on
4455 non-eroding items */
4456 && !obj->oerodeproof
4457 /* fire_damage() knows how to deal with containers and contents */
4458 && !Has_contents(obj)) {
4460 /* this feedback is pretty clunky and can become very verbose
4461 when former contents of a burned container get here via
4463 if (obj == thrownobj || obj == kickedobj)
4465 pline("%s %s up!", is_plural(obj) ? "They" : "It",
4466 otense(obj, "burn"));
4468 pline("
\82»
\82ê
\82Í
\94R
\82¦
\82Â
\82«
\82½
\81I");
4472 You_see("%s hit lava and burn up!", doname(obj));
4474 You_see("%s
\82Í
\97n
\8aâ
\82É
\93\96\82½
\82Á
\82Ä
\94R
\82¦
\82Â
\82«
\82½
\81I", doname(obj));
4476 if (carried(obj)) { /* shouldn't happen */
4477 remove_worn_item(obj, TRUE);
4483 return fire_damage(obj, TRUE, x, y);
4490 /* Scrolls but not spellbooks can be erased by acid. */
4491 struct monst *victim;
4497 victim = carried(obj) ? &youmonst : mcarried(obj) ? obj->ocarry : NULL;
4498 vismon = victim && (victim != &youmonst) && canseemon(victim);
4501 grease_protect(obj, (char *) 0, victim);
4502 } else if (obj->oclass == SCROLL_CLASS && obj->otyp != SCR_BLANK_PAPER) {
4503 if (obj->otyp != SCR_BLANK_PAPER
4505 && obj->otyp != SCR_MAIL
4509 if (victim == &youmonst)
4511 pline("Your %s.", aobjnam(obj, "fade"));
4513 pline("%s
\82Ì
\95¶
\8e\9a\82Í
\94\96\82ê
\82½
\81D", xname(obj));
4516 pline("%s %s.", s_suffix(Monnam(victim)),
4517 aobjnam(obj, "fade"));
4519 pline("%s
\82Ì%s
\82Ì
\95¶
\8e\9a\82Í
\94\96\82ê
\82½
\81D", Monnam(victim),
4524 obj->otyp = SCR_BLANK_PAPER;
4528 erode_obj(obj, (char *) 0, ERODE_CORRODE, EF_GREASE | EF_VERBOSE);
4531 /* context for water_damage(), managed by water_damage_chain();
4532 when more than one stack of potions of acid explode while processing
4533 a chain of objects, use alternate phrasing after the first message */
4534 static struct h2o_ctx {
4535 int dkn_boom, unk_boom; /* track dknown, !dknown separately */
4537 } acid_ctx = { 0, 0, FALSE };
4539 /* Get an object wet and damage it appropriately.
4540 * "ostr", if present, is used instead of the object name in some
4542 * "force" means not to roll luck to protect some objects.
4543 * Returns an erosion return value (ER_*)
4546 water_damage(obj, ostr, force)
4560 if (obj->otyp == CAN_OF_GREASE && obj->spe > 0) {
4562 } else if (obj->otyp == TOWEL && obj->spe < 7) {
4563 wet_a_towel(obj, rnd(7), TRUE);
4565 } else if (obj->greased) {
4571 } else if (Is_container(obj) && !Is_box(obj)
4572 && (obj->otyp != OILSKIN_SACK || (obj->cursed && !rn2(3)))) {
4575 pline("Water gets into your %s!", ostr);
4577 pline("
\90\85\82ª%s
\82Ì
\92\86\82É
\93ü
\82Á
\82½
\81I", ostr);
4579 water_damage_chain(obj->cobj, FALSE);
4580 return ER_DAMAGED; /* contents were damaged */
4581 } else if (obj->otyp == OILSKIN_SACK) {
4584 pline("Some water slides right off your %s.", ostr);
4586 pline("%s
\82Í
\90\85\82ð
\92e
\82¢
\82½
\81D", ostr);
4587 makeknown(OILSKIN_SACK);
4588 /* not actually damaged, but because we /didn't/ get the "water
4589 gets into!" message, the player now has more information and
4590 thus we need to waste any potion they may have used (also,
4591 flavourwise the water is now on the floor) */
4593 } else if (!force && (Luck + 5) > rn2(20)) {
4594 /* chance per item of sustaining damage:
4596 * avg luck (Luck==0): 75%
4597 * awful luck (Luck<-4): 100%
4600 } else if (obj->oclass == SCROLL_CLASS) {
4601 if (obj->otyp == SCR_BLANK_PAPER
4603 || obj->otyp == SCR_MAIL
4608 pline("Your %s %s.", ostr, vtense(ostr, "fade"));
4610 pline("%s
\82Ì
\95¶
\8e\9a\82Í
\94\96\82ê
\82½
\81D", ostr);
4612 obj->otyp = SCR_BLANK_PAPER;
4618 } else if (obj->oclass == SPBOOK_CLASS) {
4619 if (obj->otyp == SPE_BOOK_OF_THE_DEAD) {
4621 pline("Steam rises from %s.", the(xname(obj)));
4623 pline("
\8fö
\8bC
\82ª%s
\82©
\82ç
\97§
\82¿
\82Ì
\82Ú
\82Á
\82½
\81D", xname(obj));
4625 } else if (obj->otyp == SPE_BLANK_PAPER) {
4630 pline("Your %s %s.", ostr, vtense(ostr, "fade"));
4632 pline("%s
\82Ì
\95¶
\8e\9a\82Í
\94\96\82ê
\82½
\81D", ostr);
4634 if (obj->otyp == SPE_NOVEL) {
4639 obj->otyp = SPE_BLANK_PAPER;
4644 } else if (obj->oclass == POTION_CLASS) {
4645 if (obj->otyp == POT_ACID) {
4648 boolean one = (obj->quan == 1L), update = carried(obj),
4651 boolean update = carried(obj);
4654 if (Blind && !carried(obj))
4657 if (acid_ctx.ctx_valid)
4658 exploded = ((obj->dknown ? acid_ctx.dkn_boom
4659 : acid_ctx.unk_boom) > 0);
4662 * "a [potion|<color> potion|potion of acid] explodes"
4663 * depending on obj->dknown (potion has been seen) and
4664 * objects[POT_ACID].oc_name_known (fully discovered),
4665 * or "some {plural version} explode" when relevant.
4666 * Second and subsequent messages for same chain and
4667 * matching dknown status are
4668 * "another [potion|<color> &c] explodes" or plural
4671 bufp = simpleonames(obj);
4673 pline("%s %s %s!", /* "A potion explodes!" */
4674 !exploded ? (one ? "A" : "Some")
4675 : (one ? "Another" : "More"),
4676 bufp, vtense(bufp, "explode"));
4678 pline("%s
\82Í
\94\9a\94
\82µ
\82½
\81I", bufp);
4680 if (acid_ctx.ctx_valid) {
4682 acid_ctx.dkn_boom++;
4684 acid_ctx.unk_boom++;
4690 return ER_DESTROYED;
4691 } else if (obj->odiluted) {
4694 pline("Your %s %s further.", ostr, vtense(ostr, "dilute"));
4696 pline("%s
\82Í
\82³
\82ç
\82É
\94\96\82Ü
\82Á
\82½
\81D", ostr);
4698 obj->otyp = POT_WATER;
4700 obj->blessed = obj->cursed = 0;
4705 } else if (obj->otyp != POT_WATER) {
4708 pline("Your %s %s.", ostr, vtense(ostr, "dilute"));
4710 pline("%s
\82Í
\94\96\82Ü
\82Á
\82½
\81D", ostr);
4718 return erode_obj(obj, ostr, ERODE_RUST, EF_NONE);
4724 water_damage_chain(obj, here)
4730 /* initialize acid context: so far, neither seen (dknown) potions of
4731 acid nor unseen have exploded during this water damage sequence */
4732 acid_ctx.dkn_boom = acid_ctx.unk_boom = 0;
4733 acid_ctx.ctx_valid = TRUE;
4735 for (; obj; obj = otmp) {
4736 otmp = here ? obj->nexthere : obj->nobj;
4737 water_damage(obj, (char *) 0, FALSE);
4740 /* reset acid context */
4741 acid_ctx.dkn_boom = acid_ctx.unk_boom = 0;
4742 acid_ctx.ctx_valid = FALSE;
4746 * This function is potentially expensive - rolling
4747 * inventory list multiple times. Luckily it's seldom needed.
4748 * Returns TRUE if disrobing made player unencumbered enough to
4749 * crawl out of the current predicament.
4752 emergency_disrobe(lostsome)
4755 int invc = inv_cnt(TRUE);
4757 while (near_capacity() > (Punished ? UNENCUMBERED : SLT_ENCUMBER)) {
4758 register struct obj *obj, *otmp = (struct obj *) 0;
4761 /* Pick a random object */
4764 for (obj = invent; obj; obj = obj->nobj) {
4766 * Undroppables are: body armor, boots, gloves,
4767 * amulets, and rings because of the time and effort
4768 * in removing them + loadstone and other cursed stuff
4769 * for obvious reasons.
4771 if (!((obj->otyp == LOADSTONE && obj->cursed) || obj == uamul
4772 || obj == uleft || obj == uright || obj == ublindf
4773 || obj == uarm || obj == uarmc || obj == uarmg
4774 || obj == uarmf || obj == uarmu
4775 || (obj->cursed && (obj == uarmh || obj == uarms))
4778 /* reached the mark and found some stuff to drop? */
4779 if (--i < 0 && otmp)
4786 return FALSE; /* nothing to drop! */
4787 if (otmp->owornmask)
4788 remove_worn_item(otmp, FALSE);
4797 /* return TRUE iff player relocated */
4801 const char *pool_of_water;
4802 boolean inpool_ok = FALSE, crawl_ok;
4805 /* happily wading in the same contiguous pool */
4806 if (u.uinwater && is_pool(u.ux - u.dx, u.uy - u.dy)
4807 && (Swimming || Amphibious)) {
4808 /* water effects on objects every now and then */
4817 You("%s into the %s%c", Is_waterlevel(&u.uz) ? "plunge" : "fall",
4819 Amphibious || Swimming ? '.' : '!');
4821 You("%s
\82Ì
\92\86\82É%s%s", hliquid("
\90\85"),
4822 Is_waterlevel(&u.uz) ? "
\94ò
\82Ñ
\82±
\82ñ
\82¾" : "
\97\8e\82¿
\82½",
4823 Amphibious || Swimming ? "
\81D" : "
\81I");
4825 if (!Swimming && !Is_waterlevel(&u.uz))
4827 You("sink like %s.", Hallucination ? "the Titanic" : "a rock");
4829 You("%s
\82Ì
\82æ
\82¤
\82É
\92¾
\82ñ
\82¾
\81D", Hallucination ? "
\83^
\83C
\83^
\83j
\83b
\83N
\8d\86" : "
\8aâ");
4832 water_damage_chain(invent, FALSE);
4834 if (u.umonnum == PM_GREMLIN && rn2(3))
4835 (void) split_mon(&youmonst, (struct monst *) 0);
4836 else if (u.umonnum == PM_IRON_GOLEM) {
4840 You("
\8eK
\82Ñ
\82½
\81I");
4841 i = Maybe_Half_Phys(d(2, 6));
4845 losehp(i, "rusting away", KILLED_BY);
4847 losehp(i, "
\8a®
\91S
\82É
\8eK
\82Ñ
\82Ä", KILLED_BY);
4852 if ((i = number_leashed()) > 0) {
4854 pline_The("leash%s slip%s loose.", (i > 1) ? "es" : "",
4855 (i > 1) ? "" : "s");
4857 pline("
\95R
\82ª
\82ä
\82é
\82ñ
\82¾
\81D");
4862 if (Amphibious || Swimming) {
4866 pline("But you aren't drowning.");
4868 pline("
\82µ
\82©
\82µ
\81C
\82 \82È
\82½
\82Í
\93M
\82ê
\82È
\82©
\82Á
\82½
\81D");
4869 if (!Is_waterlevel(&u.uz)) {
4872 Your("keel hits the bottom.");
4874 You("
\92ê
\82É
\83j
\81[
\83h
\83\8d\83b
\83v
\82ð
\8c\88\82ß
\82½
\81D");
4877 You("touch bottom.");
4879 You("
\92ê
\82É
\82Â
\82¢
\82½
\81D");
4886 vision_recalc(2); /* unsee old position */
4889 vision_full_recalc = 1;
4892 if ((Teleportation || can_teleport(youmonst.data)) && !Unaware
4893 && (Teleport_control || rn2(3) < Luck + 2)) {
4895 You("attempt a teleport spell."); /* utcsri!carroll */
4897 You("
\8fu
\8aÔ
\88Ú
\93®
\82Ì
\8eô
\95¶
\82ð
\8f¥
\82¦
\82Ä
\82Ý
\82½
\81D");
4899 if (!level.flags.noteleport) {
4900 (void) dotele(FALSE);
4901 if (!is_pool(u.ux, u.uy))
4905 pline_The("attempted teleport spell fails.");
4907 pline("
\8fu
\8aÔ
\88Ú
\93®
\82Ì
\8eô
\95¶
\82Í
\8e¸
\94s
\82µ
\82½
\81D");
4910 dismount_steed(DISMOUNT_GENERIC);
4911 if (!is_pool(u.ux, u.uy))
4915 x = y = 0; /* lint suppression */
4916 /* if sleeping, wake up now so that we don't crawl out of water
4917 while still asleep; we can't do that the same way that waking
4918 due to combat is handled; note unmul() clears u.usleep */
4921 unmul("Suddenly you wake up!");
4923 unmul("
\93Ë
\91R
\82 \82È
\82½
\82Í
\96Ú
\82ª
\8ao
\82ß
\82½
\81I");
4924 /* being doused will revive from fainting */
4927 /* can't crawl if unable to move (crawl_ok flag stays false) */
4928 if (multi < 0 || (Upolyd && !youmonst.data->mmove))
4930 /* look around for a place to crawl to */
4931 for (i = 0; i < 100; i++) {
4932 x = rn1(3, u.ux - 1);
4933 y = rn1(3, u.uy - 1);
4934 if (crawl_destination(x, y)) {
4940 for (x = u.ux - 1; x <= u.ux + 1; x++)
4941 for (y = u.uy - 1; y <= u.uy + 1; y++)
4942 if (crawl_destination(x, y)) {
4948 boolean lost = FALSE;
4949 /* time to do some strip-tease... */
4950 boolean succ = Is_waterlevel(&u.uz) ? TRUE : emergency_disrobe(&lost);
4953 You("try to crawl out of the %s.", hliquid("water"));
4955 You("%s
\82©
\82ç
\82Í
\82¢
\82 \82ª
\82ë
\82¤
\82Æ
\82µ
\82½
\81D", hliquid("
\90\85"));
4958 You("dump some of your gear to lose weight...");
4960 You("
\91Ì
\82ð
\8cy
\82
\82·
\82é
\82½
\82ß
\82¢
\82
\82Â
\82©
\95¨
\82ð
\93\8a\82°
\82·
\82Ä
\82½
\81D
\81D
\81D");
4963 pline("Pheew! That was close.");
4965 pline("
\83n
\83@
\83n
\83@
\81I
\82 \82Ô
\82È
\82©
\82Á
\82½
\81D");
4969 /* still too much weight */
4971 pline("But in vain.");
4973 pline("
\82ª
\81C
\96³
\91Ê
\82¾
\82Á
\82½
\81D");
4979 You("
\93M
\82ê
\82½
\81D");
4980 for (i = 0; i < 5; i++) { /* arbitrary number of loops */
4981 /* killer format and name are reconstructed every iteration
4982 because lifesaving resets them */
4983 pool_of_water = waterbody_name(u.ux, u.uy);
4984 killer.format = KILLED_BY_AN;
4986 /* avoid "drowned in [a] water" */
4987 if (!strcmp(pool_of_water, "water"))
4988 pool_of_water = "deep water", killer.format = KILLED_BY;
4990 Strcpy(killer.name, pool_of_water);
4992 /* oops, we're still alive. better get out of the water. */
4993 if (safe_teleds(TRUE))
4994 break; /* successful life-save */
4995 /* nowhere safe to land; repeat drowning loop... */
4997 pline("You're still drowning.");
4999 You("
\82Ü
\82¾
\93M
\82ê
\82Ä
\82¢
\82é
\81D");
5004 You("find yourself back %s.",
5005 Is_waterlevel(&u.uz) ? "in an air bubble" : "on land");
5007 You("
\82¢
\82Â
\82Ì
\82Ü
\82É
\82©%s
\82É
\82¢
\82é
\82Ì
\82É
\8bC
\82ª
\82Â
\82¢
\82½
\81D",
5008 Is_waterlevel(&u.uz) ? "
\8bó
\8bC
\82Ì
\96A
\82Ì
\92\86" : "
\92n
\96Ê");
5019 /* energy is completely gone */
5021 You_feel("momentarily lethargic.");
5023 You("
\88ê
\8fu
\96³
\8bC
\97Í
\8a´
\82ð
\8a´
\82¶
\82½
\81D");
5025 /* throttle further loss a bit when there's not much left to lose */
5026 if (n > u.uenmax || n > u.ulevel)
5030 You_feel("your magical energy drain away%c", (n > u.uen) ? '!' : '.');
5032 You("
\96\82\96@
\82Ì
\83G
\83l
\83\8b\83M
\81[
\82ª
\8bz
\82¢
\82Æ
\82ç
\82ê
\82½
\82æ
\82¤
\82È
\8bC
\82ª
\82µ
\82½%s", (n > u.uen) ? "
\81I" : "
\81D");
5035 u.uenmax -= rnd(-u.uen);
5048 if (near_capacity() >= HVY_ENCUMBER) {
5050 pline("You're too strained to do that.");
5052 pline("ã©
\82ð
\89ð
\8f\9c\82µ
\82æ
\82¤
\82É
\82à
\95¨
\82ð
\8e\9d\82¿
\82·
\82¬
\82Ä
\82¢
\82é
\81D");
5055 if ((nohands(youmonst.data) && !webmaker(youmonst.data))
5056 || !youmonst.data->mmove) {
5058 pline("And just how do you expect to do that?");
5060 pline("
\82¢
\82Á
\82½
\82¢
\89½
\82ð
\8aú
\91Ò
\82µ
\82Ä
\82¢
\82é
\82ñ
\82¾
\82¢
\81H");
5062 } else if (u.ustuck && sticks(youmonst.data)) {
5064 pline("You'll have to let go of %s first.", mon_nam(u.ustuck));
5066 pline("%s
\82ð
\8eè
\97£
\82³
\82È
\82¢
\82±
\82Æ
\82É
\82Í
\82Å
\82«
\82È
\82¢
\81D", mon_nam(u.ustuck));
5069 if (u.ustuck || (welded(uwep) && bimanual(uwep))) {
5071 Your("%s seem to be too busy for that.", makeplural(body_part(HAND)));
5073 Your("
\82»
\82ñ
\82È
\82±
\82Æ
\82ð
\82·
\82é
\97]
\97T
\82È
\82ñ
\82Ä
\82È
\82¢
\81D");
5076 return untrap(FALSE);
5079 /* Probability of disabling a trap. Helge Hafting */
5086 /* Only spiders know how to deal with webs reliably */
5087 if (ttmp->ttyp == WEB && !webmaker(youmonst.data))
5089 if (Confusion || Hallucination)
5097 /* Your own traps are better known than others. */
5098 if (ttmp && ttmp->madeby_u)
5100 if (Role_if(PM_ROGUE)) {
5101 if (rn2(2 * MAXULEV) < u.ulevel)
5103 if (u.uhave.questart && chance > 1)
5105 } else if (Role_if(PM_RANGER) && chance > 1)
5110 /* Replace trap with object(s). Helge Hafting */
5112 cnv_trap_obj(otyp, cnt, ttmp, bury_it)
5118 struct obj *otmp = mksobj(otyp, TRUE, FALSE);
5121 otmp->owt = weight(otmp);
5122 /* Only dart traps are capable of being poisonous */
5124 otmp->opoisoned = 0;
5125 place_object(otmp, ttmp->tx, ttmp->ty);
5127 /* magical digging first disarms this trap, then will unearth it */
5128 (void) bury_an_obj(otmp, (boolean *) 0);
5130 /* Sell your own traps only... */
5132 sellobj(otmp, ttmp->tx, ttmp->ty);
5135 newsym(ttmp->tx, ttmp->ty);
5136 if (u.utrap && ttmp->tx == u.ux && ttmp->ty == u.uy)
5141 /* while attempting to disarm an adjacent trap, we've fallen into it */
5143 move_into_trap(ttmp)
5147 xchar x = ttmp->tx, y = ttmp->ty, bx, by, cx, cy;
5150 bx = by = cx = cy = 0; /* lint suppression */
5151 /* we know there's no monster in the way, and we're not trapped */
5153 || drag_ball(x, y, &bc, &bx, &by, &cx, &cy, &unused, TRUE)) {
5154 u.ux0 = u.ux, u.uy0 = u.uy;
5157 newsym(u.ux0, u.uy0);
5159 check_leash(u.ux0, u.uy0);
5161 move_bc(0, bc, bx, by, cx, cy);
5162 /* marking the trap unseen forces dotrap() to treat it like a new
5163 discovery and prevents pickup() -> look_here() -> check_here()
5164 from giving a redundant "there is a <trap> here" message when
5165 there are objects covering this trap */
5166 ttmp->tseen = 0; /* hack for check_here() */
5167 /* trigger the trap */
5168 iflags.failing_untrap++; /* spoteffects() -> dotrap(,FAILEDUNTRAP) */
5169 spoteffects(TRUE); /* pickup() + dotrap() */
5170 iflags.failing_untrap--;
5171 /* this should no longer be necessary; before the failing_untrap
5172 hack, Flying hero would not trigger an unseen bear trap and
5173 setting it not-yet-seen above resulted in leaving it hidden */
5174 if ((ttmp = t_at(u.ux, u.uy)) != 0)
5176 exercise(A_WIS, FALSE);
5180 /* 0: doesn't even try
5181 * 1: tries and fails
5185 try_disarm(ttmp, force_failure)
5187 boolean force_failure;
5189 struct monst *mtmp = m_at(ttmp->tx, ttmp->ty);
5190 int ttype = ttmp->ttyp;
5191 boolean under_u = (!u.dx && !u.dy);
5192 boolean holdingtrap = (ttype == BEAR_TRAP || ttype == WEB);
5194 /* Test for monster first, monsters are displayed instead of trap. */
5195 if (mtmp && (!mtmp->mtrapped || !holdingtrap)) {
5197 pline("%s is in the way.", Monnam(mtmp));
5199 pline("
\82»
\82±
\82É
\82Í%s
\82ª
\82¢
\82é
\81D", Monnam(mtmp));
5202 /* We might be forced to move onto the trap's location. */
5203 if (sobj_at(BOULDER, ttmp->tx, ttmp->ty) && !Passes_walls && !under_u) {
5205 There("is a boulder in your way.");
5207 pline("
\82»
\82±
\82É
\82Í
\8aâ
\82ª
\82 \82é
\81D");
5210 /* duplicate tight-space checks from test_move */
5211 if (u.dx && u.dy && bad_rock(youmonst.data, u.ux, ttmp->ty)
5212 && bad_rock(youmonst.data, ttmp->tx, u.uy)) {
5213 if ((invent && (inv_weight() + weight_cap() > 600))
5214 || bigmonst(youmonst.data)) {
5215 /* don't allow untrap if they can't get thru to it */
5217 You("are unable to reach the %s!",
5218 defsyms[trap_to_defsym(ttype)].explanation);
5220 You("%s
\82É
\93Í
\82©
\82È
\82¢
\81I",
5221 defsyms[trap_to_defsym(ttype)].explanation);
5226 /* untrappable traps are located on the ground. */
5227 if (!can_reach_floor(under_u)) {
5228 if (u.usteed && P_SKILL(P_RIDING) < P_BASIC)
5232 You("are unable to reach the %s!",
5233 defsyms[trap_to_defsym(ttype)].explanation);
5235 You("%s
\82É
\93Í
\82©
\82È
\82¢
\81I",
5236 defsyms[trap_to_defsym(ttype)].explanation);
5241 /* Will our hero succeed? */
5242 if (force_failure || untrap_prob(ttmp)) {
5247 pline("
\82¤
\82í
\82Á
\81D
\81D
\81D");
5248 if (mtmp) { /* must be a trap that holds monsters */
5249 if (ttype == BEAR_TRAP) {
5252 mtmp->mhp -= rnd(4);
5253 if (DEADMONSTER(mtmp))
5255 } else if (ttype == WEB) {
5256 if (!webmaker(youmonst.data)) {
5257 struct trap *ttmp2 = maketrap(u.ux, u.uy, WEB);
5262 "webbing sticks to you. You're caught too!");
5264 "
\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");
5265 dotrap(ttmp2, NOWEBMSG);
5266 if (u.usteed && u.utrap) {
5267 /* you, not steed, are trapped */
5268 dismount_steed(DISMOUNT_FELL);
5273 pline("%s remains entangled.", Monnam(mtmp));
5275 pline("%s
\82Í
\82©
\82ç
\82Ü
\82Á
\82½
\82Ü
\82Ü
\82¾
\81D", Monnam(mtmp));
5277 } else if (under_u) {
5278 /* [don't need the iflags.failing_untrap hack here] */
5279 dotrap(ttmp, FAILEDUNTRAP);
5281 move_into_trap(ttmp);
5285 pline("%s %s is difficult to %s.",
5286 ttmp->madeby_u ? "Your" : under_u ? "This" : "That",
5287 defsyms[trap_to_defsym(ttype)].explanation,
5288 (ttype == WEB) ? "remove" : "disarm");
5290 pline("%s%s
\82ð
\89ð
\8f\9c\82·
\82é
\82Ì
\82Í
\8d¢
\93ï
\82¾
\81D",
5291 ttmp->madeby_u ? "
\82 \82È
\82½
\82Ì
\8ed
\8a|
\82¯
\82½" : under_u ? "
\82±
\82Ì" : "
\82»
\82Ì",
5292 defsyms[trap_to_defsym(ttype)].explanation);
5301 reward_untrap(ttmp, mtmp)
5305 if (!ttmp->madeby_u) {
5306 if (rnl(10) < 8 && !mtmp->mpeaceful && !mtmp->msleeping
5307 && !mtmp->mfrozen && !mindless(mtmp->data)
5308 && mtmp->data->mlet != S_HUMAN) {
5309 mtmp->mpeaceful = 1;
5310 set_malign(mtmp); /* reset alignment */
5312 pline("%s is grateful.", Monnam(mtmp));
5314 pline("%s
\82Í
\8aì
\82ñ
\82Å
\82¢
\82é
\81D", Monnam(mtmp));
5316 /* Helping someone out of a trap is a nice thing to do,
5317 * A lawful may be rewarded, but not too often. */
5318 if (!rn2(3) && !rnl(8) && u.ualign.type == A_LAWFUL) {
5321 You_feel("that you did the right thing.");
5323 You("
\90³
\82µ
\82¢
\82±
\82Æ
\82ð
\82µ
\82½
\82æ
\82¤
\82È
\8bC
\82ª
\82µ
\82½
\81D");
5329 disarm_holdingtrap(ttmp) /* Helge Hafting */
5333 int fails = try_disarm(ttmp, FALSE);
5338 /* ok, disarm it. */
5340 /* untrap the monster, if any.
5341 There's no need for a cockatrice test, only the trap is touched */
5342 if ((mtmp = m_at(ttmp->tx, ttmp->ty)) != 0) {
5345 You("remove %s %s from %s.", the_your[ttmp->madeby_u],
5346 (ttmp->ttyp == BEAR_TRAP) ? "bear trap" : "webbing",
5349 You("%s%s
\82ð%s
\82©
\82ç
\82Í
\82¸
\82µ
\82½
\81D", set_you[ttmp->madeby_u],
5350 (ttmp->ttyp == BEAR_TRAP) ? "
\8cF
\82Ìã©" : "
\82
\82à
\82Ì
\91\83",
5353 reward_untrap(ttmp, mtmp);
5355 if (ttmp->ttyp == BEAR_TRAP) {
5357 You("disarm %s bear trap.", the_your[ttmp->madeby_u]);
5359 You("%s
\8cF
\82Ìã©
\82ð
\89ð
\8f\9c\82µ
\82½
\81D", set_you[ttmp->madeby_u]);
5360 cnv_trap_obj(BEARTRAP, 1, ttmp, FALSE);
5361 } else /* if (ttmp->ttyp == WEB) */ {
5363 You("succeed in removing %s web.", the_your[ttmp->madeby_u]);
5365 You("%s
\82
\82à
\82Ì
\91\83\82ð
\8eæ
\82è
\8f\9c\82¢
\82½
\81D", set_you[ttmp->madeby_u]);
5369 newsym(u.ux + u.dx, u.uy + u.dy);
5374 disarm_landmine(ttmp) /* Helge Hafting */
5377 int fails = try_disarm(ttmp, FALSE);
5382 You("disarm %s land mine.", the_your[ttmp->madeby_u]);
5384 You("%s
\92n
\97\8b\82ð
\89ð
\8f\9c\82µ
\82½
\81D", set_you[ttmp->madeby_u]);
5385 cnv_trap_obj(LAND_MINE, 1, ttmp, FALSE);
5389 /* getobj will filter down to cans of grease and known potions of oil */
5390 static NEARDATA const char oil[] = { ALL_CLASSES, TOOL_CLASS, POTION_CLASS,
5393 /* it may not make much sense to use grease on floor boards, but so what? */
5395 disarm_squeaky_board(ttmp)
5402 obj = getobj(oil, "untrap with");
5406 bad_tool = (obj->cursed
5407 || ((obj->otyp != POT_OIL || obj->lamplit)
5408 && (obj->otyp != CAN_OF_GREASE || !obj->spe)));
5409 fails = try_disarm(ttmp, bad_tool);
5413 /* successfully used oil or grease to fix squeaky board */
5414 if (obj->otyp == CAN_OF_GREASE) {
5415 consume_obj_charge(obj, TRUE);
5417 useup(obj); /* oil */
5421 You("repair the squeaky board."); /* no madeby_u */
5423 You("
\82«
\82µ
\82Þ
\94Â
\82ð
\8fC
\97\9d\82µ
\82½
\81D"); /* no madeby_u */
5426 newsym(u.ux + u.dx, u.uy + u.dy);
5427 more_experienced(1, 5);
5432 /* removes traps that shoot arrows, darts, etc. */
5434 disarm_shooting_trap(ttmp, otyp)
5438 int fails = try_disarm(ttmp, FALSE);
5443 You("disarm %s trap.", the_your[ttmp->madeby_u]);
5445 pline("%sã©
\82ð
\89ð
\8f\9c\82µ
\82½
\81D", set_you[ttmp->madeby_u]);
5446 cnv_trap_obj(otyp, 50 - rnl(50), ttmp, FALSE);
5450 /* Is the weight too heavy?
5451 * Formula as in near_capacity() & check_capacity() */
5453 try_lift(mtmp, ttmp, wt, stuff)
5459 int wc = weight_cap();
5461 if (((wt * 2) / wc) >= HVY_ENCUMBER) {
5463 pline("%s is %s for you to lift.", Monnam(mtmp),
5464 stuff ? "carrying too much" : "too heavy");
5466 pline("%s
\82Í%s
\8e\9d\82¿
\82 \82°
\82é
\82±
\82Æ
\82ª
\82Å
\82«
\82È
\82¢
\81D", Monnam(mtmp),
5467 stuff ? "
\95¨
\82ð
\8e\9d\82¿
\82·
\82¬
\82Ä
\82¨
\82è" : "
\8fd
\82·
\82¬
\82Ä");
5469 if (!ttmp->madeby_u && !mtmp->mpeaceful && mtmp->mcanmove
5470 && !mindless(mtmp->data) && mtmp->data->mlet != S_HUMAN
5472 mtmp->mpeaceful = 1;
5473 set_malign(mtmp); /* reset alignment */
5475 pline("%s thinks it was nice of you to try.", Monnam(mtmp));
5477 pline("%s
\82Í
\82 \82È
\82½
\82Ì
\93w
\97Í
\82É
\8a´
\8eÓ
\82µ
\82Ä
\82¢
\82é
\82æ
\82¤
\82¾
\81D", Monnam(mtmp));
5484 /* Help trapped monster (out of a (spiked) pit) */
5486 help_monster_out(mtmp, ttmp)
5495 * This works when levitating too -- consistent with the ability
5496 * to hit monsters while levitating.
5498 * Should perhaps check that our hero has arms/hands at the
5499 * moment. Helping can also be done by engulfing...
5501 * Test the monster first - monsters are displayed before traps.
5503 if (!mtmp->mtrapped) {
5505 pline("%s isn't trapped.", Monnam(mtmp));
5507 pline("%s
\82Íã©
\82É
\82©
\82©
\82Á
\82Ä
\82¢
\82È
\82¢
\81D", Monnam(mtmp));
5510 /* Do you have the necessary capacity to lift anything? */
5511 if (check_capacity((char *) 0))
5514 /* Will our hero succeed? */
5515 if ((uprob = untrap_prob(ttmp)) && !mtmp->msleeping && mtmp->mcanmove) {
5517 You("try to reach out your %s, but %s backs away skeptically.",
5518 makeplural(body_part(ARM)), mon_nam(mtmp));
5520 You("%s
\82ð
\8d·
\82µ
\89\84\82×
\82æ
\82¤
\82Æ
\82µ
\82½
\82ª%s
\82Í
\8cx
\89ú
\82µ
\82Ä
\82¢
\82é
\81D",
5521 body_part(ARM), mon_nam(mtmp));
5526 /* is it a cockatrice?... */
5527 if (touch_petrifies(mtmp->data) && !uarmg && !Stone_resistance) {
5529 You("grab the trapped %s using your bare %s.", mtmp->data->mname,
5530 makeplural(body_part(HAND)));
5532 You("ã©
\82É
\82©
\82©
\82Á
\82Ä
\82¢
\82é%s
\82ð
\91f%s
\82Å
\92Í
\82ñ
\82¾
\81D", mtmp->data->mname,
5536 if (poly_when_stoned(youmonst.data) && polymon(PM_STONE_GOLEM)) {
5537 display_nhwindow(WIN_MESSAGE, FALSE);
5542 Sprintf(kbuf, "trying to help %s out of a pit",
5543 an(mtmp->data->mname));
5545 Sprintf(kbuf, "ã©
\82É
\82©
\82©
\82Á
\82Ä
\82¢
\82é%s
\82ð
\8f\95\82¯
\82æ
\82¤
\82Æ
\82µ
\82Ä",
5552 /* need to do cockatrice check first if sleeping or paralyzed */
5555 You("try to grab %s, but cannot get a firm grasp.", mon_nam(mtmp));
5557 You("%s
\82ð
\82Â
\82©
\82à
\82¤
\82Æ
\82µ
\82½
\82ª
\81C
\82µ
\82Á
\82©
\82è
\82Æ
\88¬
\82ê
\82È
\82©
\82Á
\82½
\81D", mon_nam(mtmp));
5558 if (mtmp->msleeping) {
5559 mtmp->msleeping = 0;
5561 pline("%s awakens.", Monnam(mtmp));
5563 pline("%s
\82Í
\96Ú
\82ð
\8ao
\82Ü
\82µ
\82½
\81D", Monnam(mtmp));
5569 You("reach out your %s and grab %s.", makeplural(body_part(ARM)),
5572 You("%s
\82ð
\90L
\82Î
\82µ
\82Ä%s
\82ð
\82Â
\82©
\82ñ
\82¾
\81D", body_part(ARM),
5576 if (mtmp->msleeping) {
5577 mtmp->msleeping = 0;
5579 pline("%s awakens.", Monnam(mtmp));
5581 pline("%s
\82Í
\96Ú
\82ð
\8ao
\82Ü
\82µ
\82½
\81D", Monnam(mtmp));
5582 } else if (mtmp->mfrozen && !rn2(mtmp->mfrozen)) {
5583 /* After such manhandling, perhaps the effect wears off */
5587 pline("%s stirs.", Monnam(mtmp));
5589 pline("%s
\82Í
\93®
\82«
\8en
\82ß
\82½
\81D", Monnam(mtmp));
5592 /* is the monster too heavy? */
5593 wt = inv_weight() + mtmp->data->cwt;
5594 if (!try_lift(mtmp, ttmp, wt, FALSE))
5597 /* is the monster with inventory too heavy? */
5598 for (otmp = mtmp->minvent; otmp; otmp = otmp->nobj)
5600 if (!try_lift(mtmp, ttmp, wt, TRUE))
5604 You("pull %s out of the pit.", mon_nam(mtmp));
5606 You("%s
\82ð
\97\8e\82µ
\8c\8a\82©
\82ç
\82Ð
\82Á
\82Ï
\82Á
\82½
\81D", mon_nam(mtmp));
5608 fill_pit(mtmp->mx, mtmp->my);
5609 reward_untrap(ttmp, mtmp);
5617 register struct obj *otmp;
5622 const char *trapdescr;
5624 boolean here, useplural, deal_with_floor_trap,
5625 confused = (Confusion || Hallucination),
5626 trap_skipped = FALSE;
5628 boolean here, deal_with_floor_trap,
5629 confused = (Confusion || Hallucination),
5630 trap_skipped = FALSE;
5633 char the_trap[BUFSZ], qbuf[QBUFSZ];
5635 if (!getdir((char *) 0))
5641 pline_The("perils lurking there are beyond your grasp.");
5643 pline_The("
\82»
\82±
\82É
\82 \82é
\8aë
\8c¯
\82Í
\82 \82È
\82½
\82Ì
\8eè
\82É
\95\89\82¦
\82È
\82¢
\81D");
5646 /* 'force' is true for #invoke; make it be true for #untrap if
5648 if (!force && has_magic_key(&youmonst))
5652 if (ttmp && !ttmp->tseen)
5654 trapdescr = ttmp ? defsyms[trap_to_defsym(ttmp->ttyp)].explanation : 0;
5655 here = (x == u.ux && y == u.uy); /* !u.dx && !u.dy */
5657 if (here) /* are there are one or more containers here? */
5658 for (otmp = level.objects[x][y]; otmp; otmp = otmp->nexthere)
5664 deal_with_floor_trap = can_reach_floor(FALSE);
5665 if (!deal_with_floor_trap) {
5668 Strcat(the_trap, an(trapdescr));
5671 Strcat(the_trap, " and ");
5673 Strcat(the_trap, "
\82Æ");
5676 Strcat(the_trap, (boxcnt == 1) ? "a container" : "containers");
5678 Strcat(the_trap, "
\97e
\8aí");
5680 useplural = ((ttmp && boxcnt > 0) || boxcnt > 1);
5682 /* note: boxcnt and useplural will always be 0 for !here case */
5685 There("%s %s %s but you can't reach %s%s.",
5686 useplural ? "are" : "is", the_trap, here ? "here" : "there",
5687 useplural ? "them" : "it",
5688 u.usteed ? " while mounted" : "");
5690 pline("%s
\82ª
\82 \82é
\82ª
\81C%s
\93Í
\82©
\82È
\82¢
\81D",
5692 u.usteed ? "
\8fæ
\82Á
\82Ä
\82¢
\82é
\82Æ" : "");
5694 trap_skipped = (ttmp != 0);
5695 } else { /* deal_with_floor_trap */
5698 Strcpy(the_trap, the(trapdescr));
5700 if (is_pit(ttmp->ttyp)) {
5702 You_cant("do much about %s%s.", the_trap,
5703 u.utrap ? " that you're stuck in"
5704 : " while standing on the edge of it");
5706 pline("%s%s
\82É
\91Î
\82µ
\82Ä
\82Í
\82½
\82¢
\82µ
\82½
\82±
\82Æ
\82Í
\82Å
\82«
\82È
\82¢
\81D",
5707 u.utrap ? "
\8e©
\95ª
\82ª
\82Í
\82Ü
\82Á
\82Ä
\82¢
\82é"
5708 : "
\82·
\82®
\82»
\82Î
\82Ì",
5711 trap_skipped = TRUE;
5712 deal_with_floor_trap = FALSE;
5716 qbuf, "There %s and %s here. %s %s?",
5717 (boxcnt == 1) ? "is a container" : "are containers",
5719 (ttmp->ttyp == WEB) ? "Remove" : "Disarm", the_trap);
5722 qbuf, "
\94 \82Æ%s
\82ª
\82 \82é
\81D%s
\81H",
5724 (ttmp->ttyp == WEB) ? "
\8eæ
\82è
\8f\9c\82" : "
\89ð
\8f\9c\82·
\82é");
5726 switch (ynq(qbuf)) {
5730 trap_skipped = TRUE;
5731 deal_with_floor_trap = FALSE;
5736 if (deal_with_floor_trap) {
5739 You("cannot deal with %s while trapped%s!", the_trap,
5740 (x == u.ux && y == u.uy) ? " in it" : "");
5742 pline("ã©
\82É
\82©
\82©
\82Á
\82Ä
\82¢
\82é
\8aÔ
\82Íã©
\82ð
\89ð
\8f\9c\82Å
\82«
\82È
\82¢
\81I");
5746 if ((mtmp = m_at(x, y)) != 0
5747 && (M_AP_TYPE(mtmp) == M_AP_FURNITURE
5748 || M_AP_TYPE(mtmp) == M_AP_OBJECT)) {
5749 stumble_onto_mimic(mtmp);
5752 switch (ttmp->ttyp) {
5755 return disarm_holdingtrap(ttmp);
5757 return disarm_landmine(ttmp);
5759 return disarm_squeaky_board(ttmp);
5761 return disarm_shooting_trap(ttmp, DART);
5763 return disarm_shooting_trap(ttmp, ARROW);
5768 You("are already on the edge of the pit.");
5770 You("
\82à
\82¤
\97\8e\82µ
\8c\8a\82Ì
\92[
\82É
\82¢
\82é
\81D");
5775 pline("Try filling the pit instead.");
5777 pline("
\82È
\82ñ
\82Æ
\82©
\96\84\82ß
\82é
\82±
\82Æ
\82ð
\8dl
\82¦
\82Ä
\82Ý
\82½
\82ç
\81H");
5780 return help_monster_out(mtmp, ttmp);
5783 You("cannot disable %s trap.", !here ? "that" : "this");
5785 pline("%sã©
\82Í
\89ð
\8f\9c\82Å
\82«
\82È
\82¢
\81D", !here ? "
\82»
\82Ì" : "
\82±
\82Ì");
5792 for (otmp = level.objects[x][y]; otmp; otmp = otmp->nexthere)
5795 (void) safe_qbuf(qbuf, "There is ",
5796 " here. Check it for traps?", otmp,
5797 doname, ansimpleoname, "a box");
5799 (void) safe_qbuf(qbuf, "",
5800 "
\82ª
\82 \82é
\81Dã©
\82ð
\92²
\82×
\82Ü
\82·
\82©
\81H", otmp,
5801 doname, ansimpleoname, "
\94 ");
5803 switch (ynq(qbuf)) {
5811 && (force || (!confused
5812 && rn2(MAXULEV + 1 - u.ulevel) < 10)))
5813 || (!force && confused && !rn2(3))) {
5815 You("find a trap on %s!", the(xname(otmp)));
5817 pline("%s
\82Éã©
\82ð
\94
\8c©
\82µ
\82½
\81I", the(xname(otmp)));
5819 exercise(A_WIS, TRUE);
5822 switch (ynq("Disarm it?")) {
5824 switch (ynq("
\89ð
\8f\9c\82µ
\82Ü
\82·
\82©
\81H")) {
5828 trap_skipped = TRUE;
5832 if (otmp->otrapped) {
5833 exercise(A_DEX, TRUE);
5834 ch = ACURR(A_DEX) + u.ulevel;
5835 if (Role_if(PM_ROGUE))
5837 if (!force && (confused || Fumbling
5838 || rnd(75 + level_difficulty() / 2)
5840 (void) chest_trap(otmp, FINGER, TRUE);
5845 You("
\89ð
\8f\9c\82µ
\82½
\81I");
5850 pline("That %s was not trapped.", xname(otmp));
5852 pline("
\82»
\82Ì%s
\82Éã©
\82Í
\82È
\82¢
\81D", xname(otmp));
5856 You("find no traps on %s.", the(xname(otmp)));
5858 pline("ã©
\82ð
\94
\8c©
\82Å
\82«
\82È
\82©
\82Á
\82½
\81D");
5864 You(trap_skipped ? "find no other traps here."
5865 : "know of no traps here.");
5867 You(trap_skipped ? "
\91¼
\82Ìã©
\82ð
\8c©
\82Â
\82¯
\82ç
\82ê
\82È
\82©
\82Á
\82½
\81D"
5868 : "
\82±
\82±
\82Éã©
\82ª
\82È
\82¢
\82±
\82Æ
\82ð
\92m
\82Á
\82Ä
\82¢
\82é
\81D");
5873 if (stumble_on_door_mimic(x, y))
5876 } /* deal_with_floor_trap */
5877 /* doors can be manipulated even while levitating/unskilled riding */
5879 if (!IS_DOOR(levl[x][y].typ)) {
5882 You("know of no traps there.");
5884 You("
\82»
\82±
\82Éã©
\82ª
\82È
\82¢
\82±
\82Æ
\82ð
\92m
\82Á
\82Ä
\82¢
\82é
\81D");
5888 switch (levl[x][y].doormask) {
5891 You("%s no door there.", Blind ? "feel" : "see");
5893 pline("
\82»
\82±
\82É
\82Í
\94à
\82ª
\82È
\82¢%s
\81D", Blind ? "
\82æ
\82¤
\82¾" : "
\82æ
\82¤
\82É
\8c©
\82¦
\82é");
5897 pline("This door is safely open.");
5899 pline("
\82»
\82Ì
\94à
\82Í
\88À
\91S
\82É
\8aJ
\82¢
\82Ä
\82¢
\82é
\81D");
5903 pline("This door is broken.");
5905 pline("
\82»
\82Ì
\94à
\82Í
\89ó
\82ê
\82Ä
\82¢
\82é
\81D");
5909 if (((levl[x][y].doormask & D_TRAPPED) != 0
5910 && (force || (!confused && rn2(MAXULEV - u.ulevel + 11) < 10)))
5911 || (!force && confused && !rn2(3))) {
5913 You("find a trap on the door!");
5915 pline("
\94à
\82Éã©
\82ð
\94
\8c©
\82µ
\82½
\81I");
5916 exercise(A_WIS, TRUE);
5918 if (ynq("Disarm it?") != 'y')
5920 if (ynq("
\89ð
\8f\9c\82µ
\82Ü
\82·
\82©
\81H") != 'y')
5922 if (levl[x][y].doormask & D_TRAPPED) {
5923 ch = 15 + (Role_if(PM_ROGUE) ? u.ulevel * 3 : u.ulevel);
5924 exercise(A_DEX, TRUE);
5925 if (!force && (confused || Fumbling
5926 || rnd(75 + level_difficulty() / 2) > ch)) {
5930 You("
\83X
\83C
\83b
\83`
\82ð
\93ü
\82ê
\82Ä
\82µ
\82Ü
\82Á
\82½
\81I");
5932 b_trapped("door", FINGER);
5934 b_trapped("
\94à", FINGER);
5935 levl[x][y].doormask = D_NODOOR;
5936 unblock_point(x, y);
5938 /* (probably ought to charge for this damage...) */
5939 if (*in_rooms(x, y, SHOPBASE))
5940 add_damage(x, y, 0L);
5945 You("
\89ð
\8f\9c\82µ
\82½
\81I");
5946 levl[x][y].doormask &= ~D_TRAPPED;
5950 pline("This door was not trapped.");
5952 pline("
\94à
\82Éã©
\82Í
\82È
\82©
\82Á
\82½
\81D");
5956 You("find no traps on the door.");
5958 pline("
\94à
\82Éã©
\82ð
\94
\8c©
\82Å
\82«
\82È
\82©
\82Á
\82½
\81D");
5963 /* for magic unlocking; returns true if targetted monster (which might
5964 be hero) gets untrapped; the trap remains intact */
5966 openholdingtrap(mon, noticed)
5968 boolean *noticed; /* set to true iff hero notices the effect; */
5969 { /* otherwise left with its previous value intact */
5971 char buf[BUFSZ], whichbuf[20];
5972 const char *trapdescr = 0, *which = 0;
5973 boolean ishero = (mon == &youmonst);
5977 if (mon == u.usteed)
5980 t = t_at(ishero ? u.ux : mon->mx, ishero ? u.uy : mon->my);
5982 if (ishero && u.utrap) { /* all u.utraptype values are holding traps */
5984 switch (u.utraptype) {
5987 trapdescr = "molten lava";
5989 trapdescr = "
\82Ç
\82ë
\82Ç
\82ë
\82Ì
\97n
\8aâ";
5992 /* solidified lava, so not "floor" even if within a room */
5994 trapdescr = "ground";
5996 trapdescr = "
\92n
\96Ê";
6000 trapdescr = "your anchor";
6002 trapdescr = "
\82
\82³
\82Ñ";
6007 trapdescr = 0; /* use defsyms[].explanation */
6010 /* lint suppression in case 't' is unexpectedly Null
6011 or u.utraptype has new value we don't know about yet */
6019 /* if no trap here or it's not a holding trap, we're done */
6020 if (!t || (t->ttyp != BEAR_TRAP && t->ttyp != WEB))
6025 trapdescr = defsyms[trap_to_defsym(t->ttyp)].explanation;
6028 which = t->tseen ? the_your[t->madeby_u]
6029 : index(vowels, *trapdescr) ? "an" : "a";
6031 which = t->tseen ? set_you[t->madeby_u] : "";
6034 which = strcat(strcpy(whichbuf, which), " ");
6042 Sprintf(buf, "%s is", noit_Monnam(u.usteed));
6044 Strcpy(buf, noit_Monnam(u.usteed));
6047 Strcpy(buf, "You are");
6049 Strcpy(buf, "
\82 \82È
\82½");
6051 pline("%s released from %s%s.", buf, which, trapdescr);
6053 pline("%s
\82Í%s%s
\82©
\82ç
\89ð
\95ú
\82³
\82ê
\82½
\81D", buf, which, trapdescr);
6059 if (canspotmon(mon)) {
6062 pline("%s is released from %s%s.", Monnam(mon), which,
6065 pline("%s
\82Í%s%s
\82©
\82ç
\89ð
\95ú
\82³
\82ê
\82½
\81D", Monnam(mon), which,
6068 } else if (cansee(t->tx, t->ty) && t->tseen) {
6072 pline("%s is released from %s%s.", Something, which,
6075 pline("
\89½
\8eÒ
\82©
\82Í%s%s
\82©
\82ç
\89ð
\95ú
\82³
\82ê
\82½
\81D", which,
6078 else /* BEAR_TRAP */
6080 pline("%s%s opens.", upstart(strcpy(buf, which)), trapdescr);
6082 pline("%s%s
\82Í
\8aJ
\82¢
\82½
\81D", which, trapdescr);
6084 /* might pacify monster if adjacent */
6085 if (rn2(2) && distu(mon->mx, mon->my) <= 2)
6086 reward_untrap(t, mon);
6091 /* for magic locking; returns true if targetted monster (which might
6092 be hero) gets hit by a trap (might avoid actually becoming trapped) */
6094 closeholdingtrap(mon, noticed)
6096 boolean *noticed; /* set to true iff hero notices the effect; */
6097 { /* otherwise left with its previous value intact */
6099 unsigned dotrapflags;
6100 boolean ishero = (mon == &youmonst), result;
6104 if (mon == u.usteed)
6106 t = t_at(ishero ? u.ux : mon->mx, ishero ? u.uy : mon->my);
6107 /* if no trap here or it's not a holding trap, we're done */
6108 if (!t || (t->ttyp != BEAR_TRAP && t->ttyp != WEB))
6113 return FALSE; /* already trapped */
6115 dotrapflags = FORCETRAP;
6116 /* dotrap calls mintrap when mounted hero encounters a web */
6118 dotrapflags |= NOWEBMSG;
6120 dotrap(t, dotrapflags);
6122 result = (u.utrap != 0);
6125 return FALSE; /* already trapped */
6126 /* you notice it if you see the trap close/tremble/whatever
6127 or if you sense the monster who becomes trapped */
6128 *noticed = cansee(t->tx, t->ty) || canspotmon(mon);
6130 result = (mintrap(mon) != 0);
6136 /* for magic unlocking; returns true if targetted monster (which might
6137 be hero) gets hit by a trap (target might avoid its effect) */
6139 openfallingtrap(mon, trapdoor_only, noticed)
6141 boolean trapdoor_only;
6142 boolean *noticed; /* set to true iff hero notices the effect; */
6143 { /* otherwise left with its previous value intact */
6145 boolean ishero = (mon == &youmonst), result;
6149 if (mon == u.usteed)
6151 t = t_at(ishero ? u.ux : mon->mx, ishero ? u.uy : mon->my);
6152 /* if no trap here or it's not a falling trap, we're done
6153 (note: falling rock traps have a trapdoor in the ceiling) */
6154 if (!t || ((t->ttyp != TRAPDOOR && t->ttyp != ROCKTRAP)
6155 && (trapdoor_only || (t->ttyp != HOLE && !is_pit(t->ttyp)))))
6160 return FALSE; /* already trapped */
6162 dotrap(t, FORCETRAP);
6163 result = (u.utrap != 0);
6166 return FALSE; /* already trapped */
6167 /* you notice it if you see the trap close/tremble/whatever
6168 or if you sense the monster who becomes trapped */
6169 *noticed = cansee(t->tx, t->ty) || canspotmon(mon);
6170 /* monster will be angered; mintrap doesn't handle that */
6173 result = (mintrap(mon) != 0);
6175 /* mon might now be on the migrating monsters list */
6180 /* only called when the player is doing something to the chest directly */
6182 chest_trap(obj, bodypart, disarm)
6183 register struct obj *obj;
6184 register int bodypart;
6187 register struct obj *otmp = obj, *otmp2;
6192 if (get_obj_location(obj, &cc.x, &cc.y, 0)) /* might be carried */
6193 obj->ox = cc.x, obj->oy = cc.y;
6195 otmp->otrapped = 0; /* trap is one-shot; clear flag first in case
6196 chest kills you and ends up in bones file */
6198 You(disarm ? "set it off!" : "trigger a trap!");
6200 You(disarm ? "
\83X
\83C
\83b
\83`
\82ð
\93ü
\82ê
\82Ä
\82µ
\82Ü
\82Á
\82½
\81I" : "ã©
\82É
\82Ð
\82Á
\82©
\82©
\82Á
\82½
\81I");
6201 display_nhwindow(WIN_MESSAGE, FALSE);
6202 if (Luck > -13 && rn2(13 + Luck) > 7) { /* saved by luck */
6203 /* trap went off, but good luck prevents damage */
6208 msg = "explosive charge is a dud";
6210 msg = "
\94\9a\94
\82Í
\95s
\94
\82¾
\82Á
\82½";
6215 msg = "electric charge is grounded";
6217 msg = "
\93d
\8c\82\82ª
\95ú
\8fo
\82³
\82ê
\82½
\82ª
\83A
\81[
\83X
\82³
\82ê
\82Ä
\82¢
\82½";
6222 msg = "flame fizzles out";
6224 msg = "
\89\8a\82Í
\83V
\83\85\81[
\82Á
\82Æ
\8fÁ
\82¦
\82½";
6230 msg = "poisoned needle misses";
6232 msg = "
\93Å
\90j
\82Í
\8eh
\82³
\82ç
\82È
\82©
\82Á
\82½";
6239 msg = "gas cloud blows away";
6241 msg = "
\83K
\83X
\89_
\82Í
\90\81\82«
\94ò
\82ñ
\82¾";
6244 impossible("chest disarm bug");
6250 pline("But luckily the %s!", msg);
6252 pline("
\82µ
\82©
\82µ
\89^
\82Ì
\82æ
\82¢
\82±
\82Æ
\82É%s
\81I", msg);
6254 switch (rn2(20) ? ((Luck >= 13) ? 0 : rn2(13 - Luck)) : rn2(26)) {
6260 struct monst *shkp = 0;
6262 boolean costly, insider;
6263 register xchar ox = obj->ox, oy = obj->oy;
6265 /* the obj location need not be that of player */
6266 costly = (costly_spot(ox, oy)
6267 && (shkp = shop_keeper(*in_rooms(ox, oy, SHOPBASE)))
6268 != (struct monst *) 0);
6269 insider = (*u.ushops && inside_shop(u.ux, u.uy)
6270 && *in_rooms(ox, oy, SHOPBASE) == *u.ushops);
6273 pline("%s!", Tobjnam(obj, "explode"));
6275 pline("%s
\82Í
\94\9a\94
\82µ
\82½
\81I", xname(obj));
6277 Sprintf(buf, "exploding %s", xname(obj));
6279 Sprintf(buf, "%s
\82Ì
\94\9a\94
\82Å", xname(obj));
6282 loss += stolen_value(obj, ox, oy, (boolean) shkp->mpeaceful,
6284 delete_contents(obj);
6285 /* unpunish() in advance if either ball or chain (or both)
6286 is going to be destroyed */
6287 if (Punished && ((uchain->ox == u.ux && uchain->oy == u.uy)
6288 || (uball->where == OBJ_FLOOR
6289 && uball->ox == u.ux && uball->oy == u.uy)))
6292 for (otmp = level.objects[u.ux][u.uy]; otmp; otmp = otmp2) {
6293 otmp2 = otmp->nexthere;
6295 loss += stolen_value(otmp, otmp->ox, otmp->oy,
6296 (boolean) shkp->mpeaceful, TRUE);
6300 losehp(Maybe_Half_Phys(d(6, 6)), buf, KILLED_BY_AN);
6301 exercise(A_STR, FALSE);
6302 if (costly && loss) {
6305 You("owe %ld %s for objects destroyed.", loss,
6308 You("
\8aí
\95¨
\94j
\91¹
\82Å%ld%s
\82Ì
\8eØ
\82è
\82ð
\82Â
\82
\82Á
\82½
\81D", loss,
6313 You("caused %ld %s worth of damage!", loss,
6316 You("%ld%s
\95ª
\82Ì
\91¹
\8aQ
\82ð
\88ø
\82«
\82¨
\82±
\82µ
\82½
\81I", loss,
6319 make_angry_shk(shkp, ox, oy);
6329 pline("A cloud of noxious gas billows from %s.", the(xname(obj)));
6331 pline("
\97L
\93Å
\83K
\83X
\82ª%s
\82©
\82ç
\89Q
\82Ü
\82¢
\82½
\81D", the(xname(obj)));
6333 poisoned("gas cloud", A_STR, "cloud of poison gas", 15, FALSE);
6335 poisoned("
\83K
\83X
\89_", A_STR, "
\83K
\83X
\89_", 15, FALSE);
6336 exercise(A_CON, FALSE);
6343 You_feel("a needle prick your %s.", body_part(bodypart));
6345 You("%s
\83`
\83N
\83b
\82Æ
\82¢
\82¤
\92É
\82Ý
\82ð
\8a´
\82¶
\82½
\81D", body_part(bodypart));
6347 poisoned("needle", A_CON, "poisoned needle", 10, FALSE);
6349 poisoned("
\90j", A_CON, "
\93Å
\90j", 10, FALSE);
6350 exercise(A_CON, FALSE);
6364 You("are jolted by a surge of electricity!");
6366 You("
\93d
\8bC
\83V
\83\87\83b
\83N
\82ð
\82
\82ç
\82Á
\82½
\81I");
6367 if (Shock_resistance) {
6368 shieldeff(u.ux, u.uy);
6370 You("don't seem to be affected.");
6372 pline("
\82µ
\82©
\82µ
\82 \82È
\82½
\82Í
\89e
\8b¿
\82ð
\8eó
\82¯
\82È
\82¢
\81D");
6376 destroy_item(RING_CLASS, AD_ELEC);
6377 destroy_item(WAND_CLASS, AD_ELEC);
6380 losehp(dmg, "electric shock", KILLED_BY_AN);
6382 losehp(dmg, "
\93d
\8bC
\83V
\83\87\83b
\83N
\82Å", KILLED_BY_AN);
6390 pline("Suddenly you are frozen in place!");
6392 pline("
\93Ë
\91R
\82»
\82Ì
\8fê
\82Å
\93®
\82¯
\82È
\82
\82È
\82Á
\82½
\81I");
6395 multi_reason = "frozen by a trap";
6397 multi_reason = "ã©
\82Å
\8dd
\92¼
\82µ
\82Ä
\82¢
\82é
\8e\9e\82É";
6398 exercise(A_DEX, FALSE);
6399 nomovemsg = You_can_move_again;
6402 You("momentarily stiffen.");
6404 You("
\88ê
\8fu
\8dd
\92¼
\82µ
\82½
\81D");
6410 pline("A cloud of %s gas billows from %s.",
6411 Blind ? blindgas[rn2(SIZE(blindgas))] : rndcolor(),
6414 pline("%s
\83K
\83X
\89_
\82ª%s
\82Ì
\92ê
\82Å
\89Q
\82Ü
\82¢
\82½
\81D",
6415 Blind ? blindgas[rn2(SIZE(blindgas))] :
6416 jconj_adj(rndcolor()), xname(obj));
6421 pline("What a groovy feeling!");
6423 pline("
\82È
\82ñ
\82Ä
\91f
\93G
\82È
\82ñ
\82¾
\81I");
6426 You("%s%s...", stagger(youmonst.data, "stagger"),
6427 Halluc_resistance ? ""
6428 : Blind ? " and get dizzy"
6429 : " and your vision blurs");
6431 You("
\82
\82ç
\82
\82ç
\82µ%s
\82½...",
6432 Halluc_resistance ? ""
6433 : Blind ? "
\81C
\82ß
\82Ü
\82¢
\82ª
\82µ"
6434 : "
\81C
\8ci
\90F
\82ª
\82Ú
\82â
\82¯
\82Ä
\82«");
6437 make_stunned((HStun & TIMEOUT) + (long) rn1(7, 16), FALSE);
6438 (void) make_hallucinated(
6439 (HHallucination & TIMEOUT) + (long) rn1(5, 16), FALSE, 0L);
6442 impossible("bad chest trap");
6445 bot(); /* to get immediate botl re-display */
6455 register struct trap *trap = ftrap;
6458 if (trap->tx == x && trap->ty == y)
6462 return (struct trap *) 0;
6467 register struct trap *trap;
6469 register struct trap *ttmp;
6471 clear_conjoined_pits(trap);
6472 if (trap == ftrap) {
6473 ftrap = ftrap->ntrap;
6475 for (ttmp = ftrap; ttmp; ttmp = ttmp->ntrap)
6476 if (ttmp->ntrap == trap)
6479 panic("deltrap: no preceding trap!");
6480 ttmp->ntrap = trap->ntrap;
6482 if (Sokoban && (trap->ttyp == PIT || trap->ttyp == HOLE))
6483 maybe_finish_sokoban();
6488 conjoined_pits(trap2, trap1, u_entering_trap2)
6489 struct trap *trap2, *trap1;
6490 boolean u_entering_trap2;
6492 int dx, dy, diridx, adjidx;
6494 if (!trap1 || !trap2)
6496 if (!isok(trap2->tx, trap2->ty) || !isok(trap1->tx, trap1->ty)
6497 || !is_pit(trap2->ttyp)
6498 || !is_pit(trap1->ttyp)
6499 || (u_entering_trap2 && !(u.utrap && u.utraptype == TT_PIT)))
6501 dx = sgn(trap2->tx - trap1->tx);
6502 dy = sgn(trap2->ty - trap1->ty);
6503 for (diridx = 0; diridx < 8; diridx++)
6504 if (xdir[diridx] == dx && ydir[diridx] == dy)
6506 /* diridx is valid if < 8 */
6508 adjidx = (diridx + 4) % 8;
6509 if ((trap1->conjoined & (1 << diridx))
6510 && (trap2->conjoined & (1 << adjidx)))
6517 clear_conjoined_pits(trap)
6520 int diridx, adjidx, x, y;
6523 if (trap && is_pit(trap->ttyp)) {
6524 for (diridx = 0; diridx < 8; ++diridx) {
6525 if (trap->conjoined & (1 << diridx)) {
6526 x = trap->tx + xdir[diridx];
6527 y = trap->ty + ydir[diridx];
6529 && (t = t_at(x, y)) != 0
6530 && is_pit(t->ttyp)) {
6531 adjidx = (diridx + 4) % 8;
6532 t->conjoined &= ~(1 << adjidx);
6534 trap->conjoined &= ~(1 << diridx);
6541 adj_nonconjoined_pit(adjtrap)
6542 struct trap *adjtrap;
6544 struct trap *trap_with_u = t_at(u.ux0, u.uy0);
6546 if (trap_with_u && adjtrap && u.utrap && u.utraptype == TT_PIT
6547 && is_pit(trap_with_u->ttyp) && is_pit(adjtrap->ttyp)) {
6550 for (idx = 0; idx < 8; idx++) {
6551 if (xdir[idx] == u.dx && ydir[idx] == u.dy)
6560 * Mark all neighboring pits as conjoined pits.
6561 * (currently not called from anywhere)
6564 join_adjacent_pits(trap)
6572 for (diridx = 0; diridx < 8; ++diridx) {
6573 x = trap->tx + xdir[diridx];
6574 y = trap->ty + ydir[diridx];
6576 if ((t = t_at(x, y)) != 0 && is_pit(t->ttyp)) {
6577 trap->conjoined |= (1 << diridx);
6578 join_adjacent_pits(t);
6580 trap->conjoined &= ~(1 << diridx);
6587 * Returns TRUE if you escaped a pit and are standing on the precipice.
6590 uteetering_at_seen_pit(trap)
6593 if (trap && trap->tseen && (!u.utrap || u.utraptype != TT_PIT)
6594 && is_pit(trap->ttyp))
6600 /* Destroy a trap that emanates from the floor. */
6603 register struct trap *ttmp;
6605 /* some of these are arbitrary -dlc */
6606 if (ttmp && ((ttmp->ttyp == SQKY_BOARD) || (ttmp->ttyp == BEAR_TRAP)
6607 || (ttmp->ttyp == LANDMINE) || (ttmp->ttyp == FIRE_TRAP)
6608 || is_pit(ttmp->ttyp)
6609 || is_hole(ttmp->ttyp)
6610 || (ttmp->ttyp == TELEP_TRAP) || (ttmp->ttyp == LEVEL_TELEP)
6611 || (ttmp->ttyp == WEB) || (ttmp->ttyp == MAGIC_TRAP)
6612 || (ttmp->ttyp == ANTI_MAGIC))) {
6613 register struct monst *mtmp;
6615 if (ttmp->tx == u.ux && ttmp->ty == u.uy) {
6616 if (u.utraptype != TT_BURIEDBALL)
6618 } else if ((mtmp = m_at(ttmp->tx, ttmp->ty)) != 0) {
6627 /* used for doors (also tins). can be used for anything else that opens. */
6629 b_trapped(item, bodypart)
6633 int lvl = level_difficulty(),
6634 dmg = rnd(5 + (lvl < 5 ? lvl : 2 + lvl / 2));
6637 pline("KABOOM!! %s was booby-trapped!", The(item));
6639 pline("
\82¿
\82ã
\82Ç
\81[
\82ñ
\81I
\81I%s
\82É
\83u
\81[
\83r
\81[
\83g
\83\89\83b
\83v
\82ª
\8ed
\8a|
\82¯
\82ç
\82ê
\82Ä
\82¢
\82½
\81I", item);
6642 losehp(Maybe_Half_Phys(dmg), "explosion", KILLED_BY_AN);
6644 losehp(Maybe_Half_Phys(dmg), "
\83u
\81[
\83r
\81[
\83g
\83\89\83b
\83v
\82Ì
\94\9a\94
\82Å", KILLED_BY_AN);
6645 exercise(A_STR, FALSE);
6647 exercise(A_CON, FALSE);
6648 make_stunned((HStun & TIMEOUT) + (long) dmg, TRUE);
6651 /* Monster is hit by trap. */
6652 /* Note: doesn't work if both obj and d_override are null */
6654 thitm(tlev, mon, obj, d_override, nocorpse)
6662 boolean trapkilled = FALSE;
6667 strike = (find_mac(mon) + tlev + obj->spe <= rnd(20));
6669 strike = (find_mac(mon) + tlev <= rnd(20));
6671 /* Actually more accurate than thitu, which doesn't take
6672 * obj->spe into account.
6675 if (obj && cansee(mon->mx, mon->my))
6677 pline("%s is almost hit by %s!", Monnam(mon), doname(obj));
6679 pline("
\82à
\82¤
\8f
\82µ
\82Å%s
\82ª%s
\82É
\96½
\92\86\82·
\82é
\82Æ
\82±
\82ë
\82¾
\82Á
\82½
\81I", doname(obj), Monnam(mon));
6683 if (obj && cansee(mon->mx, mon->my))
6685 pline("%s is hit by %s!", Monnam(mon), doname(obj));
6687 pline("%s
\82ª%s
\82É
\96½
\92\86\82µ
\82½
\81I", doname(obj), Monnam(mon));
6691 dam = dmgval(obj, mon);
6696 if (DEADMONSTER(mon)) {
6697 int xx = mon->mx, yy = mon->my;
6699 monkilled(mon, "", nocorpse ? -AD_RBRE : AD_PHYS);
6700 if (DEADMONSTER(mon)) {
6706 if (obj && (!strike || d_override)) {
6707 place_object(obj, mon->mx, mon->my);
6722 return (boolean) (u.usleep
6724 && (!strncmp(nomovemsg, "You awake", 9)
6725 || !strncmp(nomovemsg, "You regain con", 14)
6726 || !strncmp(nomovemsg, "You are consci", 14))));
6728 /*JP 3.6.2
\82Å
\82Ì
\8fo
\8c»
\88Ê
\92u/
\89ñ
\90\94
6729 "You awake" : potion.c(1)
6730 "You regain con": eat.c(1)
6731 "You are consci": eat.c(1)
6733 return (boolean) (u.usleep
6735 && (!strncmp(nomovemsg, "
\96Ú
\82ª
\82³
\82ß
\82½
\82ª
\93ª
\92É", 18)
6736 || !strncmp(nomovemsg, "
\82 \82È
\82½
\82Í
\90³
\8bC
\82Ã
\82¢
\82½", 18)
6737 || !strncmp(nomovemsg, "
\82 \82È
\82½
\82Í
\82Ü
\82½
\90³
\8bC
\82Ã", 18))));
6742 static const char lava_killer[] = "molten lava";
6744 static const char lava_killer[] = "
\82Ç
\82ë
\82Ç
\82ë
\82Ì
\97n
\8aâ
\82Å";
6749 register struct obj *obj, *obj2;
6750 int dmg = d(6, 6); /* only applicable for water walking */
6751 boolean usurvive, boil_away;
6754 if (likes_lava(youmonst.data))
6757 usurvive = Fire_resistance || (Wwalking && dmg < u.uhp);
6759 * A timely interrupt might manage to salvage your life
6760 * but not your gear. For scrolls and potions this
6761 * will destroy whole stacks, where fire resistant hero
6762 * survivor only loses partial stacks via destroy_item().
6764 * Flag items to be destroyed before any messages so
6765 * that player causing hangup at --More-- won't get an
6766 * emergency save file created before item destruction.
6769 for (obj = invent; obj; obj = obj->nobj)
6770 if ((is_organic(obj) || obj->oclass == POTION_CLASS)
6771 && !obj->oerodeproof
6772 && objects[obj->otyp].oc_oprop != FIRE_RES
6773 && obj->otyp != SCR_FIRE && obj->otyp != SPE_FIREBALL
6774 && !obj_resists(obj, 0, 0)) /* for invocation items */
6777 /* Check whether we should burn away boots *first* so we know whether to
6778 * make the player sink into the lava. Assumption: water walking only
6781 if (uarmf && is_organic(uarmf) && !uarmf->oerodeproof) {
6784 pline("%s into flame!", Yobjnam2(obj, "burst"));
6786 Your("%s
\82Í
\94R
\82¦
\82½
\81I", xname(obj));
6787 iflags.in_lava_effects++; /* (see above) */
6790 iflags.in_lava_effects--;
6793 if (!Fire_resistance) {
6796 pline_The("%s here burns you!", hliquid("lava"));
6798 pline("%s
\82ª
\82 \82È
\82½
\82ð
\8fÄ
\82«
\82Â
\82
\82µ
\82½
\81I", hliquid("
\97n
\8aâ"));
6800 losehp(dmg, lava_killer, KILLED_BY); /* lava damage */
6805 You("fall into the %s!", hliquid("lava"));
6807 You("%s
\82É
\97\8e\82¿
\82½
\81I", hliquid("
\97n
\8aâ"));
6809 usurvive = Lifesaved || discover;
6813 /* prevent remove_worn_item() -> Boots_off(WATER_WALKING_BOOTS) ->
6814 spoteffects() -> lava_effects() recursion which would
6815 successfully delete (via useupall) the no-longer-worn boots;
6816 once recursive call returned, we would try to delete them again
6817 here in the outer call (and access stale memory, probably panic) */
6818 iflags.in_lava_effects++;
6820 for (obj = invent; obj; obj = obj2) {
6822 /* above, we set in_use for objects which are to be destroyed */
6823 if (obj->otyp == SPE_BOOK_OF_THE_DEAD && !Blind) {
6826 pline("%s glows a strange %s, but remains intact.",
6827 The(xname(obj)), hcolor("dark red"));
6829 pline("%s
\82Í
\95s
\8ev
\8bc
\82É%s
\8bP
\82¢
\82½
\82ª
\81C
\96³
\8f\9d\82Ì
\82æ
\82¤
\82¾
\81D",
6830 xname(obj), jconj_adj(hcolor("
\88Ã
\90Ô
\90F
\82Ì")));
6832 } else if (obj->in_use) {
6833 if (obj->owornmask) {
6836 pline("%s into flame!", Yobjnam2(obj, "burst"));
6838 Your("%s
\82Í
\94R
\82¦
\82½
\81I", xname(obj));
6839 remove_worn_item(obj, TRUE);
6845 iflags.in_lava_effects--;
6848 boil_away = (u.umonnum == PM_WATER_ELEMENTAL
6849 || u.umonnum == PM_STEAM_VORTEX
6850 || u.umonnum == PM_FOG_CLOUD);
6853 /* killer format and name are reconstructed every iteration
6854 because lifesaving resets them */
6855 killer.format = KILLED_BY;
6856 Strcpy(killer.name, lava_killer);
6858 You("%s...", boil_away ? "boil away" : "burn to a crisp");
6860 You("%s
\81D
\81D
\81D", boil_away ? "
\95¦
\93«
\82µ
\82½" : "
\94R
\82¦
\82Ä
\83p
\83\8a\83p
\83\8a\82É
\82È
\82Á
\82½");
6862 if (safe_teleds(TRUE))
6863 break; /* successful life-save */
6864 /* nowhere safe to land; repeat burning loop */
6866 pline("You're still burning.");
6868 You("
\82Ü
\82¾
\94R
\82¦
\82Ä
\82¢
\82é
\81D");
6871 You("find yourself back on solid %s.", surface(u.ux, u.uy));
6873 You("
\82¢
\82Â
\82Ì
\82Ü
\82É
\82©
\8cÅ
\82¢%s
\82É
\96ß
\82Á
\82Ä
\82¢
\82½
\81D", surface(u.ux, u.uy));
6875 } else if (!Wwalking && (!u.utrap || u.utraptype != TT_LAVA)) {
6876 boil_away = !Fire_resistance;
6877 /* if not fire resistant, sink_into_lava() will quickly be fatal;
6878 hero needs to escape immediately */
6879 set_utrap((unsigned) (rn1(4, 4) + ((boil_away ? 2 : rn1(4, 12)) << 8)),
6882 You("sink into the %s%s!", hliquid("lava"),
6883 !boil_away ? ", but it only burns slightly"
6884 : " and are about to be immolated");
6886 You("%s
\82É
\92¾
\82ñ%s
\82¾
\81I", hliquid("
\97n
\8aâ"),
6887 !boil_away ? "
\82¾
\82ª
\81C
\82¿
\82å
\82Á
\82Æ
\8fÅ
\82°
\82½
\82¾
\82¯"
6888 : "
\82Å
\8fÄ
\82«
\8eE
\82³
\82ê
\82»
\82¤");
6891 losehp(!boil_away ? 1 : (u.uhp / 2), lava_killer,
6892 KILLED_BY); /* lava damage */
6896 destroy_item(SCROLL_CLASS, AD_FIRE);
6897 destroy_item(SPBOOK_CLASS, AD_FIRE);
6898 destroy_item(POTION_CLASS, AD_FIRE);
6902 /* called each turn when trapped in lava */
6907 static const char sink_deeper[] = "You sink deeper into the lava.";
6909 static const char sink_deeper[] = "
\82 \82È
\82½
\82Í
\82æ
\82è
\90[
\82
\97n
\8aâ
\82É
\92¾
\82ñ
\82¾
\81D";
6911 if (!u.utrap || u.utraptype != TT_LAVA) {
6912 ; /* do nothing; this shouldn't happen */
6913 } else if (!is_lava(u.ux, u.uy)) {
6914 reset_utrap(FALSE); /* this shouldn't happen either */
6915 } else if (!u.uinvulnerable) {
6916 /* ordinarily we'd have to be fire resistant to survive long
6917 enough to become stuck in lava, but it can happen without
6918 resistance if water walking boots allow survival and then
6919 get burned up; u.utrap time will be quite short in that case */
6920 if (!Fire_resistance)
6921 u.uhp = (u.uhp + 2) / 3;
6923 u.utrap -= (1 << 8);
6924 if (u.utrap < (1 << 8)) {
6925 killer.format = KILLED_BY;
6927 Strcpy(killer.name, "molten lava");
6929 Strcpy(killer.name, "
\82Ç
\82ë
\82Ç
\82ë
\82Ì
\97n
\8aâ
\82Å");
6931 You("sink below the surface and die.");
6933 You("
\8a®
\91S
\82É
\97n
\8aâ
\82Ì
\92\86\82É
\92¾
\82ñ
\82Å
\81A
\8e\80\82É
\82Ü
\82µ
\82½
\81D
\81D
\81D");
6934 burn_away_slime(); /* add insult to injury? */
6936 /* can only get here via life-saving; try to get away from lava */
6938 /* levitation or flight have become unblocked, otherwise Tport */
6939 if (!Levitation && !Flying)
6940 (void) safe_teleds(TRUE);
6941 } else if (!u.umoved) {
6942 /* can't fully turn into slime while in lava, but might not
6943 have it be burned away until you've come awfully close */
6944 if (Slimed && rnd(10 - 1) >= (int) (Slimed & TIMEOUT)) {
6955 /* called when something has been done (breaking a boulder, for instance)
6956 which entails a luck penalty if performed on a sokoban level */
6962 /* TODO: issue some feedback so that player can learn that whatever
6963 he/she just did is a naughty thing to do in sokoban and should
6964 probably be avoided in future....
6965 Caveat: doing this might introduce message sequencing issues,
6966 depending upon feedback during the various actions which trigger
6967 Sokoban luck penalties. */
6971 /* called when a trap has been deleted or had its ttyp replaced */
6973 maybe_finish_sokoban()
6977 if (Sokoban && !in_mklev) {
6978 /* scan all remaining traps, ignoring any created by the hero;
6979 if this level has no more pits or holes, the current sokoban
6980 puzzle has been solved */
6981 for (t = ftrap; t; t = t->ntrap) {
6984 if (t->ttyp == PIT || t->ttyp == HOLE)
6988 /* we've passed the last trap without finding a pit or hole;
6989 clear the sokoban_rules flag so that luck penalties for
6990 things like breaking boulders or jumping will no longer
6991 be given, and restrictions on diagonal moves are lifted */
6992 Sokoban = 0; /* clear level.flags.sokoban_rules */
6993 /* TODO: give some feedback about solving the sokoban puzzle
6994 (perhaps say "congratulations" in Japanese?) */