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½" },
195 *const bythe[] = { "heat", "oxidation", "decay", "corrosion" };
196 boolean vulnerable = FALSE, is_primary = TRUE,
197 check_grease = (ef_flags & EF_GREASE) ? TRUE : FALSE,
198 print = (ef_flags & EF_VERBOSE) ? TRUE : FALSE,
199 uvictim, vismon, visobj;
200 int erosion, cost_type;
201 struct monst *victim;
206 victim = carried(otmp) ? &youmonst : mcarried(otmp) ? otmp->ocarry : NULL;
207 uvictim = (victim == &youmonst);
208 vismon = victim && (victim != &youmonst) && canseemon(victim);
209 /* Is bhitpos correct here? Ugh. */
210 visobj = !victim && cansee(bhitpos.x, bhitpos.y);
214 vulnerable = is_flammable(otmp);
215 check_grease = FALSE;
216 cost_type = COST_BURN;
219 vulnerable = is_rustprone(otmp);
220 cost_type = COST_RUST;
223 vulnerable = is_rottable(otmp);
224 check_grease = FALSE;
226 cost_type = COST_ROT;
229 vulnerable = is_corrodeable(otmp);
231 cost_type = COST_CORRODE;
234 impossible("Invalid erosion type in erode_obj");
237 erosion = is_primary ? otmp->oeroded : otmp->oeroded2;
241 /* 'visobj' messages insert "the"; probably ought to switch to the() */
242 if (visobj && !(uvictim || vismon) && !strncmpi(ostr, "the ", 4))
245 if (check_grease && otmp->greased) {
246 grease_protect(otmp, ostr, victim);
248 } else if (!erosion_matters(otmp)) {
250 } else if (!vulnerable || (otmp->oerodeproof && otmp->rknown)) {
251 if (flags.verbose && print && (uvictim || vismon))
253 pline("%s %s %s not affected by %s.",
254 uvictim ? "Your" : s_suffix(Monnam(victim)),
255 ostr, vtense(ostr, "are"), bythe[type]);
257 pline("%s%s
\82Í%s
\82Ì
\89e
\8b¿
\82ð
\8eó
\82¯
\82È
\82©
\82Á
\82½
\81D",
258 uvictim ? "
\82 \82È
\82½
\82Ì" : s_suffix(Monnam(victim)),
262 } else if (otmp->oerodeproof || (otmp->blessed && !rnl(4))) {
263 if (flags.verbose && (print || otmp->oerodeproof)
264 && (uvictim || vismon || visobj))
266 pline("Somehow, %s %s %s not affected by the %s.",
268 : !vismon ? "the" /* visobj */
269 : s_suffix(mon_nam(victim)),
270 ostr, vtense(ostr, "are"), bythe[type]);
272 pline("
\82È
\82º
\82©
\81C%s%s
\82Í%s
\82Ì
\89e
\8b¿
\82ð
\8eó
\82¯
\82È
\82©
\82Á
\82½
\81D",
273 uvictim ? "
\82 \82È
\82½
\82Ì"
274 : !vismon ? "" /* visobj */
275 : s_suffix(mon_nam(victim)),
278 /* We assume here that if the object is protected because it
279 * is blessed, it still shows some minor signs of wear, and
280 * the hero can distinguish this from an object that is
281 * actually proof against damage.
283 if (otmp->oerodeproof) {
285 if (victim == &youmonst)
290 } else if (erosion < MAX_ERODE) {
292 const char *adverb = (erosion + 1 == MAX_ERODE)
294 : erosion ? " further" : "";
296 const char *adverb = (erosion + 1 == MAX_ERODE)
298 : erosion ? "
\82³
\82ç
\82É" : "";
301 if (uvictim || vismon || visobj)
305 : !vismon ? "The" /* visobj */
306 : s_suffix(Monnam(victim)),
307 ostr, vtense(ostr, action[type]), adverb);
309 pline("%s%s
\82Í%s%s!",
310 uvictim ? "
\82 \82È
\82½
\82Ì"
311 : !vismon ? "" /* visobj */
312 : s_suffix(Monnam(victim)),
313 ostr, adverb, action[type]);
316 if (ef_flags & EF_PAY)
317 costly_alteration(otmp, cost_type);
324 if (victim == &youmonst)
328 } else if (ef_flags & EF_DESTROY) {
329 if (uvictim || vismon || visobj)
331 pline("%s %s %s away!",
333 : !vismon ? "The" /* visobj */
334 : s_suffix(Monnam(victim)),
335 ostr, vtense(ostr, action[type]));
337 pline("%s%s
\82Í
\8a®
\91S
\82É%s
\81I",
338 uvictim ? "
\82 \82È
\82½
\82Ì"
339 : !vismon ? "" /* visobj */
340 : s_suffix(Monnam(victim)),
344 if (ef_flags & EF_PAY)
345 costly_alteration(otmp, cost_type);
351 if (flags.verbose && print) {
354 Your("%s %s completely %s.",
355 ostr, vtense(ostr, Blind ? "feel" : "look"), msg[type]);
357 Your("%s
\82Í
\8a®
\91S
\82É%s%s
\81D",
358 ostr, msg[type], Blind ? "
\82æ
\82¤
\82¾" : "");
360 else if (vismon || visobj)
362 pline("%s %s %s completely %s.",
363 !vismon ? "The" : s_suffix(Monnam(victim)),
364 ostr, vtense(ostr, "look"), msg[type]);
366 pline("%s%s
\82Í
\8a®
\91S
\82É%s
\82æ
\82¤
\82¾
\81D",
367 !vismon ? "" : s_suffix(Monnam(victim)),
375 /* Protect an item from erosion with grease. Returns TRUE if the grease
379 grease_protect(otmp, ostr, victim)
380 register struct obj *otmp;
382 struct monst *victim;
385 static const char txt[] = "protected by the layer of grease!";
387 static const char txt[] = "
\96û
\82Ì
\93h
\82è
\82±
\82Ý
\82É
\82æ
\82Á
\82Ä
\8eç
\82ç
\82ê
\82Ä
\82¢
\82é
\81I";
388 boolean vismon = victim && (victim != &youmonst) && canseemon(victim);
391 if (victim == &youmonst)
393 Your("%s %s %s", ostr, vtense(ostr, "are"), txt);
395 Your("%s
\82Í%s", ostr, txt);
398 pline("%s's %s %s %s", Monnam(victim),
399 ostr, vtense(ostr, "are"), txt);
401 pline("%s
\82Ì%s
\82Í%s", Monnam(victim), ostr, txt);
403 } else if (victim == &youmonst || vismon) {
405 pline("%s %s", Yobjnam2(otmp, "are"), txt);
407 Your("%s
\82Í%s",xname(otmp), txt);
413 pline_The("grease dissolves.");
415 pline("
\96û
\82Í
\82Í
\82°
\82Ä
\82µ
\82Ü
\82Á
\82½
\81D");
427 static union vlaunchinfo zero_vl;
430 struct rm *lev = &levl[x][y];
432 if ((ttmp = t_at(x, y)) != 0) {
433 if (ttmp->ttyp == MAGIC_PORTAL || ttmp->ttyp == VIBRATING_SQUARE)
434 return (struct trap *) 0;
436 if (u.utrap && x == u.ux && y == u.uy
437 && ((u.utraptype == TT_BEARTRAP && typ != BEAR_TRAP)
438 || (u.utraptype == TT_WEB && typ != WEB)
439 || (u.utraptype == TT_PIT && !is_pit(typ))))
441 /* old <tx,ty> remain valid */
442 } else if (IS_FURNITURE(lev->typ)
443 && (!IS_GRAVE(lev->typ) || (typ != PIT && typ != HOLE))) {
444 /* no trap on top of furniture (caller usually screens the
445 location to inhibit this, but wizard mode wishing doesn't) */
446 return (struct trap *) 0;
450 (void) memset((genericptr_t)ttmp, 0, sizeof(struct trap));
455 /* [re-]initialize all fields except ntrap (handled below) and <tx,ty> */
457 ttmp->launch.x = ttmp->launch.y = -1; /* force error if used before set */
458 ttmp->dst.dnum = ttmp->dst.dlevel = -1;
461 ttmp->tseen = (typ == HOLE); /* hide non-holes */
466 int tavail[12], tpick[12], tcnt = 0, k;
469 for (k = 0; k < 12; ++k)
470 tavail[k] = tpick[k] = 0;
471 for (t = ftrap; t; t = t->ntrap)
472 if (t->ttyp == SQKY_BOARD && t != ttmp)
473 tavail[t->tnote] = 1;
474 /* now populate tpick[] with the available indices */
475 for (k = 0; k < 12; ++k)
478 /* choose an unused note; if all are in use, pick a random one */
479 ttmp->tnote = (short) ((tcnt > 0) ? tpick[rn2(tcnt)] : rn2(12));
482 case STATUE_TRAP: { /* create a "living" statue */
484 struct obj *otmp, *statue;
485 struct permonst *mptr;
488 do { /* avoid ultimately hostile co-aligned unicorn */
489 mptr = &mons[rndmonnum()];
490 } while (--trycount > 0 && is_unicorn(mptr)
491 && sgn(u.ualign.type) == sgn(mptr->maligntyp));
492 statue = mkcorpstat(STATUE, (struct monst *) 0, mptr, x, y,
494 mtmp = makemon(&mons[statue->corpsenm], 0, 0, MM_NOCOUNTBIRTH);
496 break; /* should never happen */
497 while (mtmp->minvent) {
498 otmp = mtmp->minvent;
500 obj_extract_self(otmp);
501 (void) add_to_container(statue, otmp);
503 statue->owt = weight(statue);
507 case ROLLING_BOULDER_TRAP: /* boulder will roll towards trigger */
508 (void) mkroll_launch(ttmp, x, y, BOULDER, 1L);
516 if (*in_rooms(x, y, SHOPBASE)
517 && (is_hole(typ) || IS_DOOR(lev->typ) || IS_WALL(lev->typ)))
518 add_damage(x, y, /* schedule repair */
519 ((IS_DOOR(lev->typ) || IS_WALL(lev->typ))
520 && !context.mon_moving)
523 lev->doormask = 0; /* subsumes altarmask, icedpool... */
524 if (IS_ROOM(lev->typ)) /* && !IS_AIR(lev->typ) */
527 * some cases which can happen when digging
528 * down while phazing thru solid areas
530 else if (lev->typ == STONE || lev->typ == SCORR)
532 else if (IS_WALL(lev->typ) || lev->typ == SDOOR)
533 lev->typ = level.flags.is_maze_lev
535 : level.flags.is_cavernous_lev ? CORR : DOOR;
546 it shouldn't be possible to override a sokoban pit or hole
547 with some other trap, but we'll check just to be safe */
549 maybe_finish_sokoban();
556 boolean td; /* td == TRUE : trap door or hole */
560 const char *dont_fall = 0;
561 int newlevel, bottom;
563 /* we'll fall even while levitating in Sokoban; otherwise, if we
564 won't fall and won't be told that we aren't falling, give up now */
565 if (Blind && Levitation && !Sokoban)
568 bottom = dunlevs_in_dungeon(&u.uz);
569 /* when in the upper half of the quest, don't fall past the
570 middle "quest locate" level if hero hasn't been there yet */
571 if (In_quest(&u.uz)) {
572 int qlocate_depth = qlocate_level.dlevel;
574 /* deepest reached < qlocate implies current < qlocate */
575 if (dunlev_reached(&u.uz) < qlocate_depth)
576 bottom = qlocate_depth; /* early cut-off */
578 newlevel = dunlev(&u.uz); /* current level */
581 } while (!rn2(4) && newlevel < bottom);
584 struct trap *t = t_at(u.ux, u.uy);
588 if (t->ttyp == TRAPDOOR)
590 pline("A trap door opens up under you!");
592 pline("
\97\8e\82µ
\94à
\82ª
\82 \82È
\82½
\82Ì
\91«
\8c³
\82É
\8aJ
\82¢
\82½
\81I");
595 pline("There's a gaping hole under you!");
597 pline("
\82 \82È
\82½
\82Ì
\91«
\89º
\82É
\82Û
\82Á
\82©
\82è
\82Æ
\8c\8a\82ª
\8aJ
\82¢
\82Ä
\82¢
\82é
\81I");
601 pline_The("%s opens up under you!", surface(u.ux, u.uy));
603 pline("
\91«
\8c³
\82Ì%s
\82É
\8c\8a\82ª
\8aJ
\82¢
\82½
\81I", surface(u.ux,u.uy));
605 if (Sokoban && Can_fall_thru(&u.uz))
606 ; /* KMH -- You can't escape the Sokoban level traps */
607 else if (Levitation || u.ustuck
608 || (!Can_fall_thru(&u.uz) && !levl[u.ux][u.uy].candig) || Flying
609 || is_clinger(youmonst.data)
610 || (Inhell && !u.uevent.invoked && newlevel == bottom)) {
612 dont_fall = "don't fall in.";
614 dont_fall = "
\82µ
\82©
\82µ
\82 \82È
\82½
\82Í
\97\8e\82¿
\82È
\82©
\82Á
\82½
\81D";
615 } else if (youmonst.data->msize >= MZ_HUGE) {
617 dont_fall = "don't fit through.";
619 dont_fall = "
\92Ê
\82è
\94²
\82¯
\82é
\82É
\82Í
\83T
\83C
\83Y
\82ª
\8d\87\82í
\82È
\82¢
\81D";
620 } else if (!next_to_u()) {
622 dont_fall = "are jerked back by your pet!";
624 dont_fall = "
\82 \82È
\82½
\82Í
\83y
\83b
\83g
\82É
\82æ
\82Á
\82Ä
\88ø
\82Á
\82Ï
\82è
\82à
\82Ç
\82³
\82ê
\82½
\81I";
627 #if 0 /*JP*//*
\81u
\82 \82È
\82½
\82Í
\81v
\82Å
\8en
\82Ü
\82ç
\82È
\82¢
\82à
\82Ì
\82à
\82 \82é*/
632 /* hero didn't fall through, but any objects here might */
633 impact_drop((struct obj *) 0, u.ux, u.uy, 0);
635 display_nhwindow(WIN_MESSAGE, FALSE);
637 pline_The("opening under you closes up.");
639 pline_The("
\91«
\89º
\82É
\8aJ
\82¢
\82Ä
\82¢
\82½
\82à
\82Ì
\82Í
\95Â
\82¶
\82½
\81D");
646 if (Is_stronghold(&u.uz)) {
649 int dist = newlevel - dunlev(&u.uz);
650 dtmp.dnum = u.uz.dnum;
651 dtmp.dlevel = newlevel;
654 You("fall down a %s%sshaft!", dist > 3 ? "very " : "",
655 dist > 2 ? "deep " : "");
657 You("%s%s
\8c\8a\82Ì
\92\86\82ð
\97\8e\82¿
\82Ä
\82¢
\82Á
\82½
\81I", dist > 3 ? "
\82Æ
\82Ä
\82à" : "",
658 dist > 2 ? "
\90[
\82¢" : "");
663 Sprintf(msgbuf, "The hole in the %s above you closes up.",
665 Sprintf(msgbuf, "%s
\82É
\8aJ
\82¢
\82½
\8c\8a\82Í
\95Â
\82¶
\82½
\81D",
666 ceiling(u.ux, u.uy));
668 schedule_goto(&dtmp, FALSE, TRUE, 0, (char *) 0,
669 !td ? msgbuf : (char *) 0);
673 * Animate the given statue. May have been via shatter attempt, trap,
674 * or stone to flesh spell. Return a monster if successfully animated.
675 * If the monster is animated, the object is deleted. If fail_reason
676 * is non-null, then fill in the reason for failure (or success).
678 * The cause of animation is:
680 * ANIMATE_NORMAL - hero "finds" the monster
681 * ANIMATE_SHATTER - hero tries to destroy the statue
682 * ANIMATE_SPELL - stone to flesh spell hits the statue
684 * Perhaps x, y is not needed if we can use get_obj_location() to find
685 * the statue's location... ???
687 * Sequencing matters:
688 * create monster; if it fails, give up with statue intact;
689 * give "statue comes to life" message;
690 * if statue belongs to shop, have shk give "you owe" message;
691 * transfer statue contents to monster (after stolen_value());
693 * [This ordering means that if the statue ends up wearing a cloak of
694 * invisibility or a mummy wrapping, the visibility checks might be
695 * wrong, but to avoid that we'd have to clone the statue contents
696 * first in order to give them to the monster before checking their
697 * shop status--it's not worth the hassle.]
700 animate_statue(statue, x, y, cause, fail_reason)
706 int mnum = statue->corpsenm;
707 struct permonst *mptr = &mons[mnum];
708 struct monst *mon = 0, *shkp;
711 boolean historic = (Role_if(PM_ARCHEOLOGIST)
712 && (statue->spe & STATUE_HISTORIC) != 0),
713 golem_xform = FALSE, use_saved_traits;
714 const char *comes_to_life;
715 char statuename[BUFSZ], tmpbuf[BUFSZ];
716 static const char historic_statue_is_gone[] =
718 "that the historic statue is now gone";
720 "
\97ð
\8ej
\93I
\82È
\92¤
\91\9c\82ª
\82È
\82
\82È
\82Á
\82Ä
\82µ
\82Ü
\82Á
\82½
\82±
\82Æ";
722 if (cant_revive(&mnum, TRUE, statue)) {
723 /* mnum has changed; we won't be animating this statue as itself */
724 if (mnum != PM_DOPPELGANGER)
726 use_saved_traits = FALSE;
727 } else if (is_golem(mptr) && cause == ANIMATE_SPELL) {
728 /* statue of any golem hit by stone-to-flesh becomes flesh golem */
729 golem_xform = (mptr != &mons[PM_FLESH_GOLEM]);
730 mnum = PM_FLESH_GOLEM;
731 mptr = &mons[PM_FLESH_GOLEM];
732 use_saved_traits = (has_omonst(statue) && !golem_xform);
734 use_saved_traits = has_omonst(statue);
737 if (use_saved_traits) {
738 /* restore a petrified monster */
740 mon = montraits(statue, &cc, (cause == ANIMATE_SPELL));
741 if (mon && mon->mtame && !mon->isminion)
744 /* statues of unique monsters from bones or wishing end
745 up here (cant_revive() sets mnum to be doppelganger;
746 mptr reflects the original form for use by newcham()) */
747 if ((mnum == PM_DOPPELGANGER && mptr != &mons[PM_DOPPELGANGER])
748 /* block quest guards from other roles */
749 || (mptr->msound == MS_GUARDIAN
750 && quest_info(MS_GUARDIAN) != mnum)) {
751 mon = makemon(&mons[PM_DOPPELGANGER], x, y,
752 NO_MINVENT | MM_NOCOUNTBIRTH | MM_ADJACENTOK);
753 /* if hero has protection from shape changers, cham field will
754 be NON_PM; otherwise, set form to match the statue */
755 if (mon && mon->cham >= LOW_PM)
756 (void) newcham(mon, mptr, FALSE, FALSE);
758 mon = makemon(mptr, x, y, (cause == ANIMATE_SPELL)
759 ? (NO_MINVENT | MM_ADJACENTOK)
765 *fail_reason = unique_corpstat(&mons[statue->corpsenm])
768 return (struct monst *) 0;
771 /* a non-montraits() statue might specify gender */
772 if (statue->spe & STATUE_MALE)
774 else if (statue->spe & STATUE_FEMALE)
776 /* if statue has been named, give same name to the monster */
777 if (has_oname(statue) && !unique_corpstat(mon->data))
778 mon = christen_monst(mon, ONAME(statue));
779 /* mimic statue becomes seen mimic; other hiders won't be hidden */
783 mon->mundetected = FALSE;
785 if (cause == ANIMATE_NORMAL || cause == ANIMATE_SHATTER) {
786 /* trap always releases hostile monster */
787 mon->mtame = 0; /* (might be petrified pet tossed onto trap) */
793 comes_to_life = !canspotmon(mon)
797 : (nonliving(mon->data) || is_vampshifter(mon))
801 comes_to_life = !canspotmon(mon)
804 ? "
\93÷
\91Ì
\82É
\96ß
\82Á"
805 : (nonliving(mon->data) || is_vampshifter(mon))
807 : "
\90¶
\96½
\82ð
\91Ñ
\82Ñ";
809 if ((x == u.ux && y == u.uy) || cause == ANIMATE_SPELL) {
810 /* "the|your|Manlobbi's statue [of a wombat]" */
811 shkp = shop_keeper(*in_rooms(mon->mx, mon->my, SHOPBASE));
813 Sprintf(statuename, "%s%s", shk_your(tmpbuf, statue),
814 (cause == ANIMATE_SPELL
815 /* avoid "of a shopkeeper" if it's Manlobbi himself
816 (if carried, it can't be unpaid--hence won't be
817 described as "Manlobbi's statue"--because there
818 wasn't any living shk when statue was picked up) */
819 && (mon != shkp || carried(statue)))
823 Sprintf(statuename, "%s%s", shk_your(tmpbuf, statue),
824 (cause == ANIMATE_SPELL
825 && (mon != shkp || carried(statue)))
830 pline("%s %s!", upstart(statuename), comes_to_life);
832 pline("%s
\82Í%s
\82½
\81I", upstart(statuename), comes_to_life);
833 } else if (Hallucination) { /* They don't know it's a statue */
835 pline_The("%s suddenly seems more animated.", rndmonnam((char *) 0));
837 pline_The("%s
\82Í
\93Ë
\91R
\82æ
\82è
\8a\88\93®
\93I
\82É
\82È
\82Á
\82½
\81D", rndmonnam((char *) 0));
838 } else if (cause == ANIMATE_SHATTER) {
840 Sprintf(statuename, "%s%s", shk_your(tmpbuf, statue),
844 Strcpy(statuename, "a statue");
846 Strcpy(statuename, "
\92¤
\91\9c");
848 pline("Instead of shattering, %s suddenly %s!", statuename,
851 pline("%s
\82Í
\8dÓ
\82¯
\82¸
\82É%s
\82½
\81I", statuename,
854 } else { /* cause == ANIMATE_NORMAL */
856 You("find %s posing as a statue.",
858 You("%s
\82ª
\92¤
\91\9c\82Ì
\82Ó
\82è
\82ð
\82µ
\82Ä
\82¢
\82é
\82Ì
\82ð
\8c©
\82Â
\82¯
\82½
\81D",
859 canspotmon(mon) ? a_monnam(mon) : something);
860 if (!canspotmon(mon) && Blind)
865 /* if this isn't caused by a monster using a wand of striking,
866 there might be consequences for the hero */
867 if (!context.mon_moving) {
868 /* if statue is owned by a shop, hero will have to pay for it;
869 stolen_value gives a message (about debt or use of credit)
870 which refers to "it" so needs to follow a message describing
871 the object ("the statue comes to life" one above) */
872 if (cause != ANIMATE_NORMAL && costly_spot(x, y)
873 && (carried(statue) ? statue->unpaid : !statue->no_charge)
874 && (shkp = shop_keeper(*in_rooms(x, y, SHOPBASE))) != 0
875 /* avoid charging for Manlobbi's statue of Manlobbi
876 if stone-to-flesh is used on petrified shopkeep */
878 (void) stolen_value(statue, x, y, (boolean) shkp->mpeaceful,
883 You_feel("guilty %s.", historic_statue_is_gone);
885 You_feel("%s
\82É
\8dß
\82ð
\8a´
\82¶
\82½
\81D", historic_statue_is_gone);
889 if (historic && cansee(x, y))
891 You_feel("regret %s.", historic_statue_is_gone);
893 You_feel("%s
\82ð
\8cã
\89÷
\82µ
\82½
\81D", historic_statue_is_gone);
894 /* no alignment penalty */
897 /* transfer any statue contents to monster's inventory */
898 while ((item = statue->cobj) != 0) {
899 obj_extract_self(item);
900 (void) mpickobj(mon, item);
903 /* in case statue is wielded and hero zaps stone-to-flesh at self */
904 if (statue->owornmask)
905 remove_worn_item(statue, TRUE);
906 /* statue no longer exists */
909 /* avoid hiding under nothing */
910 if (x == u.ux && y == u.uy && Upolyd && hides_under(youmonst.data)
915 *fail_reason = AS_OK;
920 * You've either stepped onto a statue trap's location or you've triggered a
921 * statue trap by searching next to it or by trying to break it with a wand
925 activate_statue_trap(trap, x, y, shatter)
930 struct monst *mtmp = (struct monst *) 0;
931 struct obj *otmp = sobj_at(STATUE, x, y);
935 * Try to animate the first valid statue. Stop the loop when we
936 * actually create something or the failure cause is not because
937 * the mon was unique.
941 mtmp = animate_statue(otmp, x, y,
942 shatter ? ANIMATE_SHATTER : ANIMATE_NORMAL,
944 if (mtmp || fail_reason != AS_MON_IS_UNIQUE)
947 otmp = nxtobj(otmp, STATUE, TRUE);
955 keep_saddle_with_steedcorpse(steed_mid, objchn, saddle)
957 struct obj *objchn, *saddle;
962 if (objchn->otyp == CORPSE && has_omonst(objchn)) {
963 struct monst *mtmp = OMONST(objchn);
965 if (mtmp->m_id == steed_mid) {
968 if (get_obj_location(objchn, &x, &y, 0)) {
969 obj_extract_self(saddle);
970 place_object(saddle, x, y);
976 if (Has_contents(objchn)
977 && keep_saddle_with_steedcorpse(steed_mid, objchn->cobj, saddle))
979 objchn = objchn->nobj;
984 /* monster or you go through and possibly destroy a web.
985 return TRUE if could go through. */
987 mu_maybe_destroy_web(mtmp, domsg, trap)
992 boolean isyou = (mtmp == &youmonst);
993 struct permonst *mptr = mtmp->data;
995 if (amorphous(mptr) || is_whirly(mptr) || flaming(mptr)
996 || unsolid(mptr) || mptr == &mons[PM_GELATINOUS_CUBE]) {
1000 if (flaming(mptr) || acidic(mptr)) {
1004 You("%s %s spider web!",
1005 (flaming(mptr)) ? "burn" : "dissolve",
1006 a_your[trap->madeby_u]);
1008 You("%s
\82
\82à
\82Ì
\91\83\82ð%s
\81I",
1009 web_you[trap->madeby_u],
1010 (flaming(mptr)) ? "
\8fÄ
\82¢
\82½" : "
\82±
\82È
\82²
\82È
\82É
\82µ
\82½");
1014 pline("%s %s %s spider web!", Monnam(mtmp),
1015 (flaming(mptr)) ? "burns" : "dissolves",
1016 a_your[trap->madeby_u]);
1018 pline("%s%s
\82
\82à
\82Ì
\91\83\82ð%s
\81I", Monnam(mtmp),
1019 web_you[trap->madeby_u],
1020 (flaming(mptr)) ? "
\8fÄ
\82¢
\82½" : "
\82±
\82È
\82²
\82È
\82É
\82µ
\82½");
1030 You("flow through %s spider web.", a_your[trap->madeby_u]);
1032 You("%s
\82
\82à
\82Ì
\91\83\82ð
\82·
\82é
\82è
\82Æ
\92Ê
\82è
\94²
\82¯
\82½
\81D", web_you[trap->madeby_u]);
1035 pline("%s flows through %s spider web.", Monnam(mtmp),
1036 a_your[trap->madeby_u]);
1038 pline("%s
\82Í%s
\82
\82à
\82Ì
\91\83\82ð
\82·
\82é
\82è
\82Æ
\92Ê
\82è
\94²
\82¯
\82½
\81D", Monnam(mtmp),
1039 web_you[trap->madeby_u]);
1049 /* make a single arrow/dart/rock for a trap to shoot or drop */
1050 STATIC_OVL struct obj *
1051 t_missile(otyp, trap)
1055 struct obj *otmp = mksobj(otyp, TRUE, FALSE);
1058 otmp->owt = weight(otmp);
1059 otmp->opoisoned = 0;
1060 otmp->ox = trap->tx, otmp->oy = trap->ty;
1070 * utraptype==0 is bear trap rather than 'none'; we probably ought
1071 * to change that but can't do so until save file compatability is
1072 * able to be broken.
1074 u.utraptype = tim ? typ : 0;
1076 float_vs_flight(); /* maybe block Lev and/or Fly */
1083 boolean was_Lev = (Levitation != 0), was_Fly = (Flying != 0);
1088 if (!was_Lev && Levitation)
1090 if (!was_Fly && Flying)
1096 dotrap(trap, trflags)
1097 register struct trap *trap;
1100 register int ttype = trap->ttyp;
1102 boolean already_seen = trap->tseen,
1103 forcetrap = ((trflags & FORCETRAP) != 0
1104 || (trflags & FAILEDUNTRAP) != 0),
1105 webmsgok = (trflags & NOWEBMSG) == 0,
1106 forcebungle = (trflags & FORCEBUNGLE) != 0,
1107 plunged = (trflags & TOOKPLUNGE) != 0,
1108 viasitting = (trflags & VIASITTING) != 0,
1109 conj_pit = conjoined_pits(trap, t_at(u.ux0, u.uy0), TRUE),
1110 adj_pit = adj_nonconjoined_pit(trap);
1112 int steed_article = ARTICLE_THE;
1116 /* KMH -- You can't escape the Sokoban level traps */
1117 if (Sokoban && (is_pit(ttype) || is_hole(ttype))) {
1118 /* The "air currents" message is still appropriate -- even when
1119 * the hero isn't flying or levitating -- because it conveys the
1120 * reason why the player cannot escape the trap with a dexterity
1121 * check, clinging to the ceiling, etc.
1124 pline("Air currents pull you down into %s %s!",
1125 a_your[trap->madeby_u],
1126 defsyms[trap_to_defsym(ttype)].explanation);
1128 pline("
\8bó
\8bC
\82Ì
\97¬
\82ê
\82ª
\82 \82È
\82½
\82ð%s
\82É
\88ø
\82«
\96ß
\82µ
\82½
\81I",
1129 defsyms[trap_to_defsym(ttype)].explanation);
1131 /* then proceed to normal trap effect */
1132 } else if (already_seen && !forcetrap) {
1133 if ((Levitation || (Flying && !plunged))
1134 && (is_pit(ttype) || ttype == HOLE || ttype == BEAR_TRAP)) {
1136 You("%s over %s %s.", Levitation ? "float" : "fly",
1137 a_your[trap->madeby_u],
1138 defsyms[trap_to_defsym(ttype)].explanation);
1140 You("%s%s
\82Ì
\8fã%s
\81D",
1141 set_you[trap->madeby_u],
1142 defsyms[trap_to_defsym(ttype)].explanation,
1143 Levitation ? "
\82ð
\8c©
\89º
\82ë
\82µ
\82½" : "
\82ð
\94ò
\82ñ
\82Å
\82¢
\82é");
1147 if (!Fumbling && ttype != MAGIC_PORTAL && ttype != VIBRATING_SQUARE
1148 && ttype != ANTI_MAGIC && !forcebungle && !plunged
1149 && !conj_pit && !adj_pit
1150 && (!rn2(5) || (is_pit(ttype)
1151 && is_clinger(youmonst.data)))) {
1153 You("escape %s %s.", (ttype == ARROW_TRAP && !trap->madeby_u)
1155 : a_your[trap->madeby_u],
1156 defsyms[trap_to_defsym(ttype)].explanation);
1158 You("%s%s
\82ð
\82·
\82é
\82è
\82Æ
\94ð
\82¯
\82½
\81D",
1159 set_you[trap->madeby_u],
1160 defsyms[trap_to_defsym(ttype)].explanation);
1167 u.usteed->mtrapseen |= (1 << (ttype - 1));
1168 /* suppress article in various steed messages when using its
1169 name (which won't occur when hallucinating) */
1170 if (has_mname(u.usteed) && !Hallucination)
1171 steed_article = ARTICLE_NONE;
1176 if (trap->once && trap->tseen && !rn2(15)) {
1178 You_hear("a loud click!");
1180 You_hear("
\83K
\83`
\83\83\83b
\82Æ
\82¢
\82¤
\91å
\82«
\82È
\89¹
\82ð
\95·
\82¢
\82½
\81I");
1188 pline("An arrow shoots out at you!");
1190 pline("
\96î
\82ª
\94ò
\82ñ
\82Å
\82«
\82½
\81I");
1191 otmp = t_missile(ARROW, trap);
1192 if (u.usteed && !rn2(2) && steedintrap(trap, otmp)) {
1195 } else if (thitu(8, dmgval(otmp, &youmonst), &otmp, "arrow")) {
1197 } else if (thitu(8, dmgval(otmp, &youmonst), &otmp, "
\96î")) {
1200 obfree(otmp, (struct obj *) 0);
1202 place_object(otmp, u.ux, u.uy);
1211 if (trap->once && trap->tseen && !rn2(15)) {
1213 You_hear("a soft click.");
1215 You_hear("
\83J
\83`
\83b
\82Æ
\82¢
\82¤
\89¹
\82ð
\95·
\82¢
\82½
\81D");
1223 pline("A little dart shoots out at you!");
1225 pline("
\8f¬
\82³
\82È
\93\8a\82°
\96î
\82ª
\94ò
\82ñ
\82Å
\82«
\82½
\81I");
1226 otmp = t_missile(DART, trap);
1228 otmp->opoisoned = 1;
1229 oldumort = u.umortality;
1230 if (u.usteed && !rn2(2) && steedintrap(trap, otmp)) {
1233 } else if (thitu(7, dmgval(otmp, &youmonst), &otmp, "little dart")) {
1235 } else if (thitu(7, dmgval(otmp, &youmonst), &otmp, "
\93\8a\82°
\96î")) {
1238 if (otmp->opoisoned)
1240 poisoned("dart", A_CON, "little dart",
1241 /* if damage triggered life-saving,
1242 poison is limited to attrib loss */
1243 (u.umortality > oldumort) ? 0 : 10, TRUE);
1245 poisoned("
\93\8a\82°
\96î", A_CON, "
\8f¬
\82³
\82È
\93\8a\82°
\96î",
1246 /* if damage triggered life-saving,
1247 poison is limited to attrib loss */
1248 (u.umortality > oldumort) ? 0 : 10, TRUE);
1250 obfree(otmp, (struct obj *) 0);
1253 place_object(otmp, u.ux, u.uy);
1262 if (trap->once && trap->tseen && !rn2(15)) {
1264 pline("A trap door in %s opens, but nothing falls out!",
1266 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",
1267 the(ceiling(u.ux, u.uy)));
1271 int dmg = d(2, 6); /* should be std ROCK dmg? */
1275 otmp = t_missile(ROCK, trap);
1276 place_object(otmp, u.ux, u.uy);
1279 pline("A trap door in %s opens and %s falls on your %s!",
1280 the(ceiling(u.ux, u.uy)), an(xname(otmp)), body_part(HEAD));
1282 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",
1283 ceiling(u.ux,u.uy), xname(otmp), body_part(HEAD));
1286 if (is_metallic(uarmh)) {
1288 pline("Fortunately, you are wearing a hard helmet.");
1290 pline("
\8dK
\89^
\82É
\82à
\81C
\82 \82È
\82½
\82Í
\8cÅ
\82¢
\8a\95\82ð
\90g
\82É
\82Â
\82¯
\82Ä
\82¢
\82½
\81D");
1292 } else if (flags.verbose) {
1294 pline("%s does not protect you.", Yname2(uarmh));
1296 pline("%s
\82Å
\82Í
\96h
\82°
\82È
\82¢
\81D", xname(uarmh));
1302 newsym(u.ux, u.uy); /* map the rock */
1305 losehp(Maybe_Half_Phys(dmg), "falling rock", KILLED_BY_AN);
1307 losehp(Maybe_Half_Phys(dmg), "
\97\8e\8aâ
\82Å", KILLED_BY_AN);
1308 exercise(A_STR, FALSE);
1312 case SQKY_BOARD: /* stepped on a squeaky board */
1313 if ((Levitation || Flying) && !forcetrap) {
1318 You("notice a crease in the linoleum.");
1320 You("
\8f°
\82Ì
\8ed
\8fã
\8dÞ
\82Ì
\82µ
\82í
\82É
\8bC
\82ª
\82Â
\82¢
\82½
\81D");
1323 You("notice a loose board below you.");
1325 You("
\91«
\8c³
\82Ì
\8aÉ
\82ñ
\82¾
\94Â
\82É
\8bC
\82ª
\82Â
\82¢
\82½
\81D");
1330 pline("A board beneath you %s%s%s.",
1331 Deaf ? "vibrates" : "squeaks ",
1332 Deaf ? "" : trapnote(trap, 0), Deaf ? "" : " loudly");
1335 pline("
\91«
\8c³
\82Ì
\94Â
\82ª
\82ä
\82ê
\82½
\81D");
1337 pline("
\91«
\8c³
\82Ì
\94Â
\82ª
\91å
\82«
\82%s
\82Ì
\89¹
\82É
\82«
\82µ
\82ñ
\82¾
\81D", trapnote(trap, 0));
1347 if ((Levitation || Flying) && !forcetrap)
1350 if (amorphous(youmonst.data) || is_whirly(youmonst.data)
1351 || unsolid(youmonst.data)) {
1353 pline("%s bear trap closes harmlessly through you.",
1354 A_Your[trap->madeby_u]);
1356 pline("%s
\8cF
\82Ìã©
\82Í
\8a\9a\82Ý
\82Â
\82¢
\82½
\82ª
\81C
\82·
\82é
\82Á
\82Æ
\92Ê
\82è
\94²
\82¯
\82½
\81D",
1357 set_you[trap->madeby_u]);
1361 if (!u.usteed && youmonst.data->msize <= MZ_SMALL) {
1363 pline("%s bear trap closes harmlessly over you.",
1364 A_Your[trap->madeby_u]);
1366 pline("%s
\8cF
\82Ìã©
\82Í
\8a\9a\82Ý
\82Â
\82¢
\82½
\82ª
\81C
\97y
\82©
\8fã
\95û
\82¾
\82Á
\82½
\81D",
1367 set_you[trap->madeby_u]);
1371 set_utrap((unsigned) rn1(4, 4), TT_BEARTRAP);
1374 pline("%s bear trap closes on %s %s!", A_Your[trap->madeby_u],
1375 s_suffix(mon_nam(u.usteed)), mbodypart(u.usteed, FOOT));
1377 pline("%s
\8cF
\82Ìã©
\82Í%s
\82Ì%s
\82É
\8a\9a\82Ý
\82Â
\82¢
\82½
\81I", set_you[trap->madeby_u],
1378 mon_nam(u.usteed), mbodypart(u.usteed, FOOT));
1380 if (thitm(0, u.usteed, (struct obj *) 0, dmg, FALSE))
1381 reset_utrap(TRUE); /* steed died, hero not trapped */
1384 pline("%s bear trap closes on your %s!", A_Your[trap->madeby_u],
1387 pline("%s
\8cF
\82Ìã©
\82ª
\82 \82È
\82½
\82Ì%s
\82É
\8a\9a\82Ý
\82Â
\82¢
\82½
\81I", set_you[trap->madeby_u],
1390 set_wounded_legs(rn2(2) ? RIGHT_SIDE : LEFT_SIDE, rn1(10, 10));
1391 if (u.umonnum == PM_OWLBEAR || u.umonnum == PM_BUGBEAR)
1393 You("howl in anger!");
1395 You("
\93{
\82è
\82Ì
\99ô
\9aK
\82ð
\82 \82°
\82½
\81I");
1397 losehp(Maybe_Half_Phys(dmg), "bear trap", KILLED_BY_AN);
1399 losehp(Maybe_Half_Phys(dmg), "
\8cF
\82Ìã©
\82Å", KILLED_BY_AN);
1401 exercise(A_DEX, FALSE);
1407 if (Sleep_resistance || breathless(youmonst.data)) {
1409 You("are enveloped in a cloud of gas!");
1411 You("
\83K
\83X
\89_
\82É
\82Â
\82Â
\82Ü
\82ê
\82½
\81I");
1414 pline("A cloud of gas puts you to sleep!");
1416 pline("
\82 \82È
\82½
\82Í
\83K
\83X
\89_
\82Å
\96°
\82Á
\82Ä
\82µ
\82Ü
\82Á
\82½
\81I");
1417 fall_asleep(-rnd(25), TRUE);
1419 (void) steedintrap(trap, (struct obj *) 0);
1425 /* Unlike monsters, traps cannot aim their rust attacks at
1426 * you, so instead of looping through and taking either the
1427 * first rustable one or the body, we take whatever we get,
1428 * even if it is not rustable.
1433 pline("%s you on the %s!", A_gush_of_water_hits, body_part(HEAD));
1435 pline("
\90\85\82ª
\95¬
\8fo
\82µ
\82Ä
\82 \82È
\82½
\82Ì%s
\82É
\96½
\92\86\82µ
\82½
\81I", body_part(HEAD));
1436 (void) water_damage(uarmh, helm_simple_name(uarmh), TRUE);
1440 pline("%s your left %s!", A_gush_of_water_hits, body_part(ARM));
1442 pline("
\90\85\82ª
\95¬
\8fo
\82µ
\82Ä
\82 \82È
\82½
\82Ì
\8d¶%s
\82É
\96½
\92\86\82µ
\82½
\81I", body_part(ARM));
1444 if (water_damage(uarms, "shield", TRUE) != ER_NOTHING)
1446 if (water_damage(uarms, "
\8f\82", TRUE) != ER_NOTHING)
1448 if (u.twoweap || (uwep && bimanual(uwep)))
1449 (void) water_damage(u.twoweap ? uswapwep : uwep, 0, TRUE);
1452 (void) water_damage(uarmg, "gauntlets", TRUE);
1454 (void) water_damage(uarmg, "
\8f¬
\8eè", TRUE);
1455 /* Not "metal gauntlets" since it gets called
1456 * even if it's leather for the message
1461 pline("%s your right %s!", A_gush_of_water_hits, body_part(ARM));
1463 pline("
\90\85\82ª
\95¬
\8fo
\82µ
\82Ä
\82 \82È
\82½
\82Ì
\89E%s
\82É
\96½
\92\86\82µ
\82½
\81I", body_part(ARM));
1464 (void) water_damage(uwep, 0, TRUE);
1468 pline("%s you!", A_gush_of_water_hits);
1470 pline("
\90\85\82ª
\95¬
\8fo
\82µ
\82Ä
\82 \82È
\82½
\82É
\96½
\92\86\82µ
\82½
\81I");
1471 for (otmp = invent; otmp; otmp = otmp->nobj)
1472 if (otmp->lamplit && otmp != uwep
1473 && (otmp != uswapwep || !u.twoweap))
1474 (void) snuff_lit(otmp);
1476 (void) water_damage(uarmc, cloak_simple_name(uarmc), TRUE);
1478 (void) water_damage(uarm, suit_simple_name(uarm), TRUE);
1481 (void) water_damage(uarmu, "shirt", TRUE);
1483 (void) water_damage(uarmu, "
\83V
\83\83\83c", TRUE);
1487 if (u.umonnum == PM_IRON_GOLEM) {
1491 You("are covered with rust!");
1493 You("
\8eK
\82É
\95¢
\82í
\82ê
\82½
\81I");
1495 losehp(Maybe_Half_Phys(dam), "rusting away", KILLED_BY);
1497 losehp(Maybe_Half_Phys(dam), "
\8a®
\91S
\82É
\8eK
\82Ñ
\82Ä", KILLED_BY);
1498 } else if (u.umonnum == PM_GREMLIN && rn2(3)) {
1499 (void) split_mon(&youmonst, (struct monst *) 0);
1506 dofiretrap((struct obj *) 0);
1511 /* KMH -- You can't escape the Sokoban level traps */
1512 if (!Sokoban && (Levitation || (Flying && !plunged)))
1515 if (!Sokoban && is_clinger(youmonst.data) && !plunged) {
1518 You_see("%s %spit below you.", a_your[trap->madeby_u],
1519 ttype == SPIKED_PIT ? "spiked " : "");
1521 pline("
\91«
\8c³
\82É%s%s
\97\8e\82µ
\8c\8a\82ð
\94
\8c©
\82µ
\82½
\81D", dig_you[trap->madeby_u],
1522 ttype == SPIKED_PIT ? "
\83g
\83Q
\82¾
\82ç
\82¯
\82Ì" : "");
1526 pline("%s pit %sopens up under you!", A_Your[trap->madeby_u],
1527 ttype == SPIKED_PIT ? "full of spikes " : "");
1529 pline("%s%s
\97\8e\82µ
\8c\8a\82ª
\91«
\8c³
\82É
\8aJ
\82¢
\82½
\81I", dig_you[trap->madeby_u],
1530 ttype == SPIKED_PIT ? "
\83g
\83Q
\82¾
\82ç
\82¯
\82Ì" : "");
1533 You("don't fall in!");
1535 pline("
\82µ
\82©
\82µ
\81C
\82 \82È
\82½
\82Í
\97\8e\82¿
\82È
\82©
\82Á
\82½
\81I");
1540 char verbbuf[BUFSZ];
1544 if ((trflags & RECURSIVETRAP) != 0)
1546 Sprintf(verbbuf, "and %s fall",
1548 Sprintf(verbbuf, "
\82Æ%s",
1549 x_monnam(u.usteed, steed_article, (char *) 0,
1550 SUPPRESS_SADDLE, FALSE));
1553 Sprintf(verbbuf, "lead %s",
1554 x_monnam(u.usteed, steed_article, "poor",
1555 SUPPRESS_SADDLE, FALSE));
1557 Sprintf(verbbuf, "
\82Æ%s",
1558 x_monnam(u.usteed, steed_article, "
\82©
\82í
\82¢
\82»
\82¤
\82È",
1559 SUPPRESS_SADDLE, FALSE));
1561 } else if (conj_pit) {
1563 You("move into an adjacent pit.");
1565 You("
\97×
\82Ì
\97\8e\82µ
\8c\8a\82É
\88Ú
\93®
\82µ
\82½
\81D");
1566 } else if (adj_pit) {
1567 You("stumble over debris%s.",
1568 !rn2(5) ? " between the pits" : "");
1572 !plunged ? "fall" : (Flying ? "dive" : "plunge"));
1575 !plunged ? "
\97\8e\82¿
\82½" : (Flying ? "
\94ò
\82Ñ
\8d\9e\82ñ
\82¾" : "
\93Ë
\93ü
\82µ
\82½"));
1580 You("%s into %s pit!", verbbuf, a_your[trap->madeby_u]);
1582 You("%s
\97\8e\82µ
\8c\8a\82É%s!", set_you[trap->madeby_u], verbbuf);
1584 /* wumpus reference */
1585 if (Role_if(PM_RANGER) && !trap->madeby_u && !trap->once
1586 && In_quest(&u.uz) && Is_qlocate(&u.uz)) {
1588 pline("Fortunately it has a bottom after all...");
1590 pline("
\8dK
\82¢
\81C
\8c\8b\8bÇ
\82Í
\92ê
\82ª
\82 \82Á
\82½
\81D
\81D
\81D");
1592 } else if (u.umonnum == PM_PIT_VIPER || u.umonnum == PM_PIT_FIEND) {
1594 pline("How pitiful. Isn't that the pits?");
1596 pline("
\82±
\82Ì
\97\8e\82µ
\8c\8a\82Í
\82¢
\82¢
\8ed
\8e\96\82ð
\82µ
\82Ä
\82¢
\82é
\81D");
1598 if (ttype == SPIKED_PIT) {
1600 const char *predicament = "on a set of sharp iron spikes";
1602 const char *predicament = "
\89s
\82¢
\93S
\82Ì
\83g
\83Q
\83g
\83Q
\82Ì
\8fã
\82É";
1607 upstart(x_monnam(u.usteed, steed_article, "poor",
1608 SUPPRESS_SADDLE, FALSE)),
1609 conj_pit ? "steps" : "lands", predicament);
1611 pline("%s
\82Í%s%s
\81I",
1612 upstart(x_monnam(u.usteed, steed_article, "
\82©
\82í
\82¢
\82»
\82¤
\82È",
1613 SUPPRESS_SADDLE, FALSE)),
1614 predicament, conj_pit ? "
\97\8e\82¿
\82½" : "
\8d~
\82è
\82½");
1618 You("%s %s!", conj_pit ? "step" : "land", predicament);
1620 You("%s%s
\81I", predicament, conj_pit ? "
\97\8e\82¿
\82½" : "
\8d~
\82è
\82½");
1623 * if hero gets killed here, setting u.utrap in advance will
1624 * show "you were trapped in a pit" during disclosure's display
1625 * of enlightenment, but hero is dying *before* becoming trapped.
1627 set_utrap((unsigned) rn1(6, 2), TT_PIT);
1628 if (!steedintrap(trap, (struct obj *) 0)) {
1629 if (ttype == SPIKED_PIT) {
1630 oldumort = u.umortality;
1632 losehp(Maybe_Half_Phys(rnd(conj_pit ? 4 : adj_pit ? 6 : 10)),
1633 /* note: these don't need locomotion() handling;
1634 if fatal while poly'd and Unchanging, the
1635 death reason will be overridden with
1636 "killed while stuck in creature form" */
1638 ? "deliberately plunged into a pit of iron spikes"
1640 ? "stepped into a pit of iron spikes"
1642 ? "stumbled into a pit of iron spikes"
1643 : "fell into a pit of iron spikes",
1646 losehp(Maybe_Half_Phys(rnd(conj_pit ? 4 : adj_pit ? 6 : 10)),
1648 ? "
\82í
\82´
\82í
\82´
\83g
\83Q
\82¾
\82ç
\82¯
\82Ì
\97\8e\82µ
\8c\8a\82É
\93Ë
\93ü
\82µ
\82Ä"
1650 ? "
\83g
\83Q
\82¾
\82ç
\82¯
\82Ì
\97\8e\82µ
\8c\8a\82É
\93¥
\82Ý
\8d\9e\82ñ
\82Å"
1652 ? "
\83g
\83Q
\82¾
\82ç
\82¯
\82Ì
\97\8e\82µ
\8c\8a\82É
\82æ
\82ë
\82ß
\82«
\97\8e\82¿
\82Ä"
1653 : "
\83g
\83Q
\82¾
\82ç
\82¯
\82Ì
\97\8e\82µ
\8c\8a\82É
\97\8e\82¿
\82Ä",
1658 poisoned("spikes", A_STR,
1659 (conj_pit || adj_pit)
1660 ? "stepping on poison spikes"
1661 : "fall onto poison spikes",
1662 /* if damage triggered life-saving,
1663 poison is limited to attrib loss */
1664 (u.umortality > oldumort) ? 0 : 8, FALSE);
1666 poisoned("
\83g
\83Q", A_STR,
1667 (conj_pit || adj_pit)
1668 ? "
\93Å
\82Ì
\93h
\82ç
\82ê
\82½
\83g
\83Q
\82ð
\93¥
\82ñ
\82Å"
1669 : "
\93Å
\82Ì
\93h
\82ç
\82ê
\82½
\83g
\83Q
\82Ì
\8fã
\82É
\97\8e\82¿
\82Ä",
1670 /* if damage triggered life-saving,
1671 poison is limited to attrib loss */
1672 (u.umortality > oldumort) ? 0 : 8, FALSE);
1675 /* plunging flyers take spike damage but not pit damage */
1677 && !(plunged && (Flying || is_clinger(youmonst.data))))
1679 losehp(Maybe_Half_Phys(rnd(adj_pit ? 3 : 6)),
1680 plunged ? "deliberately plunged into a pit"
1681 : "fell into a pit",
1684 losehp(Maybe_Half_Phys(rnd(adj_pit ? 3 : 6)),
1685 plunged ? "
\82í
\82´
\82í
\82´
\97\8e\82µ
\8c\8a\82É
\93Ë
\93ü
\82µ
\82Ä"
1686 : "
\97\8e\82µ
\8c\8a\82É
\97\8e\82¿
\82Ä",
1690 if (Punished && !carried(uball)) {
1697 selftouch("Falling, you");
1699 selftouch("
\97\8e\89º
\92\86\81C
\82 \82È
\82½
\82Í");
1700 vision_full_recalc = 1; /* vision limits change */
1701 exercise(A_STR, FALSE);
1702 exercise(A_DEX, FALSE);
1708 if (!Can_fall_thru(&u.uz)) {
1709 seetrap(trap); /* normally done in fall_through */
1710 impossible("dotrap: %ss cannot exist on this level.",
1711 defsyms[trap_to_defsym(ttype)].explanation);
1712 break; /* don't activate it after all */
1724 level_tele_trap(trap, trflags);
1727 case WEB: /* Our luckless player has stumbled into a web. */
1729 if (mu_maybe_destroy_web(&youmonst, webmsgok, trap))
1731 if (webmaker(youmonst.data)) {
1734 pline(trap->madeby_u ? "You take a walk on your web."
1735 : "There is a spider web here.");
1737 pline(trap->madeby_u ? "
\8e©
\95ª
\82Å
\92£
\82Á
\82½
\82
\82à
\82Ì
\91\83\82Ì
\8fã
\82ð
\95à
\82¢
\82½
\81D"
1738 : "
\82±
\82±
\82É
\82Í
\82
\82à
\82Ì
\91\83\82ª
\82 \82é
\81D");
1743 char verbbuf[BUFSZ];
1746 if (forcetrap || viasitting) {
1747 Strcpy(verbbuf, "are caught by");
1748 } else if (u.usteed) {
1749 Sprintf(verbbuf, "lead %s into",
1750 x_monnam(u.usteed, steed_article, "poor",
1751 SUPPRESS_SADDLE, FALSE));
1753 Sprintf(verbbuf, "%s into",
1754 Levitation ? (const char *) "float"
1755 : locomotion(youmonst.data, "stumble"));
1757 You("%s %s spider web!", verbbuf, a_your[trap->madeby_u]);
1760 Strcpy(verbbuf, "
\82 \82È
\82½
\82Í");
1761 } else if (u.usteed) {
1762 Sprintf(verbbuf, "
\82 \82È
\82½
\82Æ%s",
1763 x_monnam(u.usteed, steed_article, "
\82©
\82í
\82¢
\82»
\82¤
\82È",
1764 SUPPRESS_SADDLE, FALSE));
1766 Sprintf(verbbuf, "
\82 \82È
\82½
\82Í%s",
1767 Levitation ? (const char *) "
\95\82\82«
\82È
\82ª
\82ç"
1768 : jconj(locomotion(youmonst.data, "
\82Â
\82Ü
\82¸
\82"), "
\82Ä"));
1770 pline("%s%s
\82
\82à
\82Ì
\91\83\82É
\82Ð
\82Á
\82©
\82©
\82Á
\82½
\81I", verbbuf, web_you[trap->madeby_u]);
1774 /* time will be adjusted below */
1775 set_utrap(1, TT_WEB);
1777 /* Time stuck in the web depends on your/steed strength. */
1779 int tim, str = ACURR(A_STR);
1781 /* If mounted, the steed gets trapped. Use mintrap
1782 * to do all the work. If mtrapped is set as a result,
1783 * unset it and set utrap instead. In the case of a
1784 * strongmonst and mintrap said it's trapped, use a
1785 * short but non-zero trap time. Otherwise, monsters
1786 * have no specific strength, so use player strength.
1787 * This gets skipped for webmsgok, which implies that
1788 * the steed isn't a factor.
1790 if (u.usteed && webmsgok) {
1791 /* mtmp location might not be up to date */
1792 u.usteed->mx = u.ux;
1793 u.usteed->my = u.uy;
1795 /* mintrap currently does not return 2(died) for webs */
1796 if (mintrap(u.usteed)) {
1797 u.usteed->mtrapped = 0;
1798 if (strongmonst(u.usteed->data))
1805 webmsgok = FALSE; /* mintrap printed the messages */
1825 You("tear through %s web!", a_your[trap->madeby_u]);
1827 You("%s
\82
\82à
\82Ì
\91\83\82ð
\90Ø
\82è
\97ô
\82¢
\82½
\81I", web_you[trap->madeby_u]);
1829 newsym(u.ux, u.uy); /* get rid of trap symbol */
1831 set_utrap((unsigned) tim, TT_WEB);
1836 (void) activate_statue_trap(trap, u.ux, u.uy, FALSE);
1839 case MAGIC_TRAP: /* A magic trap. */
1843 newsym(u.ux, u.uy); /* update position */
1845 You("are caught in a magical explosion!");
1847 You("
\96\82\96@
\82Ì
\94\9a\94
\82ð
\97\81\82Ñ
\82½
\81I");
1849 losehp(rnd(10), "magical explosion", KILLED_BY_AN);
1851 losehp(rnd(10), "
\96\82\96@
\82Ì
\94\9a\94
\82ð
\97\81\82Ñ
\82Ä", KILLED_BY_AN);
1853 Your("body absorbs some of the magical energy!");
1855 Your("
\91Ì
\82Í
\96\82\96@
\82Ì
\83G
\83l
\83\8b\83M
\81[
\82ð
\8f
\82µ
\8bz
\82¢
\82Æ
\82Á
\82½
\81I");
1856 u.uen = (u.uenmax += 2);
1861 (void) steedintrap(trap, (struct obj *) 0);
1866 /* hero without magic resistance loses spell energy,
1867 hero with magic resistance takes damage instead;
1868 possibly non-intuitive but useful for play balance */
1870 drain_en(rnd(u.ulevel) + 1);
1872 int dmgval2 = rnd(4), hp = Upolyd ? u.mh : u.uhp;
1874 /* Half_XXX_damage has opposite its usual effect (approx)
1875 but isn't cumulative if hero has more than one */
1876 if (Half_physical_damage || Half_spell_damage)
1878 /* give Magicbane wielder dose of own medicine */
1879 if (uwep && uwep->oartifact == ART_MAGICBANE)
1881 /* having an artifact--other than own quest one--which
1882 confers magic resistance simply by being carried
1883 also increases the effect */
1884 for (otmp = invent; otmp; otmp = otmp->nobj)
1885 if (otmp->oartifact && !is_quest_artifact(otmp)
1886 && defends_when_carried(AD_MAGM, otmp))
1891 dmgval2 = (dmgval2 + 3) / 4;
1894 You_feel((dmgval2 >= hp) ? "unbearably torpid!"
1895 : (dmgval2 >= hp / 4) ? "very lethargic."
1898 You_feel((dmgval2 >= hp) ? "
\91Ï
\82¦
\82ç
\82ê
\82È
\82¢
\82Ù
\82Ç
\96³
\8bC
\97Í
\82É
\82È
\82Á
\82½
\81I"
1899 : (dmgval2 >= hp / 4) ? "
\82Æ
\82Ä
\82à
\8bC
\82¾
\82é
\82
\82È
\82Á
\82½
\81D"
1900 : "
\82à
\82Ì
\82®
\82³
\82È
\8bC
\95ª
\82É
\82È
\82Á
\82½
\81D");
1902 /* opposite of magical explosion */
1904 losehp(dmgval2, "anti-magic implosion", KILLED_BY_AN);
1906 losehp(dmgval2, "
\94½
\96\82\96@
\82Ì
\93à
\95\94\94j
\97ô
\82Å", KILLED_BY_AN);
1911 char verbbuf[BUFSZ];
1915 Strcpy(verbbuf, "trigger"); /* follows "You sit down." */
1918 Sprintf(verbbuf, "lead %s onto",
1919 x_monnam(u.usteed, steed_article, (char *) 0,
1920 SUPPRESS_SADDLE, FALSE));
1922 Sprintf(verbbuf, "%s
\82Æ
\82Æ
\82à
\82É
\94ò
\82Ñ
\8d\9e\82ñ
\82¾",
1923 x_monnam(u.usteed, steed_article, (char *) 0,
1924 SUPPRESS_SADDLE, FALSE));
1928 Sprintf(verbbuf, "%s onto",
1929 Levitation ? (const char *) "float"
1930 : locomotion(youmonst.data, "step"));
1932 Sprintf(verbbuf,"%s",
1933 jpast(Levitation ? (const char *)"
\95\82\82«
\82È
\82ª
\82ç
\94ò
\82Ñ
\82±
\82Þ"
1934 : locomotion(youmonst.data, "
\93¥
\82Ý
\8d\9e\82Þ")));
1937 You("%s a polymorph trap!", verbbuf);
1939 You("
\95Ï
\89»
\82Ìã©
\82É%s
\81I", verbbuf);
1940 if (Antimagic || Unchanging) {
1941 shieldeff(u.ux, u.uy);
1943 You_feel("momentarily different.");
1945 You("
\88ê
\8fu
\88á
\82Á
\82½
\8a´
\82¶
\82ª
\82µ
\82½
\81D");
1946 /* Trap did nothing; don't remove it --KAA */
1948 (void) steedintrap(trap, (struct obj *) 0);
1949 deltrap(trap); /* delete trap before polymorph */
1950 newsym(u.ux, u.uy); /* get rid of trap symbol */
1952 You_feel("a change coming over you.");
1954 You("
\95Ï
\89»
\82ª
\96K
\82ê
\82½
\82æ
\82¤
\82È
\8bC
\82ª
\82µ
\82½
\81D");
1960 unsigned steed_mid = 0;
1961 struct obj *saddle = 0;
1963 if ((Levitation || Flying) && !forcetrap) {
1964 if (!already_seen && rn2(3))
1968 pline("%s %s in a pile of soil below you.",
1969 already_seen ? "There is" : "You discover",
1970 trap->madeby_u ? "the trigger of your mine" : "a trigger");
1973 pline("
\82±
\82±
\82É
\82Í%s
\92n
\97\8b\82Ì
\8bN
\94\9a\83X
\83C
\83b
\83`
\82ª
\82 \82é
\81D",
1974 set_you[trap->madeby_u]);
1976 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",
1977 set_you[trap->madeby_u]);
1979 if (already_seen && rn2(3))
1982 pline("KAABLAMM!!! %s %s%s off!",
1983 forcebungle ? "Your inept attempt sets"
1984 : "The air currents set",
1985 already_seen ? a_your[trap->madeby_u] : "",
1986 already_seen ? " land mine" : "it");
1988 pline("
\82¿
\82ã
\82Ç
\81[
\82ñ
\81I
\81I%s%s%s
\8bN
\94\9a\83X
\83C
\83b
\83`
\82ª
\94
\93®
\82µ
\82½
\81I",
1989 forcebungle ? "
\95s
\8aí
\97p
\82È
\82¹
\82¢
\82Å"
1990 : "
\8bó
\8bC
\82Ì
\97¬
\82ê
\82Å",
1991 already_seen ? set_you[trap->madeby_u] : "",
1992 already_seen ? "
\92n
\97\8b\82Ì" : "");
1995 /* prevent landmine from killing steed, throwing you to
1996 * the ground, and you being affected again by the same
1997 * mine because it hasn't been deleted yet
1999 static boolean recursive_mine = FALSE;
2005 pline("KAABLAMM!!! You triggered %s land mine!",
2006 a_your[trap->madeby_u]);
2008 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",
2009 set_you[trap->madeby_u]);
2012 steed_mid = u.usteed->m_id;
2013 recursive_mine = TRUE;
2014 (void) steedintrap(trap, (struct obj *) 0);
2015 recursive_mine = FALSE;
2016 saddle = sobj_at(SADDLE, u.ux, u.uy);
2017 set_wounded_legs(LEFT_SIDE, rn1(35, 41));
2018 set_wounded_legs(RIGHT_SIDE, rn1(35, 41));
2019 exercise(A_DEX, FALSE);
2021 blow_up_landmine(trap);
2022 if (steed_mid && saddle && !u.usteed)
2023 (void) keep_saddle_with_steedcorpse(steed_mid, fobj, saddle);
2024 newsym(u.ux, u.uy); /* update trap symbol */
2026 losehp(Maybe_Half_Phys(rnd(16)), "land mine", KILLED_BY_AN);
2028 losehp(Maybe_Half_Phys(rnd(16)), "
\92n
\97\8b\82ð
\93¥
\82ñ
\82Å", KILLED_BY_AN);
2029 /* fall recursively into the pit... */
2030 if ((trap = t_at(u.ux, u.uy)) != 0)
2031 dotrap(trap, RECURSIVETRAP);
2032 fill_pit(u.ux, u.uy);
2036 case ROLLING_BOULDER_TRAP: {
2037 int style = ROLL | (trap->tseen ? LAUNCH_KNOWN : 0);
2041 pline("Click! You trigger a rolling boulder trap!");
2043 pline("
\83J
\83`
\83b
\81I
\82 \82È
\82½
\82Í
\8b\90\8aâ
\82Ìã©
\82Ì
\83X
\83C
\83b
\83`
\82ð
\93¥
\82ñ
\82¾
\81I");
2044 if (!launch_obj(BOULDER, trap->launch.x, trap->launch.y,
2045 trap->launch2.x, trap->launch2.y, style)) {
2047 newsym(u.ux, u.uy); /* get rid of trap symbol */
2049 pline("Fortunately for you, no boulder was released.");
2051 pline("
\89^
\82Ì
\82æ
\82¢
\82±
\82Æ
\82É
\8aâ
\82Í
\93]
\82ª
\82Á
\82Ä
\82±
\82È
\82©
\82Á
\82½
\81D");
2058 domagicportal(trap);
2061 case VIBRATING_SQUARE:
2063 /* messages handled elsewhere; the trap symbol is merely to mark the
2064 * square for future reference */
2069 impossible("You hit a trap of type %u", trap->ttyp);
2074 trapnote(trap, noprefix)
2078 static char tnbuf[12];
2081 *tnnames[12] = { "C note", "D flat", "D note", "E flat",
2082 "E note", "F note", "F sharp", "G note",
2083 "G sharp", "A note", "B flat", "B note" };
2085 *tnnames[12] = { "
\83h", "
\83\8c\81ó", "
\83\8c", "
\83~
\81ó",
2086 "
\83~", "
\83t
\83@", "
\83t
\83@
\81ò", "
\83\",
2087 "
\83\
\81ò", "
\83\89", "
\83V
\81ó", "
\83V" };
2091 tn = tnnames[trap->tnote];
2094 Sprintf(tnbuf, "%s ",
2095 (*tn == 'A' || *tn == 'E' || *tn == 'F') ? "an" : "a");
2096 Sprintf(eos(tnbuf), "%s", tn);
2098 Sprintf(tnbuf, "%s
\82Ì
\89¹", tn);
2104 steedintrap(trap, otmp)
2108 struct monst *steed = u.usteed;
2110 boolean trapkilled, steedhit;
2112 if (!steed || !trap)
2117 trapkilled = steedhit = FALSE;
2122 impossible("steed hit by non-existant arrow?");
2125 trapkilled = thitm(8, steed, otmp, 0, FALSE);
2130 impossible("steed hit by non-existant dart?");
2133 trapkilled = thitm(7, steed, otmp, 0, FALSE);
2137 if (!resists_sleep(steed) && !breathless(steed->data)
2138 && !steed->msleeping && steed->mcanmove) {
2139 if (sleep_monst(steed, rnd(25), -1))
2140 /* no in_sight check here; you can feel it even if blind */
2142 pline("%s suddenly falls asleep!", Monnam(steed));
2144 pline("%s
\82Í
\82Æ
\82Â
\82º
\82ñ
\96°
\82Á
\82Ä
\82µ
\82Ü
\82Á
\82½
\81I", Monnam(steed));
2149 trapkilled = thitm(0, steed, (struct obj *) 0, rnd(16), FALSE);
2154 trapkilled = (DEADMONSTER(steed)
2155 || thitm(0, steed, (struct obj *) 0,
2156 rnd((tt == PIT) ? 6 : 10), FALSE));
2160 if (!resists_magm(steed) && !resist(steed, WAND_CLASS, 0, NOTELL)) {
2161 (void) newcham(steed, (struct permonst *) 0, FALSE, FALSE);
2162 if (!can_saddle(steed) || !can_ride(steed))
2163 dismount_steed(DISMOUNT_POLY);
2166 You("have to adjust yourself in the saddle on %s.",
2168 You("%s
\82Ì
\88Æ
\82Ì
\8fã
\82Å
\8dÀ
\82è
\82È
\82¨
\82µ
\82½
\81D",
2169 x_monnam(steed, ARTICLE_A, (char *) 0, SUPPRESS_SADDLE,
2179 dismount_steed(DISMOUNT_POLY);
2182 return steedhit ? 1 : 0;
2185 /* some actions common to both player and monsters for triggered landmine */
2187 blow_up_landmine(trap)
2190 int x = trap->tx, y = trap->ty, dbx, dby;
2191 struct rm *lev = &levl[x][y];
2193 (void) scatter(x, y, 4,
2194 MAY_DESTROY | MAY_HIT | MAY_FRACTURE | VIS_EFFECTS,
2197 wake_nearto(x, y, 400);
2198 if (IS_DOOR(lev->typ))
2199 lev->doormask = D_BROKEN;
2200 /* destroy drawbridge if present */
2201 if (lev->typ == DRAWBRIDGE_DOWN || is_drawbridge_wall(x, y) >= 0) {
2203 /* if under the portcullis, the bridge is adjacent */
2204 if (find_drawbridge(&dbx, &dby))
2205 destroy_drawbridge(dbx, dby);
2206 trap = t_at(x, y); /* expected to be null after destruction */
2208 /* convert landmine into pit */
2210 if (Is_waterlevel(&u.uz) || Is_airlevel(&u.uz)) {
2214 trap->ttyp = PIT; /* explosion creates a pit */
2215 trap->madeby_u = FALSE; /* resulting pit isn't yours */
2216 seetrap(trap); /* and it isn't concealed */
2222 * The following are used to track launched objects to
2223 * prevent them from vanishing if you are killed. They
2224 * will reappear at the launchplace in bones files.
2232 launch_drop_spot(obj, x, y)
2237 launchplace.obj = (struct obj *) 0;
2241 launchplace.obj = obj;
2248 launch_in_progress()
2250 if (launchplace.obj)
2256 force_launch_placement()
2258 if (launchplace.obj) {
2259 launchplace.obj->otrapped = 0;
2260 place_object(launchplace.obj, launchplace.x, launchplace.y);
2265 * Move obj from (x1,y1) to (x2,y2)
2267 * Return 0 if no object was launched.
2268 * 1 if an object was launched and placed somewhere.
2269 * 2 if an object was launched, but used up.
2272 launch_obj(otyp, x1, y1, x2, y2, style)
2274 register int x1, y1, x2, y2;
2277 register struct monst *mtmp;
2278 register struct obj *otmp, *otmp2;
2279 register int dx, dy;
2280 struct obj *singleobj;
2281 boolean used_up = FALSE;
2282 boolean otherside = FALSE;
2287 otmp = sobj_at(otyp, x1, y1);
2288 /* Try the other side too, for rolling boulder traps */
2289 if (!otmp && otyp == BOULDER) {
2291 otmp = sobj_at(otyp, x2, y2);
2295 if (otherside) { /* swap 'em */
2306 if (otmp->quan == 1L) {
2307 obj_extract_self(otmp);
2309 otmp = (struct obj *) 0;
2311 singleobj = splitobj(otmp, 1L);
2312 obj_extract_self(singleobj);
2315 /* in case you're using a pick-axe to chop the boulder that's being
2316 launched (perhaps a monster triggered it), destroy context so that
2317 next dig attempt never thinks you're resuming previous effort */
2318 if ((otyp == BOULDER || otyp == STATUE)
2319 && singleobj->ox == context.digging.pos.x
2320 && singleobj->oy == context.digging.pos.y)
2321 (void) memset((genericptr_t) &context.digging, 0,
2322 sizeof(struct dig_info));
2324 dist = distmin(x1, y1, x2, y2);
2330 case ROLL | LAUNCH_UNSEEN:
2331 if (otyp == BOULDER) {
2333 You_hear(Hallucination ? "someone bowling."
2334 : "rumbling in the distance.");
2336 You_hear(Hallucination ? "
\92N
\82©
\82ª
\83{
\81[
\83\8a\83\93\83O
\82ð
\82µ
\82Ä
\82¢
\82é
\89¹
\82ð
\95·
\82¢
\82½
\81D"
2337 : "
\89\93\82
\82Ì
\83S
\83\8d\83S
\83\8d\82Æ
\82¢
\82¤
\89¹
\82ð
\95·
\82¢
\82½
\81D");
2340 style &= ~LAUNCH_UNSEEN;
2342 case ROLL | LAUNCH_KNOWN:
2343 /* use otrapped as a flag to ohitmon */
2344 singleobj->otrapped = 1;
2345 style &= ~LAUNCH_KNOWN;
2354 if (!cansee(bhitpos.x, bhitpos.y))
2356 tmp_at(DISP_FLASH, obj_to_glyph(singleobj, rn2_on_display_rng));
2357 tmp_at(bhitpos.x, bhitpos.y);
2359 /* Mark a spot to place object in bones files to prevent
2360 * loss of object. Use the starting spot to ensure that
2361 * a rolling boulder will still launch, which it wouldn't
2362 * do if left midstream. Unfortunately we can't use the
2363 * target resting spot, because there are some things/situations
2364 * that would prevent it from ever getting there (bars), and we
2365 * can't tell that yet.
2367 launch_drop_spot(singleobj, bhitpos.x, bhitpos.y);
2369 /* Set the object in motion */
2370 while (dist-- > 0 && !used_up) {
2372 tmp_at(bhitpos.x, bhitpos.y);
2375 /* dstage@u.washington.edu -- Delay only if hero sees it */
2376 if (cansee(bhitpos.x, bhitpos.y))
2382 t = t_at(bhitpos.x, bhitpos.y);
2384 if ((mtmp = m_at(bhitpos.x, bhitpos.y)) != 0) {
2385 if (otyp == BOULDER && throws_rocks(mtmp->data)) {
2387 if (cansee(bhitpos.x, bhitpos.y))
2389 pline("%s snatches the boulder.", Monnam(mtmp));
2391 pline("%s
\82Í
\8aâ
\82ð
\82Â
\82©
\82Ý
\8eæ
\82Á
\82½
\81D", Monnam(mtmp));
2392 singleobj->otrapped = 0;
2393 (void) mpickobj(mtmp, singleobj);
2395 launch_drop_spot((struct obj *) 0, 0, 0);
2399 if (ohitmon(mtmp, singleobj, (style == ROLL) ? -1 : dist,
2402 launch_drop_spot((struct obj *) 0, 0, 0);
2405 } else if (bhitpos.x == u.ux && bhitpos.y == u.uy) {
2408 if (thitu(9 + singleobj->spe, dmgval(singleobj, &youmonst),
2409 &singleobj, (char *) 0))
2412 if (style == ROLL) {
2413 if (down_gate(bhitpos.x, bhitpos.y) != -1) {
2414 if (ship_object(singleobj, bhitpos.x, bhitpos.y, FALSE)) {
2416 launch_drop_spot((struct obj *) 0, 0, 0);
2420 if (t && otyp == BOULDER) {
2427 cansee(bhitpos.x, bhitpos.y)
2428 ? " The rolling boulder triggers a land mine."
2432 "
\82¿
\82ã
\82Ç
\81[
\82ñ
\81I
\81I%s",
2433 cansee(bhitpos.x, bhitpos.y)
2434 ? "
\93]
\82ª
\82Á
\82Ä
\82«
\82½
\8aâ
\82ª
\92n
\97\8b\82Ì
\8bN
\94\9a\83X
\83C
\83b
\83`
\82ð
\93¥
\82ñ
\82¾
\81D"
2438 del_engr_at(bhitpos.x, bhitpos.y);
2439 place_object(singleobj, bhitpos.x, bhitpos.y);
2440 singleobj->otrapped = 0;
2441 fracture_rock(singleobj);
2442 (void) scatter(bhitpos.x, bhitpos.y, 4,
2443 MAY_DESTROY | MAY_HIT | MAY_FRACTURE
2446 if (cansee(bhitpos.x, bhitpos.y))
2447 newsym(bhitpos.x, bhitpos.y);
2449 launch_drop_spot((struct obj *) 0, 0, 0);
2454 if (cansee(bhitpos.x, bhitpos.y))
2456 pline("Suddenly the rolling boulder disappears!");
2458 pline("
\93]
\82ª
\82Á
\82Ä
\82«
\82½
\8aâ
\82ª
\82Æ
\82Â
\82º
\82ñ
\8fÁ
\82¦
\82½
\81I");
2461 You_hear("a rumbling stop abruptly.");
2463 pline("
\83S
\83\8d\83S
\83\8d\82Æ
\82¢
\82¤
\89¹
\82ª
\93Ë
\91R
\8e~
\82Ü
\82Á
\82½
\81D");
2464 singleobj->otrapped = 0;
2465 if (t->ttyp == TELEP_TRAP)
2466 (void) rloco(singleobj);
2468 int newlev = random_teleport_level();
2471 if (newlev == depth(&u.uz) || In_endgame(&u.uz))
2473 add_to_migration(singleobj);
2474 get_level(&dest, newlev);
2475 singleobj->ox = dest.dnum;
2476 singleobj->oy = dest.dlevel;
2477 singleobj->owornmask = (long) MIGR_RANDOM;
2481 launch_drop_spot((struct obj *) 0, 0, 0);
2487 /* the boulder won't be used up if there is a
2488 monster in the trap; stop rolling anyway */
2489 x2 = bhitpos.x, y2 = bhitpos.y; /* stops here */
2491 if (flooreffects(singleobj, x2, y2, "fall")) {
2493 if (flooreffects(singleobj, x2, y2, "
\97\8e\82¿
\82é")) {
2495 launch_drop_spot((struct obj *) 0, 0, 0);
2497 dist = -1; /* stop rolling immediately */
2500 if (used_up || dist == -1)
2504 if (flooreffects(singleobj, bhitpos.x, bhitpos.y, "fall")) {
2506 if (flooreffects(singleobj, bhitpos.x, bhitpos.y, "
\97\8e\82¿
\82é")) {
2508 launch_drop_spot((struct obj *) 0, 0, 0);
2512 && (otmp2 = sobj_at(BOULDER, bhitpos.x, bhitpos.y)) != 0) {
2514 const char *bmsg = " as one boulder sets another in motion";
2516 const char *bmsg = "
\82Ð
\82Æ
\82Â
\82Ì
\8aâ
\82ª
\91¼
\82Ì
\8aâ
\82ð
\93®
\82©
\82µ
\82½
\82©
\82Ì
\82æ
\82¤
\82È
\81C";
2518 if (!isok(bhitpos.x + dx, bhitpos.y + dy) || !dist
2519 || IS_ROCK(levl[bhitpos.x + dx][bhitpos.y + dy].typ))
2521 bmsg = " as one boulder hits another";
2523 bmsg = "
\82Ð
\82Æ
\82Â
\82Ì
\8aâ
\82ª
\91¼
\82Ì
\8aâ
\82É
\93\96\82½
\82Á
\82½
\82æ
\82¤
\82È";
2526 You_hear("a loud crash%s!",
2528 You_hear("%s
\91å
\82«
\82È
\83S
\83\93\82Æ
\82¢
\82¤
\89¹
\82ð
\95·
\82¢
\82½
\81I",
2529 cansee(bhitpos.x, bhitpos.y) ? bmsg : "");
2530 obj_extract_self(otmp2);
2531 /* pass off the otrapped flag to the next boulder */
2532 otmp2->otrapped = singleobj->otrapped;
2533 singleobj->otrapped = 0;
2534 place_object(singleobj, bhitpos.x, bhitpos.y);
2536 otmp2 = (struct obj *) 0;
2537 wake_nearto(bhitpos.x, bhitpos.y, 10 * 10);
2540 if (otyp == BOULDER && closed_door(bhitpos.x, bhitpos.y)) {
2541 if (cansee(bhitpos.x, bhitpos.y))
2543 pline_The("boulder crashes through a door.");
2545 pline("
\8aâ
\82Í
\94à
\82ð
\94j
\89ó
\82µ
\82½
\81D");
2546 levl[bhitpos.x][bhitpos.y].doormask = D_BROKEN;
2548 unblock_point(bhitpos.x, bhitpos.y);
2551 /* if about to hit iron bars, do so now */
2552 if (dist > 0 && isok(bhitpos.x + dx, bhitpos.y + dy)
2553 && levl[bhitpos.x + dx][bhitpos.y + dy].typ == IRONBARS) {
2554 x2 = bhitpos.x, y2 = bhitpos.y; /* object stops here */
2555 if (hits_bars(&singleobj,
2556 x2, y2, x2+dx, y2+dy,
2560 launch_drop_spot((struct obj *) 0, 0, 0);
2566 tmp_at(DISP_END, 0);
2567 launch_drop_spot((struct obj *) 0, 0, 0);
2569 singleobj->otrapped = 0;
2570 place_object(singleobj, x2, y2);
2583 newsym(trap->tx, trap->ty);
2587 /* like seetrap() but overrides vision */
2594 /* in case it's beneath something, redisplay the something */
2595 newsym(trap->tx, trap->ty);
2599 mkroll_launch(ttmp, x, y, otyp, ocount)
2612 boolean success = FALSE;
2615 if (ttmp->ttyp == ROLLING_BOULDER_TRAP)
2617 distance = rn1(5, 4); /* 4..8 away */
2618 tmp = rn2(8); /* randomly pick a direction to try first */
2619 while (distance >= mindist) {
2624 /* Prevent boulder from being placed on water */
2625 if (ttmp->ttyp == ROLLING_BOULDER_TRAP
2626 && is_pool_or_lava(x + distance * dx, y + distance * dy))
2629 success = isclearpath(&cc, distance, dx, dy);
2630 if (ttmp->ttyp == ROLLING_BOULDER_TRAP) {
2631 boolean success_otherway;
2635 success_otherway = isclearpath(&bcc, distance, -(dx), -(dy));
2636 if (!success_otherway)
2643 if ((++trycount % 8) == 0)
2647 /* create the trap without any ammo, launch pt at trap location */
2651 otmp = mksobj(otyp, TRUE, FALSE);
2652 otmp->quan = ocount;
2653 otmp->owt = weight(otmp);
2654 place_object(otmp, cc.x, cc.y);
2657 ttmp->launch.x = cc.x;
2658 ttmp->launch.y = cc.y;
2659 if (ttmp->ttyp == ROLLING_BOULDER_TRAP) {
2660 ttmp->launch2.x = bcc.x;
2661 ttmp->launch2.y = bcc.y;
2663 ttmp->launch_otyp = otyp;
2664 newsym(ttmp->launch.x, ttmp->launch.y);
2669 isclearpath(cc, distance, dx, dy)
2679 while (distance-- > 0) {
2682 typ = levl[x][y].typ;
2683 if (!isok(x, y) || !ZAP_POS(typ) || closed_door(x, y))
2693 register struct monst *mtmp;
2695 register struct trap *trap = t_at(mtmp->mx, mtmp->my);
2696 boolean trapkilled = FALSE;
2697 struct permonst *mptr = mtmp->data;
2701 mtmp->mtrapped = 0; /* perhaps teleported? */
2702 } else if (mtmp->mtrapped) { /* is currently in the trap */
2703 if (!trap->tseen && cansee(mtmp->mx, mtmp->my) && canseemon(mtmp)
2704 && (is_pit(trap->ttyp) || trap->ttyp == BEAR_TRAP
2705 || trap->ttyp == HOLE
2706 || trap->ttyp == WEB)) {
2707 /* If you come upon an obviously trapped monster, then
2708 * you must be able to see the trap it's in too.
2714 if (sobj_at(BOULDER, mtmp->mx, mtmp->my)
2715 && is_pit(trap->ttyp)) {
2718 if (canseemon(mtmp))
2720 pline("%s pulls free...", Monnam(mtmp));
2722 pline("%s
\82Í
\8f\95\82¯
\8fã
\82°
\82ç
\82ê
\82½
\81D", Monnam(mtmp));
2723 fill_pit(mtmp->mx, mtmp->my);
2728 } else if (metallivorous(mptr)) {
2729 if (trap->ttyp == BEAR_TRAP) {
2730 if (canseemon(mtmp))
2732 pline("%s eats a bear trap!", Monnam(mtmp));
2734 pline("%s
\82Í
\8cF
\82Ìã©
\82ð
\90H
\82×
\82½
\81I", Monnam(mtmp));
2738 } else if (trap->ttyp == SPIKED_PIT) {
2739 if (canseemon(mtmp))
2741 pline("%s munches on some spikes!", Monnam(mtmp));
2743 pline("%s
\82Í
\83g
\83Q
\83g
\83Q
\82ð
\90H
\82×
\82½
\81I", Monnam(mtmp));
2749 register int tt = trap->ttyp;
2750 boolean in_sight, tear_web, see_it,
2751 inescapable = force_mintrap || ((tt == HOLE || tt == PIT)
2752 && Sokoban && !trap->madeby_u);
2753 const char *fallverb;
2755 /* true when called from dotrap, inescapable is not an option */
2756 if (mtmp == u.usteed)
2758 if (!inescapable && ((mtmp->mtrapseen & (1 << (tt - 1))) != 0
2759 || (tt == HOLE && !mindless(mptr)))) {
2760 /* it has been in such a trap - perhaps it escapes */
2764 mtmp->mtrapseen |= (1 << (tt - 1));
2766 /* Monster is aggravated by being trapped by you.
2767 Recognizing who made the trap isn't completely
2768 unreasonable; everybody has their own style. */
2769 if (trap->madeby_u && rnl(5))
2770 setmangry(mtmp, TRUE);
2772 in_sight = canseemon(mtmp);
2773 see_it = cansee(mtmp->mx, mtmp->my);
2774 /* assume hero can tell what's going on for the steed */
2775 if (mtmp == u.usteed)
2779 if (trap->once && trap->tseen && !rn2(15)) {
2780 if (in_sight && see_it)
2782 pline("%s triggers a trap but nothing happens.",
2785 pline("%s
\82ª
\82í
\82È
\82ð
\8bN
\93®
\82³
\82¹
\82½
\82ª
\89½
\82à
\8bN
\82±
\82ç
\82È
\82©
\82Á
\82½
\81D",
2789 newsym(mtmp->mx, mtmp->my);
2793 otmp = t_missile(ARROW, trap);
2796 if (thitm(8, mtmp, otmp, 0, FALSE))
2800 if (trap->once && trap->tseen && !rn2(15)) {
2801 if (in_sight && see_it)
2803 pline("%s triggers a trap but nothing happens.",
2806 pline("%s
\82ª
\82í
\82È
\82ð
\8bN
\93®
\82³
\82¹
\82½
\82ª
\89½
\82à
\8bN
\82±
\82ç
\82È
\82©
\82Á
\82½
\81D",
2810 newsym(mtmp->mx, mtmp->my);
2814 otmp = t_missile(DART, trap);
2816 otmp->opoisoned = 1;
2819 if (thitm(7, mtmp, otmp, 0, FALSE))
2823 if (trap->once && trap->tseen && !rn2(15)) {
2824 if (in_sight && see_it)
2827 "A trap door above %s opens, but nothing falls out!",
2829 "%s
\82Ì
\8fã
\82Ì
\94à
\82ª
\8aJ
\82¢
\82½
\82ª
\81C
\89½
\82à
\97\8e\82¿
\82Ä
\82±
\82È
\82©
\82Á
\82½
\81I",
2832 newsym(mtmp->mx, mtmp->my);
2836 otmp = t_missile(ROCK, trap);
2839 if (thitm(0, mtmp, otmp, d(2, 6), FALSE))
2845 /* stepped on a squeaky board */
2849 pline("A board beneath %s squeaks %s loudly.",
2850 mon_nam(mtmp), trapnote(trap, 0));
2852 pline("%s
\82Ì
\91«
\8c³
\82Ì
\94Â
\82ª
\91å
\82«
\82%s
\82É
\82«
\82µ
\82ñ
\82¾
\81D",
2853 mon_nam(mtmp), trapnote(trap, 0));
2858 pline("%s stops momentarily and appears to cringe.",
2860 pline("%s
\82Í
\88ê
\8fu
\8e~
\82Ü
\82Á
\82Ä
\90g
\82ð
\82·
\82
\82ß
\82½
\82æ
\82¤
\82¾
\81D",
2864 /* same near/far threshold as mzapmsg() */
2865 int range = couldsee(mtmp->mx, mtmp->my) /* 9 or 5 */
2866 ? (BOLT_LIM + 1) : (BOLT_LIM - 3);
2869 You_hear("a %s squeak %s.", trapnote(trap, 1),
2870 (distu(mtmp->mx, mtmp->my) <= range * range)
2871 ? "nearby" : "in the distance");
2873 You_hear("%s
\82
\82Å%s
\82ª
\82«
\82µ
\82Þ
\89¹
\82ð
\95·
\82¢
\82½
\81D",
2874 (distu(mtmp->mx, mtmp->my) <= range * range)
2875 ? "
\8bß" : "
\89\93",
2879 /* wake up nearby monsters */
2880 wake_nearto(mtmp->mx, mtmp->my, 40);
2883 if (mptr->msize > MZ_SMALL && !amorphous(mptr) && !is_flyer(mptr)
2884 && !is_whirly(mptr) && !unsolid(mptr)) {
2888 pline("%s is caught in %s bear trap!", Monnam(mtmp),
2889 a_your[trap->madeby_u]);
2891 pline("%s
\82Í%s
\8cF
\82Ìã©
\82É
\82Â
\82©
\82Ü
\82Á
\82½
\81I", Monnam(mtmp),
2892 set_you[trap->madeby_u]);
2896 if (mptr == &mons[PM_OWLBEAR]
2897 || mptr == &mons[PM_BUGBEAR])
2899 You_hear("the roaring of an angry bear!");
2901 You_hear("
\93{
\82è
\82Ì
\99ô
\9aK
\82ð
\95·
\82¢
\82½
\81I");
2903 } else if (force_mintrap) {
2906 pline("%s evades %s bear trap!", Monnam(mtmp),
2907 a_your[trap->madeby_u]);
2909 pline("%s
\82Í%s
\8cF
\82Ìã©
\82ð
\82½
\82
\82Ý
\82É
\94ð
\82¯
\82½
\81I", Monnam(mtmp),
2910 set_you[trap->madeby_u]);
2916 trapkilled = thitm(0, mtmp, (struct obj *) 0, d(2, 4), FALSE);
2919 if (!resists_sleep(mtmp) && !breathless(mptr) && !mtmp->msleeping
2920 && mtmp->mcanmove) {
2921 if (sleep_monst(mtmp, rnd(25), -1) && in_sight) {
2923 pline("%s suddenly falls asleep!", Monnam(mtmp));
2925 pline("%s
\82Í
\93Ë
\91R
\96°
\82è
\82É
\97\8e\82¿
\82½
\81I", Monnam(mtmp));
2939 pline("%s %s on the %s!", A_gush_of_water_hits,
2940 mon_nam(mtmp), mbodypart(mtmp, HEAD));
2942 pline("
\90\85\82ª
\95¬
\8fo
\82µ
\82Ä
\81C%s
\82Ì%s
\82É
\96½
\92\86\82µ
\82½
\81I",
2943 mon_nam(mtmp), mbodypart(mtmp, HEAD));
2945 target = which_armor(mtmp, W_ARMH);
2946 (void) water_damage(target, helm_simple_name(target), TRUE);
2951 pline("%s %s's left %s!", A_gush_of_water_hits,
2952 mon_nam(mtmp), mbodypart(mtmp, ARM));
2954 pline("
\90\85\82ª
\95¬
\8fo
\82µ
\82Ä
\81C%s
\82Ì
\8d¶%s
\82É
\96½
\92\86\82µ
\82½
\81I",
2955 mon_nam(mtmp), mbodypart(mtmp, ARM));
2957 target = which_armor(mtmp, W_ARMS);
2959 if (water_damage(target, "shield", TRUE) != ER_NOTHING)
2961 if (water_damage(target, "
\8f\82", TRUE) != ER_NOTHING)
2963 target = MON_WEP(mtmp);
2964 if (target && bimanual(target))
2965 (void) water_damage(target, 0, TRUE);
2967 target = which_armor(mtmp, W_ARMG);
2969 (void) water_damage(target, "gauntlets", TRUE);
2971 (void) water_damage(target, "
\8f¬
\8eè", TRUE);
2976 pline("%s %s's right %s!", A_gush_of_water_hits,
2977 mon_nam(mtmp), mbodypart(mtmp, ARM));
2979 pline("
\90\85\82ª
\95¬
\8fo
\82µ
\82Ä
\81C%s
\82Ì
\89E%s
\82É
\96½
\92\86\82µ
\82½
\81I",
2980 mon_nam(mtmp), mbodypart(mtmp, ARM));
2982 (void) water_damage(MON_WEP(mtmp), 0, TRUE);
2987 pline("%s %s!", A_gush_of_water_hits, mon_nam(mtmp));
2989 pline("
\90\85\82ª
\95¬
\8fo
\82µ
\82Ä
\81C%s
\82É
\96½
\92\86\82µ
\82½
\81I", mon_nam(mtmp));
2990 for (otmp = mtmp->minvent; otmp; otmp = otmp->nobj)
2992 && (otmp->owornmask & (W_WEP | W_SWAPWEP)) == 0)
2993 (void) snuff_lit(otmp);
2994 if ((target = which_armor(mtmp, W_ARMC)) != 0)
2995 (void) water_damage(target, cloak_simple_name(target),
2997 else if ((target = which_armor(mtmp, W_ARM)) != 0)
2998 (void) water_damage(target, suit_simple_name(target),
3000 else if ((target = which_armor(mtmp, W_ARMU)) != 0)
3002 (void) water_damage(target, "shirt", TRUE);
3004 (void) water_damage(target, "
\83V
\83\83\83c", TRUE);
3007 if (mptr == &mons[PM_IRON_GOLEM]) {
3010 pline("%s falls to pieces!", Monnam(mtmp));
3012 pline("%s
\82Í
\82
\82¾
\82¯
\82¿
\82Á
\82½
\81I", Monnam(mtmp));
3013 else if (mtmp->mtame)
3015 pline("May %s rust in peace.", mon_nam(mtmp));
3017 pline("%s
\82æ
\81C
\88À
\82ç
\82©
\82É
\8eK
\82Ñ
\82ñ
\8e\96\82ð
\81D", mon_nam(mtmp));
3019 if (DEADMONSTER(mtmp))
3021 } else if (mptr == &mons[PM_GREMLIN] && rn2(3)) {
3022 (void) split_mon(mtmp, (struct monst *) 0);
3030 pline("A %s erupts from the %s under %s!", tower_of_flame,
3031 surface(mtmp->mx, mtmp->my), mon_nam(mtmp));
3033 pline("
\89Î
\92\8c\82ª%s
\82Ì
\91«
\8c³
\82Ì%s
\82©
\82ç
\97§
\82¿
\82Ì
\82Ú
\82Á
\82½
\81I",
3034 mon_nam(mtmp), surface(mtmp->mx,mtmp->my));
3036 else if (see_it) /* evidently `mtmp' is invisible */
3038 You_see("a %s erupt from the %s!", tower_of_flame,
3039 surface(mtmp->mx, mtmp->my));
3041 You("
\89Î
\92\8c\82ª%s
\82©
\82ç
\90¶
\82¶
\82é
\82Ì
\82ð
\8c©
\82½
\81I",
3042 surface(mtmp->mx,mtmp->my));
3045 if (resists_fire(mtmp)) {
3047 shieldeff(mtmp->mx, mtmp->my);
3049 pline("%s is uninjured.", Monnam(mtmp));
3051 pline("
\82ª
\81C%s
\82Í
\8f\9d\82Â
\82©
\82È
\82¢
\81D", Monnam(mtmp));
3054 int num = d(2, 4), alt;
3055 boolean immolate = FALSE;
3057 /* paper burns very fast, assume straw is tightly
3058 * packed and burns a bit slower */
3059 switch (monsndx(mptr)) {
3060 case PM_PAPER_GOLEM:
3064 case PM_STRAW_GOLEM:
3065 alt = mtmp->mhpmax / 2;
3068 alt = mtmp->mhpmax / 4;
3070 case PM_LEATHER_GOLEM:
3071 alt = mtmp->mhpmax / 8;
3080 if (thitm(0, mtmp, (struct obj *) 0, num, immolate))
3083 /* we know mhp is at least `num' below mhpmax,
3084 so no (mhp > mhpmax) check is needed here */
3085 mtmp->mhpmax -= rn2(num + 1);
3087 if (burnarmor(mtmp) || rn2(3)) {
3088 (void) destroy_mitem(mtmp, SCROLL_CLASS, AD_FIRE);
3089 (void) destroy_mitem(mtmp, SPBOOK_CLASS, AD_FIRE);
3090 (void) destroy_mitem(mtmp, POTION_CLASS, AD_FIRE);
3092 if (burn_floor_objects(mtmp->mx, mtmp->my, see_it, FALSE)
3093 && !see_it && distu(mtmp->mx, mtmp->my) <= 3 * 3)
3095 You("smell smoke.");
3097 pline("
\89\8c\82Ì
\93õ
\82¢
\82ª
\82µ
\82½
\81D");
3098 if (is_ice(mtmp->mx, mtmp->my))
3099 melt_ice(mtmp->mx, mtmp->my, (char *) 0);
3100 if (see_it && t_at(mtmp->mx, mtmp->my))
3108 fallverb = "
\97\8e\82¿
\82½";
3109 if (is_flyer(mptr) || is_floater(mptr)
3110 || (mtmp->wormno && count_wsegs(mtmp) > 5)
3111 || is_clinger(mptr)) {
3112 if (force_mintrap && !Sokoban) {
3113 /* openfallingtrap; not inescapable here */
3117 pline("%s doesn't fall into the pit.", Monnam(mtmp));
3119 pline("%s
\82Í
\97\8e\82µ
\8c\8a\82É
\97\8e\82¿
\82È
\82©
\82Á
\82½
\81D", Monnam(mtmp));
3121 break; /* inescapable = FALSE; */
3124 break; /* avoids trap */
3126 fallverb = "is dragged"; /* sokoban pit */
3128 fallverb = "
\82¸
\82è
\97\8e\82¿
\82½"; /* sokoban pit */
3131 if (!passes_walls(mptr))
3135 pline("%s %s into %s pit!", Monnam(mtmp), fallverb,
3136 a_your[trap->madeby_u]);
3138 pline("%s
\82Í%s
\97\8e\82µ
\8c\8a\82É%s
\81I", Monnam(mtmp),
3139 set_you[trap->madeby_u], fallverb);
3141 if (mptr == &mons[PM_PIT_VIPER]
3142 || mptr == &mons[PM_PIT_FIEND])
3144 pline("How pitiful. Isn't that the pits?");
3146 pline("
\82±
\82Ì
\97\8e\82µ
\8c\8a\82Í
\82¢
\82¢
\8ed
\8e\96\82ð
\82µ
\82Ä
\82¢
\82é
\81D");
3150 mselftouch(mtmp, "Falling, ", FALSE);
3152 mselftouch(mtmp, "
\97\8e\89º
\92\86\81C", FALSE);
3153 if (DEADMONSTER(mtmp) || thitm(0, mtmp, (struct obj *) 0,
3154 rnd((tt == PIT) ? 6 : 10), FALSE))
3159 if (!Can_fall_thru(&u.uz)) {
3160 impossible("mintrap: %ss cannot exist on this level.",
3161 defsyms[trap_to_defsym(tt)].explanation);
3162 break; /* don't activate it after all */
3164 if (is_flyer(mptr) || is_floater(mptr) || mptr == &mons[PM_WUMPUS]
3165 || (mtmp->wormno && count_wsegs(mtmp) > 5)
3166 || mptr->msize >= MZ_HUGE) {
3167 if (force_mintrap && !Sokoban) {
3168 /* openfallingtrap; not inescapable here */
3174 "A trap door opens, but %s doesn't fall through.",
3176 "
\97\8e\82µ
\94à
\82ª
\8aJ
\82¢
\82½
\82ª
\81C%s
\82Í
\97\8e\82¿
\82È
\82©
\82Á
\82½
\81D",
3178 else /* (tt == HOLE) */
3180 pline("%s doesn't fall through the hole.",
3182 pline("%s
\82Í
\8c\8a\82É
\97\8e\82¿
\82È
\82©
\82Á
\82½
\81D",
3185 break; /* inescapable = FALSE; */
3187 if (inescapable) { /* sokoban hole */
3190 pline("%s seems to be yanked down!", Monnam(mtmp));
3192 pline("%s
\82Í
\88ø
\82«
\97\8e\82³
\82ê
\82½
\82æ
\82¤
\82¾
\81I", Monnam(mtmp));
3193 /* suppress message in mlevel_tele_trap() */
3202 case MAGIC_PORTAL: {
3205 mlev_res = mlevel_tele_trap(mtmp, trap, inescapable, in_sight);
3211 mtele_trap(mtmp, trap, in_sight);
3214 /* Monster in a web. */
3217 if (mu_maybe_destroy_web(mtmp, in_sight, trap))
3220 switch (monsndx(mptr)) {
3221 case PM_OWLBEAR: /* Eric Backus */
3225 You_hear("the roaring of a confused bear!");
3227 You_hear("
\8d¬
\97\90\82Ì
\99ô
\9aK
\82ð
\95·
\82¢
\82½
\81I");
3233 if (mptr->mlet == S_GIANT
3234 /* exclude baby dragons and relatively short worms */
3235 || (mptr->mlet == S_DRAGON && extra_nasty(mptr))
3236 || (mtmp->wormno && count_wsegs(mtmp) > 5)) {
3238 } else if (in_sight) {
3240 pline("%s is caught in %s spider web.", Monnam(mtmp),
3241 a_your[trap->madeby_u]);
3243 pline("%s
\82Í%s
\82
\82à
\82Ì
\91\83\82É
\82Â
\82©
\82Ü
\82Á
\82½
\81D", Monnam(mtmp),
3244 web_you[trap->madeby_u]);
3248 mtmp->mtrapped = tear_web ? 0 : 1;
3250 /* this list is fairly arbitrary; it deliberately
3251 excludes wumpus & giant/ettin zombies/mummies */
3252 case PM_TITANOTHERE:
3253 case PM_BALUCHITHERIUM:
3254 case PM_PURPLE_WORM:
3263 case PM_LORD_SURTUR:
3270 pline("%s tears through %s spider web!", Monnam(mtmp),
3271 a_your[trap->madeby_u]);
3273 pline("%s
\82Í%s
\82
\82à
\82Ì
\91\83\82ð
\88ø
\82«
\97ô
\82¢
\82½
\81I", Monnam(mtmp),
3274 web_you[trap->madeby_u]);
3277 newsym(mtmp->mx, mtmp->my);
3278 } else if (force_mintrap && !mtmp->mtrapped) {
3281 pline("%s avoids %s spider web!", Monnam(mtmp),
3282 a_your[trap->madeby_u]);
3284 pline("%s
\82Í%s
\82
\82à
\82Ì
\91\83\82ð
\94ð
\82¯
\82½
\81I", Monnam(mtmp),
3285 web_you[trap->madeby_u]);
3294 /* A magic trap. Monsters usually immune. */
3299 /* similar to hero's case, more or less */
3300 if (!resists_magm(mtmp)) { /* lose spell energy */
3301 if (!mtmp->mcan && (attacktype(mptr, AT_MAGC)
3302 || attacktype(mptr, AT_BREA))) {
3303 mtmp->mspec_used += d(2, 2);
3307 pline("%s seems lethargic.", Monnam(mtmp));
3309 pline("%s
\88ê
\8fu
\96³
\8bC
\97Í
\8a´
\82ð
\8a´
\82¶
\82½
\81D", Monnam(mtmp));
3312 } else { /* take some damage */
3313 int dmgval2 = rnd(4);
3315 if ((otmp = MON_WEP(mtmp)) != 0
3316 && otmp->oartifact == ART_MAGICBANE)
3318 for (otmp = mtmp->minvent; otmp; otmp = otmp->nobj)
3320 && defends_when_carried(AD_MAGM, otmp))
3324 if (passes_walls(mptr))
3325 dmgval2 = (dmgval2 + 3) / 4;
3329 mtmp->mhp -= dmgval2;
3330 if (DEADMONSTER(mtmp))
3334 ? "compression from an anti-magic field"
3336 ? "
\94½
\96\82\96@
\8bó
\8aÔ
\82Ì
\88³
\8fk"
3339 if (DEADMONSTER(mtmp))
3342 newsym(trap->tx, trap->ty);
3347 break; /* monsters usually don't set it off */
3348 if (is_flyer(mptr)) {
3349 boolean already_seen = trap->tseen;
3351 if (in_sight && !already_seen) {
3353 pline("A trigger appears in a pile of soil below %s.",
3355 pline("%s
\82Ì
\91«
\8c³
\82Ì
\93y
\82Ì
\8eR
\82É
\8bN
\94\9a\83X
\83C
\83b
\83`
\82ª
\8c»
\82í
\82ê
\82½
\81D",
3362 newsym(mtmp->mx, mtmp->my);
3364 pline_The("air currents set %s off!",
3365 already_seen ? "a land mine" : "it");
3367 pline("
\8bó
\8bC
\82Ì
\97¬
\82ê
\82Å
\83X
\83C
\83b
\83`
\82ª
\93ü
\82Á
\82½
\81I");
3370 } else if (in_sight) {
3371 newsym(mtmp->mx, mtmp->my);
3373 pline("%s%s triggers %s land mine!",
3374 !Deaf ? "KAABLAMM!!! " : "", Monnam(mtmp),
3375 a_your[trap->madeby_u]);
3377 pline("%s%s
\82Í%s
\92n
\97\8b\82Ì
\8bN
\94\9a\83X
\83C
\83b
\83`
\82ð
\93¥
\82ñ
\82¾
\81I",
3378 !Deaf ? "
\82¿
\82ã
\82Ç
\81[
\82ñ
\81I
\81I" : "", Monnam(mtmp),
3379 set_you[trap->madeby_u]);
3382 if (!in_sight && !Deaf)
3384 pline("Kaablamm! You hear an explosion in the distance!");
3386 pline("
\82¿
\82ã
\82Ç
\81[
\82ñ
\81I
\82 \82È
\82½
\82Í
\89\93\95û
\82Ì
\94\9a\94
\89¹
\82ð
\95·
\82¢
\82½
\81I");
3387 blow_up_landmine(trap);
3388 /* explosion might have destroyed a drawbridge; don't
3389 dish out more damage if monster is already dead */
3390 if (DEADMONSTER(mtmp)
3391 || thitm(0, mtmp, (struct obj *) 0, rnd(16), FALSE)) {
3394 /* monsters recursively fall into new pit */
3395 if (mintrap(mtmp) == 2)
3398 /* a boulder may fill the new pit, crushing monster */
3399 fill_pit(trap->tx, trap->ty);
3400 if (DEADMONSTER(mtmp))
3402 if (unconscious()) {
3405 nomovemsg = "The explosion awakens you!";
3407 nomovemsg = "
\94\9a\94
\82Å
\82 \82È
\82½
\82Í
\8bN
\82«
\82½
\81I";
3411 if (resists_magm(mtmp)) {
3412 shieldeff(mtmp->mx, mtmp->my);
3413 } else if (!resist(mtmp, WAND_CLASS, 0, NOTELL)) {
3414 if (newcham(mtmp, (struct permonst *) 0, FALSE, FALSE))
3415 /* we're done with mptr but keep it up to date */
3421 case ROLLING_BOULDER_TRAP:
3422 if (!is_flyer(mptr)) {
3423 int style = ROLL | (in_sight ? 0 : LAUNCH_UNSEEN);
3425 newsym(mtmp->mx, mtmp->my);
3428 pline("Click! %s triggers %s.", Monnam(mtmp),
3429 trap->tseen ? "a rolling boulder trap" : something);
3431 pline("
\83J
\83`
\83b
\81I%s
\82Í%s
\82Ì
\83X
\83C
\83b
\83`
\82ð
\93¥
\82ñ
\82¾
\81I", Monnam(mtmp),
3432 trap->tseen ? "
\97\8e\8aâ
\82Ìã©" : "
\89½
\82©");
3434 if (launch_obj(BOULDER, trap->launch.x, trap->launch.y,
3435 trap->launch2.x, trap->launch2.y, style)) {
3438 if (DEADMONSTER(mtmp))
3442 newsym(mtmp->mx, mtmp->my);
3446 case VIBRATING_SQUARE:
3447 if (see_it && !Blind) {
3448 seetrap(trap); /* before messages */
3451 char buf[BUFSZ], *p, *monnm = mon_nam(mtmp);
3453 if (nolimbs(mtmp->data)
3454 || is_floater(mtmp->data) || is_flyer(mtmp->data)) {
3455 /* just "beneath <mon>" */
3458 Strcpy(buf, s_suffix(monnm));
3459 p = eos(strcat(buf, " "));
3460 Strcpy(p, makeplural(mbodypart(mtmp, FOOT)));
3461 /* avoid "beneath 'rear paws'" or 'rear hooves' */
3462 (void) strsubst(p, "rear ", "");
3464 You_see("a strange vibration beneath %s.", buf);
3465 #else /*
\91«
\82ª
\82È
\82
\82Ä
\82à
\81u
\91«
\8c³
\81v
\82Å
\93\9d\88ê */
3466 You_see("%s
\82Ì
\91«
\8c³
\82ª
\95s
\8ev
\8bc
\82É
\90U
\93®
\82µ
\82Ä
\82¢
\82é
\82Ì
\82ð
\8c©
\82½
\81D",
3470 /* notice something (hearing uses a larger threshold
3473 You_see("the ground vibrate %s.",
3474 (distu(mtmp->mx, mtmp->my) <= 2 * 2)
3475 ? "nearby" : "in the distance");
3477 You_see("%s
\82
\82Å
\92n
\96Ê
\82ª
\90U
\93®
\82µ
\82Ä
\82¢
\82é
\82Ì
\82ð
\8c©
\82½
\81D",
3478 (distu(mtmp->mx, mtmp->my) <= 2 * 2)
3479 ? "
\8bß" : "
\89\93");
3485 impossible("Some monster encountered a strange trap of type %d.",
3491 return mtmp->mtrapped;
3494 /* Combine cockatrice checks into single functions to avoid repeating code. */
3499 if (Stone_resistance)
3501 if (poly_when_stoned(youmonst.data) && polymon(PM_STONE_GOLEM))
3504 You("turn to stone...");
3506 You("
\90Î
\82É
\82È
\82Á
\82½
\81D
\81D
\81D");
3507 killer.format = KILLED_BY;
3508 if (str != killer.name)
3509 Strcpy(killer.name, str ? str : "");
3514 minstapetrify(mon, byplayer)
3518 if (resists_ston(mon))
3520 if (poly_when_stoned(mon->data)) {
3524 if (!vamp_stone(mon))
3527 /* give a "<mon> is slowing down" message and also remove
3528 intrinsic speed (comparable to similar effect on the hero) */
3529 mon_adjust_speed(mon, -3, (struct obj *) 0);
3531 if (cansee(mon->mx, mon->my))
3533 pline("%s turns to stone.", Monnam(mon));
3535 pline("%s
\82Í
\90Î
\82É
\82È
\82Á
\82½
\81D", Monnam(mon));
3538 xkilled(mon, XKILL_NOMSG);
3549 if (uwep && uwep->otyp == CORPSE && touch_petrifies(&mons[uwep->corpsenm])
3550 && !Stone_resistance) {
3552 pline("%s touch the %s corpse.", arg, mons[uwep->corpsenm].mname);
3554 pline("%s%s
\82Ì
\8e\80\91Ì
\82É
\90G
\82Á
\82½
\81D", arg, mons[uwep->corpsenm].mname);
3556 Sprintf(kbuf, "%s corpse", an(mons[uwep->corpsenm].mname));
3558 Sprintf(kbuf, "%s
\82Ì
\8e\80\91Ì
\82Å", mons[uwep->corpsenm].mname);
3560 /* life-saved; unwield the corpse if we can't handle it */
3561 if (!uarmg && !Stone_resistance)
3564 /* Or your secondary weapon, if wielded [hypothetical; we don't
3565 allow two-weapon combat when either weapon is a corpse] */
3566 if (u.twoweap && uswapwep && uswapwep->otyp == CORPSE
3567 && touch_petrifies(&mons[uswapwep->corpsenm]) && !Stone_resistance) {
3569 pline("%s touch the %s corpse.", arg, mons[uswapwep->corpsenm].mname);
3571 pline("%s%s
\82Ì
\8e\80\91Ì
\82É
\90G
\82Á
\82½
\81D", arg, mons[uswapwep->corpsenm].mname);
3573 Sprintf(kbuf, "%s corpse", an(mons[uswapwep->corpsenm].mname));
3575 Sprintf(kbuf, "%s
\82Ì
\8e\80\91Ì
\82Å", mons[uswapwep->corpsenm].mname);
3577 /* life-saved; unwield the corpse */
3578 if (!uarmg && !Stone_resistance)
3584 mselftouch(mon, arg, byplayer)
3589 struct obj *mwep = MON_WEP(mon);
3591 if (mwep && mwep->otyp == CORPSE && touch_petrifies(&mons[mwep->corpsenm])
3592 && !resists_ston(mon)) {
3593 if (cansee(mon->mx, mon->my)) {
3595 pline("%s%s touches %s.", arg ? arg : "",
3596 arg ? mon_nam(mon) : Monnam(mon),
3597 corpse_xname(mwep, (const char *) 0, CXN_PFX_THE));
3599 pline("%s%s
\82Í%s
\82Ì
\8e\80\91Ì
\82É
\90G
\82Á
\82½
\81D", arg ? arg : "",
3600 arg ? mon_nam(mon) : Monnam(mon),
3601 corpse_xname(mwep, (const char *) 0, CXN_PFX_THE));
3604 minstapetrify(mon, byplayer);
3605 /* if life-saved, might not be able to continue wielding */
3606 if (!DEADMONSTER(mon) && !which_armor(mon, W_ARMG) && !resists_ston(mon))
3611 /* start levitating */
3615 context.botl = TRUE;
3617 if (u.utraptype == TT_PIT) {
3620 You("float up, out of the pit!");
3622 You("
\95\82\82«
\8fã
\82ª
\82Á
\82Ä
\81C
\97\8e\82µ
\8c\8a\82©
\82ç
\8fo
\82½
\81I");
3623 vision_full_recalc = 1; /* vision limits change */
3624 fill_pit(u.ux, u.uy);
3625 } else if (u.utraptype == TT_LAVA /* molten lava */
3626 || u.utraptype == TT_INFLOOR) { /* solidified lava */
3628 Your("body pulls upward, but your %s are still stuck.",
3630 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",
3631 makeplural(body_part(LEG)));
3632 } else if (u.utraptype == TT_BURIEDBALL) { /* tethered */
3635 cc.x = u.ux, cc.y = u.uy;
3636 /* caveat: this finds the first buried iron ball within
3637 one step of the specified location, not necessarily the
3638 buried [former] uball at the original anchor point */
3639 (void) buried_ball(&cc);
3640 /* being chained to the floor blocks levitation from floating
3641 above that floor but not from enhancing carrying capacity */
3642 You("feel lighter, but your %s is still chained to the %s.",
3644 IS_ROOM(levl[cc.x][cc.y].typ) ? "floor" : "ground");
3645 } else if (u.utraptype == WEB) {
3646 You("float up slightly, but you are still stuck in the web.");
3647 } else { /* bear trap */
3649 You("float up slightly, but your %s is still stuck.",
3651 You("
\8f
\82µ
\95\82\82«
\8fã
\82ª
\82Á
\82½
\82ª%s
\82Í
\82Ü
\82¾
\82Í
\82Ü
\82Á
\82Ä
\82¢
\82é
\81D",
3654 /* when still trapped, float_vs_flight() below will block levitation */
3656 } else if (Is_waterlevel(&u.uz)) {
3658 pline("It feels as though you've lost some weight.");
3660 You("
\82Ü
\82é
\82Å
\91Ì
\8fd
\82ª
\8c¸
\82Á
\82½
\82æ
\82¤
\82É
\8a´
\82¶
\82½
\81D");
3662 } else if (u.uinwater) {
3664 } else if (u.uswallow) {
3666 You(is_animal(u.ustuck->data) ? "float away from the %s."
3667 : "spiral up into %s.",
3668 is_animal(u.ustuck->data) ? surface(u.ux, u.uy)
3669 : mon_nam(u.ustuck));
3671 You(is_animal(u.ustuck->data) ? "%s
\82Ì
\92\86\82Å
\95\82\82¢
\82½
\81D"
3672 : "%s
\82Ì
\92\86\82Å
\82®
\82é
\82®
\82é
\89ñ
\93]
\82µ
\82½
\81D",
3673 is_animal(u.ustuck->data) ? surface(u.ux, u.uy)
3674 : mon_nam(u.ustuck));
3676 } else if (Hallucination) {
3678 pline("Up, up, and awaaaay! You're walking on air!");
3680 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");
3681 } else if (Is_airlevel(&u.uz)) {
3683 You("gain control over your movements.");
3685 You("
\82¤
\82Ü
\82
\93®
\82¯
\82é
\82æ
\82¤
\82É
\82È
\82Á
\82½
\81D");
3688 You("start to float in the air!");
3690 You("
\8bó
\92\86\82É
\95\82\82«
\82Í
\82¶
\82ß
\82½
\81I");
3692 if (u.usteed && !is_floater(u.usteed->data) && !is_flyer(u.usteed->data)) {
3695 pline("%s magically floats up!", Monnam(u.usteed));
3697 pline("%s
\82Í
\96\82\96@
\82Ì
\97Í
\82Å
\95\82\82¢
\82½
\81I", Monnam(u.usteed));
3700 You("cannot stay on %s.", mon_nam(u.usteed));
3702 You("%s
\82Ì
\8fã
\82É
\8fæ
\82Á
\82Ä
\82¢
\82ç
\82ê
\82È
\82¢
\81D", mon_nam(u.usteed));
3703 dismount_steed(DISMOUNT_GENERIC);
3708 You("are no longer able to control your flight.");
3710 You("
\8bó
\92\86\82Å
\82¤
\82Ü
\82
\93®
\82¯
\82È
\82
\82È
\82Á
\82½
\81D");
3711 float_vs_flight(); /* set BFlying, also BLevitation if still trapped */
3712 /* levitation gives maximum carrying capacity, so encumbrance
3713 state might be reduced */
3714 (void) encumber_msg();
3725 if ((t = t_at(x, y)) && is_pit(t->ttyp)
3726 && (otmp = sobj_at(BOULDER, x, y))) {
3727 obj_extract_self(otmp);
3729 (void) flooreffects(otmp, x, y, "settle");
3731 (void) flooreffects(otmp, x, y, "
\82Í
\82Ü
\82é");
3735 /* stop levitating */
3737 float_down(hmask, emask)
3738 long hmask, emask; /* might cancel timeout */
3740 register struct trap *trap = (struct trap *) 0;
3741 d_level current_dungeon_level;
3742 boolean no_msg = FALSE;
3744 HLevitation &= ~hmask;
3745 ELevitation &= ~emask;
3747 return 0; /* maybe another ring/potion/boots */
3749 /* if blocked by terrain, we haven't actually been levitating so
3750 we don't give any end-of-levitation feedback or side-effects,
3751 but if blocking is solely due to being trapped in/on floor,
3752 do give some feedback but skip other float_down() effects */
3753 boolean trapped = (BLevitation == I_SPECIAL);
3756 if (trapped && u.utrap) /* u.utrap => paranoia */
3757 You("are no longer trying to float up from the %s.",
3758 (u.utraptype == TT_BEARTRAP) ? "trap's jaws"
3759 : (u.utraptype == TT_WEB) ? "web"
3760 : (u.utraptype == TT_BURIEDBALL) ? "chain"
3761 : (u.utraptype == TT_LAVA) ? "lava"
3762 : "ground"); /* TT_INFLOOR */
3763 (void) encumber_msg(); /* carrying capacity might have changed */
3766 context.botl = TRUE;
3767 nomul(0); /* stop running or resting */
3769 /* controlled flight no longer overridden by levitation */
3770 float_vs_flight(); /* clears BFlying & I_SPECIAL
3771 * unless hero is stuck in floor */
3774 You("have stopped levitating and are now flying.");
3776 You("
\8bó
\92\86\95\82\97V
\82ð
\8e~
\82ß
\82Ä
\8bó
\82ð
\94ò
\82Ñ
\82Í
\82¶
\82ß
\82½
\81D");
3777 (void) encumber_msg(); /* carrying capacity might have changed */
3783 You("float down, but you are still %s.",
3784 is_animal(u.ustuck->data) ? "swallowed" : "engulfed");
3786 You("
\92\85\92n
\82µ
\82½
\82ª
\81C
\82Ü
\82¾
\88ù
\82Ý
\8d\9e\82Ü
\82ê
\82½
\82Ü
\82Ü
\82¾
\81D");
3788 (void) encumber_msg();
3792 if (Punished && !carried(uball)
3793 && (is_pool(uball->ox, uball->oy)
3794 || ((trap = t_at(uball->ox, uball->oy))
3795 && (is_pit(trap->ttyp) || is_hole(trap->ttyp))))) {
3800 movobj(uchain, uball->ox, uball->oy);
3801 newsym(u.ux0, u.uy0);
3802 vision_full_recalc = 1; /* in case the hero moved. */
3804 /* check for falling into pool - added by GAN 10/20/86 */
3806 if (!u.uswallow && u.ustuck) {
3807 if (sticks(youmonst.data))
3809 You("aren't able to maintain your hold on %s.",
3812 You("%s
\82ð
\82Â
\82©
\82Ü
\82¦
\91±
\82¯
\82Ä
\82¢
\82ç
\82ê
\82È
\82
\82È
\82Á
\82½
\81D",
3817 pline("Startled, %s can no longer hold you!",
3820 pline("%s
\82Í
\8bÁ
\82¢
\82Ä
\82 \82È
\82½
\82ð
\95ú
\82µ
\82Ä
\82µ
\82Ü
\82Á
\82½
\81I",
3826 * drown() and lava_effects() print various messages almost
3827 * every time they're called which conflict with the "fall
3828 * into" message below. Thus, we want to avoid printing
3829 * confusing, duplicate or out-of-order messages.
3830 * Use knowledge of the two routines as a hack -- this
3831 * should really be handled differently -dlc
3833 if (is_pool(u.ux, u.uy) && !Wwalking && !Swimming && !u.uinwater)
3836 if (is_lava(u.ux, u.uy)) {
3837 (void) lava_effects();
3842 trap = t_at(u.ux, u.uy);
3843 if (Is_airlevel(&u.uz)) {
3845 You("begin to tumble in place.");
3847 You("
\82»
\82Ì
\8fê
\82Å
\82Ð
\82Á
\82
\82è
\95Ô
\82è
\82Í
\82¶
\82ß
\82½
\81D");
3848 } else if (Is_waterlevel(&u.uz) && !no_msg) {
3850 You_feel("heavier.");
3852 You("
\8fd
\82
\82È
\82Á
\82½
\82æ
\82¤
\82È
\8bC
\82ª
\82µ
\82½
\81D");
3853 /* u.uinwater msgs already in spoteffects()/drown() */
3854 } else if (!u.uinwater && !no_msg) {
3855 if (!(emask & W_SADDLE)) {
3856 if (Sokoban && trap) {
3857 /* Justification elsewhere for Sokoban traps is based
3858 * on air currents. This is consistent with that.
3859 * The unexpected additional force of the air currents
3860 * once levitation ceases knocks you off your feet.
3864 pline("Bummer! You've crashed.");
3866 pline("
\82â
\82ß
\82Ä
\82¥
\81I
\82 \82È
\82½
\82Í
\92@
\82«
\82Â
\82¯
\82ç
\82ê
\82½
\81D");
3871 You("
\82Â
\82Ü
\82Ã
\82¢
\82½
\81D");
3873 losehp(rnd(2), "dangerous winds", KILLED_BY);
3875 losehp(rnd(2), "
\8aë
\8c¯
\82È
\95\97\82Å", KILLED_BY);
3877 dismount_steed(DISMOUNT_FELL);
3879 selftouch("As you fall, you");
3881 selftouch("
\97\8e\82¿
\82È
\82ª
\82ç
\81C
\82 \82È
\82½
\82Í");
3882 } else if (u.usteed && (is_floater(u.usteed->data)
3883 || is_flyer(u.usteed->data))) {
3885 You("settle more firmly in the saddle.");
3887 You("
\82æ
\82è
\82µ
\82Á
\82©
\82è
\82Æ
\88Æ
\82É
\94[
\82Ü
\82Á
\82½
\81D");
3888 } else if (Hallucination) {
3890 pline("Bummer! You've %s.",
3893 : "hit the ground");
3895 pline("
\82â
\82ß
\82Ä
\82¥
\81I
\82 \82È
\82½
\82Í%s
\82É
\92@
\82«
\82Â
\82¯
\82ç
\82ê
\82½
\81D",
3902 You("float gently to the %s.", surface(u.ux, u.uy));
3904 You("
\90Ã
\82©
\82É%s
\82Ü
\82Å
\92H
\82è
\82Â
\82¢
\82½
\81D", surface(u.ux, u.uy));
3910 /* levitation gives maximum carrying capacity, so having it end
3911 potentially triggers greater encumbrance; do this after
3912 'come down' messages, before trap activation or autopickup */
3913 (void) encumber_msg();
3915 /* can't rely on u.uz0 for detecting trap door-induced level change;
3916 it gets changed to reflect the new level before we can check it */
3917 assign_level(¤t_dungeon_level, &u.uz);
3919 switch (trap->ttyp) {
3924 if (!Can_fall_thru(&u.uz) || u.ustuck)
3928 if (!u.utrap) /* not already in the trap */
3932 if (!Is_airlevel(&u.uz) && !Is_waterlevel(&u.uz) && !u.uswallow
3933 /* falling through trap door calls goto_level,
3934 and goto_level does its own pickup() call */
3935 && on_level(&u.uz, ¤t_dungeon_level))
3940 /* shared code for climbing out of a pit */
3944 if (!u.utrap || u.utraptype != TT_PIT)
3948 /* marked as trapped so they can pick things up */
3950 You("ascend from the pit.");
3952 You("
\97\8e\82µ
\8c\8a\82ð
\8fã
\82Á
\82Ä
\82¢
\82Á
\82½
\81D");
3954 fill_pit(u.ux, u.uy);
3955 vision_full_recalc = 1; /* vision limits change */
3956 } else if (!rn2(2) && sobj_at(BOULDER, u.ux, u.uy)) {
3958 Your("%s gets stuck in a crevice.", body_part(LEG));
3960 Your("%s
\82Í
\8a\84\82ê
\96Ú
\82É
\82Í
\82Ü
\82Á
\82½
\81D", body_part(LEG));
3961 display_nhwindow(WIN_MESSAGE, FALSE);
3962 clear_nhwindow(WIN_MESSAGE);
3964 You("free your %s.", body_part(LEG));
3966 Your("%s
\82Í
\8e©
\97R
\82É
\82È
\82Á
\82½
\81D", body_part(LEG));
3967 } else if ((Flying || is_clinger(youmonst.data)) && !Sokoban) {
3968 /* eg fell in pit, then poly'd to a flying monster;
3969 or used '>' to deliberately enter it */
3971 You("%s from the pit.", Flying ? "fly" : "climb");
3973 You("
\97\8e\82µ
\8c\8a\82©
\82ç%s
\82¢
\82Á
\82½
\81D", Flying ? "
\8fã
\82Á
\82Ä" : "
\93o
\82Á
\82Ä");
3975 fill_pit(u.ux, u.uy);
3976 vision_full_recalc = 1; /* vision limits change */
3977 } else if (!(--u.utrap)) {
3980 You("%s to the edge of the pit.",
3981 (Sokoban && Levitation)
3982 ? "struggle against the air currents and float"
3983 : u.usteed ? "ride" : "crawl");
3985 You("%s
\97\8e\82µ
\8c\8a\82Ì
\92[
\82É
\82½
\82Ç
\82è
\92\85\82¢
\82½
\81D",
3986 (Sokoban && Levitation)
3987 ? "
\8bó
\8bC
\82Ì
\97¬
\82ê
\82Ì
\92\86\82Å
\82à
\82ª
\82«
\82È
\82ª
\82ç" : "");
3989 fill_pit(u.ux, u.uy);
3990 vision_full_recalc = 1; /* vision limits change */
3991 } else if (u.dz || flags.verbose) {
3994 Norep("%s is still in a pit.", upstart(y_monnam(u.usteed)));
3996 Norep("%s
\82Í
\82Ü
\82¾
\97\8e\82µ
\8c\8a\82Ì
\92\86\82É
\82¢
\82é
\81D", y_monnam(u.usteed));
3999 Norep((Hallucination && !rn2(5))
4000 ? "You've fallen, and you can't get up."
4001 : "You are still in a pit.");
4003 Norep((Hallucination && !rn2(5))
4004 ? "
\82 \82È
\82½
\82Í
\97\8e\82¿
\81C
\8fã
\82ª
\82ê
\82È
\82¢
\81D"
4005 : "
\82 \82È
\82½
\82Í
\82Ü
\82¾
\97\8e\82µ
\8c\8a\82Ì
\92\86\82É
\82¢
\82é
\81D");
4012 struct obj *box; /* null for floor trap */
4014 boolean see_it = !Blind;
4017 /* Bug: for box case, the equivalent of burn_floor_objects() ought
4018 * to be done upon its contents.
4021 if ((box && !carried(box)) ? is_pool(box->ox, box->oy) : Underwater) {
4023 pline("A cascade of steamy bubbles erupts from %s!",
4025 pline("
\8fö
\8bC
\82Ì
\96A
\82ª%s
\82©
\82ç
\82µ
\82ã
\81[
\82Á
\82Æ
\94
\90¶
\82µ
\82½
\81I",
4026 the(box ? xname(box) : surface(u.ux, u.uy)));
4027 if (Fire_resistance)
4029 You("are uninjured.");
4031 You("
\8f\9d\82Â
\82©
\82È
\82¢
\81D");
4034 losehp(rnd(3), "boiling water", KILLED_BY);
4036 losehp(rnd(3), "
\95¦
\93«
\82µ
\82½
\90\85\82Å", KILLED_BY);
4040 pline("A %s %s from %s!", tower_of_flame, box ? "bursts" : "erupts",
4041 the(box ? xname(box) : surface(u.ux, u.uy)));
4043 pline("
\89Î
\92\8c\82ª%s
\82©
\82ç%s
\81I", box ? xname(box) : surface(u.ux,u.uy),
4044 box ? "
\90\81\82«
\8fo
\82µ
\82½" : "
\97§
\82¿
\82Ì
\82Ú
\82Á
\82½");
4046 if (Fire_resistance) {
4047 shieldeff(u.ux, u.uy);
4049 } else if (Upolyd) {
4051 switch (u.umonnum) {
4052 case PM_PAPER_GOLEM:
4055 case PM_STRAW_GOLEM:
4061 case PM_LEATHER_GOLEM:
4070 if (u.mhmax > mons[u.umonnum].mlevel)
4071 u.mhmax -= rn2(min(u.mhmax, num + 1)), context.botl = 1;
4074 if (u.uhpmax > u.ulevel)
4075 u.uhpmax -= rn2(min(u.uhpmax, num + 1)), context.botl = 1;
4079 You("are uninjured.");
4081 You("
\8f\9d\82Â
\82©
\82È
\82¢
\81D");
4084 losehp(num, tower_of_flame, KILLED_BY_AN); /* fire damage */
4086 losehp(num, "
\89Î
\92\8c\82Å", KILLED_BY_AN); /* fire damage */
4090 if (burnarmor(&youmonst) || rn2(3)) {
4091 destroy_item(SCROLL_CLASS, AD_FIRE);
4092 destroy_item(SPBOOK_CLASS, AD_FIRE);
4093 destroy_item(POTION_CLASS, AD_FIRE);
4095 if (!box && burn_floor_objects(u.ux, u.uy, see_it, TRUE) && !see_it)
4097 You("smell paper burning.");
4099 You("
\8e\86\82Ì
\82±
\82°
\82é
\93õ
\82¢
\82ª
\82µ
\82½
\81D");
4100 if (is_ice(u.ux, u.uy))
4101 melt_ice(u.ux, u.uy, (char *) 0);
4107 register int fate = rnd(20);
4109 /* What happened to the poor sucker? */
4112 /* Most of the time, it creates some monsters. */
4115 /* blindness effects */
4116 if (!resists_blnd(&youmonst)) {
4118 You("are momentarily blinded by a flash of light!");
4120 You("
\82Ü
\82Î
\82ä
\82¢
\8cõ
\82Å
\88ê
\8fu
\96Ú
\82ª
\82
\82ç
\82ñ
\82¾
\81I");
4121 make_blinded((long) rn1(5, 10), FALSE);
4123 Your1(vision_clears);
4124 } else if (!Blind) {
4126 You_see("a flash of light!");
4128 You("
\82Ü
\82Î
\82ä
\82¢
\8cõ
\82ð
\97\81\82Ñ
\82½
\81I");
4131 /* deafness effects */
4134 You_hear("a deafening roar!");
4136 You_hear("
\8e¨
\82ð
\82Â
\82ñ
\82´
\82
\82æ
\82¤
\82È
\99ô
\9aK
\82ð
\95·
\82¢
\82½
\81I");
4137 incr_itimeout(&HDeaf, rn1(20, 30));
4138 context.botl = TRUE;
4140 /* magic vibrations still hit you */
4141 You_feel("rankled.");
4142 incr_itimeout(&HDeaf, rn1(5, 15));
4143 context.botl = TRUE;
4146 (void) makemon((struct permonst *) 0, u.ux, u.uy, NO_MM_FLAGS);
4147 /* roar: wake monsters in vicinity, after placing trap-created ones */
4148 wake_nearto(u.ux, u.uy, 7 * 7);
4149 /* [flash: should probably also hit nearby gremlins with light] */
4154 /* sometimes nothing happens */
4156 case 12: /* a flash of fire */
4157 dofiretrap((struct obj *) 0);
4163 pline("A shiver runs up and down your %s!", body_part(SPINE));
4165 pline("
\90k
\82¦
\82ª
\82 \82È
\82½
\82Ì%s
\82ð
\91\96\82Á
\82½
\81I", body_part(SPINE));
4169 You_hear(Hallucination ? "the moon howling at you."
4170 : "distant howling.");
4172 You_hear(Hallucination ? "
\8c\8e\82ª
\96i
\82¦
\82Ä
\82¢
\82é
\82Ì
\82ð
\95·
\82¢
\82½
\81D"
4173 : "
\89\93\95û
\82Ì
\89\93\96i
\82ð
\95·
\82¢
\82½
\81D");
4177 if (on_level(&u.uz, &qstart_level))
4180 "%slike the prodigal son.",
4181 (flags.female || (Upolyd && is_neuter(youmonst.data)))
4184 #else /*JP
\90¹
\8f\91\82Ì
\83\8b\83J
\93`
\82æ
\82è */
4185 You("%s
\95ú
\93 \91§
\8eq
\82Ì
\82æ
\82¤
\82É
\82È
\82Á
\82½
\82æ
\82¤
\82È
\8bC
\82ª
\82µ
\82½
\81D",
4186 (flags.female || (Upolyd && is_neuter(youmonst.data)))
4192 You("suddenly yearn for %s.",
4195 : (In_quest(&u.uz) || at_dgn_entrance("The Quest"))
4196 ? "your nearby homeland"
4197 : "your distant homeland");
4199 You("
\93Ë
\91R%s
\82ª
\97ö
\82µ
\82
\82È
\82Á
\82½
\81D",
4200 Hallucination ? "
\90Â
\90X"
4201 : (In_quest(&u.uz) || at_dgn_entrance("
\83N
\83G
\83X
\83g"))
4202 ? "
\82·
\82®
\82»
\82±
\82É
\82 \82é
\8cÌ
\8b½"
4203 : "
\82Í
\82é
\82©
\82©
\82È
\82½
\82Ì
\8cÌ
\8b½");
4208 Your("pack shakes violently!");
4210 Your("
\91Ü
\82Í
\8c\83\82µ
\82
\97h
\82ê
\82½
\81I");
4214 You(Hallucination ? "smell hamburgers." : "smell charred flesh.");
4216 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");
4222 You("
\94æ
\82ê
\82ð
\8a´
\82¶
\82½
\81D");
4225 /* very occasionally something nice happens. */
4226 case 19: { /* tame nearby monsters */
4230 (void) adjattrib(A_CHA, 1, FALSE);
4231 for (i = -1; i <= 1; i++)
4232 for (j = -1; j <= 1; j++) {
4233 if (!isok(u.ux + i, u.uy + j))
4235 mtmp = m_at(u.ux + i, u.uy + j);
4237 (void) tamedog(mtmp, (struct obj *) 0);
4241 case 20: { /* uncurse stuff */
4243 long save_conf = HConfusion;
4245 pseudo = zeroobj; /* neither cursed nor blessed,
4246 and zero out oextra */
4247 pseudo.otyp = SCR_REMOVE_CURSE;
4249 (void) seffects(&pseudo);
4250 HConfusion = save_conf;
4258 /* Set an item on fire.
4259 * "force" means not to roll a luck-based protection check for the
4261 * "x" and "y" are the coordinates to dump the contents of a
4262 * container, if it burns up.
4264 * Return whether the object was destroyed.
4267 fire_damage(obj, force, x, y)
4273 struct obj *otmp, *ncobj;
4274 int in_sight = !Blind && couldsee(x, y); /* Don't care if it's lit */
4277 /* object might light in a controlled manner */
4281 if (Is_container(obj)) {
4282 switch (obj->otyp) {
4284 return FALSE; /* Immune */
4295 if ((!force && (Luck + 5) > rn2(chance))
4296 || (is_flammable(obj) && obj->oerodeproof))
4298 /* Container is burnt up - dump contents out */
4301 pline("%s catches fire and burns.", Yname2(obj));
4303 pline("%s
\82Í
\89Î
\82ª
\82Â
\82¢
\82Ä
\94R
\82¦
\82½
\81D", Yname2(obj));
4304 if (Has_contents(obj)) {
4307 pline("Its contents fall out.");
4309 pline("
\92\86\90g
\82ª
\8fo
\82Ä
\82«
\82½
\81D");
4310 for (otmp = obj->cobj; otmp; otmp = ncobj) {
4312 obj_extract_self(otmp);
4313 if (!flooreffects(otmp, x, y, ""))
4314 place_object(otmp, x, y);
4320 } else if (!force && (Luck + 5) > rn2(20)) {
4321 /* chance per item of sustaining damage:
4322 * max luck (Luck==13): 10%
4323 * avg luck (Luck==0): 75%
4324 * awful luck (Luck<-4): 100%
4327 } else if (obj->oclass == SCROLL_CLASS || obj->oclass == SPBOOK_CLASS) {
4328 if (obj->otyp == SCR_FIRE || obj->otyp == SPE_FIREBALL)
4330 if (obj->otyp == SPE_BOOK_OF_THE_DEAD) {
4333 pline("Smoke rises from %s.", the(xname(obj)));
4335 pline("%s
\82©
\82ç
\89\8c\82ª
\82 \82ª
\82Á
\82½
\81D", the(xname(obj)));
4338 dindx = (obj->oclass == SCROLL_CLASS) ? 3 : 4;
4341 pline("%s %s.", Yname2(obj),
4342 destroy_strings[dindx][(obj->quan > 1L)]);
4344 pline("%s
\82Í%s
\81D", Yname2(obj),
4345 destroy_strings[dindx][(obj->quan > 1L)]);
4350 } else if (obj->oclass == POTION_CLASS) {
4351 dindx = (obj->otyp != POT_OIL) ? 1 : 2;
4354 pline("%s %s.", Yname2(obj),
4355 destroy_strings[dindx][(obj->quan > 1L)]);
4357 pline("%s
\82Í%s
\81D", Yname2(obj),
4358 destroy_strings[dindx][(obj->quan > 1L)]);
4363 } else if (erode_obj(obj, (char *) 0, ERODE_BURN, EF_DESTROY)
4371 * Apply fire_damage() to an entire chain.
4373 * Return number of objects destroyed. --ALI
4376 fire_damage_chain(chain, force, here, x, y)
4378 boolean force, here;
4381 struct obj *obj, *nobj;
4384 for (obj = chain; obj; obj = nobj) {
4385 nobj = here ? obj->nexthere : obj->nobj;
4386 if (fire_damage(obj, force, x, y))
4390 if (num && (Blind && !couldsee(x, y)))
4392 You("smell smoke.");
4394 You("
\89\8c\82Ì
\82É
\82¨
\82¢
\82ª
\82µ
\82½
\81D");
4398 /* obj has been thrown or dropped into lava; damage is worse than mere fire */
4400 lava_damage(obj, x, y)
4404 int otyp = obj->otyp, ocls = obj->oclass;
4406 /* the Amulet, invocation items, and Rider corpses are never destroyed
4407 (let Book of the Dead fall through to fire_damage() to get feedback) */
4408 if (obj_resists(obj, 0, 0) && otyp != SPE_BOOK_OF_THE_DEAD)
4410 /* destroy liquid (venom), wax, veggy, flesh, paper (except for scrolls
4411 and books--let fire damage deal with them), cloth, leather, wood, bone
4412 unless it's inherently or explicitly fireproof or contains something;
4413 note: potions are glass so fall through to fire_damage() and boil */
4414 if (objects[otyp].oc_material < DRAGON_HIDE
4415 && ocls != SCROLL_CLASS && ocls != SPBOOK_CLASS
4416 && objects[otyp].oc_oprop != FIRE_RES
4417 && otyp != WAN_FIRE && otyp != FIRE_HORN
4418 /* assumes oerodeproof isn't overloaded for some other purpose on
4419 non-eroding items */
4420 && !obj->oerodeproof
4421 /* fire_damage() knows how to deal with containers and contents */
4422 && !Has_contents(obj)) {
4424 /* this feedback is pretty clunky and can become very verbose
4425 when former contents of a burned container get here via
4427 if (obj == thrownobj || obj == kickedobj)
4429 pline("%s %s up!", is_plural(obj) ? "They" : "It",
4430 otense(obj, "burn"));
4432 pline("
\82»
\82ê
\82Í
\94R
\82¦
\82Â
\82«
\82½
\81I");
4436 You_see("%s hit lava and burn up!", doname(obj));
4438 You_see("%s
\82Í
\97n
\8aâ
\82É
\93\96\82½
\82Á
\82Ä
\94R
\82¦
\82Â
\82«
\82½
\81I", doname(obj));
4440 if (carried(obj)) { /* shouldn't happen */
4441 remove_worn_item(obj, TRUE);
4447 return fire_damage(obj, TRUE, x, y);
4454 /* Scrolls but not spellbooks can be erased by acid. */
4455 struct monst *victim;
4461 victim = carried(obj) ? &youmonst : mcarried(obj) ? obj->ocarry : NULL;
4462 vismon = victim && (victim != &youmonst) && canseemon(victim);
4465 grease_protect(obj, (char *) 0, victim);
4466 } else if (obj->oclass == SCROLL_CLASS && obj->otyp != SCR_BLANK_PAPER) {
4467 if (obj->otyp != SCR_BLANK_PAPER
4469 && obj->otyp != SCR_MAIL
4473 if (victim == &youmonst)
4475 pline("Your %s.", aobjnam(obj, "fade"));
4477 pline("%s
\82Ì
\95¶
\8e\9a\82Í
\94\96\82ê
\82½
\81D", xname(obj));
4480 pline("%s %s.", s_suffix(Monnam(victim)),
4481 aobjnam(obj, "fade"));
4483 pline("%s
\82Ì%s
\82Ì
\95¶
\8e\9a\82Í
\94\96\82ê
\82½
\81D", Monnam(victim),
4488 obj->otyp = SCR_BLANK_PAPER;
4492 erode_obj(obj, (char *) 0, ERODE_CORRODE, EF_GREASE | EF_VERBOSE);
4495 /* context for water_damage(), managed by water_damage_chain();
4496 when more than one stack of potions of acid explode while processing
4497 a chain of objects, use alternate phrasing after the first message */
4498 static struct h2o_ctx {
4499 int dkn_boom, unk_boom; /* track dknown, !dknown separately */
4501 } acid_ctx = { 0, 0, FALSE };
4503 /* Get an object wet and damage it appropriately.
4504 * "ostr", if present, is used instead of the object name in some
4506 * "force" means not to roll luck to protect some objects.
4507 * Returns an erosion return value (ER_*)
4510 water_damage(obj, ostr, force)
4524 if (obj->otyp == CAN_OF_GREASE && obj->spe > 0) {
4526 } else if (obj->otyp == TOWEL && obj->spe < 7) {
4527 wet_a_towel(obj, rnd(7), TRUE);
4529 } else if (obj->greased) {
4535 } else if (Is_container(obj) && !Is_box(obj)
4536 && (obj->otyp != OILSKIN_SACK || (obj->cursed && !rn2(3)))) {
4539 pline("Water gets into your %s!", ostr);
4541 pline("
\90\85\82ª%s
\82Ì
\92\86\82É
\93ü
\82Á
\82½
\81I", ostr);
4543 water_damage_chain(obj->cobj, FALSE);
4544 return ER_DAMAGED; /* contents were damaged */
4545 } else if (obj->otyp == OILSKIN_SACK) {
4548 pline("Some water slides right off your %s.", ostr);
4550 pline("%s
\82Í
\90\85\82ð
\92e
\82¢
\82½
\81D", ostr);
4551 makeknown(OILSKIN_SACK);
4552 /* not actually damaged, but because we /didn't/ get the "water
4553 gets into!" message, the player now has more information and
4554 thus we need to waste any potion they may have used (also,
4555 flavourwise the water is now on the floor) */
4557 } else if (!force && (Luck + 5) > rn2(20)) {
4558 /* chance per item of sustaining damage:
4560 * avg luck (Luck==0): 75%
4561 * awful luck (Luck<-4): 100%
4564 } else if (obj->oclass == SCROLL_CLASS) {
4565 if (obj->otyp == SCR_BLANK_PAPER
4567 || obj->otyp == SCR_MAIL
4572 pline("Your %s %s.", ostr, vtense(ostr, "fade"));
4574 pline("%s
\82Ì
\95¶
\8e\9a\82Í
\94\96\82ê
\82½
\81D", ostr);
4576 obj->otyp = SCR_BLANK_PAPER;
4582 } else if (obj->oclass == SPBOOK_CLASS) {
4583 if (obj->otyp == SPE_BOOK_OF_THE_DEAD) {
4585 pline("Steam rises from %s.", the(xname(obj)));
4587 pline("
\8fö
\8bC
\82ª%s
\82©
\82ç
\97§
\82¿
\82Ì
\82Ú
\82Á
\82½
\81D", xname(obj));
4589 } else if (obj->otyp == SPE_BLANK_PAPER) {
4594 pline("Your %s %s.", ostr, vtense(ostr, "fade"));
4596 pline("%s
\82Ì
\95¶
\8e\9a\82Í
\94\96\82ê
\82½
\81D", ostr);
4598 if (obj->otyp == SPE_NOVEL) {
4603 obj->otyp = SPE_BLANK_PAPER;
4608 } else if (obj->oclass == POTION_CLASS) {
4609 if (obj->otyp == POT_ACID) {
4612 boolean one = (obj->quan == 1L), update = carried(obj),
4615 boolean update = carried(obj);
4618 if (Blind && !carried(obj))
4621 if (acid_ctx.ctx_valid)
4622 exploded = ((obj->dknown ? acid_ctx.dkn_boom
4623 : acid_ctx.unk_boom) > 0);
4626 * "a [potion|<color> potion|potion of acid] explodes"
4627 * depending on obj->dknown (potion has been seen) and
4628 * objects[POT_ACID].oc_name_known (fully discovered),
4629 * or "some {plural version} explode" when relevant.
4630 * Second and subsequent messages for same chain and
4631 * matching dknown status are
4632 * "another [potion|<color> &c] explodes" or plural
4635 bufp = simpleonames(obj);
4637 pline("%s %s %s!", /* "A potion explodes!" */
4638 !exploded ? (one ? "A" : "Some")
4639 : (one ? "Another" : "More"),
4640 bufp, vtense(bufp, "explode"));
4642 pline("%s
\82Í
\94\9a\94
\82µ
\82½
\81I", bufp);
4644 if (acid_ctx.ctx_valid) {
4646 acid_ctx.dkn_boom++;
4648 acid_ctx.unk_boom++;
4654 return ER_DESTROYED;
4655 } else if (obj->odiluted) {
4658 pline("Your %s %s further.", ostr, vtense(ostr, "dilute"));
4660 pline("%s
\82Í
\82³
\82ç
\82É
\94\96\82Ü
\82Á
\82½
\81D", ostr);
4662 obj->otyp = POT_WATER;
4664 obj->blessed = obj->cursed = 0;
4669 } else if (obj->otyp != POT_WATER) {
4672 pline("Your %s %s.", ostr, vtense(ostr, "dilute"));
4674 pline("%s
\82Í
\94\96\82Ü
\82Á
\82½
\81D", ostr);
4682 return erode_obj(obj, ostr, ERODE_RUST, EF_NONE);
4688 water_damage_chain(obj, here)
4694 /* initialize acid context: so far, neither seen (dknown) potions of
4695 acid nor unseen have exploded during this water damage sequence */
4696 acid_ctx.dkn_boom = acid_ctx.unk_boom = 0;
4697 acid_ctx.ctx_valid = TRUE;
4699 for (; obj; obj = otmp) {
4700 otmp = here ? obj->nexthere : obj->nobj;
4701 water_damage(obj, (char *) 0, FALSE);
4704 /* reset acid context */
4705 acid_ctx.dkn_boom = acid_ctx.unk_boom = 0;
4706 acid_ctx.ctx_valid = FALSE;
4710 * This function is potentially expensive - rolling
4711 * inventory list multiple times. Luckily it's seldom needed.
4712 * Returns TRUE if disrobing made player unencumbered enough to
4713 * crawl out of the current predicament.
4716 emergency_disrobe(lostsome)
4719 int invc = inv_cnt(TRUE);
4721 while (near_capacity() > (Punished ? UNENCUMBERED : SLT_ENCUMBER)) {
4722 register struct obj *obj, *otmp = (struct obj *) 0;
4725 /* Pick a random object */
4728 for (obj = invent; obj; obj = obj->nobj) {
4730 * Undroppables are: body armor, boots, gloves,
4731 * amulets, and rings because of the time and effort
4732 * in removing them + loadstone and other cursed stuff
4733 * for obvious reasons.
4735 if (!((obj->otyp == LOADSTONE && obj->cursed) || obj == uamul
4736 || obj == uleft || obj == uright || obj == ublindf
4737 || obj == uarm || obj == uarmc || obj == uarmg
4738 || obj == uarmf || obj == uarmu
4739 || (obj->cursed && (obj == uarmh || obj == uarms))
4742 /* reached the mark and found some stuff to drop? */
4743 if (--i < 0 && otmp)
4750 return FALSE; /* nothing to drop! */
4751 if (otmp->owornmask)
4752 remove_worn_item(otmp, FALSE);
4761 /* return TRUE iff player relocated */
4765 const char *pool_of_water;
4766 boolean inpool_ok = FALSE, crawl_ok;
4769 /* happily wading in the same contiguous pool */
4770 if (u.uinwater && is_pool(u.ux - u.dx, u.uy - u.dy)
4771 && (Swimming || Amphibious)) {
4772 /* water effects on objects every now and then */
4781 You("%s into the %s%c", Is_waterlevel(&u.uz) ? "plunge" : "fall",
4783 Amphibious || Swimming ? '.' : '!');
4785 You("%s
\82Ì
\92\86\82É%s%s", hliquid("
\90\85"),
4786 Is_waterlevel(&u.uz) ? "
\94ò
\82Ñ
\82±
\82ñ
\82¾" : "
\97\8e\82¿
\82½",
4787 Amphibious || Swimming ? "
\81D" : "
\81I");
4789 if (!Swimming && !Is_waterlevel(&u.uz))
4791 You("sink like %s.", Hallucination ? "the Titanic" : "a rock");
4793 You("%s
\82Ì
\82æ
\82¤
\82É
\92¾
\82ñ
\82¾
\81D", Hallucination ? "
\83^
\83C
\83^
\83j
\83b
\83N
\8d\86" : "
\8aâ");
4796 water_damage_chain(invent, FALSE);
4798 if (u.umonnum == PM_GREMLIN && rn2(3))
4799 (void) split_mon(&youmonst, (struct monst *) 0);
4800 else if (u.umonnum == PM_IRON_GOLEM) {
4804 You("
\8eK
\82Ñ
\82½
\81I");
4805 i = Maybe_Half_Phys(d(2, 6));
4809 losehp(i, "rusting away", KILLED_BY);
4811 losehp(i, "
\8a®
\91S
\82É
\8eK
\82Ñ
\82Ä", KILLED_BY);
4816 if ((i = number_leashed()) > 0) {
4818 pline_The("leash%s slip%s loose.", (i > 1) ? "es" : "",
4819 (i > 1) ? "" : "s");
4821 pline("
\95R
\82ª
\82ä
\82é
\82ñ
\82¾
\81D");
4826 if (Amphibious || Swimming) {
4830 pline("But you aren't drowning.");
4832 pline("
\82µ
\82©
\82µ
\81C
\82 \82È
\82½
\82Í
\93M
\82ê
\82È
\82©
\82Á
\82½
\81D");
4833 if (!Is_waterlevel(&u.uz)) {
4836 Your("keel hits the bottom.");
4838 You("
\92ê
\82É
\83j
\81[
\83h
\83\8d\83b
\83v
\82ð
\8c\88\82ß
\82½
\81D");
4841 You("touch bottom.");
4843 You("
\92ê
\82É
\82Â
\82¢
\82½
\81D");
4850 vision_recalc(2); /* unsee old position */
4853 vision_full_recalc = 1;
4856 if ((Teleportation || can_teleport(youmonst.data)) && !Unaware
4857 && (Teleport_control || rn2(3) < Luck + 2)) {
4859 You("attempt a teleport spell."); /* utcsri!carroll */
4861 You("
\8fu
\8aÔ
\88Ú
\93®
\82Ì
\8eô
\95¶
\82ð
\8f¥
\82¦
\82Ä
\82Ý
\82½
\81D");
4863 if (!level.flags.noteleport) {
4864 (void) dotele(FALSE);
4865 if (!is_pool(u.ux, u.uy))
4869 pline_The("attempted teleport spell fails.");
4871 pline("
\8fu
\8aÔ
\88Ú
\93®
\82Ì
\8eô
\95¶
\82Í
\8e¸
\94s
\82µ
\82½
\81D");
4874 dismount_steed(DISMOUNT_GENERIC);
4875 if (!is_pool(u.ux, u.uy))
4879 x = y = 0; /* lint suppression */
4880 /* if sleeping, wake up now so that we don't crawl out of water
4881 while still asleep; we can't do that the same way that waking
4882 due to combat is handled; note unmul() clears u.usleep */
4885 unmul("Suddenly you wake up!");
4887 unmul("
\93Ë
\91R
\82 \82È
\82½
\82Í
\96Ú
\82ª
\8ao
\82ß
\82½
\81I");
4888 /* being doused will revive from fainting */
4891 /* can't crawl if unable to move (crawl_ok flag stays false) */
4892 if (multi < 0 || (Upolyd && !youmonst.data->mmove))
4894 /* look around for a place to crawl to */
4895 for (i = 0; i < 100; i++) {
4896 x = rn1(3, u.ux - 1);
4897 y = rn1(3, u.uy - 1);
4898 if (crawl_destination(x, y)) {
4904 for (x = u.ux - 1; x <= u.ux + 1; x++)
4905 for (y = u.uy - 1; y <= u.uy + 1; y++)
4906 if (crawl_destination(x, y)) {
4912 boolean lost = FALSE;
4913 /* time to do some strip-tease... */
4914 boolean succ = Is_waterlevel(&u.uz) ? TRUE : emergency_disrobe(&lost);
4917 You("try to crawl out of the %s.", hliquid("water"));
4919 You("%s
\82©
\82ç
\82Í
\82¢
\82 \82ª
\82ë
\82¤
\82Æ
\82µ
\82½
\81D", hliquid("
\90\85"));
4922 You("dump some of your gear to lose weight...");
4924 You("
\91Ì
\82ð
\8cy
\82
\82·
\82é
\82½
\82ß
\82¢
\82
\82Â
\82©
\95¨
\82ð
\93\8a\82°
\82·
\82Ä
\82½
\81D
\81D
\81D");
4927 pline("Pheew! That was close.");
4929 pline("
\83n
\83@
\83n
\83@
\81I
\82 \82Ô
\82È
\82©
\82Á
\82½
\81D");
4933 /* still too much weight */
4935 pline("But in vain.");
4937 pline("
\82ª
\81C
\96³
\91Ê
\82¾
\82Á
\82½
\81D");
4943 You("
\93M
\82ê
\82½
\81D");
4944 for (i = 0; i < 5; i++) { /* arbitrary number of loops */
4945 /* killer format and name are reconstructed every iteration
4946 because lifesaving resets them */
4947 pool_of_water = waterbody_name(u.ux, u.uy);
4948 killer.format = KILLED_BY_AN;
4950 /* avoid "drowned in [a] water" */
4951 if (!strcmp(pool_of_water, "water"))
4952 pool_of_water = "deep water", killer.format = KILLED_BY;
4954 Strcpy(killer.name, pool_of_water);
4956 /* oops, we're still alive. better get out of the water. */
4957 if (safe_teleds(TRUE))
4958 break; /* successful life-save */
4959 /* nowhere safe to land; repeat drowning loop... */
4961 pline("You're still drowning.");
4963 You("
\82Ü
\82¾
\93M
\82ê
\82Ä
\82¢
\82é
\81D");
4968 You("find yourself back %s.",
4969 Is_waterlevel(&u.uz) ? "in an air bubble" : "on land");
4971 You("
\82¢
\82Â
\82Ì
\82Ü
\82É
\82©%s
\82É
\82¢
\82é
\82Ì
\82É
\8bC
\82ª
\82Â
\82¢
\82½
\81D",
4972 Is_waterlevel(&u.uz) ? "
\8bó
\8bC
\82Ì
\96A
\82Ì
\92\86" : "
\92n
\96Ê");
4983 /* energy is completely gone */
4985 You_feel("momentarily lethargic.");
4987 You("
\88ê
\8fu
\96³
\8bC
\97Í
\8a´
\82ð
\8a´
\82¶
\82½
\81D");
4989 /* throttle further loss a bit when there's not much left to lose */
4990 if (n > u.uenmax || n > u.ulevel)
4994 You_feel("your magical energy drain away%c", (n > u.uen) ? '!' : '.');
4996 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");
4999 u.uenmax -= rnd(-u.uen);
5012 if (near_capacity() >= HVY_ENCUMBER) {
5014 pline("You're too strained to do that.");
5016 pline("ã©
\82ð
\89ð
\8f\9c\82µ
\82æ
\82¤
\82É
\82à
\95¨
\82ð
\8e\9d\82¿
\82·
\82¬
\82Ä
\82¢
\82é
\81D");
5019 if ((nohands(youmonst.data) && !webmaker(youmonst.data))
5020 || !youmonst.data->mmove) {
5022 pline("And just how do you expect to do that?");
5024 pline("
\82¢
\82Á
\82½
\82¢
\89½
\82ð
\8aú
\91Ò
\82µ
\82Ä
\82¢
\82é
\82ñ
\82¾
\82¢
\81H");
5026 } else if (u.ustuck && sticks(youmonst.data)) {
5028 pline("You'll have to let go of %s first.", mon_nam(u.ustuck));
5030 pline("%s
\82ð
\8eè
\97£
\82³
\82È
\82¢
\82±
\82Æ
\82É
\82Í
\82Å
\82«
\82È
\82¢
\81D", mon_nam(u.ustuck));
5033 if (u.ustuck || (welded(uwep) && bimanual(uwep))) {
5035 Your("%s seem to be too busy for that.", makeplural(body_part(HAND)));
5037 Your("
\82»
\82ñ
\82È
\82±
\82Æ
\82ð
\82·
\82é
\97]
\97T
\82È
\82ñ
\82Ä
\82È
\82¢
\81D");
5040 return untrap(FALSE);
5043 /* Probability of disabling a trap. Helge Hafting */
5050 /* Only spiders know how to deal with webs reliably */
5051 if (ttmp->ttyp == WEB && !webmaker(youmonst.data))
5053 if (Confusion || Hallucination)
5061 /* Your own traps are better known than others. */
5062 if (ttmp && ttmp->madeby_u)
5064 if (Role_if(PM_ROGUE)) {
5065 if (rn2(2 * MAXULEV) < u.ulevel)
5067 if (u.uhave.questart && chance > 1)
5069 } else if (Role_if(PM_RANGER) && chance > 1)
5074 /* Replace trap with object(s). Helge Hafting */
5076 cnv_trap_obj(otyp, cnt, ttmp, bury_it)
5082 struct obj *otmp = mksobj(otyp, TRUE, FALSE);
5085 otmp->owt = weight(otmp);
5086 /* Only dart traps are capable of being poisonous */
5088 otmp->opoisoned = 0;
5089 place_object(otmp, ttmp->tx, ttmp->ty);
5091 /* magical digging first disarms this trap, then will unearth it */
5092 (void) bury_an_obj(otmp, (boolean *) 0);
5094 /* Sell your own traps only... */
5096 sellobj(otmp, ttmp->tx, ttmp->ty);
5099 newsym(ttmp->tx, ttmp->ty);
5100 if (u.utrap && ttmp->tx == u.ux && ttmp->ty == u.uy)
5105 /* while attempting to disarm an adjacent trap, we've fallen into it */
5107 move_into_trap(ttmp)
5111 xchar x = ttmp->tx, y = ttmp->ty, bx, by, cx, cy;
5114 bx = by = cx = cy = 0; /* lint suppression */
5115 /* we know there's no monster in the way, and we're not trapped */
5117 || drag_ball(x, y, &bc, &bx, &by, &cx, &cy, &unused, TRUE)) {
5118 u.ux0 = u.ux, u.uy0 = u.uy;
5121 newsym(u.ux0, u.uy0);
5123 check_leash(u.ux0, u.uy0);
5125 move_bc(0, bc, bx, by, cx, cy);
5126 /* marking the trap unseen forces dotrap() to treat it like a new
5127 discovery and prevents pickup() -> look_here() -> check_here()
5128 from giving a redundant "there is a <trap> here" message when
5129 there are objects covering this trap */
5130 ttmp->tseen = 0; /* hack for check_here() */
5131 /* trigger the trap */
5132 iflags.failing_untrap++; /* spoteffects() -> dotrap(,FAILEDUNTRAP) */
5133 spoteffects(TRUE); /* pickup() + dotrap() */
5134 iflags.failing_untrap--;
5135 /* this should no longer be necessary; before the failing_untrap
5136 hack, Flying hero would not trigger an unseen bear trap and
5137 setting it not-yet-seen above resulted in leaving it hidden */
5138 if ((ttmp = t_at(u.ux, u.uy)) != 0)
5140 exercise(A_WIS, FALSE);
5144 /* 0: doesn't even try
5145 * 1: tries and fails
5149 try_disarm(ttmp, force_failure)
5151 boolean force_failure;
5153 struct monst *mtmp = m_at(ttmp->tx, ttmp->ty);
5154 int ttype = ttmp->ttyp;
5155 boolean under_u = (!u.dx && !u.dy);
5156 boolean holdingtrap = (ttype == BEAR_TRAP || ttype == WEB);
5158 /* Test for monster first, monsters are displayed instead of trap. */
5159 if (mtmp && (!mtmp->mtrapped || !holdingtrap)) {
5161 pline("%s is in the way.", Monnam(mtmp));
5163 pline("
\82»
\82±
\82É
\82Í%s
\82ª
\82¢
\82é
\81D", Monnam(mtmp));
5166 /* We might be forced to move onto the trap's location. */
5167 if (sobj_at(BOULDER, ttmp->tx, ttmp->ty) && !Passes_walls && !under_u) {
5169 There("is a boulder in your way.");
5171 pline("
\82»
\82±
\82É
\82Í
\8aâ
\82ª
\82 \82é
\81D");
5174 /* duplicate tight-space checks from test_move */
5175 if (u.dx && u.dy && bad_rock(youmonst.data, u.ux, ttmp->ty)
5176 && bad_rock(youmonst.data, ttmp->tx, u.uy)) {
5177 if ((invent && (inv_weight() + weight_cap() > 600))
5178 || bigmonst(youmonst.data)) {
5179 /* don't allow untrap if they can't get thru to it */
5181 You("are unable to reach the %s!",
5182 defsyms[trap_to_defsym(ttype)].explanation);
5184 You("%s
\82É
\93Í
\82©
\82È
\82¢
\81I",
5185 defsyms[trap_to_defsym(ttype)].explanation);
5190 /* untrappable traps are located on the ground. */
5191 if (!can_reach_floor(under_u)) {
5192 if (u.usteed && P_SKILL(P_RIDING) < P_BASIC)
5196 You("are unable to reach the %s!",
5197 defsyms[trap_to_defsym(ttype)].explanation);
5199 You("%s
\82É
\93Í
\82©
\82È
\82¢
\81I",
5200 defsyms[trap_to_defsym(ttype)].explanation);
5205 /* Will our hero succeed? */
5206 if (force_failure || untrap_prob(ttmp)) {
5211 pline("
\82¤
\82í
\82Á
\81D
\81D
\81D");
5212 if (mtmp) { /* must be a trap that holds monsters */
5213 if (ttype == BEAR_TRAP) {
5216 mtmp->mhp -= rnd(4);
5217 if (DEADMONSTER(mtmp))
5219 } else if (ttype == WEB) {
5220 if (!webmaker(youmonst.data)) {
5221 struct trap *ttmp2 = maketrap(u.ux, u.uy, WEB);
5226 "webbing sticks to you. You're caught too!");
5228 "
\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");
5229 dotrap(ttmp2, NOWEBMSG);
5230 if (u.usteed && u.utrap) {
5231 /* you, not steed, are trapped */
5232 dismount_steed(DISMOUNT_FELL);
5237 pline("%s remains entangled.", Monnam(mtmp));
5239 pline("%s
\82Í
\82©
\82ç
\82Ü
\82Á
\82½
\82Ü
\82Ü
\82¾
\81D", Monnam(mtmp));
5241 } else if (under_u) {
5242 /* [don't need the iflags.failing_untrap hack here] */
5243 dotrap(ttmp, FAILEDUNTRAP);
5245 move_into_trap(ttmp);
5249 pline("%s %s is difficult to %s.",
5250 ttmp->madeby_u ? "Your" : under_u ? "This" : "That",
5251 defsyms[trap_to_defsym(ttype)].explanation,
5252 (ttype == WEB) ? "remove" : "disarm");
5254 pline("%s%s
\82ð
\89ð
\8f\9c\82·
\82é
\82Ì
\82Í
\8d¢
\93ï
\82¾
\81D",
5255 ttmp->madeby_u ? "
\82 \82È
\82½
\82Ì
\8ed
\8a|
\82¯
\82½" : under_u ? "
\82±
\82Ì" : "
\82»
\82Ì",
5256 defsyms[trap_to_defsym(ttype)].explanation);
5265 reward_untrap(ttmp, mtmp)
5269 if (!ttmp->madeby_u) {
5270 if (rnl(10) < 8 && !mtmp->mpeaceful && !mtmp->msleeping
5271 && !mtmp->mfrozen && !mindless(mtmp->data)
5272 && mtmp->data->mlet != S_HUMAN) {
5273 mtmp->mpeaceful = 1;
5274 set_malign(mtmp); /* reset alignment */
5276 pline("%s is grateful.", Monnam(mtmp));
5278 pline("%s
\82Í
\8aì
\82ñ
\82Å
\82¢
\82é
\81D", Monnam(mtmp));
5280 /* Helping someone out of a trap is a nice thing to do,
5281 * A lawful may be rewarded, but not too often. */
5282 if (!rn2(3) && !rnl(8) && u.ualign.type == A_LAWFUL) {
5285 You_feel("that you did the right thing.");
5287 You("
\90³
\82µ
\82¢
\82±
\82Æ
\82ð
\82µ
\82½
\82æ
\82¤
\82È
\8bC
\82ª
\82µ
\82½
\81D");
5293 disarm_holdingtrap(ttmp) /* Helge Hafting */
5297 int fails = try_disarm(ttmp, FALSE);
5302 /* ok, disarm it. */
5304 /* untrap the monster, if any.
5305 There's no need for a cockatrice test, only the trap is touched */
5306 if ((mtmp = m_at(ttmp->tx, ttmp->ty)) != 0) {
5309 You("remove %s %s from %s.", the_your[ttmp->madeby_u],
5310 (ttmp->ttyp == BEAR_TRAP) ? "bear trap" : "webbing",
5313 You("%s%s
\82ð%s
\82©
\82ç
\82Í
\82¸
\82µ
\82½
\81D", set_you[ttmp->madeby_u],
5314 (ttmp->ttyp == BEAR_TRAP) ? "
\8cF
\82Ìã©" : "
\82
\82à
\82Ì
\91\83",
5317 reward_untrap(ttmp, mtmp);
5319 if (ttmp->ttyp == BEAR_TRAP) {
5321 You("disarm %s bear trap.", the_your[ttmp->madeby_u]);
5323 You("%s
\8cF
\82Ìã©
\82ð
\89ð
\8f\9c\82µ
\82½
\81D", set_you[ttmp->madeby_u]);
5324 cnv_trap_obj(BEARTRAP, 1, ttmp, FALSE);
5325 } else /* if (ttmp->ttyp == WEB) */ {
5327 You("succeed in removing %s web.", the_your[ttmp->madeby_u]);
5329 You("%s
\82
\82à
\82Ì
\91\83\82ð
\8eæ
\82è
\8f\9c\82¢
\82½
\81D", set_you[ttmp->madeby_u]);
5333 newsym(u.ux + u.dx, u.uy + u.dy);
5338 disarm_landmine(ttmp) /* Helge Hafting */
5341 int fails = try_disarm(ttmp, FALSE);
5346 You("disarm %s land mine.", the_your[ttmp->madeby_u]);
5348 You("%s
\92n
\97\8b\82ð
\89ð
\8f\9c\82µ
\82½
\81D", set_you[ttmp->madeby_u]);
5349 cnv_trap_obj(LAND_MINE, 1, ttmp, FALSE);
5353 /* getobj will filter down to cans of grease and known potions of oil */
5354 static NEARDATA const char oil[] = { ALL_CLASSES, TOOL_CLASS, POTION_CLASS,
5357 /* it may not make much sense to use grease on floor boards, but so what? */
5359 disarm_squeaky_board(ttmp)
5366 obj = getobj(oil, "untrap with");
5370 bad_tool = (obj->cursed
5371 || ((obj->otyp != POT_OIL || obj->lamplit)
5372 && (obj->otyp != CAN_OF_GREASE || !obj->spe)));
5373 fails = try_disarm(ttmp, bad_tool);
5377 /* successfully used oil or grease to fix squeaky board */
5378 if (obj->otyp == CAN_OF_GREASE) {
5379 consume_obj_charge(obj, TRUE);
5381 useup(obj); /* oil */
5385 You("repair the squeaky board."); /* no madeby_u */
5387 You("
\82«
\82µ
\82Þ
\94Â
\82ð
\8fC
\97\9d\82µ
\82½
\81D"); /* no madeby_u */
5390 newsym(u.ux + u.dx, u.uy + u.dy);
5391 more_experienced(1, 5);
5396 /* removes traps that shoot arrows, darts, etc. */
5398 disarm_shooting_trap(ttmp, otyp)
5402 int fails = try_disarm(ttmp, FALSE);
5407 You("disarm %s trap.", the_your[ttmp->madeby_u]);
5409 pline("%sã©
\82ð
\89ð
\8f\9c\82µ
\82½
\81D", set_you[ttmp->madeby_u]);
5410 cnv_trap_obj(otyp, 50 - rnl(50), ttmp, FALSE);
5414 /* Is the weight too heavy?
5415 * Formula as in near_capacity() & check_capacity() */
5417 try_lift(mtmp, ttmp, wt, stuff)
5423 int wc = weight_cap();
5425 if (((wt * 2) / wc) >= HVY_ENCUMBER) {
5427 pline("%s is %s for you to lift.", Monnam(mtmp),
5428 stuff ? "carrying too much" : "too heavy");
5430 pline("%s
\82Í%s
\8e\9d\82¿
\82 \82°
\82é
\82±
\82Æ
\82ª
\82Å
\82«
\82È
\82¢
\81D", Monnam(mtmp),
5431 stuff ? "
\95¨
\82ð
\8e\9d\82¿
\82·
\82¬
\82Ä
\82¨
\82è" : "
\8fd
\82·
\82¬
\82Ä");
5433 if (!ttmp->madeby_u && !mtmp->mpeaceful && mtmp->mcanmove
5434 && !mindless(mtmp->data) && mtmp->data->mlet != S_HUMAN
5436 mtmp->mpeaceful = 1;
5437 set_malign(mtmp); /* reset alignment */
5439 pline("%s thinks it was nice of you to try.", Monnam(mtmp));
5441 pline("%s
\82Í
\82 \82È
\82½
\82Ì
\93w
\97Í
\82É
\8a´
\8eÓ
\82µ
\82Ä
\82¢
\82é
\82æ
\82¤
\82¾
\81D", Monnam(mtmp));
5448 /* Help trapped monster (out of a (spiked) pit) */
5450 help_monster_out(mtmp, ttmp)
5459 * This works when levitating too -- consistent with the ability
5460 * to hit monsters while levitating.
5462 * Should perhaps check that our hero has arms/hands at the
5463 * moment. Helping can also be done by engulfing...
5465 * Test the monster first - monsters are displayed before traps.
5467 if (!mtmp->mtrapped) {
5469 pline("%s isn't trapped.", Monnam(mtmp));
5471 pline("%s
\82Íã©
\82É
\82©
\82©
\82Á
\82Ä
\82¢
\82È
\82¢
\81D", Monnam(mtmp));
5474 /* Do you have the necessary capacity to lift anything? */
5475 if (check_capacity((char *) 0))
5478 /* Will our hero succeed? */
5479 if ((uprob = untrap_prob(ttmp)) && !mtmp->msleeping && mtmp->mcanmove) {
5481 You("try to reach out your %s, but %s backs away skeptically.",
5482 makeplural(body_part(ARM)), mon_nam(mtmp));
5484 You("%s
\82ð
\8d·
\82µ
\89\84\82×
\82æ
\82¤
\82Æ
\82µ
\82½
\82ª%s
\82Í
\8cx
\89ú
\82µ
\82Ä
\82¢
\82é
\81D",
5485 body_part(ARM), mon_nam(mtmp));
5490 /* is it a cockatrice?... */
5491 if (touch_petrifies(mtmp->data) && !uarmg && !Stone_resistance) {
5493 You("grab the trapped %s using your bare %s.", mtmp->data->mname,
5494 makeplural(body_part(HAND)));
5496 You("ã©
\82É
\82©
\82©
\82Á
\82Ä
\82¢
\82é%s
\82ð
\91f%s
\82Å
\92Í
\82ñ
\82¾
\81D", mtmp->data->mname,
5500 if (poly_when_stoned(youmonst.data) && polymon(PM_STONE_GOLEM)) {
5501 display_nhwindow(WIN_MESSAGE, FALSE);
5506 Sprintf(kbuf, "trying to help %s out of a pit",
5507 an(mtmp->data->mname));
5509 Sprintf(kbuf, "ã©
\82É
\82©
\82©
\82Á
\82Ä
\82¢
\82é%s
\82ð
\8f\95\82¯
\82æ
\82¤
\82Æ
\82µ
\82Ä",
5516 /* need to do cockatrice check first if sleeping or paralyzed */
5519 You("try to grab %s, but cannot get a firm grasp.", mon_nam(mtmp));
5521 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));
5522 if (mtmp->msleeping) {
5523 mtmp->msleeping = 0;
5525 pline("%s awakens.", Monnam(mtmp));
5527 pline("%s
\82Í
\96Ú
\82ð
\8ao
\82Ü
\82µ
\82½
\81D", Monnam(mtmp));
5533 You("reach out your %s and grab %s.", makeplural(body_part(ARM)),
5536 You("%s
\82ð
\90L
\82Î
\82µ
\82Ä%s
\82ð
\82Â
\82©
\82ñ
\82¾
\81D", body_part(ARM),
5540 if (mtmp->msleeping) {
5541 mtmp->msleeping = 0;
5543 pline("%s awakens.", Monnam(mtmp));
5545 pline("%s
\82Í
\96Ú
\82ð
\8ao
\82Ü
\82µ
\82½
\81D", Monnam(mtmp));
5546 } else if (mtmp->mfrozen && !rn2(mtmp->mfrozen)) {
5547 /* After such manhandling, perhaps the effect wears off */
5551 pline("%s stirs.", Monnam(mtmp));
5553 pline("%s
\82Í
\93®
\82«
\8en
\82ß
\82½
\81D", Monnam(mtmp));
5556 /* is the monster too heavy? */
5557 wt = inv_weight() + mtmp->data->cwt;
5558 if (!try_lift(mtmp, ttmp, wt, FALSE))
5561 /* is the monster with inventory too heavy? */
5562 for (otmp = mtmp->minvent; otmp; otmp = otmp->nobj)
5564 if (!try_lift(mtmp, ttmp, wt, TRUE))
5568 You("pull %s out of the pit.", mon_nam(mtmp));
5570 You("%s
\82ð
\97\8e\82µ
\8c\8a\82©
\82ç
\82Ð
\82Á
\82Ï
\82Á
\82½
\81D", mon_nam(mtmp));
5572 fill_pit(mtmp->mx, mtmp->my);
5573 reward_untrap(ttmp, mtmp);
5581 register struct obj *otmp;
5586 const char *trapdescr;
5588 boolean here, useplural, deal_with_floor_trap,
5589 confused = (Confusion || Hallucination),
5590 trap_skipped = FALSE;
5592 boolean here, deal_with_floor_trap,
5593 confused = (Confusion || Hallucination),
5594 trap_skipped = FALSE;
5597 char the_trap[BUFSZ], qbuf[QBUFSZ];
5599 if (!getdir((char *) 0))
5605 pline_The("perils lurking there are beyond your grasp.");
5607 pline_The("
\82»
\82±
\82É
\82 \82é
\8aë
\8c¯
\82Í
\82 \82È
\82½
\82Ì
\8eè
\82É
\95\89\82¦
\82È
\82¢
\81D");
5610 /* 'force' is true for #invoke; make it be true for #untrap if
5612 if (!force && has_magic_key(&youmonst))
5616 if (ttmp && !ttmp->tseen)
5618 trapdescr = ttmp ? defsyms[trap_to_defsym(ttmp->ttyp)].explanation : 0;
5619 here = (x == u.ux && y == u.uy); /* !u.dx && !u.dy */
5621 if (here) /* are there are one or more containers here? */
5622 for (otmp = level.objects[x][y]; otmp; otmp = otmp->nexthere)
5628 deal_with_floor_trap = can_reach_floor(FALSE);
5629 if (!deal_with_floor_trap) {
5632 Strcat(the_trap, an(trapdescr));
5635 Strcat(the_trap, " and ");
5637 Strcat(the_trap, "
\82Æ");
5640 Strcat(the_trap, (boxcnt == 1) ? "a container" : "containers");
5642 Strcat(the_trap, "
\97e
\8aí");
5644 useplural = ((ttmp && boxcnt > 0) || boxcnt > 1);
5646 /* note: boxcnt and useplural will always be 0 for !here case */
5649 There("%s %s %s but you can't reach %s%s.",
5650 useplural ? "are" : "is", the_trap, here ? "here" : "there",
5651 useplural ? "them" : "it",
5652 u.usteed ? " while mounted" : "");
5654 pline("%s
\82ª
\82 \82é
\82ª
\81C%s
\93Í
\82©
\82È
\82¢
\81D",
5656 u.usteed ? "
\8fæ
\82Á
\82Ä
\82¢
\82é
\82Æ" : "");
5658 trap_skipped = (ttmp != 0);
5659 } else { /* deal_with_floor_trap */
5662 Strcpy(the_trap, the(trapdescr));
5664 if (is_pit(ttmp->ttyp)) {
5666 You_cant("do much about %s%s.", the_trap,
5667 u.utrap ? " that you're stuck in"
5668 : " while standing on the edge of it");
5670 pline("%s%s
\82É
\91Î
\82µ
\82Ä
\82Í
\82½
\82¢
\82µ
\82½
\82±
\82Æ
\82Í
\82Å
\82«
\82È
\82¢
\81D",
5671 u.utrap ? "
\8e©
\95ª
\82ª
\82Í
\82Ü
\82Á
\82Ä
\82¢
\82é"
5672 : "
\82·
\82®
\82»
\82Î
\82Ì",
5675 trap_skipped = TRUE;
5676 deal_with_floor_trap = FALSE;
5680 qbuf, "There %s and %s here. %s %s?",
5681 (boxcnt == 1) ? "is a container" : "are containers",
5683 (ttmp->ttyp == WEB) ? "Remove" : "Disarm", the_trap);
5686 qbuf, "
\94 \82Æ%s
\82ª
\82 \82é
\81D%s
\81H",
5688 (ttmp->ttyp == WEB) ? "
\8eæ
\82è
\8f\9c\82" : "
\89ð
\8f\9c\82·
\82é");
5690 switch (ynq(qbuf)) {
5694 trap_skipped = TRUE;
5695 deal_with_floor_trap = FALSE;
5700 if (deal_with_floor_trap) {
5703 You("cannot deal with %s while trapped%s!", the_trap,
5704 (x == u.ux && y == u.uy) ? " in it" : "");
5706 pline("ã©
\82É
\82©
\82©
\82Á
\82Ä
\82¢
\82é
\8aÔ
\82Íã©
\82ð
\89ð
\8f\9c\82Å
\82«
\82È
\82¢
\81I");
5710 if ((mtmp = m_at(x, y)) != 0
5711 && (M_AP_TYPE(mtmp) == M_AP_FURNITURE
5712 || M_AP_TYPE(mtmp) == M_AP_OBJECT)) {
5713 stumble_onto_mimic(mtmp);
5716 switch (ttmp->ttyp) {
5719 return disarm_holdingtrap(ttmp);
5721 return disarm_landmine(ttmp);
5723 return disarm_squeaky_board(ttmp);
5725 return disarm_shooting_trap(ttmp, DART);
5727 return disarm_shooting_trap(ttmp, ARROW);
5732 You("are already on the edge of the pit.");
5734 You("
\82à
\82¤
\97\8e\82µ
\8c\8a\82Ì
\92[
\82É
\82¢
\82é
\81D");
5739 pline("Try filling the pit instead.");
5741 pline("
\82È
\82ñ
\82Æ
\82©
\96\84\82ß
\82é
\82±
\82Æ
\82ð
\8dl
\82¦
\82Ä
\82Ý
\82½
\82ç
\81H");
5744 return help_monster_out(mtmp, ttmp);
5747 You("cannot disable %s trap.", !here ? "that" : "this");
5749 pline("%sã©
\82Í
\89ð
\8f\9c\82Å
\82«
\82È
\82¢
\81D", !here ? "
\82»
\82Ì" : "
\82±
\82Ì");
5756 for (otmp = level.objects[x][y]; otmp; otmp = otmp->nexthere)
5759 (void) safe_qbuf(qbuf, "There is ",
5760 " here. Check it for traps?", otmp,
5761 doname, ansimpleoname, "a box");
5763 (void) safe_qbuf(qbuf, "",
5764 "
\82ª
\82 \82é
\81Dã©
\82ð
\92²
\82×
\82Ü
\82·
\82©
\81H", otmp,
5765 doname, ansimpleoname, "
\94 ");
5767 switch (ynq(qbuf)) {
5775 && (force || (!confused
5776 && rn2(MAXULEV + 1 - u.ulevel) < 10)))
5777 || (!force && confused && !rn2(3))) {
5779 You("find a trap on %s!", the(xname(otmp)));
5781 pline("%s
\82Éã©
\82ð
\94
\8c©
\82µ
\82½
\81I", the(xname(otmp)));
5783 exercise(A_WIS, TRUE);
5786 switch (ynq("Disarm it?")) {
5788 switch (ynq("
\89ð
\8f\9c\82µ
\82Ü
\82·
\82©
\81H")) {
5792 trap_skipped = TRUE;
5796 if (otmp->otrapped) {
5797 exercise(A_DEX, TRUE);
5798 ch = ACURR(A_DEX) + u.ulevel;
5799 if (Role_if(PM_ROGUE))
5801 if (!force && (confused || Fumbling
5802 || rnd(75 + level_difficulty() / 2)
5804 (void) chest_trap(otmp, FINGER, TRUE);
5809 You("
\89ð
\8f\9c\82µ
\82½
\81I");
5814 pline("That %s was not trapped.", xname(otmp));
5816 pline("
\82»
\82Ì%s
\82Éã©
\82Í
\82È
\82¢
\81D", xname(otmp));
5820 You("find no traps on %s.", the(xname(otmp)));
5822 pline("ã©
\82ð
\94
\8c©
\82Å
\82«
\82È
\82©
\82Á
\82½
\81D");
5828 You(trap_skipped ? "find no other traps here."
5829 : "know of no traps here.");
5831 You(trap_skipped ? "
\91¼
\82Ìã©
\82ð
\8c©
\82Â
\82¯
\82ç
\82ê
\82È
\82©
\82Á
\82½
\81D"
5832 : "
\82±
\82±
\82Éã©
\82ª
\82È
\82¢
\82±
\82Æ
\82ð
\92m
\82Á
\82Ä
\82¢
\82é
\81D");
5837 if (stumble_on_door_mimic(x, y))
5840 } /* deal_with_floor_trap */
5841 /* doors can be manipulated even while levitating/unskilled riding */
5843 if (!IS_DOOR(levl[x][y].typ)) {
5846 You("know of no traps there.");
5848 You("
\82»
\82±
\82Éã©
\82ª
\82È
\82¢
\82±
\82Æ
\82ð
\92m
\82Á
\82Ä
\82¢
\82é
\81D");
5852 switch (levl[x][y].doormask) {
5855 You("%s no door there.", Blind ? "feel" : "see");
5857 pline("
\82»
\82±
\82É
\82Í
\94à
\82ª
\82È
\82¢%s
\81D", Blind ? "
\82æ
\82¤
\82¾" : "
\82æ
\82¤
\82É
\8c©
\82¦
\82é");
5861 pline("This door is safely open.");
5863 pline("
\82»
\82Ì
\94à
\82Í
\88À
\91S
\82É
\8aJ
\82¢
\82Ä
\82¢
\82é
\81D");
5867 pline("This door is broken.");
5869 pline("
\82»
\82Ì
\94à
\82Í
\89ó
\82ê
\82Ä
\82¢
\82é
\81D");
5873 if (((levl[x][y].doormask & D_TRAPPED) != 0
5874 && (force || (!confused && rn2(MAXULEV - u.ulevel + 11) < 10)))
5875 || (!force && confused && !rn2(3))) {
5877 You("find a trap on the door!");
5879 pline("
\94à
\82Éã©
\82ð
\94
\8c©
\82µ
\82½
\81I");
5880 exercise(A_WIS, TRUE);
5882 if (ynq("Disarm it?") != 'y')
5884 if (ynq("
\89ð
\8f\9c\82µ
\82Ü
\82·
\82©
\81H") != 'y')
5886 if (levl[x][y].doormask & D_TRAPPED) {
5887 ch = 15 + (Role_if(PM_ROGUE) ? u.ulevel * 3 : u.ulevel);
5888 exercise(A_DEX, TRUE);
5889 if (!force && (confused || Fumbling
5890 || rnd(75 + level_difficulty() / 2) > ch)) {
5894 You("
\83X
\83C
\83b
\83`
\82ð
\93ü
\82ê
\82Ä
\82µ
\82Ü
\82Á
\82½
\81I");
5896 b_trapped("door", FINGER);
5898 b_trapped("
\94à", FINGER);
5899 levl[x][y].doormask = D_NODOOR;
5900 unblock_point(x, y);
5902 /* (probably ought to charge for this damage...) */
5903 if (*in_rooms(x, y, SHOPBASE))
5904 add_damage(x, y, 0L);
5909 You("
\89ð
\8f\9c\82µ
\82½
\81I");
5910 levl[x][y].doormask &= ~D_TRAPPED;
5914 pline("This door was not trapped.");
5916 pline("
\94à
\82Éã©
\82Í
\82È
\82©
\82Á
\82½
\81D");
5920 You("find no traps on the door.");
5922 pline("
\94à
\82Éã©
\82ð
\94
\8c©
\82Å
\82«
\82È
\82©
\82Á
\82½
\81D");
5927 /* for magic unlocking; returns true if targetted monster (which might
5928 be hero) gets untrapped; the trap remains intact */
5930 openholdingtrap(mon, noticed)
5932 boolean *noticed; /* set to true iff hero notices the effect; */
5933 { /* otherwise left with its previous value intact */
5935 char buf[BUFSZ], whichbuf[20];
5936 const char *trapdescr = 0, *which = 0;
5937 boolean ishero = (mon == &youmonst);
5941 if (mon == u.usteed)
5944 t = t_at(ishero ? u.ux : mon->mx, ishero ? u.uy : mon->my);
5946 if (ishero && u.utrap) { /* all u.utraptype values are holding traps */
5948 switch (u.utraptype) {
5950 trapdescr = "molten lava";
5953 /* solidified lava, so not "floor" even if within a room */
5954 trapdescr = "ground";
5957 trapdescr = "your anchor";
5962 trapdescr = 0; /* use defsyms[].explanation */
5965 /* lint suppression in case 't' is unexpectedly Null
5966 or u.utraptype has new value we don't know about yet */
5971 /* if no trap here or it's not a holding trap, we're done */
5972 if (!t || (t->ttyp != BEAR_TRAP && t->ttyp != WEB))
5977 trapdescr = defsyms[trap_to_defsym(t->ttyp)].explanation;
5980 which = t->tseen ? the_your[t->madeby_u]
5981 : index(vowels, *trapdescr) ? "an" : "a";
5983 which = t->tseen ? set_you[t->madeby_u] : "";
5986 which = strcat(strcpy(whichbuf, which), " ");
5994 Sprintf(buf, "%s is", noit_Monnam(u.usteed));
5996 Strcpy(buf, noit_Monnam(u.usteed));
5999 Strcpy(buf, "You are");
6001 Strcpy(buf, "
\82 \82È
\82½");
6003 pline("%s released from %s%s.", buf, which, trapdescr);
6005 pline("%s
\82Í%s%s
\82©
\82ç
\89ð
\95ú
\82³
\82ê
\82½
\81D", buf, which, trapdescr);
6011 if (canspotmon(mon)) {
6014 pline("%s is released from %s%s.", Monnam(mon), which,
6017 pline("%s
\82Í%s%s
\82©
\82ç
\89ð
\95ú
\82³
\82ê
\82½
\81D", Monnam(mon), which,
6020 } else if (cansee(t->tx, t->ty) && t->tseen) {
6024 pline("%s is released from %s%s.", Something, which,
6027 pline("
\89½
\8eÒ
\82©
\82Í%s%s
\82©
\82ç
\89ð
\95ú
\82³
\82ê
\82½
\81D", which,
6030 else /* BEAR_TRAP */
6032 pline("%s%s opens.", upstart(strcpy(buf, which)), trapdescr);
6034 pline("%s%s
\82Í
\8aJ
\82¢
\82½
\81D", which, trapdescr);
6036 /* might pacify monster if adjacent */
6037 if (rn2(2) && distu(mon->mx, mon->my) <= 2)
6038 reward_untrap(t, mon);
6043 /* for magic locking; returns true if targetted monster (which might
6044 be hero) gets hit by a trap (might avoid actually becoming trapped) */
6046 closeholdingtrap(mon, noticed)
6048 boolean *noticed; /* set to true iff hero notices the effect; */
6049 { /* otherwise left with its previous value intact */
6051 unsigned dotrapflags;
6052 boolean ishero = (mon == &youmonst), result;
6056 if (mon == u.usteed)
6058 t = t_at(ishero ? u.ux : mon->mx, ishero ? u.uy : mon->my);
6059 /* if no trap here or it's not a holding trap, we're done */
6060 if (!t || (t->ttyp != BEAR_TRAP && t->ttyp != WEB))
6065 return FALSE; /* already trapped */
6067 dotrapflags = FORCETRAP;
6068 /* dotrap calls mintrap when mounted hero encounters a web */
6070 dotrapflags |= NOWEBMSG;
6072 dotrap(t, dotrapflags);
6074 result = (u.utrap != 0);
6077 return FALSE; /* already trapped */
6078 /* you notice it if you see the trap close/tremble/whatever
6079 or if you sense the monster who becomes trapped */
6080 *noticed = cansee(t->tx, t->ty) || canspotmon(mon);
6082 result = (mintrap(mon) != 0);
6088 /* for magic unlocking; returns true if targetted monster (which might
6089 be hero) gets hit by a trap (target might avoid its effect) */
6091 openfallingtrap(mon, trapdoor_only, noticed)
6093 boolean trapdoor_only;
6094 boolean *noticed; /* set to true iff hero notices the effect; */
6095 { /* otherwise left with its previous value intact */
6097 boolean ishero = (mon == &youmonst), result;
6101 if (mon == u.usteed)
6103 t = t_at(ishero ? u.ux : mon->mx, ishero ? u.uy : mon->my);
6104 /* if no trap here or it's not a falling trap, we're done
6105 (note: falling rock traps have a trapdoor in the ceiling) */
6106 if (!t || ((t->ttyp != TRAPDOOR && t->ttyp != ROCKTRAP)
6107 && (trapdoor_only || (t->ttyp != HOLE && !is_pit(t->ttyp)))))
6112 return FALSE; /* already trapped */
6114 dotrap(t, FORCETRAP);
6115 result = (u.utrap != 0);
6118 return FALSE; /* already trapped */
6119 /* you notice it if you see the trap close/tremble/whatever
6120 or if you sense the monster who becomes trapped */
6121 *noticed = cansee(t->tx, t->ty) || canspotmon(mon);
6122 /* monster will be angered; mintrap doesn't handle that */
6125 result = (mintrap(mon) != 0);
6127 /* mon might now be on the migrating monsters list */
6132 /* only called when the player is doing something to the chest directly */
6134 chest_trap(obj, bodypart, disarm)
6135 register struct obj *obj;
6136 register int bodypart;
6139 register struct obj *otmp = obj, *otmp2;
6144 if (get_obj_location(obj, &cc.x, &cc.y, 0)) /* might be carried */
6145 obj->ox = cc.x, obj->oy = cc.y;
6147 otmp->otrapped = 0; /* trap is one-shot; clear flag first in case
6148 chest kills you and ends up in bones file */
6150 You(disarm ? "set it off!" : "trigger a trap!");
6152 You(disarm ? "
\83X
\83C
\83b
\83`
\82ð
\93ü
\82ê
\82Ä
\82µ
\82Ü
\82Á
\82½
\81I" : "ã©
\82É
\82Ð
\82Á
\82©
\82©
\82Á
\82½
\81I");
6153 display_nhwindow(WIN_MESSAGE, FALSE);
6154 if (Luck > -13 && rn2(13 + Luck) > 7) { /* saved by luck */
6155 /* trap went off, but good luck prevents damage */
6160 msg = "explosive charge is a dud";
6162 msg = "
\94\9a\94
\82Í
\95s
\94
\82¾
\82Á
\82½";
6167 msg = "electric charge is grounded";
6169 msg = "
\93d
\8c\82\82ª
\95ú
\8fo
\82³
\82ê
\82½
\82ª
\83A
\81[
\83X
\82³
\82ê
\82Ä
\82¢
\82½";
6174 msg = "flame fizzles out";
6176 msg = "
\89\8a\82Í
\83V
\83\85\81[
\82Á
\82Æ
\8fÁ
\82¦
\82½";
6182 msg = "poisoned needle misses";
6184 msg = "
\93Å
\90j
\82Í
\8eh
\82³
\82ç
\82È
\82©
\82Á
\82½";
6191 msg = "gas cloud blows away";
6193 msg = "
\83K
\83X
\89_
\82Í
\90\81\82«
\94ò
\82ñ
\82¾";
6196 impossible("chest disarm bug");
6202 pline("But luckily the %s!", msg);
6204 pline("
\82µ
\82©
\82µ
\89^
\82Ì
\82æ
\82¢
\82±
\82Æ
\82É%s
\81I", msg);
6206 switch (rn2(20) ? ((Luck >= 13) ? 0 : rn2(13 - Luck)) : rn2(26)) {
6212 struct monst *shkp = 0;
6214 boolean costly, insider;
6215 register xchar ox = obj->ox, oy = obj->oy;
6217 /* the obj location need not be that of player */
6218 costly = (costly_spot(ox, oy)
6219 && (shkp = shop_keeper(*in_rooms(ox, oy, SHOPBASE)))
6220 != (struct monst *) 0);
6221 insider = (*u.ushops && inside_shop(u.ux, u.uy)
6222 && *in_rooms(ox, oy, SHOPBASE) == *u.ushops);
6225 pline("%s!", Tobjnam(obj, "explode"));
6227 pline("%s
\82Í
\94\9a\94
\82µ
\82½
\81I", xname(obj));
6229 Sprintf(buf, "exploding %s", xname(obj));
6231 Sprintf(buf, "%s
\82Ì
\94\9a\94
\82Å", xname(obj));
6234 loss += stolen_value(obj, ox, oy, (boolean) shkp->mpeaceful,
6236 delete_contents(obj);
6237 /* unpunish() in advance if either ball or chain (or both)
6238 is going to be destroyed */
6239 if (Punished && ((uchain->ox == u.ux && uchain->oy == u.uy)
6240 || (uball->where == OBJ_FLOOR
6241 && uball->ox == u.ux && uball->oy == u.uy)))
6244 for (otmp = level.objects[u.ux][u.uy]; otmp; otmp = otmp2) {
6245 otmp2 = otmp->nexthere;
6247 loss += stolen_value(otmp, otmp->ox, otmp->oy,
6248 (boolean) shkp->mpeaceful, TRUE);
6252 losehp(Maybe_Half_Phys(d(6, 6)), buf, KILLED_BY_AN);
6253 exercise(A_STR, FALSE);
6254 if (costly && loss) {
6257 You("owe %ld %s for objects destroyed.", loss,
6260 You("
\8aí
\95¨
\94j
\91¹
\82Å%ld%s
\82Ì
\8eØ
\82è
\82ð
\82Â
\82
\82Á
\82½
\81D", loss,
6265 You("caused %ld %s worth of damage!", loss,
6268 You("%ld%s
\95ª
\82Ì
\91¹
\8aQ
\82ð
\88ø
\82«
\82¨
\82±
\82µ
\82½
\81I", loss,
6271 make_angry_shk(shkp, ox, oy);
6281 pline("A cloud of noxious gas billows from %s.", the(xname(obj)));
6283 pline("
\97L
\93Å
\83K
\83X
\82ª%s
\82©
\82ç
\89Q
\82Ü
\82¢
\82½
\81D", the(xname(obj)));
6285 poisoned("gas cloud", A_STR, "cloud of poison gas", 15, FALSE);
6287 poisoned("
\83K
\83X
\89_", A_STR, "
\83K
\83X
\89_", 15, FALSE);
6288 exercise(A_CON, FALSE);
6295 You_feel("a needle prick your %s.", body_part(bodypart));
6297 You("%s
\83`
\83N
\83b
\82Æ
\82¢
\82¤
\92É
\82Ý
\82ð
\8a´
\82¶
\82½
\81D", body_part(bodypart));
6299 poisoned("needle", A_CON, "poisoned needle", 10, FALSE);
6301 poisoned("
\90j", A_CON, "
\93Å
\90j", 10, FALSE);
6302 exercise(A_CON, FALSE);
6316 You("are jolted by a surge of electricity!");
6318 You("
\93d
\8bC
\83V
\83\87\83b
\83N
\82ð
\82
\82ç
\82Á
\82½
\81I");
6319 if (Shock_resistance) {
6320 shieldeff(u.ux, u.uy);
6322 You("don't seem to be affected.");
6324 pline("
\82µ
\82©
\82µ
\82 \82È
\82½
\82Í
\89e
\8b¿
\82ð
\8eó
\82¯
\82È
\82¢
\81D");
6328 destroy_item(RING_CLASS, AD_ELEC);
6329 destroy_item(WAND_CLASS, AD_ELEC);
6332 losehp(dmg, "electric shock", KILLED_BY_AN);
6334 losehp(dmg, "
\93d
\8bC
\83V
\83\87\83b
\83N
\82Å", KILLED_BY_AN);
6342 pline("Suddenly you are frozen in place!");
6344 pline("
\93Ë
\91R
\82»
\82Ì
\8fê
\82Å
\93®
\82¯
\82È
\82
\82È
\82Á
\82½
\81I");
6347 multi_reason = "frozen by a trap";
6349 multi_reason = "ã©
\82Å
\8dd
\92¼
\82µ
\82Ä
\82¢
\82é
\8e\9e\82É";
6350 exercise(A_DEX, FALSE);
6351 nomovemsg = You_can_move_again;
6354 You("momentarily stiffen.");
6356 You("
\88ê
\8fu
\8dd
\92¼
\82µ
\82½
\81D");
6362 pline("A cloud of %s gas billows from %s.",
6363 Blind ? blindgas[rn2(SIZE(blindgas))] : rndcolor(),
6366 pline("%s
\83K
\83X
\89_
\82ª%s
\82Ì
\92ê
\82Å
\89Q
\82Ü
\82¢
\82½
\81D",
6367 Blind ? blindgas[rn2(SIZE(blindgas))] :
6368 jconj_adj(rndcolor()), xname(obj));
6373 pline("What a groovy feeling!");
6375 pline("
\82È
\82ñ
\82Ä
\91f
\93G
\82È
\82ñ
\82¾
\81I");
6378 You("%s%s...", stagger(youmonst.data, "stagger"),
6379 Halluc_resistance ? ""
6380 : Blind ? " and get dizzy"
6381 : " and your vision blurs");
6383 You("
\82
\82ç
\82
\82ç
\82µ%s
\82½...",
6384 Halluc_resistance ? ""
6385 : Blind ? "
\81C
\82ß
\82Ü
\82¢
\82ª
\82µ"
6386 : "
\81C
\8ci
\90F
\82ª
\82Ú
\82â
\82¯
\82Ä
\82«");
6389 make_stunned((HStun & TIMEOUT) + (long) rn1(7, 16), FALSE);
6390 (void) make_hallucinated(
6391 (HHallucination & TIMEOUT) + (long) rn1(5, 16), FALSE, 0L);
6394 impossible("bad chest trap");
6397 bot(); /* to get immediate botl re-display */
6407 register struct trap *trap = ftrap;
6410 if (trap->tx == x && trap->ty == y)
6414 return (struct trap *) 0;
6419 register struct trap *trap;
6421 register struct trap *ttmp;
6423 clear_conjoined_pits(trap);
6424 if (trap == ftrap) {
6425 ftrap = ftrap->ntrap;
6427 for (ttmp = ftrap; ttmp; ttmp = ttmp->ntrap)
6428 if (ttmp->ntrap == trap)
6431 panic("deltrap: no preceding trap!");
6432 ttmp->ntrap = trap->ntrap;
6434 if (Sokoban && (trap->ttyp == PIT || trap->ttyp == HOLE))
6435 maybe_finish_sokoban();
6440 conjoined_pits(trap2, trap1, u_entering_trap2)
6441 struct trap *trap2, *trap1;
6442 boolean u_entering_trap2;
6444 int dx, dy, diridx, adjidx;
6446 if (!trap1 || !trap2)
6448 if (!isok(trap2->tx, trap2->ty) || !isok(trap1->tx, trap1->ty)
6449 || !is_pit(trap2->ttyp)
6450 || !is_pit(trap1->ttyp)
6451 || (u_entering_trap2 && !(u.utrap && u.utraptype == TT_PIT)))
6453 dx = sgn(trap2->tx - trap1->tx);
6454 dy = sgn(trap2->ty - trap1->ty);
6455 for (diridx = 0; diridx < 8; diridx++)
6456 if (xdir[diridx] == dx && ydir[diridx] == dy)
6458 /* diridx is valid if < 8 */
6460 adjidx = (diridx + 4) % 8;
6461 if ((trap1->conjoined & (1 << diridx))
6462 && (trap2->conjoined & (1 << adjidx)))
6469 clear_conjoined_pits(trap)
6472 int diridx, adjidx, x, y;
6475 if (trap && is_pit(trap->ttyp)) {
6476 for (diridx = 0; diridx < 8; ++diridx) {
6477 if (trap->conjoined & (1 << diridx)) {
6478 x = trap->tx + xdir[diridx];
6479 y = trap->ty + ydir[diridx];
6481 && (t = t_at(x, y)) != 0
6482 && is_pit(t->ttyp)) {
6483 adjidx = (diridx + 4) % 8;
6484 t->conjoined &= ~(1 << adjidx);
6486 trap->conjoined &= ~(1 << diridx);
6493 adj_nonconjoined_pit(adjtrap)
6494 struct trap *adjtrap;
6496 struct trap *trap_with_u = t_at(u.ux0, u.uy0);
6498 if (trap_with_u && adjtrap && u.utrap && u.utraptype == TT_PIT
6499 && is_pit(trap_with_u->ttyp) && is_pit(adjtrap->ttyp)) {
6502 for (idx = 0; idx < 8; idx++) {
6503 if (xdir[idx] == u.dx && ydir[idx] == u.dy)
6512 * Mark all neighboring pits as conjoined pits.
6513 * (currently not called from anywhere)
6516 join_adjacent_pits(trap)
6524 for (diridx = 0; diridx < 8; ++diridx) {
6525 x = trap->tx + xdir[diridx];
6526 y = trap->ty + ydir[diridx];
6528 if ((t = t_at(x, y)) != 0 && is_pit(t->ttyp)) {
6529 trap->conjoined |= (1 << diridx);
6530 join_adjacent_pits(t);
6532 trap->conjoined &= ~(1 << diridx);
6539 * Returns TRUE if you escaped a pit and are standing on the precipice.
6542 uteetering_at_seen_pit(trap)
6545 if (trap && trap->tseen && (!u.utrap || u.utraptype != TT_PIT)
6546 && is_pit(trap->ttyp))
6552 /* Destroy a trap that emanates from the floor. */
6555 register struct trap *ttmp;
6557 /* some of these are arbitrary -dlc */
6558 if (ttmp && ((ttmp->ttyp == SQKY_BOARD) || (ttmp->ttyp == BEAR_TRAP)
6559 || (ttmp->ttyp == LANDMINE) || (ttmp->ttyp == FIRE_TRAP)
6560 || is_pit(ttmp->ttyp)
6561 || is_hole(ttmp->ttyp)
6562 || (ttmp->ttyp == TELEP_TRAP) || (ttmp->ttyp == LEVEL_TELEP)
6563 || (ttmp->ttyp == WEB) || (ttmp->ttyp == MAGIC_TRAP)
6564 || (ttmp->ttyp == ANTI_MAGIC))) {
6565 register struct monst *mtmp;
6567 if (ttmp->tx == u.ux && ttmp->ty == u.uy) {
6568 if (u.utraptype != TT_BURIEDBALL)
6570 } else if ((mtmp = m_at(ttmp->tx, ttmp->ty)) != 0) {
6579 /* used for doors (also tins). can be used for anything else that opens. */
6581 b_trapped(item, bodypart)
6585 int lvl = level_difficulty(),
6586 dmg = rnd(5 + (lvl < 5 ? lvl : 2 + lvl / 2));
6589 pline("KABOOM!! %s was booby-trapped!", The(item));
6591 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);
6594 losehp(Maybe_Half_Phys(dmg), "explosion", KILLED_BY_AN);
6596 losehp(Maybe_Half_Phys(dmg), "
\83u
\81[
\83r
\81[
\83g
\83\89\83b
\83v
\82Ì
\94\9a\94
\82Å", KILLED_BY_AN);
6597 exercise(A_STR, FALSE);
6599 exercise(A_CON, FALSE);
6600 make_stunned((HStun & TIMEOUT) + (long) dmg, TRUE);
6603 /* Monster is hit by trap. */
6604 /* Note: doesn't work if both obj and d_override are null */
6606 thitm(tlev, mon, obj, d_override, nocorpse)
6614 boolean trapkilled = FALSE;
6619 strike = (find_mac(mon) + tlev + obj->spe <= rnd(20));
6621 strike = (find_mac(mon) + tlev <= rnd(20));
6623 /* Actually more accurate than thitu, which doesn't take
6624 * obj->spe into account.
6627 if (obj && cansee(mon->mx, mon->my))
6629 pline("%s is almost hit by %s!", Monnam(mon), doname(obj));
6631 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));
6635 if (obj && cansee(mon->mx, mon->my))
6637 pline("%s is hit by %s!", Monnam(mon), doname(obj));
6639 pline("%s
\82ª%s
\82É
\96½
\92\86\82µ
\82½
\81I", doname(obj), Monnam(mon));
6643 dam = dmgval(obj, mon);
6648 if (DEADMONSTER(mon)) {
6649 int xx = mon->mx, yy = mon->my;
6651 monkilled(mon, "", nocorpse ? -AD_RBRE : AD_PHYS);
6652 if (DEADMONSTER(mon)) {
6658 if (obj && (!strike || d_override)) {
6659 place_object(obj, mon->mx, mon->my);
6674 return (boolean) (u.usleep
6676 && (!strncmp(nomovemsg, "You awake", 9)
6677 || !strncmp(nomovemsg, "You regain con", 14)
6678 || !strncmp(nomovemsg, "You are consci", 14))));
6680 /*JP 3.6.0
\82Å
\82Ì
\8fo
\8c»
\88Ê
\92u/
\89ñ
\90\94
6681 "You awake" : potion.c(1)
6682 "You regain con": eat.c(1)
6683 "You are consci": eat.c(1)
6685 return (boolean) (u.usleep
6687 && (!strncmp(nomovemsg, "
\96Ú
\82ª
\82³
\82ß
\82½
\82ª
\93ª
\92É", 18)
6688 || !strncmp(nomovemsg, "
\82 \82È
\82½
\82Í
\90³
\8bC
\82Ã
\82¢
\82½", 18)
6689 || !strncmp(nomovemsg, "
\82 \82È
\82½
\82Í
\82Ü
\82½
\90³
\8bC
\82Ã", 18))));
6694 static const char lava_killer[] = "molten lava";
6696 static const char lava_killer[] = "
\82Ç
\82ë
\82Ç
\82ë
\82Ì
\97n
\8aâ
\82Å";
6701 register struct obj *obj, *obj2;
6702 int dmg = d(6, 6); /* only applicable for water walking */
6703 boolean usurvive, boil_away;
6706 if (likes_lava(youmonst.data))
6709 usurvive = Fire_resistance || (Wwalking && dmg < u.uhp);
6711 * A timely interrupt might manage to salvage your life
6712 * but not your gear. For scrolls and potions this
6713 * will destroy whole stacks, where fire resistant hero
6714 * survivor only loses partial stacks via destroy_item().
6716 * Flag items to be destroyed before any messages so
6717 * that player causing hangup at --More-- won't get an
6718 * emergency save file created before item destruction.
6721 for (obj = invent; obj; obj = obj->nobj)
6722 if ((is_organic(obj) || obj->oclass == POTION_CLASS)
6723 && !obj->oerodeproof
6724 && objects[obj->otyp].oc_oprop != FIRE_RES
6725 && obj->otyp != SCR_FIRE && obj->otyp != SPE_FIREBALL
6726 && !obj_resists(obj, 0, 0)) /* for invocation items */
6729 /* Check whether we should burn away boots *first* so we know whether to
6730 * make the player sink into the lava. Assumption: water walking only
6733 if (uarmf && is_organic(uarmf) && !uarmf->oerodeproof) {
6736 pline("%s into flame!", Yobjnam2(obj, "burst"));
6738 Your("%s
\82Í
\94R
\82¦
\82½
\81I", xname(obj));
6739 iflags.in_lava_effects++; /* (see above) */
6742 iflags.in_lava_effects--;
6745 if (!Fire_resistance) {
6748 pline_The("%s here burns you!", hliquid("lava"));
6750 pline("%s
\82ª
\82 \82È
\82½
\82ð
\8fÄ
\82«
\82Â
\82
\82µ
\82½
\81I", hliquid("
\97n
\8aâ"));
6752 losehp(dmg, lava_killer, KILLED_BY); /* lava damage */
6757 You("fall into the %s!", hliquid("lava"));
6759 You("%s
\82É
\97\8e\82¿
\82½
\81I", hliquid("
\97n
\8aâ"));
6761 usurvive = Lifesaved || discover;
6765 /* prevent remove_worn_item() -> Boots_off(WATER_WALKING_BOOTS) ->
6766 spoteffects() -> lava_effects() recursion which would
6767 successfully delete (via useupall) the no-longer-worn boots;
6768 once recursive call returned, we would try to delete them again
6769 here in the outer call (and access stale memory, probably panic) */
6770 iflags.in_lava_effects++;
6772 for (obj = invent; obj; obj = obj2) {
6774 /* above, we set in_use for objects which are to be destroyed */
6775 if (obj->otyp == SPE_BOOK_OF_THE_DEAD && !Blind) {
6778 pline("%s glows a strange %s, but remains intact.",
6779 The(xname(obj)), hcolor("dark red"));
6781 pline("%s
\82Í
\95s
\8ev
\8bc
\82É%s
\8bP
\82¢
\82½
\82ª
\81C
\96³
\8f\9d\82Ì
\82æ
\82¤
\82¾
\81D",
6782 xname(obj), jconj_adj(hcolor("
\88Ã
\90Ô
\90F
\82Ì")));
6784 } else if (obj->in_use) {
6785 if (obj->owornmask) {
6788 pline("%s into flame!", Yobjnam2(obj, "burst"));
6790 Your("%s
\82Í
\94R
\82¦
\82½
\81I", xname(obj));
6791 remove_worn_item(obj, TRUE);
6797 iflags.in_lava_effects--;
6800 boil_away = (u.umonnum == PM_WATER_ELEMENTAL
6801 || u.umonnum == PM_STEAM_VORTEX
6802 || u.umonnum == PM_FOG_CLOUD);
6805 /* killer format and name are reconstructed every iteration
6806 because lifesaving resets them */
6807 killer.format = KILLED_BY;
6808 Strcpy(killer.name, lava_killer);
6810 You("%s...", boil_away ? "boil away" : "burn to a crisp");
6812 You("%s
\81D
\81D
\81D", boil_away ? "
\95¦
\93«
\82µ
\82½" : "
\94R
\82¦
\82Ä
\83p
\83\8a\83p
\83\8a\82É
\82È
\82Á
\82½");
6814 if (safe_teleds(TRUE))
6815 break; /* successful life-save */
6816 /* nowhere safe to land; repeat burning loop */
6818 pline("You're still burning.");
6820 You("
\82Ü
\82¾
\94R
\82¦
\82Ä
\82¢
\82é
\81D");
6823 You("find yourself back on solid %s.", surface(u.ux, u.uy));
6825 You("
\82¢
\82Â
\82Ì
\82Ü
\82É
\82©
\8cÅ
\82¢%s
\82É
\96ß
\82Á
\82Ä
\82¢
\82½
\81D", surface(u.ux, u.uy));
6827 } else if (!Wwalking && (!u.utrap || u.utraptype != TT_LAVA)) {
6828 boil_away = !Fire_resistance;
6829 /* if not fire resistant, sink_into_lava() will quickly be fatal;
6830 hero needs to escape immediately */
6831 set_utrap((unsigned) (rn1(4, 4) + ((boil_away ? 2 : rn1(4, 12)) << 8)),
6834 You("sink into the %s%s!", hliquid("lava"),
6835 !boil_away ? ", but it only burns slightly"
6836 : " and are about to be immolated");
6838 You("%s
\82É
\92¾
\82ñ%s
\82¾
\81I", hliquid("
\97n
\8aâ"),
6839 !boil_away ? "
\82¾
\82ª
\81C
\82¿
\82å
\82Á
\82Æ
\8fÅ
\82°
\82½
\82¾
\82¯"
6840 : "
\82Å
\8fÄ
\82«
\8eE
\82³
\82ê
\82»
\82¤");
6843 losehp(!boil_away ? 1 : (u.uhp / 2), lava_killer,
6844 KILLED_BY); /* lava damage */
6848 destroy_item(SCROLL_CLASS, AD_FIRE);
6849 destroy_item(SPBOOK_CLASS, AD_FIRE);
6850 destroy_item(POTION_CLASS, AD_FIRE);
6854 /* called each turn when trapped in lava */
6859 static const char sink_deeper[] = "You sink deeper into the lava.";
6861 static const char sink_deeper[] = "
\82 \82È
\82½
\82Í
\82æ
\82è
\90[
\82
\97n
\8aâ
\82É
\92¾
\82ñ
\82¾
\81D";
6863 if (!u.utrap || u.utraptype != TT_LAVA) {
6864 ; /* do nothing; this shouldn't happen */
6865 } else if (!is_lava(u.ux, u.uy)) {
6866 reset_utrap(FALSE); /* this shouldn't happen either */
6867 } else if (!u.uinvulnerable) {
6868 /* ordinarily we'd have to be fire resistant to survive long
6869 enough to become stuck in lava, but it can happen without
6870 resistance if water walking boots allow survival and then
6871 get burned up; u.utrap time will be quite short in that case */
6872 if (!Fire_resistance)
6873 u.uhp = (u.uhp + 2) / 3;
6875 u.utrap -= (1 << 8);
6876 if (u.utrap < (1 << 8)) {
6877 killer.format = KILLED_BY;
6879 Strcpy(killer.name, "molten lava");
6881 Strcpy(killer.name, "
\82Ç
\82ë
\82Ç
\82ë
\82Ì
\97n
\8aâ
\82Å");
6883 You("sink below the surface and die.");
6885 You("
\8a®
\91S
\82É
\97n
\8aâ
\82Ì
\92\86\82É
\92¾
\82ñ
\82Å
\81A
\8e\80\82É
\82Ü
\82µ
\82½
\81D
\81D
\81D");
6886 burn_away_slime(); /* add insult to injury? */
6888 /* can only get here via life-saving; try to get away from lava */
6890 /* levitation or flight have become unblocked, otherwise Tport */
6891 if (!Levitation && !Flying)
6892 (void) safe_teleds(TRUE);
6893 } else if (!u.umoved) {
6894 /* can't fully turn into slime while in lava, but might not
6895 have it be burned away until you've come awfully close */
6896 if (Slimed && rnd(10 - 1) >= (int) (Slimed & TIMEOUT)) {
6907 /* called when something has been done (breaking a boulder, for instance)
6908 which entails a luck penalty if performed on a sokoban level */
6914 /* TODO: issue some feedback so that player can learn that whatever
6915 he/she just did is a naughty thing to do in sokoban and should
6916 probably be avoided in future....
6917 Caveat: doing this might introduce message sequencing issues,
6918 depending upon feedback during the various actions which trigger
6919 Sokoban luck penalties. */
6923 /* called when a trap has been deleted or had its ttyp replaced */
6925 maybe_finish_sokoban()
6929 if (Sokoban && !in_mklev) {
6930 /* scan all remaining traps, ignoring any created by the hero;
6931 if this level has no more pits or holes, the current sokoban
6932 puzzle has been solved */
6933 for (t = ftrap; t; t = t->ntrap) {
6936 if (t->ttyp == PIT || t->ttyp == HOLE)
6940 /* we've passed the last trap without finding a pit or hole;
6941 clear the sokoban_rules flag so that luck penalties for
6942 things like breaking boulders or jumping will no longer
6943 be given, and restrictions on diagonal moves are lifted */
6944 Sokoban = 0; /* clear level.flags.sokoban_rules */
6945 /* TODO: give some feedback about solving the sokoban puzzle
6946 (perhaps say "congratulations" in Japanese?) */