1 /* NetHack 3.6 trap.c $NHDT-Date: 1576638501 2019/12/18 03:08:21 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.329 $ */
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-2020 */
9 /* JNetHack may be freely redistributed. See license for details. */
13 extern const char *const destroy_strings[][3]; /* from zap.c */
15 STATIC_DCL boolean FDECL(keep_saddle_with_steedcorpse, (unsigned, struct obj *,
17 STATIC_DCL struct obj *FDECL(t_missile, (int, struct trap *));
18 STATIC_DCL char *FDECL(trapnote, (struct trap *, BOOLEAN_P));
19 STATIC_DCL int FDECL(steedintrap, (struct trap *, struct obj *));
20 STATIC_DCL void FDECL(launch_drop_spot, (struct obj *, XCHAR_P, XCHAR_P));
21 STATIC_DCL int FDECL(mkroll_launch, (struct trap *, XCHAR_P, XCHAR_P,
23 STATIC_DCL boolean FDECL(isclearpath, (coord *, int, SCHAR_P, SCHAR_P));
24 STATIC_DCL void FDECL(dofiretrap, (struct obj *));
25 STATIC_DCL void NDECL(domagictrap);
26 STATIC_DCL boolean FDECL(emergency_disrobe, (boolean *));
27 STATIC_DCL int FDECL(untrap_prob, (struct trap *));
28 STATIC_DCL void FDECL(move_into_trap, (struct trap *));
29 STATIC_DCL int FDECL(try_disarm, (struct trap *, BOOLEAN_P));
30 STATIC_DCL void FDECL(reward_untrap, (struct trap *, struct monst *));
31 STATIC_DCL int FDECL(disarm_holdingtrap, (struct trap *));
32 STATIC_DCL int FDECL(disarm_landmine, (struct trap *));
33 STATIC_DCL int FDECL(disarm_squeaky_board, (struct trap *));
34 STATIC_DCL int FDECL(disarm_shooting_trap, (struct trap *, int));
35 STATIC_DCL void FDECL(clear_conjoined_pits, (struct trap *));
36 STATIC_DCL boolean FDECL(adj_nonconjoined_pit, (struct trap *));
37 STATIC_DCL int FDECL(try_lift, (struct monst *, struct trap *, int,
39 STATIC_DCL int FDECL(help_monster_out, (struct monst *, struct trap *));
41 STATIC_DCL void FDECL(join_adjacent_pits, (struct trap *));
43 STATIC_DCL boolean FDECL(thitm, (int, struct monst *, struct obj *, int,
45 STATIC_DCL void NDECL(maybe_finish_sokoban);
47 /* mintrap() should take a flags argument, but for time being we use this */
48 STATIC_VAR int force_mintrap = 0;
51 STATIC_VAR const char *const a_your[2] = { "a", "your" };
52 STATIC_VAR const char *const A_Your[2] = { "A", "Your" };
53 STATIC_VAR const char tower_of_flame[] = "tower of flame";
54 STATIC_VAR const char *const A_gush_of_water_hits = "A gush of water hits";
57 STATIC_VAR const char *const blindgas[6] = { "humid", "odorless",
58 "pungent", "chilling",
61 STATIC_VAR const char * const blindgas[6] = {
62 "
\82Þ
\82µ
\82Þ
\82µ
\82·
\82é", "
\96³
\8fL
\82Ì",
63 "
\8eh
\8c\83\8fL
\82Ì
\82·
\82é", "
\97â
\82½
\82¢",
64 "
\83c
\83\93\82Æ
\82µ
\82½
\82É
\82¨
\82¢
\82Ì", "
\82Ð
\82è
\82Ð
\82è
\82·
\82é"
68 const char *set_you[2] = { "", "
\82 \82È
\82½
\82Ì
\8ed
\8a|
\82¯
\82½" };
69 STATIC_VAR const char *dig_you[2] = { "", "
\82 \82È
\82½
\82ª
\8c@
\82Á
\82½" };
70 STATIC_VAR const char *web_you[2] = { "", "
\82 \82È
\82½
\82ª
\92£
\82Á
\82½" };
73 /* called when you're hit by fire (dofiretrap,buzz,zapyourself,explode);
74 returns TRUE if hit on torso */
86 hitting_u = (victim == &youmonst);
88 /* burning damage may dry wet towel */
89 item = hitting_u ? carrying(TOWEL) : m_carrying(victim, TOWEL);
91 if (is_wet_towel(item)) {
93 dry_a_towel(item, rn2(oldspe + 1), TRUE);
94 if (item->spe != oldspe)
95 break; /* stop once one towel has been affected */
100 #define burn_dmg(obj, descr) erode_obj(obj, descr, ERODE_BURN, EF_GREASE)
104 item = hitting_u ? uarmh : which_armor(victim, W_ARMH);
106 mat_idx = objects[item->otyp].oc_material;
108 Sprintf(buf, "%s %s", materialnm[mat_idx],
109 helm_simple_name(item));
111 Sprintf(buf, "%s
\82Ì%s", materialnm[mat_idx],
112 helm_simple_name(item));
116 if (!burn_dmg(item, item ? buf : "helmet"))
118 if (!burn_dmg(item, item ? buf : "
\8a\95"))
122 item = hitting_u ? uarmc : which_armor(victim, W_ARMC);
124 (void) burn_dmg(item, cloak_simple_name(item));
127 item = hitting_u ? uarm : which_armor(victim, W_ARM);
129 (void) burn_dmg(item, xname(item));
132 item = hitting_u ? uarmu : which_armor(victim, W_ARMU);
135 (void) burn_dmg(item, "shirt");
137 (void) burn_dmg(item, "
\83V
\83\83\83c");
140 item = hitting_u ? uarms : which_armor(victim, W_ARMS);
142 if (!burn_dmg(item, "wooden shield"))
144 if (!burn_dmg(item, "
\96Ø
\82Ì
\8f\82"))
148 item = hitting_u ? uarmg : which_armor(victim, W_ARMG);
150 if (!burn_dmg(item, "gloves"))
152 if (!burn_dmg(item, "
\8f¬
\8eè"))
156 item = hitting_u ? uarmf : which_armor(victim, W_ARMF);
158 if (!burn_dmg(item, "boots"))
160 if (!burn_dmg(item, "
\8cC"))
164 break; /* Out of while loop */
171 /* Generic erode-item function.
172 * "ostr", if non-null, is an alternate string to print instead of the
174 * "type" is an ERODE_* value for the erosion type
175 * "flags" is an or-ed list of EF_* flags
177 * Returns an erosion return value (ER_*)
180 erode_obj(otmp, ostr, type, ef_flags)
181 register struct obj *otmp;
186 static NEARDATA const char
188 *const action[] = { "smoulder", "rust", "rot", "corrode" },
190 *const action[] = { "
\82
\82·
\82Ô
\82Á
\82½", "
\8eK
\82Ñ
\82½", "
\95\85\82Á
\82½", "
\95\85\90H
\82µ
\82½" },
192 *const msg[] = { "burnt", "rusted", "rotten", "corroded" },
194 *const msg[] = { "
\8fÅ
\82°
\82½", "
\8eK
\82Ñ
\82½", "
\95\85\82Á
\82½", "
\95\85\90H
\82µ
\82½" },
196 *const bythe[] = { "heat", "oxidation", "decay", "corrosion" };
198 *const bythe[] = { "
\94M", "
\8e_
\89»", "
\95\85\94s", "
\95\85\90H" };
199 boolean vulnerable = FALSE, is_primary = TRUE,
200 check_grease = (ef_flags & EF_GREASE) ? TRUE : FALSE,
201 print = (ef_flags & EF_VERBOSE) ? TRUE : FALSE,
202 uvictim, vismon, visobj;
203 int erosion, cost_type;
204 struct monst *victim;
209 victim = carried(otmp) ? &youmonst : mcarried(otmp) ? otmp->ocarry : NULL;
210 uvictim = (victim == &youmonst);
211 vismon = victim && (victim != &youmonst) && canseemon(victim);
212 /* Is bhitpos correct here? Ugh. */
213 visobj = !victim && cansee(bhitpos.x, bhitpos.y);
217 vulnerable = is_flammable(otmp);
218 check_grease = FALSE;
219 cost_type = COST_BURN;
222 vulnerable = is_rustprone(otmp);
223 cost_type = COST_RUST;
226 vulnerable = is_rottable(otmp);
227 check_grease = FALSE;
229 cost_type = COST_ROT;
232 vulnerable = is_corrodeable(otmp);
234 cost_type = COST_CORRODE;
237 impossible("Invalid erosion type in erode_obj");
240 erosion = is_primary ? otmp->oeroded : otmp->oeroded2;
244 /* 'visobj' messages insert "the"; probably ought to switch to the() */
245 if (visobj && !(uvictim || vismon) && !strncmpi(ostr, "the ", 4))
248 if (check_grease && otmp->greased) {
249 grease_protect(otmp, ostr, victim);
251 } else if (!erosion_matters(otmp)) {
253 } else if (!vulnerable || (otmp->oerodeproof && otmp->rknown)) {
254 if (flags.verbose && print && (uvictim || vismon))
256 pline("%s %s %s not affected by %s.",
257 uvictim ? "Your" : s_suffix(Monnam(victim)),
258 ostr, vtense(ostr, "are"), bythe[type]);
260 pline("%s%s
\82Í%s
\82Ì
\89e
\8b¿
\82ð
\8eó
\82¯
\82È
\82©
\82Á
\82½
\81D",
261 uvictim ? "
\82 \82È
\82½
\82Ì" : s_suffix(Monnam(victim)),
265 } else if (otmp->oerodeproof || (otmp->blessed && !rnl(4))) {
266 if (flags.verbose && (print || otmp->oerodeproof)
267 && (uvictim || vismon || visobj))
269 pline("Somehow, %s %s %s not affected by the %s.",
271 : !vismon ? "the" /* visobj */
272 : s_suffix(mon_nam(victim)),
273 ostr, vtense(ostr, "are"), bythe[type]);
275 pline("
\82È
\82º
\82©
\81C%s%s
\82Í%s
\82Ì
\89e
\8b¿
\82ð
\8eó
\82¯
\82È
\82©
\82Á
\82½
\81D",
276 uvictim ? "
\82 \82È
\82½
\82Ì"
277 : !vismon ? "" /* visobj */
278 : s_suffix(mon_nam(victim)),
281 /* We assume here that if the object is protected because it
282 * is blessed, it still shows some minor signs of wear, and
283 * the hero can distinguish this from an object that is
284 * actually proof against damage.
286 if (otmp->oerodeproof) {
288 if (victim == &youmonst)
293 } else if (erosion < MAX_ERODE) {
295 const char *adverb = (erosion + 1 == MAX_ERODE)
297 : erosion ? " further" : "";
299 const char *adverb = (erosion + 1 == MAX_ERODE)
301 : erosion ? "
\82³
\82ç
\82É" : "";
304 if (uvictim || vismon || visobj)
308 : !vismon ? "The" /* visobj */
309 : s_suffix(Monnam(victim)),
310 ostr, vtense(ostr, action[type]), adverb);
312 pline("%s%s
\82Í%s%s!",
313 uvictim ? "
\82 \82È
\82½
\82Ì"
314 : !vismon ? "" /* visobj */
315 : s_suffix(Monnam(victim)),
316 ostr, adverb, action[type]);
319 if (ef_flags & EF_PAY)
320 costly_alteration(otmp, cost_type);
327 if (victim == &youmonst)
331 } else if (ef_flags & EF_DESTROY) {
332 if (uvictim || vismon || visobj)
334 pline("%s %s %s away!",
336 : !vismon ? "The" /* visobj */
337 : s_suffix(Monnam(victim)),
338 ostr, vtense(ostr, action[type]));
340 pline("%s%s
\82Í
\8a®
\91S
\82É%s
\81I",
341 uvictim ? "
\82 \82È
\82½
\82Ì"
342 : !vismon ? "" /* visobj */
343 : s_suffix(Monnam(victim)),
347 if (ef_flags & EF_PAY)
348 costly_alteration(otmp, cost_type);
354 if (flags.verbose && print) {
357 Your("%s %s completely %s.",
358 ostr, vtense(ostr, Blind ? "feel" : "look"), msg[type]);
360 Your("%s
\82Í
\8a®
\91S
\82É%s%s
\81D",
361 ostr, msg[type], Blind ? "
\82æ
\82¤
\82¾" : "");
363 else if (vismon || visobj)
365 pline("%s %s %s completely %s.",
366 !vismon ? "The" : s_suffix(Monnam(victim)),
367 ostr, vtense(ostr, "look"), msg[type]);
369 pline("%s%s
\82Í
\8a®
\91S
\82É%s
\82æ
\82¤
\82¾
\81D",
370 !vismon ? "" : s_suffix(Monnam(victim)),
378 /* Protect an item from erosion with grease. Returns TRUE if the grease
382 grease_protect(otmp, ostr, victim)
383 register struct obj *otmp;
385 struct monst *victim;
388 static const char txt[] = "protected by the layer of grease!";
390 static const char txt[] = "
\96û
\82Ì
\93h
\82è
\82±
\82Ý
\82É
\82æ
\82Á
\82Ä
\8eç
\82ç
\82ê
\82Ä
\82¢
\82é
\81I";
391 boolean vismon = victim && (victim != &youmonst) && canseemon(victim);
394 if (victim == &youmonst)
396 Your("%s %s %s", ostr, vtense(ostr, "are"), txt);
398 Your("%s
\82Í%s", ostr, txt);
401 pline("%s's %s %s %s", Monnam(victim),
402 ostr, vtense(ostr, "are"), txt);
404 pline("%s
\82Ì%s
\82Í%s", Monnam(victim), ostr, txt);
406 } else if (victim == &youmonst || vismon) {
408 pline("%s %s", Yobjnam2(otmp, "are"), txt);
410 Your("%s
\82Í%s",xname(otmp), txt);
416 pline_The("grease dissolves.");
418 pline("
\96û
\82Í
\82Í
\82°
\82Ä
\82µ
\82Ü
\82Á
\82½
\81D");
430 static union vlaunchinfo zero_vl;
433 struct rm *lev = &levl[x][y];
435 if ((ttmp = t_at(x, y)) != 0) {
436 if (ttmp->ttyp == MAGIC_PORTAL || ttmp->ttyp == VIBRATING_SQUARE)
437 return (struct trap *) 0;
439 if (u.utrap && x == u.ux && y == u.uy
440 && ((u.utraptype == TT_BEARTRAP && typ != BEAR_TRAP)
441 || (u.utraptype == TT_WEB && typ != WEB)
442 || (u.utraptype == TT_PIT && !is_pit(typ))))
444 /* old <tx,ty> remain valid */
445 } else if (IS_FURNITURE(lev->typ)
446 && (!IS_GRAVE(lev->typ) || (typ != PIT && typ != HOLE))) {
447 /* no trap on top of furniture (caller usually screens the
448 location to inhibit this, but wizard mode wishing doesn't) */
449 return (struct trap *) 0;
453 (void) memset((genericptr_t)ttmp, 0, sizeof(struct trap));
458 /* [re-]initialize all fields except ntrap (handled below) and <tx,ty> */
460 ttmp->launch.x = ttmp->launch.y = -1; /* force error if used before set */
461 ttmp->dst.dnum = ttmp->dst.dlevel = -1;
464 ttmp->tseen = (typ == HOLE); /* hide non-holes */
469 int tavail[12], tpick[12], tcnt = 0, k;
472 for (k = 0; k < 12; ++k)
473 tavail[k] = tpick[k] = 0;
474 for (t = ftrap; t; t = t->ntrap)
475 if (t->ttyp == SQKY_BOARD && t != ttmp)
476 tavail[t->tnote] = 1;
477 /* now populate tpick[] with the available indices */
478 for (k = 0; k < 12; ++k)
481 /* choose an unused note; if all are in use, pick a random one */
482 ttmp->tnote = (short) ((tcnt > 0) ? tpick[rn2(tcnt)] : rn2(12));
485 case STATUE_TRAP: { /* create a "living" statue */
487 struct obj *otmp, *statue;
488 struct permonst *mptr;
491 do { /* avoid ultimately hostile co-aligned unicorn */
492 mptr = &mons[rndmonnum()];
493 } while (--trycount > 0 && is_unicorn(mptr)
494 && sgn(u.ualign.type) == sgn(mptr->maligntyp));
495 statue = mkcorpstat(STATUE, (struct monst *) 0, mptr, x, y,
497 mtmp = makemon(&mons[statue->corpsenm], 0, 0, MM_NOCOUNTBIRTH);
499 break; /* should never happen */
500 while (mtmp->minvent) {
501 otmp = mtmp->minvent;
503 obj_extract_self(otmp);
504 (void) add_to_container(statue, otmp);
506 statue->owt = weight(statue);
510 case ROLLING_BOULDER_TRAP: /* boulder will roll towards trigger */
511 (void) mkroll_launch(ttmp, x, y, BOULDER, 1L);
519 if (*in_rooms(x, y, SHOPBASE)
520 && (is_hole(typ) || IS_DOOR(lev->typ) || IS_WALL(lev->typ)))
521 add_damage(x, y, /* schedule repair */
522 ((IS_DOOR(lev->typ) || IS_WALL(lev->typ))
523 && !context.mon_moving)
526 lev->doormask = 0; /* subsumes altarmask, icedpool... */
527 if (IS_ROOM(lev->typ)) /* && !IS_AIR(lev->typ) */
530 * some cases which can happen when digging
531 * down while phazing thru solid areas
533 else if (lev->typ == STONE || lev->typ == SCORR)
535 else if (IS_WALL(lev->typ) || lev->typ == SDOOR)
536 lev->typ = level.flags.is_maze_lev
538 : level.flags.is_cavernous_lev ? CORR : DOOR;
549 it shouldn't be possible to override a sokoban pit or hole
550 with some other trap, but we'll check just to be safe */
552 maybe_finish_sokoban();
558 fall_through(td, ftflags)
559 boolean td; /* td == TRUE : trap door or hole */
564 const char *dont_fall = 0;
565 int newlevel, bottom;
566 struct trap *t = (struct trap *) 0;
568 /* we'll fall even while levitating in Sokoban; otherwise, if we
569 won't fall and won't be told that we aren't falling, give up now */
570 if (Blind && Levitation && !Sokoban)
573 bottom = dunlevs_in_dungeon(&u.uz);
574 /* when in the upper half of the quest, don't fall past the
575 middle "quest locate" level if hero hasn't been there yet */
576 if (In_quest(&u.uz)) {
577 int qlocate_depth = qlocate_level.dlevel;
579 /* deepest reached < qlocate implies current < qlocate */
580 if (dunlev_reached(&u.uz) < qlocate_depth)
581 bottom = qlocate_depth; /* early cut-off */
583 newlevel = dunlev(&u.uz); /* current level */
586 } while (!rn2(4) && newlevel < bottom);
589 t = t_at(u.ux, u.uy);
591 if (!Sokoban && !(ftflags & TOOKPLUNGE)) {
592 if (t->ttyp == TRAPDOOR)
594 pline("A trap door opens up under you!");
596 pline("
\97\8e\82µ
\94à
\82ª
\82 \82È
\82½
\82Ì
\91«
\8c³
\82É
\8aJ
\82¢
\82½
\81I");
599 pline("There's a gaping hole under you!");
601 pline("
\82 \82È
\82½
\82Ì
\91«
\89º
\82É
\82Û
\82Á
\82©
\82è
\82Æ
\8c\8a\82ª
\8aJ
\82¢
\82Ä
\82¢
\82é
\81I");
605 pline_The("%s opens up under you!", surface(u.ux, u.uy));
607 pline("
\91«
\8c³
\82Ì%s
\82É
\8c\8a\82ª
\8aJ
\82¢
\82½
\81I", surface(u.ux,u.uy));
609 if (Sokoban && Can_fall_thru(&u.uz))
610 ; /* KMH -- You can't escape the Sokoban level traps */
611 else if (Levitation || u.ustuck
612 || (!Can_fall_thru(&u.uz) && !levl[u.ux][u.uy].candig)
613 || ((Flying || is_clinger(youmonst.data)
614 || (ceiling_hider(youmonst.data) && u.uundetected))
615 && !(ftflags & TOOKPLUNGE))
616 || (Inhell && !u.uevent.invoked && newlevel == bottom)) {
618 dont_fall = "don't fall in.";
620 dont_fall = "
\82µ
\82©
\82µ
\82 \82È
\82½
\82Í
\97\8e\82¿
\82È
\82©
\82Á
\82½
\81D";
621 } else if (youmonst.data->msize >= MZ_HUGE) {
623 dont_fall = "don't fit through.";
625 dont_fall = "
\92Ê
\82è
\94²
\82¯
\82é
\82É
\82Í
\83T
\83C
\83Y
\82ª
\8d\87\82í
\82È
\82¢
\81D";
626 } else if (!next_to_u()) {
628 dont_fall = "are jerked back by your pet!";
630 dont_fall = "
\82 \82È
\82½
\82Í
\83y
\83b
\83g
\82É
\82æ
\82Á
\82Ä
\88ø
\82Á
\82Ï
\82è
\82à
\82Ç
\82³
\82ê
\82½
\81I";
633 #if 0 /*JP*//*
\81u
\82 \82È
\82½
\82Í
\81v
\82Å
\8en
\82Ü
\82ç
\82È
\82¢
\82à
\82Ì
\82à
\82 \82é*/
638 /* hero didn't fall through, but any objects here might */
639 impact_drop((struct obj *) 0, u.ux, u.uy, 0);
641 display_nhwindow(WIN_MESSAGE, FALSE);
643 pline_The("opening under you closes up.");
645 pline_The("
\91«
\89º
\82É
\8aJ
\82¢
\82Ä
\82¢
\82½
\82à
\82Ì
\82Í
\95Â
\82¶
\82½
\81D");
649 if ((Flying || is_clinger(youmonst.data))
650 && (ftflags & TOOKPLUNGE) && td && t)
653 Flying ? "swoop" : "deliberately drop",
654 (t->ttyp == TRAPDOOR)
655 ? "through the trap door"
656 : "into the gaping hole");
659 (t->ttyp == TRAPDOOR)
662 Flying ? "
\8b}
\8d~
\89º
\82µ
\82½" : "
\82í
\82´
\82Æ
\97\8e\82¿
\82½");
667 if (Is_stronghold(&u.uz)) {
670 int dist = newlevel - dunlev(&u.uz);
671 dtmp.dnum = u.uz.dnum;
672 dtmp.dlevel = newlevel;
675 You("fall down a %s%sshaft!", dist > 3 ? "very " : "",
676 dist > 2 ? "deep " : "");
678 You("%s%s
\8c\8a\82Ì
\92\86\82ð
\97\8e\82¿
\82Ä
\82¢
\82Á
\82½
\81I", dist > 3 ? "
\82Æ
\82Ä
\82à" : "",
679 dist > 2 ? "
\90[
\82¢" : "");
684 Sprintf(msgbuf, "The hole in the %s above you closes up.",
686 Sprintf(msgbuf, "%s
\82É
\8aJ
\82¢
\82½
\8c\8a\82Í
\95Â
\82¶
\82½
\81D",
687 ceiling(u.ux, u.uy));
689 schedule_goto(&dtmp, FALSE, TRUE, 0, (char *) 0,
690 !td ? msgbuf : (char *) 0);
694 * Animate the given statue. May have been via shatter attempt, trap,
695 * or stone to flesh spell. Return a monster if successfully animated.
696 * If the monster is animated, the object is deleted. If fail_reason
697 * is non-null, then fill in the reason for failure (or success).
699 * The cause of animation is:
701 * ANIMATE_NORMAL - hero "finds" the monster
702 * ANIMATE_SHATTER - hero tries to destroy the statue
703 * ANIMATE_SPELL - stone to flesh spell hits the statue
705 * Perhaps x, y is not needed if we can use get_obj_location() to find
706 * the statue's location... ???
708 * Sequencing matters:
709 * create monster; if it fails, give up with statue intact;
710 * give "statue comes to life" message;
711 * if statue belongs to shop, have shk give "you owe" message;
712 * transfer statue contents to monster (after stolen_value());
714 * [This ordering means that if the statue ends up wearing a cloak of
715 * invisibility or a mummy wrapping, the visibility checks might be
716 * wrong, but to avoid that we'd have to clone the statue contents
717 * first in order to give them to the monster before checking their
718 * shop status--it's not worth the hassle.]
721 animate_statue(statue, x, y, cause, fail_reason)
727 int mnum = statue->corpsenm;
728 struct permonst *mptr = &mons[mnum];
729 struct monst *mon = 0, *shkp;
732 boolean historic = (Role_if(PM_ARCHEOLOGIST)
733 && (statue->spe & STATUE_HISTORIC) != 0),
734 golem_xform = FALSE, use_saved_traits;
735 const char *comes_to_life;
736 char statuename[BUFSZ], tmpbuf[BUFSZ];
737 static const char historic_statue_is_gone[] =
739 "that the historic statue is now gone";
741 "
\97ð
\8ej
\93I
\82È
\92¤
\91\9c\82ª
\82È
\82
\82È
\82Á
\82Ä
\82µ
\82Ü
\82Á
\82½
\82±
\82Æ";
743 if (cant_revive(&mnum, TRUE, statue)) {
744 /* mnum has changed; we won't be animating this statue as itself */
745 if (mnum != PM_DOPPELGANGER)
747 use_saved_traits = FALSE;
748 } else if (is_golem(mptr) && cause == ANIMATE_SPELL) {
749 /* statue of any golem hit by stone-to-flesh becomes flesh golem */
750 golem_xform = (mptr != &mons[PM_FLESH_GOLEM]);
751 mnum = PM_FLESH_GOLEM;
752 mptr = &mons[PM_FLESH_GOLEM];
753 use_saved_traits = (has_omonst(statue) && !golem_xform);
755 use_saved_traits = has_omonst(statue);
758 if (use_saved_traits) {
759 /* restore a petrified monster */
761 mon = montraits(statue, &cc, (cause == ANIMATE_SPELL));
762 if (mon && mon->mtame && !mon->isminion)
765 /* statues of unique monsters from bones or wishing end
766 up here (cant_revive() sets mnum to be doppelganger;
767 mptr reflects the original form for use by newcham()) */
768 if ((mnum == PM_DOPPELGANGER && mptr != &mons[PM_DOPPELGANGER])
769 /* block quest guards from other roles */
770 || (mptr->msound == MS_GUARDIAN
771 && quest_info(MS_GUARDIAN) != mnum)) {
772 mon = makemon(&mons[PM_DOPPELGANGER], x, y,
773 NO_MINVENT | MM_NOCOUNTBIRTH | MM_ADJACENTOK);
774 /* if hero has protection from shape changers, cham field will
775 be NON_PM; otherwise, set form to match the statue */
776 if (mon && mon->cham >= LOW_PM)
777 (void) newcham(mon, mptr, FALSE, FALSE);
779 mon = makemon(mptr, x, y, (cause == ANIMATE_SPELL)
780 ? (NO_MINVENT | MM_ADJACENTOK)
786 *fail_reason = unique_corpstat(&mons[statue->corpsenm])
789 return (struct monst *) 0;
792 /* a non-montraits() statue might specify gender */
793 if (statue->spe & STATUE_MALE)
795 else if (statue->spe & STATUE_FEMALE)
797 /* if statue has been named, give same name to the monster */
798 if (has_oname(statue) && !unique_corpstat(mon->data))
799 mon = christen_monst(mon, ONAME(statue));
800 /* mimic statue becomes seen mimic; other hiders won't be hidden */
804 mon->mundetected = FALSE;
806 if (cause == ANIMATE_NORMAL || cause == ANIMATE_SHATTER) {
807 /* trap always releases hostile monster */
808 mon->mtame = 0; /* (might be petrified pet tossed onto trap) */
814 comes_to_life = !canspotmon(mon)
818 : (nonliving(mon->data) || is_vampshifter(mon))
822 comes_to_life = !canspotmon(mon)
825 ? "
\93÷
\91Ì
\82É
\96ß
\82Á"
826 : (nonliving(mon->data) || is_vampshifter(mon))
828 : "
\90¶
\96½
\82ð
\91Ñ
\82Ñ";
830 if ((x == u.ux && y == u.uy) || cause == ANIMATE_SPELL) {
831 /* "the|your|Manlobbi's statue [of a wombat]" */
832 shkp = shop_keeper(*in_rooms(mon->mx, mon->my, SHOPBASE));
834 Sprintf(statuename, "%s%s", shk_your(tmpbuf, statue),
835 (cause == ANIMATE_SPELL
836 /* avoid "of a shopkeeper" if it's Manlobbi himself
837 (if carried, it can't be unpaid--hence won't be
838 described as "Manlobbi's statue"--because there
839 wasn't any living shk when statue was picked up) */
840 && (mon != shkp || carried(statue)))
844 Sprintf(statuename, "%s%s", shk_your(tmpbuf, statue),
845 (cause == ANIMATE_SPELL
846 && (mon != shkp || carried(statue)))
851 pline("%s %s!", upstart(statuename), comes_to_life);
853 pline("%s
\82Í%s
\82½
\81I", upstart(statuename), comes_to_life);
854 } else if (Hallucination) { /* They don't know it's a statue */
856 pline_The("%s suddenly seems more animated.", rndmonnam((char *) 0));
858 pline_The("%s
\82Í
\93Ë
\91R
\82æ
\82è
\8a\88\93®
\93I
\82É
\82È
\82Á
\82½
\81D", rndmonnam((char *) 0));
859 } else if (cause == ANIMATE_SHATTER) {
861 Sprintf(statuename, "%s%s", shk_your(tmpbuf, statue),
865 Strcpy(statuename, "a statue");
867 Strcpy(statuename, "
\92¤
\91\9c");
869 pline("Instead of shattering, %s suddenly %s!", statuename,
872 pline("%s
\82Í
\8dÓ
\82¯
\82¸
\82É%s
\82½
\81I", statuename,
875 } else { /* cause == ANIMATE_NORMAL */
877 You("find %s posing as a statue.",
879 You("%s
\82ª
\92¤
\91\9c\82Ì
\82Ó
\82è
\82ð
\82µ
\82Ä
\82¢
\82é
\82Ì
\82ð
\8c©
\82Â
\82¯
\82½
\81D",
880 canspotmon(mon) ? a_monnam(mon) : something);
881 if (!canspotmon(mon) && Blind)
886 /* if this isn't caused by a monster using a wand of striking,
887 there might be consequences for the hero */
888 if (!context.mon_moving) {
889 /* if statue is owned by a shop, hero will have to pay for it;
890 stolen_value gives a message (about debt or use of credit)
891 which refers to "it" so needs to follow a message describing
892 the object ("the statue comes to life" one above) */
893 if (cause != ANIMATE_NORMAL && costly_spot(x, y)
894 && (carried(statue) ? statue->unpaid : !statue->no_charge)
895 && (shkp = shop_keeper(*in_rooms(x, y, SHOPBASE))) != 0
896 /* avoid charging for Manlobbi's statue of Manlobbi
897 if stone-to-flesh is used on petrified shopkeep */
899 (void) stolen_value(statue, x, y, (boolean) shkp->mpeaceful,
904 You_feel("guilty %s.", historic_statue_is_gone);
906 You_feel("%s
\82É
\8dß
\82ð
\8a´
\82¶
\82½
\81D", historic_statue_is_gone);
910 if (historic && cansee(x, y))
912 You_feel("regret %s.", historic_statue_is_gone);
914 You_feel("%s
\82ð
\8cã
\89÷
\82µ
\82½
\81D", historic_statue_is_gone);
915 /* no alignment penalty */
918 /* transfer any statue contents to monster's inventory */
919 while ((item = statue->cobj) != 0) {
920 obj_extract_self(item);
921 (void) mpickobj(mon, item);
924 /* in case statue is wielded and hero zaps stone-to-flesh at self */
925 if (statue->owornmask)
926 remove_worn_item(statue, TRUE);
927 /* statue no longer exists */
930 /* avoid hiding under nothing */
931 if (x == u.ux && y == u.uy && Upolyd && hides_under(youmonst.data)
936 *fail_reason = AS_OK;
941 * You've either stepped onto a statue trap's location or you've triggered a
942 * statue trap by searching next to it or by trying to break it with a wand
946 activate_statue_trap(trap, x, y, shatter)
951 struct monst *mtmp = (struct monst *) 0;
952 struct obj *otmp = sobj_at(STATUE, x, y);
956 * Try to animate the first valid statue. Stop the loop when we
957 * actually create something or the failure cause is not because
958 * the mon was unique.
962 mtmp = animate_statue(otmp, x, y,
963 shatter ? ANIMATE_SHATTER : ANIMATE_NORMAL,
965 if (mtmp || fail_reason != AS_MON_IS_UNIQUE)
968 otmp = nxtobj(otmp, STATUE, TRUE);
976 keep_saddle_with_steedcorpse(steed_mid, objchn, saddle)
978 struct obj *objchn, *saddle;
983 if (objchn->otyp == CORPSE && has_omonst(objchn)) {
984 struct monst *mtmp = OMONST(objchn);
986 if (mtmp->m_id == steed_mid) {
989 if (get_obj_location(objchn, &x, &y, 0)) {
990 obj_extract_self(saddle);
991 place_object(saddle, x, y);
997 if (Has_contents(objchn)
998 && keep_saddle_with_steedcorpse(steed_mid, objchn->cobj, saddle))
1000 objchn = objchn->nobj;
1005 /* monster or you go through and possibly destroy a web.
1006 return TRUE if could go through. */
1008 mu_maybe_destroy_web(mtmp, domsg, trap)
1013 boolean isyou = (mtmp == &youmonst);
1014 struct permonst *mptr = mtmp->data;
1016 if (amorphous(mptr) || is_whirly(mptr) || flaming(mptr)
1017 || unsolid(mptr) || mptr == &mons[PM_GELATINOUS_CUBE]) {
1021 if (flaming(mptr) || acidic(mptr)) {
1025 You("%s %s spider web!",
1026 (flaming(mptr)) ? "burn" : "dissolve",
1027 a_your[trap->madeby_u]);
1029 You("%s
\82
\82à
\82Ì
\91\83\82ð%s
\81I",
1030 web_you[trap->madeby_u],
1031 (flaming(mptr)) ? "
\8fÄ
\82¢
\82½" : "
\82±
\82È
\82²
\82È
\82É
\82µ
\82½");
1035 pline("%s %s %s spider web!", Monnam(mtmp),
1036 (flaming(mptr)) ? "burns" : "dissolves",
1037 a_your[trap->madeby_u]);
1039 pline("%s%s
\82
\82à
\82Ì
\91\83\82ð%s
\81I", Monnam(mtmp),
1040 web_you[trap->madeby_u],
1041 (flaming(mptr)) ? "
\8fÄ
\82¢
\82½" : "
\82±
\82È
\82²
\82È
\82É
\82µ
\82½");
1051 You("flow through %s spider web.", a_your[trap->madeby_u]);
1053 You("%s
\82
\82à
\82Ì
\91\83\82ð
\82·
\82é
\82è
\82Æ
\92Ê
\82è
\94²
\82¯
\82½
\81D", web_you[trap->madeby_u]);
1056 pline("%s flows through %s spider web.", Monnam(mtmp),
1057 a_your[trap->madeby_u]);
1059 pline("%s
\82Í%s
\82
\82à
\82Ì
\91\83\82ð
\82·
\82é
\82è
\82Æ
\92Ê
\82è
\94²
\82¯
\82½
\81D", Monnam(mtmp),
1060 web_you[trap->madeby_u]);
1070 /* make a single arrow/dart/rock for a trap to shoot or drop */
1071 STATIC_OVL struct obj *
1072 t_missile(otyp, trap)
1076 struct obj *otmp = mksobj(otyp, TRUE, FALSE);
1079 otmp->owt = weight(otmp);
1080 otmp->opoisoned = 0;
1081 otmp->ox = trap->tx, otmp->oy = trap->ty;
1091 * utraptype==0 is bear trap rather than 'none'; we probably ought
1092 * to change that but can't do so until save file compatability is
1093 * able to be broken.
1095 u.utraptype = tim ? typ : 0;
1097 float_vs_flight(); /* maybe block Lev and/or Fly */
1104 boolean was_Lev = (Levitation != 0), was_Fly = (Flying != 0);
1109 if (!was_Lev && Levitation)
1111 if (!was_Fly && Flying)
1115 You("
\94ò
\82×
\82é
\82æ
\82¤
\82É
\82È
\82Á
\82½
\81D");
1120 dotrap(trap, trflags)
1121 register struct trap *trap;
1124 register int ttype = trap->ttyp;
1126 boolean already_seen = trap->tseen,
1127 forcetrap = ((trflags & FORCETRAP) != 0
1128 || (trflags & FAILEDUNTRAP) != 0),
1129 webmsgok = (trflags & NOWEBMSG) == 0,
1130 forcebungle = (trflags & FORCEBUNGLE) != 0,
1131 plunged = (trflags & TOOKPLUNGE) != 0,
1132 viasitting = (trflags & VIASITTING) != 0,
1133 conj_pit = conjoined_pits(trap, t_at(u.ux0, u.uy0), TRUE),
1134 adj_pit = adj_nonconjoined_pit(trap);
1136 int steed_article = ARTICLE_THE;
1140 /* KMH -- You can't escape the Sokoban level traps */
1141 if (Sokoban && (is_pit(ttype) || is_hole(ttype))) {
1142 /* The "air currents" message is still appropriate -- even when
1143 * the hero isn't flying or levitating -- because it conveys the
1144 * reason why the player cannot escape the trap with a dexterity
1145 * check, clinging to the ceiling, etc.
1148 pline("Air currents pull you down into %s %s!",
1149 a_your[trap->madeby_u],
1150 defsyms[trap_to_defsym(ttype)].explanation);
1152 pline("
\8bó
\8bC
\82Ì
\97¬
\82ê
\82ª
\82 \82È
\82½
\82ð%s
\82É
\88ø
\82«
\96ß
\82µ
\82½
\81I",
1153 defsyms[trap_to_defsym(ttype)].explanation);
1155 /* then proceed to normal trap effect */
1156 } else if (already_seen && !forcetrap) {
1157 if ((Levitation || (Flying && !plunged))
1158 && (is_pit(ttype) || ttype == HOLE || ttype == BEAR_TRAP)) {
1160 You("%s over %s %s.", Levitation ? "float" : "fly",
1161 a_your[trap->madeby_u],
1162 defsyms[trap_to_defsym(ttype)].explanation);
1164 You("%s%s
\82Ì
\8fã%s
\81D",
1165 set_you[trap->madeby_u],
1166 defsyms[trap_to_defsym(ttype)].explanation,
1167 Levitation ? "
\82ð
\8c©
\89º
\82ë
\82µ
\82½" : "
\82ð
\94ò
\82ñ
\82Å
\82¢
\82é");
1171 if (!Fumbling && ttype != MAGIC_PORTAL && ttype != VIBRATING_SQUARE
1172 && ttype != ANTI_MAGIC && !forcebungle && !plunged
1173 && !conj_pit && !adj_pit
1174 && (!rn2(5) || (is_pit(ttype)
1175 && is_clinger(youmonst.data)))) {
1177 You("escape %s %s.", (ttype == ARROW_TRAP && !trap->madeby_u)
1179 : a_your[trap->madeby_u],
1180 defsyms[trap_to_defsym(ttype)].explanation);
1182 You("%s%s
\82ð
\82·
\82é
\82è
\82Æ
\94ð
\82¯
\82½
\81D",
1183 set_you[trap->madeby_u],
1184 defsyms[trap_to_defsym(ttype)].explanation);
1191 u.usteed->mtrapseen |= (1 << (ttype - 1));
1192 /* suppress article in various steed messages when using its
1193 name (which won't occur when hallucinating) */
1194 if (has_mname(u.usteed) && !Hallucination)
1195 steed_article = ARTICLE_NONE;
1200 if (trap->once && trap->tseen && !rn2(15)) {
1202 You_hear("a loud click!");
1204 You_hear("
\83K
\83`
\83\83\83b
\82Æ
\82¢
\82¤
\91å
\82«
\82È
\89¹
\82ð
\95·
\82¢
\82½
\81I");
1212 pline("An arrow shoots out at you!");
1214 pline("
\96î
\82ª
\94ò
\82ñ
\82Å
\82«
\82½
\81I");
1215 otmp = t_missile(ARROW, trap);
1216 if (u.usteed && !rn2(2) && steedintrap(trap, otmp)) {
1219 } else if (thitu(8, dmgval(otmp, &youmonst), &otmp, "arrow")) {
1221 } else if (thitu(8, dmgval(otmp, &youmonst), &otmp, "
\96î")) {
1224 obfree(otmp, (struct obj *) 0);
1226 place_object(otmp, u.ux, u.uy);
1235 if (trap->once && trap->tseen && !rn2(15)) {
1237 You_hear("a soft click.");
1239 You_hear("
\83J
\83`
\83b
\82Æ
\82¢
\82¤
\89¹
\82ð
\95·
\82¢
\82½
\81D");
1247 pline("A little dart shoots out at you!");
1249 pline("
\8f¬
\82³
\82È
\93\8a\82°
\96î
\82ª
\94ò
\82ñ
\82Å
\82«
\82½
\81I");
1250 otmp = t_missile(DART, trap);
1252 otmp->opoisoned = 1;
1253 oldumort = u.umortality;
1254 if (u.usteed && !rn2(2) && steedintrap(trap, otmp)) {
1257 } else if (thitu(7, dmgval(otmp, &youmonst), &otmp, "little dart")) {
1259 } else if (thitu(7, dmgval(otmp, &youmonst), &otmp, "
\93\8a\82°
\96î")) {
1262 if (otmp->opoisoned)
1264 poisoned("dart", A_CON, "little dart",
1265 /* if damage triggered life-saving,
1266 poison is limited to attrib loss */
1267 (u.umortality > oldumort) ? 0 : 10, TRUE);
1269 poisoned("
\93\8a\82°
\96î", A_CON, "
\8f¬
\82³
\82È
\93\8a\82°
\96î",
1270 /* if damage triggered life-saving,
1271 poison is limited to attrib loss */
1272 (u.umortality > oldumort) ? 0 : 10, TRUE);
1274 obfree(otmp, (struct obj *) 0);
1277 place_object(otmp, u.ux, u.uy);
1286 if (trap->once && trap->tseen && !rn2(15)) {
1288 pline("A trap door in %s opens, but nothing falls out!",
1290 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",
1291 the(ceiling(u.ux, u.uy)));
1295 int dmg = d(2, 6); /* should be std ROCK dmg? */
1299 otmp = t_missile(ROCK, trap);
1300 place_object(otmp, u.ux, u.uy);
1303 pline("A trap door in %s opens and %s falls on your %s!",
1304 the(ceiling(u.ux, u.uy)), an(xname(otmp)), body_part(HEAD));
1306 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",
1307 ceiling(u.ux,u.uy), xname(otmp), body_part(HEAD));
1310 if (is_metallic(uarmh)) {
1312 pline("Fortunately, you are wearing a hard helmet.");
1314 pline("
\8dK
\89^
\82É
\82à
\81C
\82 \82È
\82½
\82Í
\8cÅ
\82¢
\8a\95\82ð
\90g
\82É
\82Â
\82¯
\82Ä
\82¢
\82½
\81D");
1316 } else if (flags.verbose) {
1318 pline("%s does not protect you.", Yname2(uarmh));
1320 pline("%s
\82Å
\82Í
\96h
\82°
\82È
\82¢
\81D", xname(uarmh));
1326 newsym(u.ux, u.uy); /* map the rock */
1329 losehp(Maybe_Half_Phys(dmg), "falling rock", KILLED_BY_AN);
1331 losehp(Maybe_Half_Phys(dmg), "
\97\8e\8aâ
\82Å", KILLED_BY_AN);
1332 exercise(A_STR, FALSE);
1336 case SQKY_BOARD: /* stepped on a squeaky board */
1337 if ((Levitation || Flying) && !forcetrap) {
1342 You("notice a crease in the linoleum.");
1344 You("
\8f°
\82Ì
\8ed
\8fã
\8dÞ
\82Ì
\82µ
\82í
\82É
\8bC
\82ª
\82Â
\82¢
\82½
\81D");
1347 You("notice a loose board below you.");
1349 You("
\91«
\8c³
\82Ì
\8aÉ
\82ñ
\82¾
\94Â
\82É
\8bC
\82ª
\82Â
\82¢
\82½
\81D");
1354 pline("A board beneath you %s%s%s.",
1355 Deaf ? "vibrates" : "squeaks ",
1356 Deaf ? "" : trapnote(trap, 0), Deaf ? "" : " loudly");
1359 pline("
\91«
\8c³
\82Ì
\94Â
\82ª
\82ä
\82ê
\82½
\81D");
1361 pline("
\91«
\8c³
\82Ì
\94Â
\82ª
\91å
\82«
\82%s
\82Ì
\89¹
\82É
\82«
\82µ
\82ñ
\82¾
\81D", trapnote(trap, 0));
1371 if ((Levitation || Flying) && !forcetrap)
1374 if (amorphous(youmonst.data) || is_whirly(youmonst.data)
1375 || unsolid(youmonst.data)) {
1377 pline("%s bear trap closes harmlessly through you.",
1378 A_Your[trap->madeby_u]);
1380 pline("%s
\8cF
\82Ìã©
\82Í
\8a\9a\82Ý
\82Â
\82¢
\82½
\82ª
\81C
\82·
\82é
\82Á
\82Æ
\92Ê
\82è
\94²
\82¯
\82½
\81D",
1381 set_you[trap->madeby_u]);
1385 if (!u.usteed && youmonst.data->msize <= MZ_SMALL) {
1387 pline("%s bear trap closes harmlessly over you.",
1388 A_Your[trap->madeby_u]);
1390 pline("%s
\8cF
\82Ìã©
\82Í
\8a\9a\82Ý
\82Â
\82¢
\82½
\82ª
\81C
\97y
\82©
\8fã
\95û
\82¾
\82Á
\82½
\81D",
1391 set_you[trap->madeby_u]);
1395 set_utrap((unsigned) rn1(4, 4), TT_BEARTRAP);
1398 pline("%s bear trap closes on %s %s!", A_Your[trap->madeby_u],
1399 s_suffix(mon_nam(u.usteed)), mbodypart(u.usteed, FOOT));
1401 pline("%s
\8cF
\82Ìã©
\82Í%s
\82Ì%s
\82É
\8a\9a\82Ý
\82Â
\82¢
\82½
\81I", set_you[trap->madeby_u],
1402 mon_nam(u.usteed), mbodypart(u.usteed, FOOT));
1404 if (thitm(0, u.usteed, (struct obj *) 0, dmg, FALSE))
1405 reset_utrap(TRUE); /* steed died, hero not trapped */
1408 pline("%s bear trap closes on your %s!", A_Your[trap->madeby_u],
1411 pline("%s
\8cF
\82Ìã©
\82ª
\82 \82È
\82½
\82Ì%s
\82É
\8a\9a\82Ý
\82Â
\82¢
\82½
\81I", set_you[trap->madeby_u],
1414 set_wounded_legs(rn2(2) ? RIGHT_SIDE : LEFT_SIDE, rn1(10, 10));
1415 if (u.umonnum == PM_OWLBEAR || u.umonnum == PM_BUGBEAR)
1417 You("howl in anger!");
1419 You("
\93{
\82è
\82Ì
\99ô
\9aK
\82ð
\82 \82°
\82½
\81I");
1421 losehp(Maybe_Half_Phys(dmg), "bear trap", KILLED_BY_AN);
1423 losehp(Maybe_Half_Phys(dmg), "
\8cF
\82Ìã©
\82Å", KILLED_BY_AN);
1425 exercise(A_DEX, FALSE);
1431 if (Sleep_resistance || breathless(youmonst.data)) {
1433 You("are enveloped in a cloud of gas!");
1435 You("
\83K
\83X
\89_
\82É
\82Â
\82Â
\82Ü
\82ê
\82½
\81I");
1438 pline("A cloud of gas puts you to sleep!");
1440 pline("
\82 \82È
\82½
\82Í
\83K
\83X
\89_
\82Å
\96°
\82Á
\82Ä
\82µ
\82Ü
\82Á
\82½
\81I");
1441 fall_asleep(-rnd(25), TRUE);
1443 (void) steedintrap(trap, (struct obj *) 0);
1449 /* Unlike monsters, traps cannot aim their rust attacks at
1450 * you, so instead of looping through and taking either the
1451 * first rustable one or the body, we take whatever we get,
1452 * even if it is not rustable.
1457 pline("%s you on the %s!", A_gush_of_water_hits, body_part(HEAD));
1459 pline("
\90\85\82ª
\95¬
\8fo
\82µ
\82Ä
\82 \82È
\82½
\82Ì%s
\82É
\96½
\92\86\82µ
\82½
\81I", body_part(HEAD));
1460 (void) water_damage(uarmh, helm_simple_name(uarmh), TRUE);
1464 pline("%s your left %s!", A_gush_of_water_hits, body_part(ARM));
1466 pline("
\90\85\82ª
\95¬
\8fo
\82µ
\82Ä
\82 \82È
\82½
\82Ì
\8d¶%s
\82É
\96½
\92\86\82µ
\82½
\81I", body_part(ARM));
1468 if (water_damage(uarms, "shield", TRUE) != ER_NOTHING)
1470 if (water_damage(uarms, "
\8f\82", TRUE) != ER_NOTHING)
1472 if (u.twoweap || (uwep && bimanual(uwep)))
1473 (void) water_damage(u.twoweap ? uswapwep : uwep, 0, TRUE);
1476 (void) water_damage(uarmg, "gauntlets", TRUE);
1478 (void) water_damage(uarmg, "
\8f¬
\8eè", TRUE);
1479 /* Not "metal gauntlets" since it gets called
1480 * even if it's leather for the message
1485 pline("%s your right %s!", A_gush_of_water_hits, body_part(ARM));
1487 pline("
\90\85\82ª
\95¬
\8fo
\82µ
\82Ä
\82 \82È
\82½
\82Ì
\89E%s
\82É
\96½
\92\86\82µ
\82½
\81I", body_part(ARM));
1488 (void) water_damage(uwep, 0, TRUE);
1492 pline("%s you!", A_gush_of_water_hits);
1494 pline("
\90\85\82ª
\95¬
\8fo
\82µ
\82Ä
\82 \82È
\82½
\82É
\96½
\92\86\82µ
\82½
\81I");
1495 for (otmp = invent; otmp; otmp = otmp->nobj)
1496 if (otmp->lamplit && otmp != uwep
1497 && (otmp != uswapwep || !u.twoweap))
1498 (void) snuff_lit(otmp);
1500 (void) water_damage(uarmc, cloak_simple_name(uarmc), TRUE);
1502 (void) water_damage(uarm, suit_simple_name(uarm), TRUE);
1505 (void) water_damage(uarmu, "shirt", TRUE);
1507 (void) water_damage(uarmu, "
\83V
\83\83\83c", TRUE);
1511 if (u.umonnum == PM_IRON_GOLEM) {
1515 You("are covered with rust!");
1517 You("
\8eK
\82É
\95¢
\82í
\82ê
\82½
\81I");
1519 losehp(Maybe_Half_Phys(dam), "rusting away", KILLED_BY);
1521 losehp(Maybe_Half_Phys(dam), "
\8a®
\91S
\82É
\8eK
\82Ñ
\82Ä", KILLED_BY);
1522 } else if (u.umonnum == PM_GREMLIN && rn2(3)) {
1523 (void) split_mon(&youmonst, (struct monst *) 0);
1530 dofiretrap((struct obj *) 0);
1535 /* KMH -- You can't escape the Sokoban level traps */
1536 if (!Sokoban && (Levitation || (Flying && !plunged)))
1539 if (!Sokoban && is_clinger(youmonst.data) && !plunged) {
1542 You_see("%s %spit below you.", a_your[trap->madeby_u],
1543 ttype == SPIKED_PIT ? "spiked " : "");
1545 pline("
\91«
\8c³
\82É%s%s
\97\8e\82µ
\8c\8a\82ð
\94
\8c©
\82µ
\82½
\81D", dig_you[trap->madeby_u],
1546 ttype == SPIKED_PIT ? "
\83g
\83Q
\82¾
\82ç
\82¯
\82Ì" : "");
1550 pline("%s pit %sopens up under you!", A_Your[trap->madeby_u],
1551 ttype == SPIKED_PIT ? "full of spikes " : "");
1553 pline("%s%s
\97\8e\82µ
\8c\8a\82ª
\91«
\8c³
\82É
\8aJ
\82¢
\82½
\81I", dig_you[trap->madeby_u],
1554 ttype == SPIKED_PIT ? "
\83g
\83Q
\82¾
\82ç
\82¯
\82Ì" : "");
1557 You("don't fall in!");
1559 pline("
\82µ
\82©
\82µ
\81C
\82 \82È
\82½
\82Í
\97\8e\82¿
\82È
\82©
\82Á
\82½
\81I");
1564 char verbbuf[BUFSZ];
1568 if ((trflags & RECURSIVETRAP) != 0)
1570 Sprintf(verbbuf, "and %s fall",
1572 Sprintf(verbbuf, "
\82Æ%s",
1573 x_monnam(u.usteed, steed_article, (char *) 0,
1574 SUPPRESS_SADDLE, FALSE));
1577 Sprintf(verbbuf, "lead %s",
1578 x_monnam(u.usteed, steed_article, "poor",
1579 SUPPRESS_SADDLE, FALSE));
1581 Sprintf(verbbuf, "
\82Æ%s",
1582 x_monnam(u.usteed, steed_article, "
\82©
\82í
\82¢
\82»
\82¤
\82È",
1583 SUPPRESS_SADDLE, FALSE));
1585 } else if (conj_pit) {
1587 You("move into an adjacent pit.");
1589 You("
\97×
\82Ì
\97\8e\82µ
\8c\8a\82É
\88Ú
\93®
\82µ
\82½
\81D");
1590 } else if (adj_pit) {
1592 You("stumble over debris%s.",
1593 !rn2(5) ? " between the pits" : "");
1595 You("
\82Í%s
\82ª
\82ç
\82
\82½
\82Å
\82Â
\82Ü
\82Ã
\82¢
\82½
\81D",
1596 !rn2(5) ? "
\97\8e\82µ
\8c\8a\82Ì" : "");
1601 !plunged ? "fall" : (Flying ? "dive" : "plunge"));
1604 !plunged ? "
\97\8e\82¿
\82½" : (Flying ? "
\94ò
\82Ñ
\8d\9e\82ñ
\82¾" : "
\93Ë
\93ü
\82µ
\82½"));
1609 You("%s into %s pit!", verbbuf, a_your[trap->madeby_u]);
1611 You("%s
\97\8e\82µ
\8c\8a\82É%s!", set_you[trap->madeby_u], verbbuf);
1613 /* wumpus reference */
1614 if (Role_if(PM_RANGER) && !trap->madeby_u && !trap->once
1615 && In_quest(&u.uz) && Is_qlocate(&u.uz)) {
1617 pline("Fortunately it has a bottom after all...");
1619 pline("
\8dK
\82¢
\81C
\8c\8b\8bÇ
\82Í
\92ê
\82ª
\82 \82Á
\82½
\81D
\81D
\81D");
1621 } else if (u.umonnum == PM_PIT_VIPER || u.umonnum == PM_PIT_FIEND) {
1623 pline("How pitiful. Isn't that the pits?");
1625 pline("
\82±
\82Ì
\97\8e\82µ
\8c\8a\82Í
\82¢
\82¢
\8ed
\8e\96\82ð
\82µ
\82Ä
\82¢
\82é
\81D");
1627 if (ttype == SPIKED_PIT) {
1629 const char *predicament = "on a set of sharp iron spikes";
1631 const char *predicament = "
\89s
\82¢
\93S
\82Ì
\83g
\83Q
\83g
\83Q
\82Ì
\8fã
\82É";
1636 upstart(x_monnam(u.usteed, steed_article, "poor",
1637 SUPPRESS_SADDLE, FALSE)),
1638 conj_pit ? "steps" : "lands", predicament);
1640 pline("%s
\82Í%s%s
\81I",
1641 upstart(x_monnam(u.usteed, steed_article, "
\82©
\82í
\82¢
\82»
\82¤
\82È",
1642 SUPPRESS_SADDLE, FALSE)),
1643 predicament, conj_pit ? "
\97\8e\82¿
\82½" : "
\8d~
\82è
\82½");
1647 You("%s %s!", conj_pit ? "step" : "land", predicament);
1649 You("%s%s
\81I", predicament, conj_pit ? "
\97\8e\82¿
\82½" : "
\8d~
\82è
\82½");
1652 * if hero gets killed here, setting u.utrap in advance will
1653 * show "you were trapped in a pit" during disclosure's display
1654 * of enlightenment, but hero is dying *before* becoming trapped.
1656 set_utrap((unsigned) rn1(6, 2), TT_PIT);
1657 if (!steedintrap(trap, (struct obj *) 0)) {
1658 if (ttype == SPIKED_PIT) {
1659 oldumort = u.umortality;
1661 losehp(Maybe_Half_Phys(rnd(conj_pit ? 4 : adj_pit ? 6 : 10)),
1662 /* note: these don't need locomotion() handling;
1663 if fatal while poly'd and Unchanging, the
1664 death reason will be overridden with
1665 "killed while stuck in creature form" */
1667 ? "deliberately plunged into a pit of iron spikes"
1669 ? "stepped into a pit of iron spikes"
1671 ? "stumbled into a pit of iron spikes"
1672 : "fell into a pit of iron spikes",
1675 losehp(Maybe_Half_Phys(rnd(conj_pit ? 4 : adj_pit ? 6 : 10)),
1677 ? "
\82í
\82´
\82í
\82´
\83g
\83Q
\82¾
\82ç
\82¯
\82Ì
\97\8e\82µ
\8c\8a\82É
\93Ë
\93ü
\82µ
\82Ä"
1679 ? "
\83g
\83Q
\82¾
\82ç
\82¯
\82Ì
\97\8e\82µ
\8c\8a\82É
\93¥
\82Ý
\8d\9e\82ñ
\82Å"
1681 ? "
\83g
\83Q
\82¾
\82ç
\82¯
\82Ì
\97\8e\82µ
\8c\8a\82É
\82æ
\82ë
\82ß
\82«
\97\8e\82¿
\82Ä"
1682 : "
\83g
\83Q
\82¾
\82ç
\82¯
\82Ì
\97\8e\82µ
\8c\8a\82É
\97\8e\82¿
\82Ä",
1687 poisoned("spikes", A_STR,
1688 (conj_pit || adj_pit)
1689 ? "stepping on poison spikes"
1690 : "fall onto poison spikes",
1691 /* if damage triggered life-saving,
1692 poison is limited to attrib loss */
1693 (u.umortality > oldumort) ? 0 : 8, FALSE);
1695 poisoned("
\83g
\83Q", A_STR,
1696 (conj_pit || adj_pit)
1697 ? "
\93Å
\82Ì
\93h
\82ç
\82ê
\82½
\83g
\83Q
\82ð
\93¥
\82ñ
\82Å"
1698 : "
\93Å
\82Ì
\93h
\82ç
\82ê
\82½
\83g
\83Q
\82Ì
\8fã
\82É
\97\8e\82¿
\82Ä",
1699 /* if damage triggered life-saving,
1700 poison is limited to attrib loss */
1701 (u.umortality > oldumort) ? 0 : 8, FALSE);
1704 /* plunging flyers take spike damage but not pit damage */
1706 && !(plunged && (Flying || is_clinger(youmonst.data))))
1708 losehp(Maybe_Half_Phys(rnd(adj_pit ? 3 : 6)),
1709 plunged ? "deliberately plunged into a pit"
1710 : "fell into a pit",
1713 losehp(Maybe_Half_Phys(rnd(adj_pit ? 3 : 6)),
1714 plunged ? "
\82í
\82´
\82í
\82´
\97\8e\82µ
\8c\8a\82É
\93Ë
\93ü
\82µ
\82Ä"
1715 : "
\97\8e\82µ
\8c\8a\82É
\97\8e\82¿
\82Ä",
1719 if (Punished && !carried(uball)) {
1726 selftouch("Falling, you");
1728 selftouch("
\97\8e\89º
\92\86\81C
\82 \82È
\82½
\82Í");
1729 vision_full_recalc = 1; /* vision limits change */
1730 exercise(A_STR, FALSE);
1731 exercise(A_DEX, FALSE);
1737 if (!Can_fall_thru(&u.uz)) {
1738 seetrap(trap); /* normally done in fall_through */
1739 impossible("dotrap: %ss cannot exist on this level.",
1740 defsyms[trap_to_defsym(ttype)].explanation);
1741 break; /* don't activate it after all */
1743 fall_through(TRUE, (trflags & TOOKPLUNGE));
1753 level_tele_trap(trap, trflags);
1756 case WEB: /* Our luckless player has stumbled into a web. */
1758 if (mu_maybe_destroy_web(&youmonst, webmsgok, trap))
1760 if (webmaker(youmonst.data)) {
1763 pline(trap->madeby_u ? "You take a walk on your web."
1764 : "There is a spider web here.");
1766 pline(trap->madeby_u ? "
\8e©
\95ª
\82Å
\92£
\82Á
\82½
\82
\82à
\82Ì
\91\83\82Ì
\8fã
\82ð
\95à
\82¢
\82½
\81D"
1767 : "
\82±
\82±
\82É
\82Í
\82
\82à
\82Ì
\91\83\82ª
\82 \82é
\81D");
1772 char verbbuf[BUFSZ];
1775 if (forcetrap || viasitting) {
1776 Strcpy(verbbuf, "are caught by");
1777 } else if (u.usteed) {
1778 Sprintf(verbbuf, "lead %s into",
1779 x_monnam(u.usteed, steed_article, "poor",
1780 SUPPRESS_SADDLE, FALSE));
1782 Sprintf(verbbuf, "%s into",
1783 Levitation ? (const char *) "float"
1784 : locomotion(youmonst.data, "stumble"));
1786 You("%s %s spider web!", verbbuf, a_your[trap->madeby_u]);
1789 Strcpy(verbbuf, "
\82 \82È
\82½
\82Í");
1790 } else if (u.usteed) {
1791 Sprintf(verbbuf, "
\82 \82È
\82½
\82Æ%s",
1792 x_monnam(u.usteed, steed_article, "
\82©
\82í
\82¢
\82»
\82¤
\82È",
1793 SUPPRESS_SADDLE, FALSE));
1795 Sprintf(verbbuf, "
\82 \82È
\82½
\82Í%s",
1796 Levitation ? (const char *) "
\95\82\82«
\82È
\82ª
\82ç"
1797 : jconj(locomotion(youmonst.data, "
\82Â
\82Ü
\82¸
\82"), "
\82Ä"));
1799 pline("%s%s
\82
\82à
\82Ì
\91\83\82É
\82Ð
\82Á
\82©
\82©
\82Á
\82½
\81I", verbbuf, web_you[trap->madeby_u]);
1803 /* time will be adjusted below */
1804 set_utrap(1, TT_WEB);
1806 /* Time stuck in the web depends on your/steed strength. */
1808 int tim, str = ACURR(A_STR);
1810 /* If mounted, the steed gets trapped. Use mintrap
1811 * to do all the work. If mtrapped is set as a result,
1812 * unset it and set utrap instead. In the case of a
1813 * strongmonst and mintrap said it's trapped, use a
1814 * short but non-zero trap time. Otherwise, monsters
1815 * have no specific strength, so use player strength.
1816 * This gets skipped for webmsgok, which implies that
1817 * the steed isn't a factor.
1819 if (u.usteed && webmsgok) {
1820 /* mtmp location might not be up to date */
1821 u.usteed->mx = u.ux;
1822 u.usteed->my = u.uy;
1824 /* mintrap currently does not return 2(died) for webs */
1825 if (mintrap(u.usteed)) {
1826 u.usteed->mtrapped = 0;
1827 if (strongmonst(u.usteed->data))
1834 webmsgok = FALSE; /* mintrap printed the messages */
1854 You("tear through %s web!", a_your[trap->madeby_u]);
1856 You("%s
\82
\82à
\82Ì
\91\83\82ð
\90Ø
\82è
\97ô
\82¢
\82½
\81I", web_you[trap->madeby_u]);
1858 newsym(u.ux, u.uy); /* get rid of trap symbol */
1860 set_utrap((unsigned) tim, TT_WEB);
1865 (void) activate_statue_trap(trap, u.ux, u.uy, FALSE);
1868 case MAGIC_TRAP: /* A magic trap. */
1872 newsym(u.ux, u.uy); /* update position */
1874 You("are caught in a magical explosion!");
1876 You("
\96\82\96@
\82Ì
\94\9a\94
\82ð
\97\81\82Ñ
\82½
\81I");
1878 losehp(rnd(10), "magical explosion", KILLED_BY_AN);
1880 losehp(rnd(10), "
\96\82\96@
\82Ì
\94\9a\94
\82ð
\97\81\82Ñ
\82Ä", KILLED_BY_AN);
1882 Your("body absorbs some of the magical energy!");
1884 Your("
\91Ì
\82Í
\96\82\96@
\82Ì
\83G
\83l
\83\8b\83M
\81[
\82ð
\8f
\82µ
\8bz
\82¢
\82Æ
\82Á
\82½
\81I");
1885 u.uen = (u.uenmax += 2);
1890 (void) steedintrap(trap, (struct obj *) 0);
1895 /* hero without magic resistance loses spell energy,
1896 hero with magic resistance takes damage instead;
1897 possibly non-intuitive but useful for play balance */
1899 drain_en(rnd(u.ulevel) + 1);
1901 int dmgval2 = rnd(4), hp = Upolyd ? u.mh : u.uhp;
1903 /* Half_XXX_damage has opposite its usual effect (approx)
1904 but isn't cumulative if hero has more than one */
1905 if (Half_physical_damage || Half_spell_damage)
1907 /* give Magicbane wielder dose of own medicine */
1908 if (uwep && uwep->oartifact == ART_MAGICBANE)
1910 /* having an artifact--other than own quest one--which
1911 confers magic resistance simply by being carried
1912 also increases the effect */
1913 for (otmp = invent; otmp; otmp = otmp->nobj)
1914 if (otmp->oartifact && !is_quest_artifact(otmp)
1915 && defends_when_carried(AD_MAGM, otmp))
1920 dmgval2 = (dmgval2 + 3) / 4;
1923 You_feel((dmgval2 >= hp) ? "unbearably torpid!"
1924 : (dmgval2 >= hp / 4) ? "very lethargic."
1927 You_feel((dmgval2 >= hp) ? "
\91Ï
\82¦
\82ç
\82ê
\82È
\82¢
\82Ù
\82Ç
\96³
\8bC
\97Í
\82É
\82È
\82Á
\82½
\81I"
1928 : (dmgval2 >= hp / 4) ? "
\82Æ
\82Ä
\82à
\8bC
\82¾
\82é
\82
\82È
\82Á
\82½
\81D"
1929 : "
\82à
\82Ì
\82®
\82³
\82È
\8bC
\95ª
\82É
\82È
\82Á
\82½
\81D");
1931 /* opposite of magical explosion */
1933 losehp(dmgval2, "anti-magic implosion", KILLED_BY_AN);
1935 losehp(dmgval2, "
\94½
\96\82\96@
\82Ì
\93à
\95\94\94j
\97ô
\82Å", KILLED_BY_AN);
1940 char verbbuf[BUFSZ];
1945 Strcpy(verbbuf, "trigger"); /* follows "You sit down." */
1947 Strcpy(verbbuf, "
\82ð
\88ø
\82«
\8bN
\82±
\82µ
\82½"); /* follows "You sit down." */
1951 Sprintf(verbbuf, "lead %s onto",
1952 x_monnam(u.usteed, steed_article, (char *) 0,
1953 SUPPRESS_SADDLE, FALSE));
1955 Sprintf(verbbuf, "
\82É%s
\82Æ
\82Æ
\82à
\82É
\94ò
\82Ñ
\8d\9e\82ñ
\82¾",
1956 x_monnam(u.usteed, steed_article, (char *) 0,
1957 SUPPRESS_SADDLE, FALSE));
1961 Sprintf(verbbuf, "%s onto",
1962 Levitation ? (const char *) "float"
1963 : locomotion(youmonst.data, "step"));
1965 Sprintf(verbbuf,"
\82É%s",
1966 jpast(Levitation ? (const char *)"
\95\82\82«
\82È
\82ª
\82ç
\94ò
\82Ñ
\82±
\82Þ"
1967 : locomotion(youmonst.data, "
\93¥
\82Ý
\8d\9e\82Þ")));
1970 You("%s a polymorph trap!", verbbuf);
1972 You("
\95Ï
\89»
\82Ìã©%s
\81I", verbbuf);
1973 if (Antimagic || Unchanging) {
1974 shieldeff(u.ux, u.uy);
1976 You_feel("momentarily different.");
1978 You("
\88ê
\8fu
\88á
\82Á
\82½
\8a´
\82¶
\82ª
\82µ
\82½
\81D");
1979 /* Trap did nothing; don't remove it --KAA */
1981 (void) steedintrap(trap, (struct obj *) 0);
1982 deltrap(trap); /* delete trap before polymorph */
1983 newsym(u.ux, u.uy); /* get rid of trap symbol */
1985 You_feel("a change coming over you.");
1987 You("
\95Ï
\89»
\82ª
\96K
\82ê
\82½
\82æ
\82¤
\82È
\8bC
\82ª
\82µ
\82½
\81D");
1993 unsigned steed_mid = 0;
1994 struct obj *saddle = 0;
1996 if ((Levitation || Flying) && !forcetrap) {
1997 if (!already_seen && rn2(3))
2001 pline("%s %s in a pile of soil below you.",
2002 already_seen ? "There is" : "You discover",
2003 trap->madeby_u ? "the trigger of your mine" : "a trigger");
2006 pline("
\82±
\82±
\82É
\82Í%s
\92n
\97\8b\82Ì
\8bN
\94\9a\83X
\83C
\83b
\83`
\82ª
\82 \82é
\81D",
2007 set_you[trap->madeby_u]);
2009 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",
2010 set_you[trap->madeby_u]);
2012 if (already_seen && rn2(3))
2015 pline("KAABLAMM!!! %s %s%s off!",
2016 forcebungle ? "Your inept attempt sets"
2017 : "The air currents set",
2018 already_seen ? a_your[trap->madeby_u] : "",
2019 already_seen ? " land mine" : "it");
2021 pline("
\82¿
\82ã
\82Ç
\81[
\82ñ
\81I
\81I%s%s%s
\8bN
\94\9a\83X
\83C
\83b
\83`
\82ª
\94
\93®
\82µ
\82½
\81I",
2022 forcebungle ? "
\95s
\8aí
\97p
\82È
\82¹
\82¢
\82Å"
2023 : "
\8bó
\8bC
\82Ì
\97¬
\82ê
\82Å",
2024 already_seen ? set_you[trap->madeby_u] : "",
2025 already_seen ? "
\92n
\97\8b\82Ì" : "");
2028 /* prevent landmine from killing steed, throwing you to
2029 * the ground, and you being affected again by the same
2030 * mine because it hasn't been deleted yet
2032 static boolean recursive_mine = FALSE;
2038 pline("KAABLAMM!!! You triggered %s land mine!",
2039 a_your[trap->madeby_u]);
2041 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",
2042 set_you[trap->madeby_u]);
2045 steed_mid = u.usteed->m_id;
2046 recursive_mine = TRUE;
2047 (void) steedintrap(trap, (struct obj *) 0);
2048 recursive_mine = FALSE;
2049 saddle = sobj_at(SADDLE, u.ux, u.uy);
2050 set_wounded_legs(LEFT_SIDE, rn1(35, 41));
2051 set_wounded_legs(RIGHT_SIDE, rn1(35, 41));
2052 exercise(A_DEX, FALSE);
2054 blow_up_landmine(trap);
2055 if (steed_mid && saddle && !u.usteed)
2056 (void) keep_saddle_with_steedcorpse(steed_mid, fobj, saddle);
2057 newsym(u.ux, u.uy); /* update trap symbol */
2059 losehp(Maybe_Half_Phys(rnd(16)), "land mine", KILLED_BY_AN);
2061 losehp(Maybe_Half_Phys(rnd(16)), "
\92n
\97\8b\82ð
\93¥
\82ñ
\82Å", KILLED_BY_AN);
2062 /* fall recursively into the pit... */
2063 if ((trap = t_at(u.ux, u.uy)) != 0)
2064 dotrap(trap, RECURSIVETRAP);
2065 fill_pit(u.ux, u.uy);
2069 case ROLLING_BOULDER_TRAP: {
2070 int style = ROLL | (trap->tseen ? LAUNCH_KNOWN : 0);
2074 pline("Click! You trigger a rolling boulder trap!");
2076 pline("
\83J
\83`
\83b
\81I
\82 \82È
\82½
\82Í
\8b\90\8aâ
\82Ìã©
\82Ì
\83X
\83C
\83b
\83`
\82ð
\93¥
\82ñ
\82¾
\81I");
2077 if (!launch_obj(BOULDER, trap->launch.x, trap->launch.y,
2078 trap->launch2.x, trap->launch2.y, style)) {
2080 newsym(u.ux, u.uy); /* get rid of trap symbol */
2082 pline("Fortunately for you, no boulder was released.");
2084 pline("
\89^
\82Ì
\82æ
\82¢
\82±
\82Æ
\82É
\8aâ
\82Í
\93]
\82ª
\82Á
\82Ä
\82±
\82È
\82©
\82Á
\82½
\81D");
2091 domagicportal(trap);
2094 case VIBRATING_SQUARE:
2096 /* messages handled elsewhere; the trap symbol is merely to mark the
2097 * square for future reference */
2102 impossible("You hit a trap of type %u", trap->ttyp);
2107 trapnote(trap, noprefix)
2111 static char tnbuf[12];
2114 *tnnames[12] = { "C note", "D flat", "D note", "E flat",
2115 "E note", "F note", "F sharp", "G note",
2116 "G sharp", "A note", "B flat", "B note" };
2118 *tnnames[12] = { "
\83h", "
\83\8c\81ó", "
\83\8c", "
\83~
\81ó",
2119 "
\83~", "
\83t
\83@", "
\83t
\83@
\81ò", "
\83\",
2120 "
\83\
\81ò", "
\83\89", "
\83V
\81ó", "
\83V" };
2124 tn = tnnames[trap->tnote];
2127 Sprintf(tnbuf, "%s ",
2128 (*tn == 'A' || *tn == 'E' || *tn == 'F') ? "an" : "a");
2129 Sprintf(eos(tnbuf), "%s", tn);
2131 Sprintf(tnbuf, "%s
\82Ì
\89¹", tn);
2137 steedintrap(trap, otmp)
2141 struct monst *steed = u.usteed;
2143 boolean trapkilled, steedhit;
2145 if (!steed || !trap)
2150 trapkilled = steedhit = FALSE;
2155 impossible("steed hit by non-existent arrow?");
2158 trapkilled = thitm(8, steed, otmp, 0, FALSE);
2163 impossible("steed hit by non-existent dart?");
2166 trapkilled = thitm(7, steed, otmp, 0, FALSE);
2170 if (!resists_sleep(steed) && !breathless(steed->data)
2171 && !steed->msleeping && steed->mcanmove) {
2172 if (sleep_monst(steed, rnd(25), -1))
2173 /* no in_sight check here; you can feel it even if blind */
2175 pline("%s suddenly falls asleep!", Monnam(steed));
2177 pline("%s
\82Í
\82Æ
\82Â
\82º
\82ñ
\96°
\82Á
\82Ä
\82µ
\82Ü
\82Á
\82½
\81I", Monnam(steed));
2182 trapkilled = thitm(0, steed, (struct obj *) 0, rnd(16), FALSE);
2187 trapkilled = (DEADMONSTER(steed)
2188 || thitm(0, steed, (struct obj *) 0,
2189 rnd((tt == PIT) ? 6 : 10), FALSE));
2193 if (!resists_magm(steed) && !resist(steed, WAND_CLASS, 0, NOTELL)) {
2194 struct permonst *mdat = steed->data;
2196 (void) newcham(steed, (struct permonst *) 0, FALSE, FALSE);
2197 if (!can_saddle(steed) || !can_ride(steed)) {
2198 dismount_steed(DISMOUNT_POLY);
2202 Strcpy(buf, x_monnam(steed, ARTICLE_YOUR, (char *) 0,
2203 SUPPRESS_SADDLE, FALSE));
2204 if (mdat != steed->data)
2205 (void) strsubst(buf, "your ", "your new ");
2207 You("adjust yourself in the saddle on %s.", buf);
2209 You("%s
\82Ì
\88Æ
\82Ì
\8fã
\82Å
\8dÀ
\82è
\82È
\82¨
\82µ
\82½
\81D", buf);
2219 dismount_steed(DISMOUNT_POLY);
2222 return steedhit ? 1 : 0;
2225 /* some actions common to both player and monsters for triggered landmine */
2227 blow_up_landmine(trap)
2230 int x = trap->tx, y = trap->ty, dbx, dby;
2231 struct rm *lev = &levl[x][y];
2233 (void) scatter(x, y, 4,
2234 MAY_DESTROY | MAY_HIT | MAY_FRACTURE | VIS_EFFECTS,
2237 wake_nearto(x, y, 400);
2238 if (IS_DOOR(lev->typ))
2239 lev->doormask = D_BROKEN;
2240 /* destroy drawbridge if present */
2241 if (lev->typ == DRAWBRIDGE_DOWN || is_drawbridge_wall(x, y) >= 0) {
2243 /* if under the portcullis, the bridge is adjacent */
2244 if (find_drawbridge(&dbx, &dby))
2245 destroy_drawbridge(dbx, dby);
2246 trap = t_at(x, y); /* expected to be null after destruction */
2248 /* convert landmine into pit */
2250 if (Is_waterlevel(&u.uz) || Is_airlevel(&u.uz)) {
2254 trap->ttyp = PIT; /* explosion creates a pit */
2255 trap->madeby_u = FALSE; /* resulting pit isn't yours */
2256 seetrap(trap); /* and it isn't concealed */
2262 * The following are used to track launched objects to
2263 * prevent them from vanishing if you are killed. They
2264 * will reappear at the launchplace in bones files.
2272 launch_drop_spot(obj, x, y)
2277 launchplace.obj = (struct obj *) 0;
2281 launchplace.obj = obj;
2288 launch_in_progress()
2290 if (launchplace.obj)
2296 force_launch_placement()
2298 if (launchplace.obj) {
2299 launchplace.obj->otrapped = 0;
2300 place_object(launchplace.obj, launchplace.x, launchplace.y);
2305 * Move obj from (x1,y1) to (x2,y2)
2307 * Return 0 if no object was launched.
2308 * 1 if an object was launched and placed somewhere.
2309 * 2 if an object was launched, but used up.
2312 launch_obj(otyp, x1, y1, x2, y2, style)
2314 register int x1, y1, x2, y2;
2317 register struct monst *mtmp;
2318 register struct obj *otmp, *otmp2;
2319 register int dx, dy;
2320 struct obj *singleobj;
2321 boolean used_up = FALSE;
2322 boolean otherside = FALSE;
2327 otmp = sobj_at(otyp, x1, y1);
2328 /* Try the other side too, for rolling boulder traps */
2329 if (!otmp && otyp == BOULDER) {
2331 otmp = sobj_at(otyp, x2, y2);
2335 if (otherside) { /* swap 'em */
2346 if (otmp->quan == 1L) {
2347 obj_extract_self(otmp);
2349 otmp = (struct obj *) 0;
2351 singleobj = splitobj(otmp, 1L);
2352 obj_extract_self(singleobj);
2355 /* in case you're using a pick-axe to chop the boulder that's being
2356 launched (perhaps a monster triggered it), destroy context so that
2357 next dig attempt never thinks you're resuming previous effort */
2358 if ((otyp == BOULDER || otyp == STATUE)
2359 && singleobj->ox == context.digging.pos.x
2360 && singleobj->oy == context.digging.pos.y)
2361 (void) memset((genericptr_t) &context.digging, 0,
2362 sizeof(struct dig_info));
2364 dist = distmin(x1, y1, x2, y2);
2370 case ROLL | LAUNCH_UNSEEN:
2371 if (otyp == BOULDER) {
2373 You_hear(Hallucination ? "someone bowling."
2374 : "rumbling in the distance.");
2376 You_hear(Hallucination ? "
\92N
\82©
\82ª
\83{
\81[
\83\8a\83\93\83O
\82ð
\82µ
\82Ä
\82¢
\82é
\89¹
\82ð
\95·
\82¢
\82½
\81D"
2377 : "
\89\93\82
\82Ì
\83S
\83\8d\83S
\83\8d\82Æ
\82¢
\82¤
\89¹
\82ð
\95·
\82¢
\82½
\81D");
2380 style &= ~LAUNCH_UNSEEN;
2382 case ROLL | LAUNCH_KNOWN:
2383 /* use otrapped as a flag to ohitmon */
2384 singleobj->otrapped = 1;
2385 style &= ~LAUNCH_KNOWN;
2394 if (!cansee(bhitpos.x, bhitpos.y))
2396 tmp_at(DISP_FLASH, obj_to_glyph(singleobj, rn2_on_display_rng));
2397 tmp_at(bhitpos.x, bhitpos.y);
2399 /* Mark a spot to place object in bones files to prevent
2400 * loss of object. Use the starting spot to ensure that
2401 * a rolling boulder will still launch, which it wouldn't
2402 * do if left midstream. Unfortunately we can't use the
2403 * target resting spot, because there are some things/situations
2404 * that would prevent it from ever getting there (bars), and we
2405 * can't tell that yet.
2407 launch_drop_spot(singleobj, bhitpos.x, bhitpos.y);
2409 /* Set the object in motion */
2410 while (dist-- > 0 && !used_up) {
2412 tmp_at(bhitpos.x, bhitpos.y);
2415 /* dstage@u.washington.edu -- Delay only if hero sees it */
2416 if (cansee(bhitpos.x, bhitpos.y))
2423 if ((mtmp = m_at(bhitpos.x, bhitpos.y)) != 0) {
2424 if (otyp == BOULDER && throws_rocks(mtmp->data)) {
2426 if (cansee(bhitpos.x, bhitpos.y))
2428 pline("%s snatches the boulder.", Monnam(mtmp));
2430 pline("%s
\82Í
\8aâ
\82ð
\82Â
\82©
\82Ý
\8eæ
\82Á
\82½
\81D", Monnam(mtmp));
2431 singleobj->otrapped = 0;
2432 (void) mpickobj(mtmp, singleobj);
2434 launch_drop_spot((struct obj *) 0, 0, 0);
2438 if (ohitmon(mtmp, singleobj, (style == ROLL) ? -1 : dist,
2441 launch_drop_spot((struct obj *) 0, 0, 0);
2444 } else if (bhitpos.x == u.ux && bhitpos.y == u.uy) {
2447 if (thitu(9 + singleobj->spe, dmgval(singleobj, &youmonst),
2448 &singleobj, (char *) 0))
2451 if (style == ROLL) {
2452 if (down_gate(bhitpos.x, bhitpos.y) != -1) {
2453 if (ship_object(singleobj, bhitpos.x, bhitpos.y, FALSE)) {
2455 launch_drop_spot((struct obj *) 0, 0, 0);
2459 if ((t = t_at(bhitpos.x, bhitpos.y)) != 0 && otyp == BOULDER) {
2466 cansee(bhitpos.x, bhitpos.y)
2467 ? " The rolling boulder triggers a land mine."
2471 "
\82¿
\82ã
\82Ç
\81[
\82ñ
\81I
\81I%s",
2472 cansee(bhitpos.x, bhitpos.y)
2473 ? "
\93]
\82ª
\82Á
\82Ä
\82«
\82½
\8aâ
\82ª
\92n
\97\8b\82Ì
\8bN
\94\9a\83X
\83C
\83b
\83`
\82ð
\93¥
\82ñ
\82¾
\81D"
2477 del_engr_at(bhitpos.x, bhitpos.y);
2478 place_object(singleobj, bhitpos.x, bhitpos.y);
2479 singleobj->otrapped = 0;
2480 fracture_rock(singleobj);
2481 (void) scatter(bhitpos.x, bhitpos.y, 4,
2482 MAY_DESTROY | MAY_HIT | MAY_FRACTURE
2485 if (cansee(bhitpos.x, bhitpos.y))
2486 newsym(bhitpos.x, bhitpos.y);
2488 launch_drop_spot((struct obj *) 0, 0, 0);
2493 if (cansee(bhitpos.x, bhitpos.y))
2495 pline("Suddenly the rolling boulder disappears!");
2497 pline("
\93]
\82ª
\82Á
\82Ä
\82«
\82½
\8aâ
\82ª
\82Æ
\82Â
\82º
\82ñ
\8fÁ
\82¦
\82½
\81I");
2500 You_hear("a rumbling stop abruptly.");
2502 pline("
\83S
\83\8d\83S
\83\8d\82Æ
\82¢
\82¤
\89¹
\82ª
\93Ë
\91R
\8e~
\82Ü
\82Á
\82½
\81D");
2503 singleobj->otrapped = 0;
2504 if (t->ttyp == TELEP_TRAP)
2505 (void) rloco(singleobj);
2507 int newlev = random_teleport_level();
2510 if (newlev == depth(&u.uz) || In_endgame(&u.uz))
2512 add_to_migration(singleobj);
2513 get_level(&dest, newlev);
2514 singleobj->ox = dest.dnum;
2515 singleobj->oy = dest.dlevel;
2516 singleobj->owornmask = (long) MIGR_RANDOM;
2520 launch_drop_spot((struct obj *) 0, 0, 0);
2526 /* the boulder won't be used up if there is a
2527 monster in the trap; stop rolling anyway */
2528 x2 = bhitpos.x, y2 = bhitpos.y; /* stops here */
2530 if (flooreffects(singleobj, x2, y2, "fall")) {
2532 if (flooreffects(singleobj, x2, y2, "
\97\8e\82¿
\82é")) {
2534 launch_drop_spot((struct obj *) 0, 0, 0);
2536 dist = -1; /* stop rolling immediately */
2539 if (used_up || dist == -1)
2543 if (flooreffects(singleobj, bhitpos.x, bhitpos.y, "fall")) {
2545 if (flooreffects(singleobj, bhitpos.x, bhitpos.y, "
\97\8e\82¿
\82é")) {
2547 launch_drop_spot((struct obj *) 0, 0, 0);
2551 && (otmp2 = sobj_at(BOULDER, bhitpos.x, bhitpos.y)) != 0) {
2553 const char *bmsg = " as one boulder sets another in motion";
2555 const char *bmsg = "
\82Ð
\82Æ
\82Â
\82Ì
\8aâ
\82ª
\91¼
\82Ì
\8aâ
\82ð
\93®
\82©
\82µ
\82½
\82©
\82Ì
\82æ
\82¤
\82È
\81C";
2557 if (!isok(bhitpos.x + dx, bhitpos.y + dy) || !dist
2558 || IS_ROCK(levl[bhitpos.x + dx][bhitpos.y + dy].typ))
2560 bmsg = " as one boulder hits another";
2562 bmsg = "
\82Ð
\82Æ
\82Â
\82Ì
\8aâ
\82ª
\91¼
\82Ì
\8aâ
\82É
\93\96\82½
\82Á
\82½
\82æ
\82¤
\82È";
2565 You_hear("a loud crash%s!",
2567 You_hear("%s
\91å
\82«
\82È
\83S
\83\93\82Æ
\82¢
\82¤
\89¹
\82ð
\95·
\82¢
\82½
\81I",
2568 cansee(bhitpos.x, bhitpos.y) ? bmsg : "");
2569 obj_extract_self(otmp2);
2570 /* pass off the otrapped flag to the next boulder */
2571 otmp2->otrapped = singleobj->otrapped;
2572 singleobj->otrapped = 0;
2573 place_object(singleobj, bhitpos.x, bhitpos.y);
2575 otmp2 = (struct obj *) 0;
2576 wake_nearto(bhitpos.x, bhitpos.y, 10 * 10);
2579 if (otyp == BOULDER && closed_door(bhitpos.x, bhitpos.y)) {
2580 if (cansee(bhitpos.x, bhitpos.y))
2582 pline_The("boulder crashes through a door.");
2584 pline("
\8aâ
\82Í
\94à
\82ð
\94j
\89ó
\82µ
\82½
\81D");
2585 levl[bhitpos.x][bhitpos.y].doormask = D_BROKEN;
2587 unblock_point(bhitpos.x, bhitpos.y);
2590 /* if about to hit iron bars, do so now */
2591 if (dist > 0 && isok(bhitpos.x + dx, bhitpos.y + dy)
2592 && levl[bhitpos.x + dx][bhitpos.y + dy].typ == IRONBARS) {
2593 x2 = bhitpos.x, y2 = bhitpos.y; /* object stops here */
2594 if (hits_bars(&singleobj,
2595 x2, y2, x2+dx, y2+dy,
2599 launch_drop_spot((struct obj *) 0, 0, 0);
2605 tmp_at(DISP_END, 0);
2606 launch_drop_spot((struct obj *) 0, 0, 0);
2608 singleobj->otrapped = 0;
2609 place_object(singleobj, x2, y2);
2622 newsym(trap->tx, trap->ty);
2626 /* like seetrap() but overrides vision */
2633 /* in case it's beneath something, redisplay the something */
2634 newsym(trap->tx, trap->ty);
2638 mkroll_launch(ttmp, x, y, otyp, ocount)
2651 boolean success = FALSE;
2654 if (ttmp->ttyp == ROLLING_BOULDER_TRAP)
2656 distance = rn1(5, 4); /* 4..8 away */
2657 tmp = rn2(8); /* randomly pick a direction to try first */
2658 while (distance >= mindist) {
2663 /* Prevent boulder from being placed on water */
2664 if (ttmp->ttyp == ROLLING_BOULDER_TRAP
2665 && is_pool_or_lava(x + distance * dx, y + distance * dy))
2668 success = isclearpath(&cc, distance, dx, dy);
2669 if (ttmp->ttyp == ROLLING_BOULDER_TRAP) {
2670 boolean success_otherway;
2674 success_otherway = isclearpath(&bcc, distance, -(dx), -(dy));
2675 if (!success_otherway)
2682 if ((++trycount % 8) == 0)
2686 /* create the trap without any ammo, launch pt at trap location */
2690 otmp = mksobj(otyp, TRUE, FALSE);
2691 otmp->quan = ocount;
2692 otmp->owt = weight(otmp);
2693 place_object(otmp, cc.x, cc.y);
2696 ttmp->launch.x = cc.x;
2697 ttmp->launch.y = cc.y;
2698 if (ttmp->ttyp == ROLLING_BOULDER_TRAP) {
2699 ttmp->launch2.x = bcc.x;
2700 ttmp->launch2.y = bcc.y;
2702 ttmp->launch_otyp = otyp;
2703 newsym(ttmp->launch.x, ttmp->launch.y);
2708 isclearpath(cc, distance, dx, dy)
2718 while (distance-- > 0) {
2721 typ = levl[x][y].typ;
2722 if (!isok(x, y) || !ZAP_POS(typ) || closed_door(x, y))
2732 register struct monst *mtmp;
2734 register struct trap *trap = t_at(mtmp->mx, mtmp->my);
2735 boolean trapkilled = FALSE;
2736 struct permonst *mptr = mtmp->data;
2740 mtmp->mtrapped = 0; /* perhaps teleported? */
2741 } else if (mtmp->mtrapped) { /* is currently in the trap */
2742 if (!trap->tseen && cansee(mtmp->mx, mtmp->my) && canseemon(mtmp)
2743 && (is_pit(trap->ttyp) || trap->ttyp == BEAR_TRAP
2744 || trap->ttyp == HOLE
2745 || trap->ttyp == WEB)) {
2746 /* If you come upon an obviously trapped monster, then
2747 * you must be able to see the trap it's in too.
2753 if (sobj_at(BOULDER, mtmp->mx, mtmp->my)
2754 && is_pit(trap->ttyp)) {
2757 if (canseemon(mtmp))
2759 pline("%s pulls free...", Monnam(mtmp));
2761 pline("%s
\82Í
\8f\95\82¯
\8fã
\82°
\82ç
\82ê
\82½
\81D", Monnam(mtmp));
2762 fill_pit(mtmp->mx, mtmp->my);
2767 } else if (metallivorous(mptr)) {
2768 if (trap->ttyp == BEAR_TRAP) {
2769 if (canseemon(mtmp))
2771 pline("%s eats a bear trap!", Monnam(mtmp));
2773 pline("%s
\82Í
\8cF
\82Ìã©
\82ð
\90H
\82×
\82½
\81I", Monnam(mtmp));
2777 } else if (trap->ttyp == SPIKED_PIT) {
2778 if (canseemon(mtmp))
2780 pline("%s munches on some spikes!", Monnam(mtmp));
2782 pline("%s
\82Í
\83g
\83Q
\83g
\83Q
\82ð
\90H
\82×
\82½
\81I", Monnam(mtmp));
2788 register int tt = trap->ttyp;
2789 boolean in_sight, tear_web, see_it,
2790 inescapable = force_mintrap || ((tt == HOLE || tt == PIT)
2791 && Sokoban && !trap->madeby_u);
2792 const char *fallverb;
2793 xchar tx = trap->tx, ty = trap->ty;
2795 /* true when called from dotrap, inescapable is not an option */
2796 if (mtmp == u.usteed)
2798 if (!inescapable && ((mtmp->mtrapseen & (1 << (tt - 1))) != 0
2799 || (tt == HOLE && !mindless(mptr)))) {
2800 /* it has been in such a trap - perhaps it escapes */
2804 mtmp->mtrapseen |= (1 << (tt - 1));
2806 /* Monster is aggravated by being trapped by you.
2807 Recognizing who made the trap isn't completely
2808 unreasonable; everybody has their own style. */
2809 if (trap->madeby_u && rnl(5))
2810 setmangry(mtmp, TRUE);
2812 in_sight = canseemon(mtmp);
2813 see_it = cansee(mtmp->mx, mtmp->my);
2814 /* assume hero can tell what's going on for the steed */
2815 if (mtmp == u.usteed)
2819 if (trap->once && trap->tseen && !rn2(15)) {
2820 if (in_sight && see_it)
2822 pline("%s triggers a trap but nothing happens.",
2825 pline("%s
\82ª
\82í
\82È
\82ð
\8bN
\93®
\82³
\82¹
\82½
\82ª
\89½
\82à
\8bN
\82±
\82ç
\82È
\82©
\82Á
\82½
\81D",
2829 newsym(mtmp->mx, mtmp->my);
2833 otmp = t_missile(ARROW, trap);
2836 if (thitm(8, mtmp, otmp, 0, FALSE))
2840 if (trap->once && trap->tseen && !rn2(15)) {
2841 if (in_sight && see_it)
2843 pline("%s triggers a trap but nothing happens.",
2846 pline("%s
\82ª
\82í
\82È
\82ð
\8bN
\93®
\82³
\82¹
\82½
\82ª
\89½
\82à
\8bN
\82±
\82ç
\82È
\82©
\82Á
\82½
\81D",
2850 newsym(mtmp->mx, mtmp->my);
2854 otmp = t_missile(DART, trap);
2856 otmp->opoisoned = 1;
2859 if (thitm(7, mtmp, otmp, 0, FALSE))
2863 if (trap->once && trap->tseen && !rn2(15)) {
2864 if (in_sight && see_it)
2867 "A trap door above %s opens, but nothing falls out!",
2869 "%s
\82Ì
\8fã
\82Ì
\94à
\82ª
\8aJ
\82¢
\82½
\82ª
\81C
\89½
\82à
\97\8e\82¿
\82Ä
\82±
\82È
\82©
\82Á
\82½
\81I",
2872 newsym(mtmp->mx, mtmp->my);
2876 otmp = t_missile(ROCK, trap);
2879 if (thitm(0, mtmp, otmp, d(2, 6), FALSE))
2885 /* stepped on a squeaky board */
2889 pline("A board beneath %s squeaks %s loudly.",
2890 mon_nam(mtmp), trapnote(trap, 0));
2892 pline("%s
\82Ì
\91«
\8c³
\82Ì
\94Â
\82ª
\91å
\82«
\82%s
\82É
\82«
\82µ
\82ñ
\82¾
\81D",
2893 mon_nam(mtmp), trapnote(trap, 0));
2898 pline("%s stops momentarily and appears to cringe.",
2900 pline("%s
\82Í
\88ê
\8fu
\8e~
\82Ü
\82Á
\82Ä
\90g
\82ð
\82·
\82
\82ß
\82½
\82æ
\82¤
\82¾
\81D",
2904 /* same near/far threshold as mzapmsg() */
2905 int range = couldsee(mtmp->mx, mtmp->my) /* 9 or 5 */
2906 ? (BOLT_LIM + 1) : (BOLT_LIM - 3);
2909 You_hear("a %s squeak %s.", trapnote(trap, 1),
2910 (distu(mtmp->mx, mtmp->my) <= range * range)
2911 ? "nearby" : "in the distance");
2913 You_hear("%s
\82
\82Å%s
\82ª
\82«
\82µ
\82Þ
\89¹
\82ð
\95·
\82¢
\82½
\81D",
2914 (distu(mtmp->mx, mtmp->my) <= range * range)
2915 ? "
\8bß" : "
\89\93",
2919 /* wake up nearby monsters */
2920 wake_nearto(mtmp->mx, mtmp->my, 40);
2923 if (mptr->msize > MZ_SMALL && !amorphous(mptr) && !is_flyer(mptr)
2924 && !is_whirly(mptr) && !unsolid(mptr)) {
2928 pline("%s is caught in %s bear trap!", Monnam(mtmp),
2929 a_your[trap->madeby_u]);
2931 pline("%s
\82Í%s
\8cF
\82Ìã©
\82É
\82Â
\82©
\82Ü
\82Á
\82½
\81I", Monnam(mtmp),
2932 set_you[trap->madeby_u]);
2936 if (mptr == &mons[PM_OWLBEAR]
2937 || mptr == &mons[PM_BUGBEAR])
2939 You_hear("the roaring of an angry bear!");
2941 You_hear("
\93{
\82è
\82Ì
\99ô
\9aK
\82ð
\95·
\82¢
\82½
\81I");
2943 } else if (force_mintrap) {
2946 pline("%s evades %s bear trap!", Monnam(mtmp),
2947 a_your[trap->madeby_u]);
2949 pline("%s
\82Í%s
\8cF
\82Ìã©
\82ð
\82½
\82
\82Ý
\82É
\94ð
\82¯
\82½
\81I", Monnam(mtmp),
2950 set_you[trap->madeby_u]);
2956 trapkilled = thitm(0, mtmp, (struct obj *) 0, d(2, 4), FALSE);
2959 if (!resists_sleep(mtmp) && !breathless(mptr) && !mtmp->msleeping
2960 && mtmp->mcanmove) {
2961 if (sleep_monst(mtmp, rnd(25), -1) && in_sight) {
2963 pline("%s suddenly falls asleep!", Monnam(mtmp));
2965 pline("%s
\82Í
\93Ë
\91R
\96°
\82è
\82É
\97\8e\82¿
\82½
\81I", Monnam(mtmp));
2979 pline("%s %s on the %s!", A_gush_of_water_hits,
2980 mon_nam(mtmp), mbodypart(mtmp, HEAD));
2982 pline("
\90\85\82ª
\95¬
\8fo
\82µ
\82Ä
\81C%s
\82Ì%s
\82É
\96½
\92\86\82µ
\82½
\81I",
2983 mon_nam(mtmp), mbodypart(mtmp, HEAD));
2985 target = which_armor(mtmp, W_ARMH);
2986 (void) water_damage(target, helm_simple_name(target), TRUE);
2991 pline("%s %s's left %s!", A_gush_of_water_hits,
2992 mon_nam(mtmp), mbodypart(mtmp, ARM));
2994 pline("
\90\85\82ª
\95¬
\8fo
\82µ
\82Ä
\81C%s
\82Ì
\8d¶%s
\82É
\96½
\92\86\82µ
\82½
\81I",
2995 mon_nam(mtmp), mbodypart(mtmp, ARM));
2997 target = which_armor(mtmp, W_ARMS);
2999 if (water_damage(target, "shield", TRUE) != ER_NOTHING)
3001 if (water_damage(target, "
\8f\82", TRUE) != ER_NOTHING)
3003 target = MON_WEP(mtmp);
3004 if (target && bimanual(target))
3005 (void) water_damage(target, 0, TRUE);
3007 target = which_armor(mtmp, W_ARMG);
3009 (void) water_damage(target, "gauntlets", TRUE);
3011 (void) water_damage(target, "
\8f¬
\8eè", TRUE);
3016 pline("%s %s's right %s!", A_gush_of_water_hits,
3017 mon_nam(mtmp), mbodypart(mtmp, ARM));
3019 pline("
\90\85\82ª
\95¬
\8fo
\82µ
\82Ä
\81C%s
\82Ì
\89E%s
\82É
\96½
\92\86\82µ
\82½
\81I",
3020 mon_nam(mtmp), mbodypart(mtmp, ARM));
3022 (void) water_damage(MON_WEP(mtmp), 0, TRUE);
3027 pline("%s %s!", A_gush_of_water_hits, mon_nam(mtmp));
3029 pline("
\90\85\82ª
\95¬
\8fo
\82µ
\82Ä
\81C%s
\82É
\96½
\92\86\82µ
\82½
\81I", mon_nam(mtmp));
3030 for (otmp = mtmp->minvent; otmp; otmp = otmp->nobj)
3032 && (otmp->owornmask & (W_WEP | W_SWAPWEP)) == 0)
3033 (void) snuff_lit(otmp);
3034 if ((target = which_armor(mtmp, W_ARMC)) != 0)
3035 (void) water_damage(target, cloak_simple_name(target),
3037 else if ((target = which_armor(mtmp, W_ARM)) != 0)
3038 (void) water_damage(target, suit_simple_name(target),
3040 else if ((target = which_armor(mtmp, W_ARMU)) != 0)
3042 (void) water_damage(target, "shirt", TRUE);
3044 (void) water_damage(target, "
\83V
\83\83\83c", TRUE);
3047 if (mptr == &mons[PM_IRON_GOLEM]) {
3050 pline("%s falls to pieces!", Monnam(mtmp));
3052 pline("%s
\82Í
\82
\82¾
\82¯
\82¿
\82Á
\82½
\81I", Monnam(mtmp));
3053 else if (mtmp->mtame)
3055 pline("May %s rust in peace.", mon_nam(mtmp));
3057 pline("%s
\82æ
\81C
\88À
\82ç
\82©
\82É
\8eK
\82Ñ
\82ñ
\8e\96\82ð
\81D", mon_nam(mtmp));
3059 if (DEADMONSTER(mtmp))
3061 } else if (mptr == &mons[PM_GREMLIN] && rn2(3)) {
3062 (void) split_mon(mtmp, (struct monst *) 0);
3070 pline("A %s erupts from the %s under %s!", tower_of_flame,
3071 surface(mtmp->mx, mtmp->my), mon_nam(mtmp));
3073 pline("
\89Î
\92\8c\82ª%s
\82Ì
\91«
\8c³
\82Ì%s
\82©
\82ç
\97§
\82¿
\82Ì
\82Ú
\82Á
\82½
\81I",
3074 mon_nam(mtmp), surface(mtmp->mx,mtmp->my));
3076 else if (see_it) /* evidently `mtmp' is invisible */
3078 You_see("a %s erupt from the %s!", tower_of_flame,
3079 surface(mtmp->mx, mtmp->my));
3081 You("
\89Î
\92\8c\82ª%s
\82©
\82ç
\90¶
\82¶
\82é
\82Ì
\82ð
\8c©
\82½
\81I",
3082 surface(mtmp->mx,mtmp->my));
3085 if (resists_fire(mtmp)) {
3087 shieldeff(mtmp->mx, mtmp->my);
3089 pline("%s is uninjured.", Monnam(mtmp));
3091 pline("
\82ª
\81C%s
\82Í
\8f\9d\82Â
\82©
\82È
\82¢
\81D", Monnam(mtmp));
3094 int num = d(2, 4), alt;
3095 boolean immolate = FALSE;
3097 /* paper burns very fast, assume straw is tightly
3098 * packed and burns a bit slower */
3099 switch (monsndx(mptr)) {
3100 case PM_PAPER_GOLEM:
3104 case PM_STRAW_GOLEM:
3105 alt = mtmp->mhpmax / 2;
3108 alt = mtmp->mhpmax / 4;
3110 case PM_LEATHER_GOLEM:
3111 alt = mtmp->mhpmax / 8;
3120 if (thitm(0, mtmp, (struct obj *) 0, num, immolate))
3123 /* we know mhp is at least `num' below mhpmax,
3124 so no (mhp > mhpmax) check is needed here */
3125 mtmp->mhpmax -= rn2(num + 1);
3127 if (burnarmor(mtmp) || rn2(3)) {
3128 (void) destroy_mitem(mtmp, SCROLL_CLASS, AD_FIRE);
3129 (void) destroy_mitem(mtmp, SPBOOK_CLASS, AD_FIRE);
3130 (void) destroy_mitem(mtmp, POTION_CLASS, AD_FIRE);
3132 if (burn_floor_objects(mtmp->mx, mtmp->my, see_it, FALSE)
3133 && !see_it && distu(mtmp->mx, mtmp->my) <= 3 * 3)
3135 You("smell smoke.");
3137 pline("
\89\8c\82Ì
\93õ
\82¢
\82ª
\82µ
\82½
\81D");
3138 if (is_ice(mtmp->mx, mtmp->my))
3139 melt_ice(mtmp->mx, mtmp->my, (char *) 0);
3140 if (see_it && t_at(mtmp->mx, mtmp->my))
3148 fallverb = "
\97\8e\82¿
\82½";
3149 if (is_flyer(mptr) || is_floater(mptr)
3150 || (mtmp->wormno && count_wsegs(mtmp) > 5)
3151 || is_clinger(mptr)) {
3152 if (force_mintrap && !Sokoban) {
3153 /* openfallingtrap; not inescapable here */
3157 pline("%s doesn't fall into the pit.", Monnam(mtmp));
3159 pline("%s
\82Í
\97\8e\82µ
\8c\8a\82É
\97\8e\82¿
\82È
\82©
\82Á
\82½
\81D", Monnam(mtmp));
3161 break; /* inescapable = FALSE; */
3164 break; /* avoids trap */
3166 fallverb = "is dragged"; /* sokoban pit */
3168 fallverb = "
\82¸
\82è
\97\8e\82¿
\82½"; /* sokoban pit */
3171 if (!passes_walls(mptr))
3175 pline("%s %s into %s pit!", Monnam(mtmp), fallverb,
3176 a_your[trap->madeby_u]);
3178 pline("%s
\82Í%s
\97\8e\82µ
\8c\8a\82É%s
\81I", Monnam(mtmp),
3179 set_you[trap->madeby_u], fallverb);
3181 if (mptr == &mons[PM_PIT_VIPER]
3182 || mptr == &mons[PM_PIT_FIEND])
3184 pline("How pitiful. Isn't that the pits?");
3186 pline("
\82±
\82Ì
\97\8e\82µ
\8c\8a\82Í
\82¢
\82¢
\8ed
\8e\96\82ð
\82µ
\82Ä
\82¢
\82é
\81D");
3190 mselftouch(mtmp, "Falling, ", FALSE);
3192 mselftouch(mtmp, "
\97\8e\89º
\92\86\81C", FALSE);
3193 if (DEADMONSTER(mtmp) || thitm(0, mtmp, (struct obj *) 0,
3194 rnd((tt == PIT) ? 6 : 10), FALSE))
3199 if (!Can_fall_thru(&u.uz)) {
3200 impossible("mintrap: %ss cannot exist on this level.",
3201 defsyms[trap_to_defsym(tt)].explanation);
3202 break; /* don't activate it after all */
3204 if (is_flyer(mptr) || is_floater(mptr) || mptr == &mons[PM_WUMPUS]
3205 || (mtmp->wormno && count_wsegs(mtmp) > 5)
3206 || mptr->msize >= MZ_HUGE) {
3207 if (force_mintrap && !Sokoban) {
3208 /* openfallingtrap; not inescapable here */
3214 "A trap door opens, but %s doesn't fall through.",
3216 "
\97\8e\82µ
\94à
\82ª
\8aJ
\82¢
\82½
\82ª
\81C%s
\82Í
\97\8e\82¿
\82È
\82©
\82Á
\82½
\81D",
3218 else /* (tt == HOLE) */
3220 pline("%s doesn't fall through the hole.",
3222 pline("%s
\82Í
\8c\8a\82É
\97\8e\82¿
\82È
\82©
\82Á
\82½
\81D",
3225 break; /* inescapable = FALSE; */
3227 if (inescapable) { /* sokoban hole */
3230 pline("%s seems to be yanked down!", Monnam(mtmp));
3232 pline("%s
\82Í
\88ø
\82«
\97\8e\82³
\82ê
\82½
\82æ
\82¤
\82¾
\81I", Monnam(mtmp));
3233 /* suppress message in mlevel_tele_trap() */
3242 case MAGIC_PORTAL: {
3245 mlev_res = mlevel_tele_trap(mtmp, trap, inescapable, in_sight);
3251 mtele_trap(mtmp, trap, in_sight);
3254 /* Monster in a web. */
3257 if (mu_maybe_destroy_web(mtmp, in_sight, trap))
3260 switch (monsndx(mptr)) {
3261 case PM_OWLBEAR: /* Eric Backus */
3265 You_hear("the roaring of a confused bear!");
3267 You_hear("
\8d¬
\97\90\82Ì
\99ô
\9aK
\82ð
\95·
\82¢
\82½
\81I");
3273 if (mptr->mlet == S_GIANT
3274 /* exclude baby dragons and relatively short worms */
3275 || (mptr->mlet == S_DRAGON && extra_nasty(mptr))
3276 || (mtmp->wormno && count_wsegs(mtmp) > 5)) {
3278 } else if (in_sight) {
3280 pline("%s is caught in %s spider web.", Monnam(mtmp),
3281 a_your[trap->madeby_u]);
3283 pline("%s
\82Í%s
\82
\82à
\82Ì
\91\83\82É
\82Â
\82©
\82Ü
\82Á
\82½
\81D", Monnam(mtmp),
3284 web_you[trap->madeby_u]);
3288 mtmp->mtrapped = tear_web ? 0 : 1;
3290 /* this list is fairly arbitrary; it deliberately
3291 excludes wumpus & giant/ettin zombies/mummies */
3292 case PM_TITANOTHERE:
3293 case PM_BALUCHITHERIUM:
3294 case PM_PURPLE_WORM:
3303 case PM_LORD_SURTUR:
3310 pline("%s tears through %s spider web!", Monnam(mtmp),
3311 a_your[trap->madeby_u]);
3313 pline("%s
\82Í%s
\82
\82à
\82Ì
\91\83\82ð
\88ø
\82«
\97ô
\82¢
\82½
\81I", Monnam(mtmp),
3314 web_you[trap->madeby_u]);
3317 newsym(mtmp->mx, mtmp->my);
3318 } else if (force_mintrap && !mtmp->mtrapped) {
3321 pline("%s avoids %s spider web!", Monnam(mtmp),
3322 a_your[trap->madeby_u]);
3324 pline("%s
\82Í%s
\82
\82à
\82Ì
\91\83\82ð
\94ð
\82¯
\82½
\81I", Monnam(mtmp),
3325 web_you[trap->madeby_u]);
3334 /* A magic trap. Monsters usually immune. */
3339 /* similar to hero's case, more or less */
3340 if (!resists_magm(mtmp)) { /* lose spell energy */
3341 if (!mtmp->mcan && (attacktype(mptr, AT_MAGC)
3342 || attacktype(mptr, AT_BREA))) {
3343 mtmp->mspec_used += d(2, 2);
3347 pline("%s seems lethargic.", Monnam(mtmp));
3349 pline("%s
\88ê
\8fu
\96³
\8bC
\97Í
\8a´
\82ð
\8a´
\82¶
\82½
\81D", Monnam(mtmp));
3352 } else { /* take some damage */
3353 int dmgval2 = rnd(4);
3355 if ((otmp = MON_WEP(mtmp)) != 0
3356 && otmp->oartifact == ART_MAGICBANE)
3358 for (otmp = mtmp->minvent; otmp; otmp = otmp->nobj)
3360 && defends_when_carried(AD_MAGM, otmp))
3364 if (passes_walls(mptr))
3365 dmgval2 = (dmgval2 + 3) / 4;
3369 mtmp->mhp -= dmgval2;
3370 if (DEADMONSTER(mtmp))
3374 ? "compression from an anti-magic field"
3376 ? "
\94½
\96\82\96@
\8bó
\8aÔ
\82Ì
\88³
\8fk"
3379 if (DEADMONSTER(mtmp))
3382 newsym(trap->tx, trap->ty);
3387 break; /* monsters usually don't set it off */
3388 if (is_flyer(mptr)) {
3389 boolean already_seen = trap->tseen;
3391 if (in_sight && !already_seen) {
3393 pline("A trigger appears in a pile of soil below %s.",
3395 pline("%s
\82Ì
\91«
\8c³
\82Ì
\93y
\82Ì
\8eR
\82É
\8bN
\94\9a\83X
\83C
\83b
\83`
\82ª
\8c»
\82í
\82ê
\82½
\81D",
3402 newsym(mtmp->mx, mtmp->my);
3404 pline_The("air currents set %s off!",
3405 already_seen ? "a land mine" : "it");
3407 pline("
\8bó
\8bC
\82Ì
\97¬
\82ê
\82Å
\83X
\83C
\83b
\83`
\82ª
\93ü
\82Á
\82½
\81I");
3410 } else if (in_sight) {
3411 newsym(mtmp->mx, mtmp->my);
3413 pline("%s%s triggers %s land mine!",
3414 !Deaf ? "KAABLAMM!!! " : "", Monnam(mtmp),
3415 a_your[trap->madeby_u]);
3417 pline("%s%s
\82Í%s
\92n
\97\8b\82Ì
\8bN
\94\9a\83X
\83C
\83b
\83`
\82ð
\93¥
\82ñ
\82¾
\81I",
3418 !Deaf ? "
\82¿
\82ã
\82Ç
\81[
\82ñ
\81I
\81I" : "", Monnam(mtmp),
3419 set_you[trap->madeby_u]);
3422 if (!in_sight && !Deaf)
3424 pline("Kaablamm! %s an explosion in the distance!",
3425 "You hear"); /* Deaf-aware */
3427 /*JP:TODO:Deaf
\91Î
\89\9e*/
3428 pline("
\82¿
\82ã
\82Ç
\81[
\82ñ
\81I
\82 \82È
\82½
\82Í
\89\93\95û
\82Ì
\94\9a\94
\89¹
\82ð
\95·
\82¢
\82½
\81I");
3430 blow_up_landmine(trap);
3431 /* explosion might have destroyed a drawbridge; don't
3432 dish out more damage if monster is already dead */
3433 if (DEADMONSTER(mtmp)
3434 || thitm(0, mtmp, (struct obj *) 0, rnd(16), FALSE)) {
3437 /* monsters recursively fall into new pit */
3438 if (mintrap(mtmp) == 2)
3441 /* a boulder may fill the new pit, crushing monster */
3442 fill_pit(tx, ty); /* thitm may have already destroyed the trap */
3443 if (DEADMONSTER(mtmp))
3445 if (unconscious()) {
3448 nomovemsg = "The explosion awakens you!";
3450 nomovemsg = "
\94\9a\94
\82Å
\82 \82È
\82½
\82Í
\8bN
\82«
\82½
\81I";
3454 if (resists_magm(mtmp)) {
3455 shieldeff(mtmp->mx, mtmp->my);
3456 } else if (!resist(mtmp, WAND_CLASS, 0, NOTELL)) {
3457 if (newcham(mtmp, (struct permonst *) 0, FALSE, FALSE))
3458 /* we're done with mptr but keep it up to date */
3464 case ROLLING_BOULDER_TRAP:
3465 if (!is_flyer(mptr)) {
3466 int style = ROLL | (in_sight ? 0 : LAUNCH_UNSEEN);
3468 newsym(mtmp->mx, mtmp->my);
3471 pline("Click! %s triggers %s.", Monnam(mtmp),
3472 trap->tseen ? "a rolling boulder trap" : something);
3474 pline("
\83J
\83`
\83b
\81I%s
\82Í%s
\82Ì
\83X
\83C
\83b
\83`
\82ð
\93¥
\82ñ
\82¾
\81I", Monnam(mtmp),
3475 trap->tseen ? "
\97\8e\8aâ
\82Ìã©" : "
\89½
\82©");
3477 if (launch_obj(BOULDER, trap->launch.x, trap->launch.y,
3478 trap->launch2.x, trap->launch2.y, style)) {
3481 if (DEADMONSTER(mtmp))
3485 newsym(mtmp->mx, mtmp->my);
3489 case VIBRATING_SQUARE:
3490 if (see_it && !Blind) {
3491 seetrap(trap); /* before messages */
3494 char buf[BUFSZ], *p, *monnm = mon_nam(mtmp);
3496 if (nolimbs(mtmp->data)
3497 || is_floater(mtmp->data) || is_flyer(mtmp->data)) {
3498 /* just "beneath <mon>" */
3501 Strcpy(buf, s_suffix(monnm));
3502 p = eos(strcat(buf, " "));
3503 Strcpy(p, makeplural(mbodypart(mtmp, FOOT)));
3504 /* avoid "beneath 'rear paws'" or 'rear hooves' */
3505 (void) strsubst(p, "rear ", "");
3507 You_see("a strange vibration beneath %s.", buf);
3508 #else /*
\91«
\82ª
\82È
\82
\82Ä
\82à
\81u
\91«
\8c³
\81v
\82Å
\93\9d\88ê */
3509 You_see("%s
\82Ì
\91«
\8c³
\82ª
\95s
\8ev
\8bc
\82É
\90U
\93®
\82µ
\82Ä
\82¢
\82é
\82Ì
\82ð
\8c©
\82½
\81D",
3513 /* notice something (hearing uses a larger threshold
3516 You_see("the ground vibrate %s.",
3517 (distu(mtmp->mx, mtmp->my) <= 2 * 2)
3518 ? "nearby" : "in the distance");
3520 You_see("%s
\82
\82Å
\92n
\96Ê
\82ª
\90U
\93®
\82µ
\82Ä
\82¢
\82é
\82Ì
\82ð
\8c©
\82½
\81D",
3521 (distu(mtmp->mx, mtmp->my) <= 2 * 2)
3522 ? "
\8bß" : "
\89\93");
3528 impossible("Some monster encountered a strange trap of type %d.",
3534 return mtmp->mtrapped;
3537 /* Combine cockatrice checks into single functions to avoid repeating code. */
3542 if (Stone_resistance)
3544 if (poly_when_stoned(youmonst.data) && polymon(PM_STONE_GOLEM))
3547 You("turn to stone...");
3549 You("
\90Î
\82É
\82È
\82Á
\82½
\81D
\81D
\81D");
3550 killer.format = KILLED_BY;
3551 if (str != killer.name)
3552 Strcpy(killer.name, str ? str : "");
3557 minstapetrify(mon, byplayer)
3561 if (resists_ston(mon))
3563 if (poly_when_stoned(mon->data)) {
3567 if (!vamp_stone(mon))
3570 /* give a "<mon> is slowing down" message and also remove
3571 intrinsic speed (comparable to similar effect on the hero) */
3572 mon_adjust_speed(mon, -3, (struct obj *) 0);
3574 if (cansee(mon->mx, mon->my))
3576 pline("%s turns to stone.", Monnam(mon));
3578 pline("%s
\82Í
\90Î
\82É
\82È
\82Á
\82½
\81D", Monnam(mon));
3581 xkilled(mon, XKILL_NOMSG);
3592 if (uwep && uwep->otyp == CORPSE && touch_petrifies(&mons[uwep->corpsenm])
3593 && !Stone_resistance) {
3595 pline("%s touch the %s corpse.", arg, mons[uwep->corpsenm].mname);
3597 pline("%s%s
\82Ì
\8e\80\91Ì
\82É
\90G
\82Á
\82½
\81D", arg, mons[uwep->corpsenm].mname);
3599 Sprintf(kbuf, "%s corpse", an(mons[uwep->corpsenm].mname));
3601 Sprintf(kbuf, "%s
\82Ì
\8e\80\91Ì
\82Å", mons[uwep->corpsenm].mname);
3603 /* life-saved; unwield the corpse if we can't handle it */
3604 if (!uarmg && !Stone_resistance)
3607 /* Or your secondary weapon, if wielded [hypothetical; we don't
3608 allow two-weapon combat when either weapon is a corpse] */
3609 if (u.twoweap && uswapwep && uswapwep->otyp == CORPSE
3610 && touch_petrifies(&mons[uswapwep->corpsenm]) && !Stone_resistance) {
3612 pline("%s touch the %s corpse.", arg, mons[uswapwep->corpsenm].mname);
3614 pline("%s%s
\82Ì
\8e\80\91Ì
\82É
\90G
\82Á
\82½
\81D", arg, mons[uswapwep->corpsenm].mname);
3616 Sprintf(kbuf, "%s corpse", an(mons[uswapwep->corpsenm].mname));
3618 Sprintf(kbuf, "%s
\82Ì
\8e\80\91Ì
\82Å", mons[uswapwep->corpsenm].mname);
3620 /* life-saved; unwield the corpse */
3621 if (!uarmg && !Stone_resistance)
3627 mselftouch(mon, arg, byplayer)
3632 struct obj *mwep = MON_WEP(mon);
3634 if (mwep && mwep->otyp == CORPSE && touch_petrifies(&mons[mwep->corpsenm])
3635 && !resists_ston(mon)) {
3636 if (cansee(mon->mx, mon->my)) {
3638 pline("%s%s touches %s.", arg ? arg : "",
3639 arg ? mon_nam(mon) : Monnam(mon),
3640 corpse_xname(mwep, (const char *) 0, CXN_PFX_THE));
3642 pline("%s%s
\82Í%s
\82Ì
\8e\80\91Ì
\82É
\90G
\82Á
\82½
\81D", arg ? arg : "",
3643 arg ? mon_nam(mon) : Monnam(mon),
3644 corpse_xname(mwep, (const char *) 0, CXN_PFX_THE));
3647 minstapetrify(mon, byplayer);
3648 /* if life-saved, might not be able to continue wielding */
3649 if (!DEADMONSTER(mon) && !which_armor(mon, W_ARMG) && !resists_ston(mon))
3654 /* start levitating */
3658 context.botl = TRUE;
3660 if (u.utraptype == TT_PIT) {
3663 You("float up, out of the pit!");
3665 You("
\95\82\82«
\8fã
\82ª
\82Á
\82Ä
\81C
\97\8e\82µ
\8c\8a\82©
\82ç
\8fo
\82½
\81I");
3666 vision_full_recalc = 1; /* vision limits change */
3667 fill_pit(u.ux, u.uy);
3668 } else if (u.utraptype == TT_LAVA /* molten lava */
3669 || u.utraptype == TT_INFLOOR) { /* solidified lava */
3671 Your("body pulls upward, but your %s are still stuck.",
3673 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",
3674 makeplural(body_part(LEG)));
3675 } else if (u.utraptype == TT_BURIEDBALL) { /* tethered */
3678 cc.x = u.ux, cc.y = u.uy;
3679 /* caveat: this finds the first buried iron ball within
3680 one step of the specified location, not necessarily the
3681 buried [former] uball at the original anchor point */
3682 (void) buried_ball(&cc);
3683 /* being chained to the floor blocks levitation from floating
3684 above that floor but not from enhancing carrying capacity */
3686 You("feel lighter, but your %s is still chained to the %s.",
3688 IS_ROOM(levl[cc.x][cc.y].typ) ? "floor" : "ground");
3690 You("
\82·
\82±
\82µ
\8cy
\82
\82È
\82Á
\82½
\82ª
\81C
\82 \82È
\82½
\82Ì%s
\82Í
\82Ü
\82¾%s
\82É
\82Â
\82È
\82ª
\82Á
\82Ä
\82¢
\82é
\81D",
3692 IS_ROOM(levl[cc.x][cc.y].typ) ? "
\8f°" : "
\92n
\96Ê");
3694 } else if (u.utraptype == WEB) {
3696 You("float up slightly, but you are still stuck in the web.");
3698 You("
\82·
\82±
\82µ
\95\82\82«
\8fã
\82ª
\82Á
\82½
\82ª
\81C
\82Ü
\82¾
\82
\82à
\82Ì
\91\83\82É
\82Â
\82©
\82Ü
\82Á
\82Ä
\82¢
\82é
\81D");
3699 } else { /* bear trap */
3701 You("float up slightly, but your %s is still stuck.",
3703 You("
\8f
\82µ
\95\82\82«
\8fã
\82ª
\82Á
\82½
\82ª%s
\82Í
\82Ü
\82¾
\82Í
\82Ü
\82Á
\82Ä
\82¢
\82é
\81D",
3706 /* when still trapped, float_vs_flight() below will block levitation */
3708 } else if (Is_waterlevel(&u.uz)) {
3710 pline("It feels as though you've lost some weight.");
3712 You("
\82Ü
\82é
\82Å
\91Ì
\8fd
\82ª
\8c¸
\82Á
\82½
\82æ
\82¤
\82É
\8a´
\82¶
\82½
\81D");
3714 } else if (u.uinwater) {
3716 } else if (u.uswallow) {
3718 You(is_animal(u.ustuck->data) ? "float away from the %s."
3719 : "spiral up into %s.",
3720 is_animal(u.ustuck->data) ? surface(u.ux, u.uy)
3721 : mon_nam(u.ustuck));
3723 You(is_animal(u.ustuck->data) ? "%s
\82Ì
\92\86\82Å
\95\82\82¢
\82½
\81D"
3724 : "%s
\82Ì
\92\86\82Å
\82®
\82é
\82®
\82é
\89ñ
\93]
\82µ
\82½
\81D",
3725 is_animal(u.ustuck->data) ? surface(u.ux, u.uy)
3726 : mon_nam(u.ustuck));
3728 } else if (Hallucination) {
3730 pline("Up, up, and awaaaay! You're walking on air!");
3732 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");
3733 } else if (Is_airlevel(&u.uz)) {
3735 You("gain control over your movements.");
3737 You("
\82¤
\82Ü
\82
\93®
\82¯
\82é
\82æ
\82¤
\82É
\82È
\82Á
\82½
\81D");
3740 You("start to float in the air!");
3742 You("
\8bó
\92\86\82É
\95\82\82«
\82Í
\82¶
\82ß
\82½
\81I");
3744 if (u.usteed && !is_floater(u.usteed->data) && !is_flyer(u.usteed->data)) {
3747 pline("%s magically floats up!", Monnam(u.usteed));
3749 pline("%s
\82Í
\96\82\96@
\82Ì
\97Í
\82Å
\95\82\82¢
\82½
\81I", Monnam(u.usteed));
3752 You("cannot stay on %s.", mon_nam(u.usteed));
3754 You("%s
\82Ì
\8fã
\82É
\8fæ
\82Á
\82Ä
\82¢
\82ç
\82ê
\82È
\82¢
\81D", mon_nam(u.usteed));
3755 dismount_steed(DISMOUNT_GENERIC);
3760 You("are no longer able to control your flight.");
3762 You("
\8bó
\92\86\82Å
\82¤
\82Ü
\82
\93®
\82¯
\82È
\82
\82È
\82Á
\82½
\81D");
3763 float_vs_flight(); /* set BFlying, also BLevitation if still trapped */
3764 /* levitation gives maximum carrying capacity, so encumbrance
3765 state might be reduced */
3766 (void) encumber_msg();
3777 if ((t = t_at(x, y)) && is_pit(t->ttyp)
3778 && (otmp = sobj_at(BOULDER, x, y))) {
3779 obj_extract_self(otmp);
3781 (void) flooreffects(otmp, x, y, "settle");
3783 (void) flooreffects(otmp, x, y, "
\82Í
\82Ü
\82é");
3787 /* stop levitating */
3789 float_down(hmask, emask)
3790 long hmask, emask; /* might cancel timeout */
3792 register struct trap *trap = (struct trap *) 0;
3793 d_level current_dungeon_level;
3794 boolean no_msg = FALSE;
3796 HLevitation &= ~hmask;
3797 ELevitation &= ~emask;
3799 return 0; /* maybe another ring/potion/boots */
3801 /* if blocked by terrain, we haven't actually been levitating so
3802 we don't give any end-of-levitation feedback or side-effects,
3803 but if blocking is solely due to being trapped in/on floor,
3804 do give some feedback but skip other float_down() effects */
3805 boolean trapped = (BLevitation == I_SPECIAL);
3808 if (trapped && u.utrap) /* u.utrap => paranoia */
3810 You("are no longer trying to float up from the %s.",
3811 (u.utraptype == TT_BEARTRAP) ? "trap's jaws"
3812 : (u.utraptype == TT_WEB) ? "web"
3813 : (u.utraptype == TT_BURIEDBALL) ? "chain"
3814 : (u.utraptype == TT_LAVA) ? "lava"
3815 : "ground"); /* TT_INFLOOR */
3817 You("
\82à
\82Í
\82â%s
\82©
\82ç
\95\82\82«
\8fã
\82ª
\82ë
\82¤
\82Æ
\82µ
\82È
\82
\82È
\82Á
\82½
\81D",
3818 (u.utraptype == TT_BEARTRAP) ? "ã©
\82Ì
\8e\95"
3819 : (u.utraptype == TT_WEB) ? "
\82
\82à
\82Ì
\91\83"
3820 : (u.utraptype == TT_BURIEDBALL) ? "
\8d½"
3821 : (u.utraptype == TT_LAVA) ? "
\97n
\8aâ"
3822 : "
\92n
\96Ê"); /* TT_INFLOOR */
3824 (void) encumber_msg(); /* carrying capacity might have changed */
3827 context.botl = TRUE;
3828 nomul(0); /* stop running or resting */
3830 /* controlled flight no longer overridden by levitation */
3831 float_vs_flight(); /* clears BFlying & I_SPECIAL
3832 * unless hero is stuck in floor */
3835 You("have stopped levitating and are now flying.");
3837 You("
\8bó
\92\86\95\82\97V
\82ð
\8e~
\82ß
\82Ä
\8bó
\82ð
\94ò
\82Ñ
\82Í
\82¶
\82ß
\82½
\81D");
3838 (void) encumber_msg(); /* carrying capacity might have changed */
3844 You("float down, but you are still %s.",
3845 is_animal(u.ustuck->data) ? "swallowed" : "engulfed");
3847 You("
\92\85\92n
\82µ
\82½
\82ª
\81C
\82Ü
\82¾
\88ù
\82Ý
\8d\9e\82Ü
\82ê
\82½
\82Ü
\82Ü
\82¾
\81D");
3849 (void) encumber_msg();
3853 if (Punished && !carried(uball)
3854 && (is_pool(uball->ox, uball->oy)
3855 || ((trap = t_at(uball->ox, uball->oy))
3856 && (is_pit(trap->ttyp) || is_hole(trap->ttyp))))) {
3861 movobj(uchain, uball->ox, uball->oy);
3862 newsym(u.ux0, u.uy0);
3863 vision_full_recalc = 1; /* in case the hero moved. */
3865 /* check for falling into pool - added by GAN 10/20/86 */
3867 if (!u.uswallow && u.ustuck) {
3868 if (sticks(youmonst.data))
3870 You("aren't able to maintain your hold on %s.",
3873 You("%s
\82ð
\82Â
\82©
\82Ü
\82¦
\91±
\82¯
\82Ä
\82¢
\82ç
\82ê
\82È
\82
\82È
\82Á
\82½
\81D",
3878 pline("Startled, %s can no longer hold you!",
3881 pline("%s
\82Í
\8bÁ
\82¢
\82Ä
\82 \82È
\82½
\82ð
\95ú
\82µ
\82Ä
\82µ
\82Ü
\82Á
\82½
\81I",
3887 * drown() and lava_effects() print various messages almost
3888 * every time they're called which conflict with the "fall
3889 * into" message below. Thus, we want to avoid printing
3890 * confusing, duplicate or out-of-order messages.
3891 * Use knowledge of the two routines as a hack -- this
3892 * should really be handled differently -dlc
3894 if (is_pool(u.ux, u.uy) && !Wwalking && !Swimming && !u.uinwater)
3897 if (is_lava(u.ux, u.uy)) {
3898 (void) lava_effects();
3903 trap = t_at(u.ux, u.uy);
3904 if (Is_airlevel(&u.uz)) {
3906 You("begin to tumble in place.");
3908 You("
\82»
\82Ì
\8fê
\82Å
\82Ð
\82Á
\82
\82è
\95Ô
\82è
\82Í
\82¶
\82ß
\82½
\81D");
3909 } else if (Is_waterlevel(&u.uz) && !no_msg) {
3911 You_feel("heavier.");
3913 You("
\8fd
\82
\82È
\82Á
\82½
\82æ
\82¤
\82È
\8bC
\82ª
\82µ
\82½
\81D");
3914 /* u.uinwater msgs already in spoteffects()/drown() */
3915 } else if (!u.uinwater && !no_msg) {
3916 if (!(emask & W_SADDLE)) {
3917 if (Sokoban && trap) {
3918 /* Justification elsewhere for Sokoban traps is based
3919 * on air currents. This is consistent with that.
3920 * The unexpected additional force of the air currents
3921 * once levitation ceases knocks you off your feet.
3925 pline("Bummer! You've crashed.");
3927 pline("
\82â
\82ß
\82Ä
\82¥
\81I
\82 \82È
\82½
\82Í
\92@
\82«
\82Â
\82¯
\82ç
\82ê
\82½
\81D");
3932 You("
\82Â
\82Ü
\82Ã
\82¢
\82½
\81D");
3934 losehp(rnd(2), "dangerous winds", KILLED_BY);
3936 losehp(rnd(2), "
\8aë
\8c¯
\82È
\95\97\82Å", KILLED_BY);
3938 dismount_steed(DISMOUNT_FELL);
3940 selftouch("As you fall, you");
3942 selftouch("
\97\8e\82¿
\82È
\82ª
\82ç
\81C
\82 \82È
\82½
\82Í");
3943 } else if (u.usteed && (is_floater(u.usteed->data)
3944 || is_flyer(u.usteed->data))) {
3946 You("settle more firmly in the saddle.");
3948 You("
\82æ
\82è
\82µ
\82Á
\82©
\82è
\82Æ
\88Æ
\82É
\94[
\82Ü
\82Á
\82½
\81D");
3949 } else if (Hallucination) {
3951 pline("Bummer! You've %s.",
3954 : "hit the ground");
3956 pline("
\82â
\82ß
\82Ä
\82¥
\81I
\82 \82È
\82½
\82Í%s
\82É
\92@
\82«
\82Â
\82¯
\82ç
\82ê
\82½
\81D",
3963 You("float gently to the %s.", surface(u.ux, u.uy));
3965 You("
\90Ã
\82©
\82É%s
\82Ü
\82Å
\92H
\82è
\82Â
\82¢
\82½
\81D", surface(u.ux, u.uy));
3971 /* levitation gives maximum carrying capacity, so having it end
3972 potentially triggers greater encumbrance; do this after
3973 'come down' messages, before trap activation or autopickup */
3974 (void) encumber_msg();
3976 /* can't rely on u.uz0 for detecting trap door-induced level change;
3977 it gets changed to reflect the new level before we can check it */
3978 assign_level(¤t_dungeon_level, &u.uz);
3980 switch (trap->ttyp) {
3985 if (!Can_fall_thru(&u.uz) || u.ustuck)
3989 if (!u.utrap) /* not already in the trap */
3993 if (!Is_airlevel(&u.uz) && !Is_waterlevel(&u.uz) && !u.uswallow
3994 /* falling through trap door calls goto_level,
3995 and goto_level does its own pickup() call */
3996 && on_level(&u.uz, ¤t_dungeon_level))
4001 /* shared code for climbing out of a pit */
4005 if (!u.utrap || u.utraptype != TT_PIT)
4009 /* marked as trapped so they can pick things up */
4011 You("ascend from the pit.");
4013 You("
\97\8e\82µ
\8c\8a\82ð
\8fã
\82Á
\82Ä
\82¢
\82Á
\82½
\81D");
4015 fill_pit(u.ux, u.uy);
4016 vision_full_recalc = 1; /* vision limits change */
4017 } else if (!rn2(2) && sobj_at(BOULDER, u.ux, u.uy)) {
4019 Your("%s gets stuck in a crevice.", body_part(LEG));
4021 Your("%s
\82Í
\8a\84\82ê
\96Ú
\82É
\82Í
\82Ü
\82Á
\82½
\81D", body_part(LEG));
4022 display_nhwindow(WIN_MESSAGE, FALSE);
4023 clear_nhwindow(WIN_MESSAGE);
4025 You("free your %s.", body_part(LEG));
4027 Your("%s
\82Í
\8e©
\97R
\82É
\82È
\82Á
\82½
\81D", body_part(LEG));
4028 } else if ((Flying || is_clinger(youmonst.data)) && !Sokoban) {
4029 /* eg fell in pit, then poly'd to a flying monster;
4030 or used '>' to deliberately enter it */
4032 You("%s from the pit.", Flying ? "fly" : "climb");
4034 You("
\97\8e\82µ
\8c\8a\82©
\82ç%s
\82¢
\82Á
\82½
\81D", Flying ? "
\8fã
\82Á
\82Ä" : "
\93o
\82Á
\82Ä");
4036 fill_pit(u.ux, u.uy);
4037 vision_full_recalc = 1; /* vision limits change */
4038 } else if (!(--u.utrap)) {
4041 You("%s to the edge of the pit.",
4042 (Sokoban && Levitation)
4043 ? "struggle against the air currents and float"
4044 : u.usteed ? "ride" : "crawl");
4046 You("%s
\97\8e\82µ
\8c\8a\82Ì
\92[
\82É
\82½
\82Ç
\82è
\92\85\82¢
\82½
\81D",
4047 (Sokoban && Levitation)
4048 ? "
\8bó
\8bC
\82Ì
\97¬
\82ê
\82Ì
\92\86\82Å
\82à
\82ª
\82«
\82È
\82ª
\82ç" : "");
4050 fill_pit(u.ux, u.uy);
4051 vision_full_recalc = 1; /* vision limits change */
4052 } else if (u.dz || flags.verbose) {
4055 Norep("%s is still in a pit.", upstart(y_monnam(u.usteed)));
4057 Norep("%s
\82Í
\82Ü
\82¾
\97\8e\82µ
\8c\8a\82Ì
\92\86\82É
\82¢
\82é
\81D", y_monnam(u.usteed));
4060 Norep((Hallucination && !rn2(5))
4061 ? "You've fallen, and you can't get up."
4062 : "You are still in a pit.");
4064 Norep((Hallucination && !rn2(5))
4065 ? "
\82 \82È
\82½
\82Í
\97\8e\82¿
\81C
\8fã
\82ª
\82ê
\82È
\82¢
\81D"
4066 : "
\82 \82È
\82½
\82Í
\82Ü
\82¾
\97\8e\82µ
\8c\8a\82Ì
\92\86\82É
\82¢
\82é
\81D");
4073 struct obj *box; /* null for floor trap */
4075 boolean see_it = !Blind;
4078 /* Bug: for box case, the equivalent of burn_floor_objects() ought
4079 * to be done upon its contents.
4082 if ((box && !carried(box)) ? is_pool(box->ox, box->oy) : Underwater) {
4084 pline("A cascade of steamy bubbles erupts from %s!",
4086 pline("
\8fö
\8bC
\82Ì
\96A
\82ª%s
\82©
\82ç
\82µ
\82ã
\81[
\82Á
\82Æ
\94
\90¶
\82µ
\82½
\81I",
4087 the(box ? xname(box) : surface(u.ux, u.uy)));
4088 if (Fire_resistance)
4090 You("are uninjured.");
4092 You("
\8f\9d\82Â
\82©
\82È
\82¢
\81D");
4095 losehp(rnd(3), "boiling water", KILLED_BY);
4097 losehp(rnd(3), "
\95¦
\93«
\82µ
\82½
\90\85\82Å", KILLED_BY);
4101 pline("A %s %s from %s!", tower_of_flame, box ? "bursts" : "erupts",
4102 the(box ? xname(box) : surface(u.ux, u.uy)));
4104 pline("
\89Î
\92\8c\82ª%s
\82©
\82ç%s
\81I", box ? xname(box) : surface(u.ux,u.uy),
4105 box ? "
\90\81\82«
\8fo
\82µ
\82½" : "
\97§
\82¿
\82Ì
\82Ú
\82Á
\82½");
4107 if (Fire_resistance) {
4108 shieldeff(u.ux, u.uy);
4110 } else if (Upolyd) {
4112 switch (u.umonnum) {
4113 case PM_PAPER_GOLEM:
4116 case PM_STRAW_GOLEM:
4122 case PM_LEATHER_GOLEM:
4131 if (u.mhmax > mons[u.umonnum].mlevel)
4132 u.mhmax -= rn2(min(u.mhmax, num + 1)), context.botl = 1;
4135 if (u.uhpmax > u.ulevel)
4136 u.uhpmax -= rn2(min(u.uhpmax, num + 1)), context.botl = 1;
4140 You("are uninjured.");
4142 You("
\8f\9d\82Â
\82©
\82È
\82¢
\81D");
4145 losehp(num, tower_of_flame, KILLED_BY_AN); /* fire damage */
4147 losehp(num, "
\89Î
\92\8c\82Å", KILLED_BY_AN); /* fire damage */
4151 if (burnarmor(&youmonst) || rn2(3)) {
4152 destroy_item(SCROLL_CLASS, AD_FIRE);
4153 destroy_item(SPBOOK_CLASS, AD_FIRE);
4154 destroy_item(POTION_CLASS, AD_FIRE);
4156 if (!box && burn_floor_objects(u.ux, u.uy, see_it, TRUE) && !see_it)
4158 You("smell paper burning.");
4160 You("
\8e\86\82Ì
\82±
\82°
\82é
\93õ
\82¢
\82ª
\82µ
\82½
\81D");
4161 if (is_ice(u.ux, u.uy))
4162 melt_ice(u.ux, u.uy, (char *) 0);
4168 register int fate = rnd(20);
4170 /* What happened to the poor sucker? */
4173 /* Most of the time, it creates some monsters. */
4176 /* blindness effects */
4177 if (!resists_blnd(&youmonst)) {
4179 You("are momentarily blinded by a flash of light!");
4181 You("
\82Ü
\82Î
\82ä
\82¢
\8cõ
\82Å
\88ê
\8fu
\96Ú
\82ª
\82
\82ç
\82ñ
\82¾
\81I");
4182 make_blinded((long) rn1(5, 10), FALSE);
4184 Your1(vision_clears);
4185 } else if (!Blind) {
4187 You_see("a flash of light!");
4189 You("
\82Ü
\82Î
\82ä
\82¢
\8cõ
\82ð
\97\81\82Ñ
\82½
\81I");
4192 /* deafness effects */
4195 You_hear("a deafening roar!");
4197 You_hear("
\8e¨
\82ð
\82Â
\82ñ
\82´
\82
\82æ
\82¤
\82È
\99ô
\9aK
\82ð
\95·
\82¢
\82½
\81I");
4198 incr_itimeout(&HDeaf, rn1(20, 30));
4199 context.botl = TRUE;
4201 /* magic vibrations still hit you */
4203 You_feel("rankled.");
4205 You_feel("
\82¢
\82ç
\82¢
\82ç
\82µ
\82½
\81D");
4206 incr_itimeout(&HDeaf, rn1(5, 15));
4207 context.botl = TRUE;
4210 (void) makemon((struct permonst *) 0, u.ux, u.uy, NO_MM_FLAGS);
4211 /* roar: wake monsters in vicinity, after placing trap-created ones */
4212 wake_nearto(u.ux, u.uy, 7 * 7);
4213 /* [flash: should probably also hit nearby gremlins with light] */
4218 /* sometimes nothing happens */
4220 case 12: /* a flash of fire */
4221 dofiretrap((struct obj *) 0);
4227 pline("A shiver runs up and down your %s!", body_part(SPINE));
4229 pline("
\90k
\82¦
\82ª
\82 \82È
\82½
\82Ì%s
\82ð
\91\96\82Á
\82½
\81I", body_part(SPINE));
4233 You_hear(Hallucination ? "the moon howling at you."
4234 : "distant howling.");
4236 You_hear(Hallucination ? "
\8c\8e\82ª
\96i
\82¦
\82Ä
\82¢
\82é
\82Ì
\82ð
\95·
\82¢
\82½
\81D"
4237 : "
\89\93\95û
\82Ì
\89\93\96i
\82ð
\95·
\82¢
\82½
\81D");
4241 if (on_level(&u.uz, &qstart_level))
4244 "%slike the prodigal son.",
4245 (flags.female || (Upolyd && is_neuter(youmonst.data)))
4249 /*JP
\90¹
\8f\91\82Ì
\83\8b\83J
\93`
\82æ
\82è */
4250 You("%s
\95ú
\93 \91§
\8eq
\82Ì
\82æ
\82¤
\82É
\82È
\82Á
\82½
\82æ
\82¤
\82È
\8bC
\82ª
\82µ
\82½
\81D",
4251 (flags.female || (Upolyd && is_neuter(youmonst.data)))
4257 You("suddenly yearn for %s.",
4260 : (In_quest(&u.uz) || at_dgn_entrance("The Quest"))
4261 ? "your nearby homeland"
4262 : "your distant homeland");
4264 You("
\93Ë
\91R%s
\82ª
\97ö
\82µ
\82
\82È
\82Á
\82½
\81D",
4265 Hallucination ? "
\90Â
\90X"
4266 : (In_quest(&u.uz) || at_dgn_entrance("
\83N
\83G
\83X
\83g"))
4267 ? "
\82·
\82®
\82»
\82±
\82É
\82 \82é
\8cÌ
\8b½"
4268 : "
\82Í
\82é
\82©
\82©
\82È
\82½
\82Ì
\8cÌ
\8b½");
4273 Your("pack shakes violently!");
4275 Your("
\91Ü
\82Í
\8c\83\82µ
\82
\97h
\82ê
\82½
\81I");
4279 You(Hallucination ? "smell hamburgers." : "smell charred flesh.");
4281 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");
4287 You("
\94æ
\82ê
\82ð
\8a´
\82¶
\82½
\81D");
4290 /* very occasionally something nice happens. */
4291 case 19: { /* tame nearby monsters */
4295 (void) adjattrib(A_CHA, 1, FALSE);
4296 for (i = -1; i <= 1; i++)
4297 for (j = -1; j <= 1; j++) {
4298 if (!isok(u.ux + i, u.uy + j))
4300 mtmp = m_at(u.ux + i, u.uy + j);
4302 (void) tamedog(mtmp, (struct obj *) 0);
4306 case 20: { /* uncurse stuff */
4308 long save_conf = HConfusion;
4310 pseudo = zeroobj; /* neither cursed nor blessed,
4311 and zero out oextra */
4312 pseudo.otyp = SCR_REMOVE_CURSE;
4314 (void) seffects(&pseudo);
4315 HConfusion = save_conf;
4323 /* Set an item on fire.
4324 * "force" means not to roll a luck-based protection check for the
4326 * "x" and "y" are the coordinates to dump the contents of a
4327 * container, if it burns up.
4329 * Return whether the object was destroyed.
4332 fire_damage(obj, force, x, y)
4338 struct obj *otmp, *ncobj;
4339 int in_sight = !Blind && couldsee(x, y); /* Don't care if it's lit */
4342 /* object might light in a controlled manner */
4346 if (Is_container(obj)) {
4347 switch (obj->otyp) {
4349 return FALSE; /* Immune */
4360 if ((!force && (Luck + 5) > rn2(chance))
4361 || (is_flammable(obj) && obj->oerodeproof))
4363 /* Container is burnt up - dump contents out */
4366 pline("%s catches fire and burns.", Yname2(obj));
4368 pline("%s
\82Í
\89Î
\82ª
\82Â
\82¢
\82Ä
\94R
\82¦
\82½
\81D", Yname2(obj));
4369 if (Has_contents(obj)) {
4372 pline("Its contents fall out.");
4374 pline("
\92\86\90g
\82ª
\8fo
\82Ä
\82«
\82½
\81D");
4375 for (otmp = obj->cobj; otmp; otmp = ncobj) {
4377 obj_extract_self(otmp);
4378 if (!flooreffects(otmp, x, y, ""))
4379 place_object(otmp, x, y);
4385 } else if (!force && (Luck + 5) > rn2(20)) {
4386 /* chance per item of sustaining damage:
4387 * max luck (Luck==13): 10%
4388 * avg luck (Luck==0): 75%
4389 * awful luck (Luck<-4): 100%
4392 } else if (obj->oclass == SCROLL_CLASS || obj->oclass == SPBOOK_CLASS) {
4393 if (obj->otyp == SCR_FIRE || obj->otyp == SPE_FIREBALL)
4395 if (obj->otyp == SPE_BOOK_OF_THE_DEAD) {
4398 pline("Smoke rises from %s.", the(xname(obj)));
4400 pline("%s
\82©
\82ç
\89\8c\82ª
\82 \82ª
\82Á
\82½
\81D", the(xname(obj)));
4403 dindx = (obj->oclass == SCROLL_CLASS) ? 3 : 4;
4406 pline("%s %s.", Yname2(obj),
4407 destroy_strings[dindx][(obj->quan > 1L)]);
4409 pline("%s
\82Í%s
\81D", Yname2(obj),
4410 destroy_strings[dindx][(obj->quan > 1L)]);
4415 } else if (obj->oclass == POTION_CLASS) {
4416 dindx = (obj->otyp != POT_OIL) ? 1 : 2;
4419 pline("%s %s.", Yname2(obj),
4420 destroy_strings[dindx][(obj->quan > 1L)]);
4422 pline("%s
\82Í%s
\81D", Yname2(obj),
4423 destroy_strings[dindx][(obj->quan > 1L)]);
4428 } else if (erode_obj(obj, (char *) 0, ERODE_BURN, EF_DESTROY)
4436 * Apply fire_damage() to an entire chain.
4438 * Return number of objects destroyed. --ALI
4441 fire_damage_chain(chain, force, here, x, y)
4443 boolean force, here;
4446 struct obj *obj, *nobj;
4449 for (obj = chain; obj; obj = nobj) {
4450 nobj = here ? obj->nexthere : obj->nobj;
4451 if (fire_damage(obj, force, x, y))
4455 if (num && (Blind && !couldsee(x, y)))
4457 You("smell smoke.");
4459 You("
\89\8c\82Ì
\82É
\82¨
\82¢
\82ª
\82µ
\82½
\81D");
4463 /* obj has been thrown or dropped into lava; damage is worse than mere fire */
4465 lava_damage(obj, x, y)
4469 int otyp = obj->otyp, ocls = obj->oclass;
4471 /* the Amulet, invocation items, and Rider corpses are never destroyed
4472 (let Book of the Dead fall through to fire_damage() to get feedback) */
4473 if (obj_resists(obj, 0, 0) && otyp != SPE_BOOK_OF_THE_DEAD)
4475 /* destroy liquid (venom), wax, veggy, flesh, paper (except for scrolls
4476 and books--let fire damage deal with them), cloth, leather, wood, bone
4477 unless it's inherently or explicitly fireproof or contains something;
4478 note: potions are glass so fall through to fire_damage() and boil */
4479 if (objects[otyp].oc_material < DRAGON_HIDE
4480 && ocls != SCROLL_CLASS && ocls != SPBOOK_CLASS
4481 && objects[otyp].oc_oprop != FIRE_RES
4482 && otyp != WAN_FIRE && otyp != FIRE_HORN
4483 /* assumes oerodeproof isn't overloaded for some other purpose on
4484 non-eroding items */
4485 && !obj->oerodeproof
4486 /* fire_damage() knows how to deal with containers and contents */
4487 && !Has_contents(obj)) {
4489 /* this feedback is pretty clunky and can become very verbose
4490 when former contents of a burned container get here via
4492 if (obj == thrownobj || obj == kickedobj)
4494 pline("%s %s up!", is_plural(obj) ? "They" : "It",
4495 otense(obj, "burn"));
4497 pline("
\82»
\82ê
\82Í
\94R
\82¦
\82Â
\82«
\82½
\81I");
4501 You_see("%s hit lava and burn up!", doname(obj));
4503 You_see("%s
\82Í
\97n
\8aâ
\82É
\93\96\82½
\82Á
\82Ä
\94R
\82¦
\82Â
\82«
\82½
\81I", doname(obj));
4505 if (carried(obj)) { /* shouldn't happen */
4506 remove_worn_item(obj, TRUE);
4512 return fire_damage(obj, TRUE, x, y);
4519 /* Scrolls but not spellbooks can be erased by acid. */
4520 struct monst *victim;
4526 victim = carried(obj) ? &youmonst : mcarried(obj) ? obj->ocarry : NULL;
4527 vismon = victim && (victim != &youmonst) && canseemon(victim);
4530 grease_protect(obj, (char *) 0, victim);
4531 } else if (obj->oclass == SCROLL_CLASS && obj->otyp != SCR_BLANK_PAPER) {
4532 if (obj->otyp != SCR_BLANK_PAPER
4534 && obj->otyp != SCR_MAIL
4538 if (victim == &youmonst)
4540 pline("Your %s.", aobjnam(obj, "fade"));
4542 pline("%s
\82Ì
\95¶
\8e\9a\82Í
\94\96\82ê
\82½
\81D", xname(obj));
4545 pline("%s %s.", s_suffix(Monnam(victim)),
4546 aobjnam(obj, "fade"));
4548 pline("%s
\82Ì%s
\82Ì
\95¶
\8e\9a\82Í
\94\96\82ê
\82½
\81D", Monnam(victim),
4553 obj->otyp = SCR_BLANK_PAPER;
4557 erode_obj(obj, (char *) 0, ERODE_CORRODE, EF_GREASE | EF_VERBOSE);
4560 /* context for water_damage(), managed by water_damage_chain();
4561 when more than one stack of potions of acid explode while processing
4562 a chain of objects, use alternate phrasing after the first message */
4563 static struct h2o_ctx {
4564 int dkn_boom, unk_boom; /* track dknown, !dknown separately */
4566 } acid_ctx = { 0, 0, FALSE };
4568 /* Get an object wet and damage it appropriately.
4569 * "ostr", if present, is used instead of the object name in some
4571 * "force" means not to roll luck to protect some objects.
4572 * Returns an erosion return value (ER_*)
4575 water_damage(obj, ostr, force)
4589 if (obj->otyp == CAN_OF_GREASE && obj->spe > 0) {
4591 } else if (obj->otyp == TOWEL && obj->spe < 7) {
4592 wet_a_towel(obj, rnd(7), TRUE);
4594 } else if (obj->greased) {
4600 } else if (Is_container(obj) && !Is_box(obj)
4601 && (obj->otyp != OILSKIN_SACK || (obj->cursed && !rn2(3)))) {
4604 pline("Water gets into your %s!", ostr);
4606 pline("
\90\85\82ª%s
\82Ì
\92\86\82É
\93ü
\82Á
\82½
\81I", ostr);
4608 water_damage_chain(obj->cobj, FALSE);
4609 return ER_DAMAGED; /* contents were damaged */
4610 } else if (obj->otyp == OILSKIN_SACK) {
4613 pline("Some water slides right off your %s.", ostr);
4615 pline("%s
\82Í
\90\85\82ð
\92e
\82¢
\82½
\81D", ostr);
4616 makeknown(OILSKIN_SACK);
4617 /* not actually damaged, but because we /didn't/ get the "water
4618 gets into!" message, the player now has more information and
4619 thus we need to waste any potion they may have used (also,
4620 flavourwise the water is now on the floor) */
4622 } else if (!force && (Luck + 5) > rn2(20)) {
4623 /* chance per item of sustaining damage:
4625 * avg luck (Luck==0): 75%
4626 * awful luck (Luck<-4): 100%
4629 } else if (obj->oclass == SCROLL_CLASS) {
4630 if (obj->otyp == SCR_BLANK_PAPER
4632 || obj->otyp == SCR_MAIL
4637 pline("Your %s %s.", ostr, vtense(ostr, "fade"));
4639 pline("%s
\82Ì
\95¶
\8e\9a\82Í
\94\96\82ê
\82½
\81D", ostr);
4641 obj->otyp = SCR_BLANK_PAPER;
4647 } else if (obj->oclass == SPBOOK_CLASS) {
4648 if (obj->otyp == SPE_BOOK_OF_THE_DEAD) {
4650 pline("Steam rises from %s.", the(xname(obj)));
4652 pline("
\8fö
\8bC
\82ª%s
\82©
\82ç
\97§
\82¿
\82Ì
\82Ú
\82Á
\82½
\81D", xname(obj));
4654 } else if (obj->otyp == SPE_BLANK_PAPER) {
4659 pline("Your %s %s.", ostr, vtense(ostr, "fade"));
4661 pline("%s
\82Ì
\95¶
\8e\9a\82Í
\94\96\82ê
\82½
\81D", ostr);
4663 if (obj->otyp == SPE_NOVEL) {
4668 obj->otyp = SPE_BLANK_PAPER;
4673 } else if (obj->oclass == POTION_CLASS) {
4674 if (obj->otyp == POT_ACID) {
4677 boolean one = (obj->quan == 1L), update = carried(obj),
4680 boolean update = carried(obj);
4683 if (Blind && !carried(obj))
4686 if (acid_ctx.ctx_valid)
4687 exploded = ((obj->dknown ? acid_ctx.dkn_boom
4688 : acid_ctx.unk_boom) > 0);
4691 * "a [potion|<color> potion|potion of acid] explodes"
4692 * depending on obj->dknown (potion has been seen) and
4693 * objects[POT_ACID].oc_name_known (fully discovered),
4694 * or "some {plural version} explode" when relevant.
4695 * Second and subsequent messages for same chain and
4696 * matching dknown status are
4697 * "another [potion|<color> &c] explodes" or plural
4700 bufp = simpleonames(obj);
4702 pline("%s %s %s!", /* "A potion explodes!" */
4703 !exploded ? (one ? "A" : "Some")
4704 : (one ? "Another" : "More"),
4705 bufp, vtense(bufp, "explode"));
4707 pline("%s
\82Í
\94\9a\94
\82µ
\82½
\81I", bufp);
4709 if (acid_ctx.ctx_valid) {
4711 acid_ctx.dkn_boom++;
4713 acid_ctx.unk_boom++;
4719 return ER_DESTROYED;
4720 } else if (obj->odiluted) {
4723 pline("Your %s %s further.", ostr, vtense(ostr, "dilute"));
4725 pline("%s
\82Í
\82³
\82ç
\82É
\94\96\82Ü
\82Á
\82½
\81D", ostr);
4727 obj->otyp = POT_WATER;
4729 obj->blessed = obj->cursed = 0;
4734 } else if (obj->otyp != POT_WATER) {
4737 pline("Your %s %s.", ostr, vtense(ostr, "dilute"));
4739 pline("%s
\82Í
\94\96\82Ü
\82Á
\82½
\81D", ostr);
4747 return erode_obj(obj, ostr, ERODE_RUST, EF_NONE);
4753 water_damage_chain(obj, here)
4759 /* initialize acid context: so far, neither seen (dknown) potions of
4760 acid nor unseen have exploded during this water damage sequence */
4761 acid_ctx.dkn_boom = acid_ctx.unk_boom = 0;
4762 acid_ctx.ctx_valid = TRUE;
4764 for (; obj; obj = otmp) {
4765 otmp = here ? obj->nexthere : obj->nobj;
4766 water_damage(obj, (char *) 0, FALSE);
4769 /* reset acid context */
4770 acid_ctx.dkn_boom = acid_ctx.unk_boom = 0;
4771 acid_ctx.ctx_valid = FALSE;
4775 * This function is potentially expensive - rolling
4776 * inventory list multiple times. Luckily it's seldom needed.
4777 * Returns TRUE if disrobing made player unencumbered enough to
4778 * crawl out of the current predicament.
4781 emergency_disrobe(lostsome)
4784 int invc = inv_cnt(TRUE);
4786 while (near_capacity() > (Punished ? UNENCUMBERED : SLT_ENCUMBER)) {
4787 register struct obj *obj, *otmp = (struct obj *) 0;
4790 /* Pick a random object */
4793 for (obj = invent; obj; obj = obj->nobj) {
4795 * Undroppables are: body armor, boots, gloves,
4796 * amulets, and rings because of the time and effort
4797 * in removing them + loadstone and other cursed stuff
4798 * for obvious reasons.
4800 if (!((obj->otyp == LOADSTONE && obj->cursed) || obj == uamul
4801 || obj == uleft || obj == uright || obj == ublindf
4802 || obj == uarm || obj == uarmc || obj == uarmg
4803 || obj == uarmf || obj == uarmu
4804 || (obj->cursed && (obj == uarmh || obj == uarms))
4807 /* reached the mark and found some stuff to drop? */
4808 if (--i < 0 && otmp)
4815 return FALSE; /* nothing to drop! */
4816 if (otmp->owornmask)
4817 remove_worn_item(otmp, FALSE);
4826 /* return TRUE iff player relocated */
4830 const char *pool_of_water;
4831 boolean inpool_ok = FALSE, crawl_ok;
4834 feel_newsym(u.ux, u.uy); /* in case Blind, map the water here */
4835 /* happily wading in the same contiguous pool */
4836 if (u.uinwater && is_pool(u.ux - u.dx, u.uy - u.dy)
4837 && (Swimming || Amphibious)) {
4838 /* water effects on objects every now and then */
4847 You("%s into the %s%c", Is_waterlevel(&u.uz) ? "plunge" : "fall",
4849 Amphibious || Swimming ? '.' : '!');
4851 You("%s
\82Ì
\92\86\82É%s%s", hliquid("
\90\85"),
4852 Is_waterlevel(&u.uz) ? "
\94ò
\82Ñ
\82±
\82ñ
\82¾" : "
\97\8e\82¿
\82½",
4853 Amphibious || Swimming ? "
\81D" : "
\81I");
4855 if (!Swimming && !Is_waterlevel(&u.uz))
4857 You("sink like %s.", Hallucination ? "the Titanic" : "a rock");
4859 You("%s
\82Ì
\82æ
\82¤
\82É
\92¾
\82ñ
\82¾
\81D", Hallucination ? "
\83^
\83C
\83^
\83j
\83b
\83N
\8d\86" : "
\8aâ");
4862 water_damage_chain(invent, FALSE);
4864 if (u.umonnum == PM_GREMLIN && rn2(3))
4865 (void) split_mon(&youmonst, (struct monst *) 0);
4866 else if (u.umonnum == PM_IRON_GOLEM) {
4870 You("
\8eK
\82Ñ
\82½
\81I");
4871 i = Maybe_Half_Phys(d(2, 6));
4875 losehp(i, "rusting away", KILLED_BY);
4877 losehp(i, "
\8a®
\91S
\82É
\8eK
\82Ñ
\82Ä", KILLED_BY);
4882 if ((i = number_leashed()) > 0) {
4884 pline_The("leash%s slip%s loose.", (i > 1) ? "es" : "",
4885 (i > 1) ? "" : "s");
4887 pline("
\95R
\82ª
\82ä
\82é
\82ñ
\82¾
\81D");
4892 if (Amphibious || Swimming) {
4896 pline("But you aren't drowning.");
4898 pline("
\82µ
\82©
\82µ
\81C
\82 \82È
\82½
\82Í
\93M
\82ê
\82È
\82©
\82Á
\82½
\81D");
4899 if (!Is_waterlevel(&u.uz)) {
4902 Your("keel hits the bottom.");
4904 You("
\92ê
\82É
\83j
\81[
\83h
\83\8d\83b
\83v
\82ð
\8c\88\82ß
\82½
\81D");
4907 You("touch bottom.");
4909 You("
\92ê
\82É
\82Â
\82¢
\82½
\81D");
4916 vision_recalc(2); /* unsee old position */
4919 vision_full_recalc = 1;
4922 if ((Teleportation || can_teleport(youmonst.data)) && !Unaware
4923 && (Teleport_control || rn2(3) < Luck + 2)) {
4925 You("attempt a teleport spell."); /* utcsri!carroll */
4927 You("
\8fu
\8aÔ
\88Ú
\93®
\82Ì
\8eô
\95¶
\82ð
\8f¥
\82¦
\82Ä
\82Ý
\82½
\81D");
4929 if (!level.flags.noteleport) {
4930 (void) dotele(FALSE);
4931 if (!is_pool(u.ux, u.uy))
4935 pline_The("attempted teleport spell fails.");
4937 pline("
\8fu
\8aÔ
\88Ú
\93®
\82Ì
\8eô
\95¶
\82Í
\8e¸
\94s
\82µ
\82½
\81D");
4940 dismount_steed(DISMOUNT_GENERIC);
4941 if (!is_pool(u.ux, u.uy))
4945 x = y = 0; /* lint suppression */
4946 /* if sleeping, wake up now so that we don't crawl out of water
4947 while still asleep; we can't do that the same way that waking
4948 due to combat is handled; note unmul() clears u.usleep */
4951 unmul("Suddenly you wake up!");
4953 unmul("
\93Ë
\91R
\82 \82È
\82½
\82Í
\96Ú
\82ª
\8ao
\82ß
\82½
\81I");
4954 /* being doused will revive from fainting */
4957 /* can't crawl if unable to move (crawl_ok flag stays false) */
4958 if (multi < 0 || (Upolyd && !youmonst.data->mmove))
4960 /* look around for a place to crawl to */
4961 for (i = 0; i < 100; i++) {
4962 x = rn1(3, u.ux - 1);
4963 y = rn1(3, u.uy - 1);
4964 if (crawl_destination(x, y)) {
4970 for (x = u.ux - 1; x <= u.ux + 1; x++)
4971 for (y = u.uy - 1; y <= u.uy + 1; y++)
4972 if (crawl_destination(x, y)) {
4978 boolean lost = FALSE;
4979 /* time to do some strip-tease... */
4980 boolean succ = Is_waterlevel(&u.uz) ? TRUE : emergency_disrobe(&lost);
4983 You("try to crawl out of the %s.", hliquid("water"));
4985 You("%s
\82©
\82ç
\82Í
\82¢
\82 \82ª
\82ë
\82¤
\82Æ
\82µ
\82½
\81D", hliquid("
\90\85"));
4988 You("dump some of your gear to lose weight...");
4990 You("
\91Ì
\82ð
\8cy
\82
\82·
\82é
\82½
\82ß
\82¢
\82
\82Â
\82©
\95¨
\82ð
\93\8a\82°
\82·
\82Ä
\82½
\81D
\81D
\81D");
4993 pline("Pheew! That was close.");
4995 pline("
\83n
\83@
\83n
\83@
\81I
\82 \82Ô
\82È
\82©
\82Á
\82½
\81D");
4999 /* still too much weight */
5001 pline("But in vain.");
5003 pline("
\82ª
\81C
\96³
\91Ê
\82¾
\82Á
\82½
\81D");
5009 You("
\93M
\82ê
\82½
\81D");
5010 for (i = 0; i < 5; i++) { /* arbitrary number of loops */
5011 /* killer format and name are reconstructed every iteration
5012 because lifesaving resets them */
5013 pool_of_water = waterbody_name(u.ux, u.uy);
5014 killer.format = KILLED_BY_AN;
5016 /* avoid "drowned in [a] water" */
5017 if (!strcmp(pool_of_water, "water"))
5018 pool_of_water = "deep water", killer.format = KILLED_BY;
5020 Strcpy(killer.name, pool_of_water);
5022 /* oops, we're still alive. better get out of the water. */
5023 if (safe_teleds(TRUE))
5024 break; /* successful life-save */
5025 /* nowhere safe to land; repeat drowning loop... */
5027 pline("You're still drowning.");
5029 You("
\82Ü
\82¾
\93M
\82ê
\82Ä
\82¢
\82é
\81D");
5034 You("find yourself back %s.",
5035 Is_waterlevel(&u.uz) ? "in an air bubble" : "on land");
5037 You("
\82¢
\82Â
\82Ì
\82Ü
\82É
\82©%s
\82É
\82¢
\82é
\82Ì
\82É
\8bC
\82ª
\82Â
\82¢
\82½
\81D",
5038 Is_waterlevel(&u.uz) ? "
\8bó
\8bC
\82Ì
\96A
\82Ì
\92\86" : "
\92n
\96Ê");
5049 /* energy is completely gone */
5051 You_feel("momentarily lethargic.");
5053 You("
\88ê
\8fu
\96³
\8bC
\97Í
\8a´
\82ð
\8a´
\82¶
\82½
\81D");
5055 /* throttle further loss a bit when there's not much left to lose */
5056 if (n > u.uenmax || n > u.ulevel)
5060 You_feel("your magical energy drain away%c", (n > u.uen) ? '!' : '.');
5062 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");
5065 u.uenmax -= rnd(-u.uen);
5078 if (near_capacity() >= HVY_ENCUMBER) {
5080 pline("You're too strained to do that.");
5082 pline("ã©
\82ð
\89ð
\8f\9c\82µ
\82æ
\82¤
\82É
\82à
\95¨
\82ð
\8e\9d\82¿
\82·
\82¬
\82Ä
\82¢
\82é
\81D");
5085 if ((nohands(youmonst.data) && !webmaker(youmonst.data))
5086 || !youmonst.data->mmove) {
5088 pline("And just how do you expect to do that?");
5090 pline("
\82¢
\82Á
\82½
\82¢
\89½
\82ð
\8aú
\91Ò
\82µ
\82Ä
\82¢
\82é
\82ñ
\82¾
\82¢
\81H");
5092 } else if (u.ustuck && sticks(youmonst.data)) {
5094 pline("You'll have to let go of %s first.", mon_nam(u.ustuck));
5096 pline("%s
\82ð
\8eè
\97£
\82³
\82È
\82¢
\82±
\82Æ
\82É
\82Í
\82Å
\82«
\82È
\82¢
\81D", mon_nam(u.ustuck));
5099 if (u.ustuck || (welded(uwep) && bimanual(uwep))) {
5101 Your("%s seem to be too busy for that.", makeplural(body_part(HAND)));
5103 Your("
\82»
\82ñ
\82È
\82±
\82Æ
\82ð
\82·
\82é
\97]
\97T
\82È
\82ñ
\82Ä
\82È
\82¢
\81D");
5106 return untrap(FALSE);
5109 /* Probability of disabling a trap. Helge Hafting */
5116 /* Only spiders know how to deal with webs reliably */
5117 if (ttmp->ttyp == WEB && !webmaker(youmonst.data))
5119 if (Confusion || Hallucination)
5127 /* Your own traps are better known than others. */
5128 if (ttmp && ttmp->madeby_u)
5130 if (Role_if(PM_ROGUE)) {
5131 if (rn2(2 * MAXULEV) < u.ulevel)
5133 if (u.uhave.questart && chance > 1)
5135 } else if (Role_if(PM_RANGER) && chance > 1)
5140 /* Replace trap with object(s). Helge Hafting */
5142 cnv_trap_obj(otyp, cnt, ttmp, bury_it)
5148 struct obj *otmp = mksobj(otyp, TRUE, FALSE);
5151 otmp->owt = weight(otmp);
5152 /* Only dart traps are capable of being poisonous */
5154 otmp->opoisoned = 0;
5155 place_object(otmp, ttmp->tx, ttmp->ty);
5157 /* magical digging first disarms this trap, then will unearth it */
5158 (void) bury_an_obj(otmp, (boolean *) 0);
5160 /* Sell your own traps only... */
5162 sellobj(otmp, ttmp->tx, ttmp->ty);
5165 newsym(ttmp->tx, ttmp->ty);
5166 if (u.utrap && ttmp->tx == u.ux && ttmp->ty == u.uy)
5171 /* while attempting to disarm an adjacent trap, we've fallen into it */
5173 move_into_trap(ttmp)
5177 xchar x = ttmp->tx, y = ttmp->ty, bx, by, cx, cy;
5180 bx = by = cx = cy = 0; /* lint suppression */
5181 /* we know there's no monster in the way, and we're not trapped */
5183 || drag_ball(x, y, &bc, &bx, &by, &cx, &cy, &unused, TRUE)) {
5184 u.ux0 = u.ux, u.uy0 = u.uy;
5187 newsym(u.ux0, u.uy0);
5189 check_leash(u.ux0, u.uy0);
5191 move_bc(0, bc, bx, by, cx, cy);
5192 /* marking the trap unseen forces dotrap() to treat it like a new
5193 discovery and prevents pickup() -> look_here() -> check_here()
5194 from giving a redundant "there is a <trap> here" message when
5195 there are objects covering this trap */
5196 ttmp->tseen = 0; /* hack for check_here() */
5197 /* trigger the trap */
5198 iflags.failing_untrap++; /* spoteffects() -> dotrap(,FAILEDUNTRAP) */
5199 spoteffects(TRUE); /* pickup() + dotrap() */
5200 iflags.failing_untrap--;
5201 /* this should no longer be necessary; before the failing_untrap
5202 hack, Flying hero would not trigger an unseen bear trap and
5203 setting it not-yet-seen above resulted in leaving it hidden */
5204 if ((ttmp = t_at(u.ux, u.uy)) != 0)
5206 exercise(A_WIS, FALSE);
5210 /* 0: doesn't even try
5211 * 1: tries and fails
5215 try_disarm(ttmp, force_failure)
5217 boolean force_failure;
5219 struct monst *mtmp = m_at(ttmp->tx, ttmp->ty);
5220 int ttype = ttmp->ttyp;
5221 boolean under_u = (!u.dx && !u.dy);
5222 boolean holdingtrap = (ttype == BEAR_TRAP || ttype == WEB);
5224 /* Test for monster first, monsters are displayed instead of trap. */
5225 if (mtmp && (!mtmp->mtrapped || !holdingtrap)) {
5227 pline("%s is in the way.", Monnam(mtmp));
5229 pline("
\82»
\82±
\82É
\82Í%s
\82ª
\82¢
\82é
\81D", Monnam(mtmp));
5232 /* We might be forced to move onto the trap's location. */
5233 if (sobj_at(BOULDER, ttmp->tx, ttmp->ty) && !Passes_walls && !under_u) {
5235 There("is a boulder in your way.");
5237 pline("
\82»
\82±
\82É
\82Í
\8aâ
\82ª
\82 \82é
\81D");
5240 /* duplicate tight-space checks from test_move */
5241 if (u.dx && u.dy && bad_rock(youmonst.data, u.ux, ttmp->ty)
5242 && bad_rock(youmonst.data, ttmp->tx, u.uy)) {
5243 if ((invent && (inv_weight() + weight_cap() > 600))
5244 || bigmonst(youmonst.data)) {
5245 /* don't allow untrap if they can't get thru to it */
5247 You("are unable to reach the %s!",
5248 defsyms[trap_to_defsym(ttype)].explanation);
5250 You("%s
\82É
\93Í
\82©
\82È
\82¢
\81I",
5251 defsyms[trap_to_defsym(ttype)].explanation);
5256 /* untrappable traps are located on the ground. */
5257 if (!can_reach_floor(under_u)) {
5258 if (u.usteed && P_SKILL(P_RIDING) < P_BASIC)
5262 You("are unable to reach the %s!",
5263 defsyms[trap_to_defsym(ttype)].explanation);
5265 You("%s
\82É
\93Í
\82©
\82È
\82¢
\81I",
5266 defsyms[trap_to_defsym(ttype)].explanation);
5271 /* Will our hero succeed? */
5272 if (force_failure || untrap_prob(ttmp)) {
5277 pline("
\82¤
\82í
\82Á
\81D
\81D
\81D");
5278 if (mtmp) { /* must be a trap that holds monsters */
5279 if (ttype == BEAR_TRAP) {
5282 mtmp->mhp -= rnd(4);
5283 if (DEADMONSTER(mtmp))
5285 } else if (ttype == WEB) {
5286 if (!webmaker(youmonst.data)) {
5287 struct trap *ttmp2 = maketrap(u.ux, u.uy, WEB);
5292 "webbing sticks to you. You're caught too!");
5294 "
\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");
5295 dotrap(ttmp2, NOWEBMSG);
5296 if (u.usteed && u.utrap) {
5297 /* you, not steed, are trapped */
5298 dismount_steed(DISMOUNT_FELL);
5303 pline("%s remains entangled.", Monnam(mtmp));
5305 pline("%s
\82Í
\82©
\82ç
\82Ü
\82Á
\82½
\82Ü
\82Ü
\82¾
\81D", Monnam(mtmp));
5307 } else if (under_u) {
5308 /* [don't need the iflags.failing_untrap hack here] */
5309 dotrap(ttmp, FAILEDUNTRAP);
5311 move_into_trap(ttmp);
5315 pline("%s %s is difficult to %s.",
5316 ttmp->madeby_u ? "Your" : under_u ? "This" : "That",
5317 defsyms[trap_to_defsym(ttype)].explanation,
5318 (ttype == WEB) ? "remove" : "disarm");
5320 pline("%s%s
\82ð
\89ð
\8f\9c\82·
\82é
\82Ì
\82Í
\8d¢
\93ï
\82¾
\81D",
5321 ttmp->madeby_u ? "
\82 \82È
\82½
\82Ì
\8ed
\8a|
\82¯
\82½" : under_u ? "
\82±
\82Ì" : "
\82»
\82Ì",
5322 defsyms[trap_to_defsym(ttype)].explanation);
5331 reward_untrap(ttmp, mtmp)
5335 if (!ttmp->madeby_u) {
5336 if (rnl(10) < 8 && !mtmp->mpeaceful && !mtmp->msleeping
5337 && !mtmp->mfrozen && !mindless(mtmp->data)
5338 && mtmp->data->mlet != S_HUMAN) {
5339 mtmp->mpeaceful = 1;
5340 set_malign(mtmp); /* reset alignment */
5342 pline("%s is grateful.", Monnam(mtmp));
5344 pline("%s
\82Í
\8aì
\82ñ
\82Å
\82¢
\82é
\81D", Monnam(mtmp));
5346 /* Helping someone out of a trap is a nice thing to do,
5347 * A lawful may be rewarded, but not too often. */
5348 if (!rn2(3) && !rnl(8) && u.ualign.type == A_LAWFUL) {
5351 You_feel("that you did the right thing.");
5353 You("
\90³
\82µ
\82¢
\82±
\82Æ
\82ð
\82µ
\82½
\82æ
\82¤
\82È
\8bC
\82ª
\82µ
\82½
\81D");
5359 disarm_holdingtrap(ttmp) /* Helge Hafting */
5363 int fails = try_disarm(ttmp, FALSE);
5368 /* ok, disarm it. */
5370 /* untrap the monster, if any.
5371 There's no need for a cockatrice test, only the trap is touched */
5372 if ((mtmp = m_at(ttmp->tx, ttmp->ty)) != 0) {
5375 You("remove %s %s from %s.", the_your[ttmp->madeby_u],
5376 (ttmp->ttyp == BEAR_TRAP) ? "bear trap" : "webbing",
5379 You("%s%s
\82ð%s
\82©
\82ç
\82Í
\82¸
\82µ
\82½
\81D", set_you[ttmp->madeby_u],
5380 (ttmp->ttyp == BEAR_TRAP) ? "
\8cF
\82Ìã©" : "
\82
\82à
\82Ì
\91\83",
5383 reward_untrap(ttmp, mtmp);
5385 if (ttmp->ttyp == BEAR_TRAP) {
5387 You("disarm %s bear trap.", the_your[ttmp->madeby_u]);
5389 You("%s
\8cF
\82Ìã©
\82ð
\89ð
\8f\9c\82µ
\82½
\81D", set_you[ttmp->madeby_u]);
5390 cnv_trap_obj(BEARTRAP, 1, ttmp, FALSE);
5391 } else /* if (ttmp->ttyp == WEB) */ {
5393 You("succeed in removing %s web.", the_your[ttmp->madeby_u]);
5395 You("%s
\82
\82à
\82Ì
\91\83\82ð
\8eæ
\82è
\8f\9c\82¢
\82½
\81D", set_you[ttmp->madeby_u]);
5399 newsym(u.ux + u.dx, u.uy + u.dy);
5404 disarm_landmine(ttmp) /* Helge Hafting */
5407 int fails = try_disarm(ttmp, FALSE);
5412 You("disarm %s land mine.", the_your[ttmp->madeby_u]);
5414 You("%s
\92n
\97\8b\82ð
\89ð
\8f\9c\82µ
\82½
\81D", set_you[ttmp->madeby_u]);
5415 cnv_trap_obj(LAND_MINE, 1, ttmp, FALSE);
5419 /* getobj will filter down to cans of grease and known potions of oil */
5420 static NEARDATA const char oil[] = { ALL_CLASSES, TOOL_CLASS, POTION_CLASS,
5423 /* it may not make much sense to use grease on floor boards, but so what? */
5425 disarm_squeaky_board(ttmp)
5432 obj = getobj(oil, "untrap with");
5436 bad_tool = (obj->cursed
5437 || ((obj->otyp != POT_OIL || obj->lamplit)
5438 && (obj->otyp != CAN_OF_GREASE || !obj->spe)));
5439 fails = try_disarm(ttmp, bad_tool);
5443 /* successfully used oil or grease to fix squeaky board */
5444 if (obj->otyp == CAN_OF_GREASE) {
5445 consume_obj_charge(obj, TRUE);
5447 useup(obj); /* oil */
5451 You("repair the squeaky board."); /* no madeby_u */
5453 You("
\82«
\82µ
\82Þ
\94Â
\82ð
\8fC
\97\9d\82µ
\82½
\81D"); /* no madeby_u */
5456 newsym(u.ux + u.dx, u.uy + u.dy);
5457 more_experienced(1, 5);
5462 /* removes traps that shoot arrows, darts, etc. */
5464 disarm_shooting_trap(ttmp, otyp)
5468 int fails = try_disarm(ttmp, FALSE);
5473 You("disarm %s trap.", the_your[ttmp->madeby_u]);
5475 pline("%sã©
\82ð
\89ð
\8f\9c\82µ
\82½
\81D", set_you[ttmp->madeby_u]);
5476 cnv_trap_obj(otyp, 50 - rnl(50), ttmp, FALSE);
5480 /* Is the weight too heavy?
5481 * Formula as in near_capacity() & check_capacity() */
5483 try_lift(mtmp, ttmp, wt, stuff)
5489 int wc = weight_cap();
5491 if (((wt * 2) / wc) >= HVY_ENCUMBER) {
5493 pline("%s is %s for you to lift.", Monnam(mtmp),
5494 stuff ? "carrying too much" : "too heavy");
5496 pline("%s
\82Í%s
\8e\9d\82¿
\82 \82°
\82é
\82±
\82Æ
\82ª
\82Å
\82«
\82È
\82¢
\81D", Monnam(mtmp),
5497 stuff ? "
\95¨
\82ð
\8e\9d\82¿
\82·
\82¬
\82Ä
\82¨
\82è" : "
\8fd
\82·
\82¬
\82Ä");
5499 if (!ttmp->madeby_u && !mtmp->mpeaceful && mtmp->mcanmove
5500 && !mindless(mtmp->data) && mtmp->data->mlet != S_HUMAN
5502 mtmp->mpeaceful = 1;
5503 set_malign(mtmp); /* reset alignment */
5505 pline("%s thinks it was nice of you to try.", Monnam(mtmp));
5507 pline("%s
\82Í
\82 \82È
\82½
\82Ì
\93w
\97Í
\82É
\8a´
\8eÓ
\82µ
\82Ä
\82¢
\82é
\82æ
\82¤
\82¾
\81D", Monnam(mtmp));
5514 /* Help trapped monster (out of a (spiked) pit) */
5516 help_monster_out(mtmp, ttmp)
5525 * This works when levitating too -- consistent with the ability
5526 * to hit monsters while levitating.
5528 * Should perhaps check that our hero has arms/hands at the
5529 * moment. Helping can also be done by engulfing...
5531 * Test the monster first - monsters are displayed before traps.
5533 if (!mtmp->mtrapped) {
5535 pline("%s isn't trapped.", Monnam(mtmp));
5537 pline("%s
\82Íã©
\82É
\82©
\82©
\82Á
\82Ä
\82¢
\82È
\82¢
\81D", Monnam(mtmp));
5540 /* Do you have the necessary capacity to lift anything? */
5541 if (check_capacity((char *) 0))
5544 /* Will our hero succeed? */
5545 if ((uprob = untrap_prob(ttmp)) && !mtmp->msleeping && mtmp->mcanmove) {
5547 You("try to reach out your %s, but %s backs away skeptically.",
5548 makeplural(body_part(ARM)), mon_nam(mtmp));
5550 You("%s
\82ð
\8d·
\82µ
\89\84\82×
\82æ
\82¤
\82Æ
\82µ
\82½
\82ª%s
\82Í
\8cx
\89ú
\82µ
\82Ä
\82¢
\82é
\81D",
5551 body_part(ARM), mon_nam(mtmp));
5556 /* is it a cockatrice?... */
5557 if (touch_petrifies(mtmp->data) && !uarmg && !Stone_resistance) {
5559 You("grab the trapped %s using your bare %s.", mtmp->data->mname,
5560 makeplural(body_part(HAND)));
5562 You("ã©
\82É
\82©
\82©
\82Á
\82Ä
\82¢
\82é%s
\82ð
\91f%s
\82Å
\92Í
\82ñ
\82¾
\81D", mtmp->data->mname,
5566 if (poly_when_stoned(youmonst.data) && polymon(PM_STONE_GOLEM)) {
5567 display_nhwindow(WIN_MESSAGE, FALSE);
5572 Sprintf(kbuf, "trying to help %s out of a pit",
5573 an(mtmp->data->mname));
5575 Sprintf(kbuf, "ã©
\82É
\82©
\82©
\82Á
\82Ä
\82¢
\82é%s
\82ð
\8f\95\82¯
\82æ
\82¤
\82Æ
\82µ
\82Ä",
5582 /* need to do cockatrice check first if sleeping or paralyzed */
5585 You("try to grab %s, but cannot get a firm grasp.", mon_nam(mtmp));
5587 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));
5588 if (mtmp->msleeping) {
5589 mtmp->msleeping = 0;
5591 pline("%s awakens.", Monnam(mtmp));
5593 pline("%s
\82Í
\96Ú
\82ð
\8ao
\82Ü
\82µ
\82½
\81D", Monnam(mtmp));
5599 You("reach out your %s and grab %s.", makeplural(body_part(ARM)),
5602 You("%s
\82ð
\90L
\82Î
\82µ
\82Ä%s
\82ð
\82Â
\82©
\82ñ
\82¾
\81D", body_part(ARM),
5606 if (mtmp->msleeping) {
5607 mtmp->msleeping = 0;
5609 pline("%s awakens.", Monnam(mtmp));
5611 pline("%s
\82Í
\96Ú
\82ð
\8ao
\82Ü
\82µ
\82½
\81D", Monnam(mtmp));
5612 } else if (mtmp->mfrozen && !rn2(mtmp->mfrozen)) {
5613 /* After such manhandling, perhaps the effect wears off */
5617 pline("%s stirs.", Monnam(mtmp));
5619 pline("%s
\82Í
\93®
\82«
\8en
\82ß
\82½
\81D", Monnam(mtmp));
5622 /* is the monster too heavy? */
5623 wt = inv_weight() + mtmp->data->cwt;
5624 if (!try_lift(mtmp, ttmp, wt, FALSE))
5627 /* is the monster with inventory too heavy? */
5628 for (otmp = mtmp->minvent; otmp; otmp = otmp->nobj)
5630 if (!try_lift(mtmp, ttmp, wt, TRUE))
5634 You("pull %s out of the pit.", mon_nam(mtmp));
5636 You("%s
\82ð
\97\8e\82µ
\8c\8a\82©
\82ç
\82Ð
\82Á
\82Ï
\82Á
\82½
\81D", mon_nam(mtmp));
5638 reward_untrap(ttmp, mtmp);
5639 fill_pit(mtmp->mx, mtmp->my);
5647 register struct obj *otmp;
5652 const char *trapdescr;
5654 boolean here, useplural, deal_with_floor_trap,
5655 confused = (Confusion || Hallucination),
5656 trap_skipped = FALSE;
5658 boolean here, deal_with_floor_trap,
5659 confused = (Confusion || Hallucination),
5660 trap_skipped = FALSE;
5663 char the_trap[BUFSZ], qbuf[QBUFSZ];
5665 if (!getdir((char *) 0))
5671 pline_The("perils lurking there are beyond your grasp.");
5673 pline_The("
\82»
\82±
\82É
\82 \82é
\8aë
\8c¯
\82Í
\82 \82È
\82½
\82Ì
\8eè
\82É
\95\89\82¦
\82È
\82¢
\81D");
5676 /* 'force' is true for #invoke; make it be true for #untrap if
5678 if (!force && has_magic_key(&youmonst))
5682 if (ttmp && !ttmp->tseen)
5684 trapdescr = ttmp ? defsyms[trap_to_defsym(ttmp->ttyp)].explanation : 0;
5685 here = (x == u.ux && y == u.uy); /* !u.dx && !u.dy */
5687 if (here) /* are there are one or more containers here? */
5688 for (otmp = level.objects[x][y]; otmp; otmp = otmp->nexthere)
5694 deal_with_floor_trap = can_reach_floor(FALSE);
5695 if (!deal_with_floor_trap) {
5698 Strcat(the_trap, an(trapdescr));
5701 Strcat(the_trap, " and ");
5703 Strcat(the_trap, "
\82Æ");
5706 Strcat(the_trap, (boxcnt == 1) ? "a container" : "containers");
5708 Strcat(the_trap, "
\97e
\8aí");
5710 useplural = ((ttmp && boxcnt > 0) || boxcnt > 1);
5712 /* note: boxcnt and useplural will always be 0 for !here case */
5715 There("%s %s %s but you can't reach %s%s.",
5716 useplural ? "are" : "is", the_trap, here ? "here" : "there",
5717 useplural ? "them" : "it",
5718 u.usteed ? " while mounted" : "");
5720 pline("%s
\82ª
\82 \82é
\82ª
\81C%s
\93Í
\82©
\82È
\82¢
\81D",
5722 u.usteed ? "
\8fæ
\82Á
\82Ä
\82¢
\82é
\82Æ" : "");
5724 trap_skipped = (ttmp != 0);
5725 } else { /* deal_with_floor_trap */
5728 Strcpy(the_trap, the(trapdescr));
5730 if (is_pit(ttmp->ttyp)) {
5732 You_cant("do much about %s%s.", the_trap,
5733 u.utrap ? " that you're stuck in"
5734 : " while standing on the edge of it");
5736 pline("%s%s
\82É
\91Î
\82µ
\82Ä
\82Í
\82½
\82¢
\82µ
\82½
\82±
\82Æ
\82Í
\82Å
\82«
\82È
\82¢
\81D",
5737 u.utrap ? "
\8e©
\95ª
\82ª
\82Í
\82Ü
\82Á
\82Ä
\82¢
\82é"
5738 : "
\82·
\82®
\82»
\82Î
\82Ì",
5741 trap_skipped = TRUE;
5742 deal_with_floor_trap = FALSE;
5746 qbuf, "There %s and %s here. %s %s?",
5747 (boxcnt == 1) ? "is a container" : "are containers",
5749 (ttmp->ttyp == WEB) ? "Remove" : "Disarm", the_trap);
5752 qbuf, "
\94 \82Æ%s
\82ª
\82 \82é
\81D%s
\81H",
5754 (ttmp->ttyp == WEB) ? "
\8eæ
\82è
\8f\9c\82" : "
\89ð
\8f\9c\82·
\82é");
5756 switch (ynq(qbuf)) {
5760 trap_skipped = TRUE;
5761 deal_with_floor_trap = FALSE;
5766 if (deal_with_floor_trap) {
5769 You("cannot deal with %s while trapped%s!", the_trap,
5770 (x == u.ux && y == u.uy) ? " in it" : "");
5772 pline("ã©
\82É
\82©
\82©
\82Á
\82Ä
\82¢
\82é
\8aÔ
\82Íã©
\82ð
\89ð
\8f\9c\82Å
\82«
\82È
\82¢
\81I");
5776 if ((mtmp = m_at(x, y)) != 0
5777 && (M_AP_TYPE(mtmp) == M_AP_FURNITURE
5778 || M_AP_TYPE(mtmp) == M_AP_OBJECT)) {
5779 stumble_onto_mimic(mtmp);
5782 switch (ttmp->ttyp) {
5785 return disarm_holdingtrap(ttmp);
5787 return disarm_landmine(ttmp);
5789 return disarm_squeaky_board(ttmp);
5791 return disarm_shooting_trap(ttmp, DART);
5793 return disarm_shooting_trap(ttmp, ARROW);
5798 You("are already on the edge of the pit.");
5800 You("
\82à
\82¤
\97\8e\82µ
\8c\8a\82Ì
\92[
\82É
\82¢
\82é
\81D");
5805 pline("Try filling the pit instead.");
5807 pline("
\82È
\82ñ
\82Æ
\82©
\96\84\82ß
\82é
\82±
\82Æ
\82ð
\8dl
\82¦
\82Ä
\82Ý
\82½
\82ç
\81H");
5810 return help_monster_out(mtmp, ttmp);
5813 You("cannot disable %s trap.", !here ? "that" : "this");
5815 pline("%sã©
\82Í
\89ð
\8f\9c\82Å
\82«
\82È
\82¢
\81D", !here ? "
\82»
\82Ì" : "
\82±
\82Ì");
5822 for (otmp = level.objects[x][y]; otmp; otmp = otmp->nexthere)
5825 (void) safe_qbuf(qbuf, "There is ",
5826 " here. Check it for traps?", otmp,
5827 doname, ansimpleoname, "a box");
5829 (void) safe_qbuf(qbuf, "",
5830 "
\82ª
\82 \82é
\81Dã©
\82ð
\92²
\82×
\82Ü
\82·
\82©
\81H", otmp,
5831 doname, ansimpleoname, "
\94 ");
5833 switch (ynq(qbuf)) {
5841 && (force || (!confused
5842 && rn2(MAXULEV + 1 - u.ulevel) < 10)))
5843 || (!force && confused && !rn2(3))) {
5845 You("find a trap on %s!", the(xname(otmp)));
5847 pline("%s
\82Éã©
\82ð
\94
\8c©
\82µ
\82½
\81I", the(xname(otmp)));
5849 exercise(A_WIS, TRUE);
5852 switch (ynq("Disarm it?")) {
5854 switch (ynq("
\89ð
\8f\9c\82µ
\82Ü
\82·
\82©
\81H")) {
5858 trap_skipped = TRUE;
5862 if (otmp->otrapped) {
5863 exercise(A_DEX, TRUE);
5864 ch = ACURR(A_DEX) + u.ulevel;
5865 if (Role_if(PM_ROGUE))
5867 if (!force && (confused || Fumbling
5868 || rnd(75 + level_difficulty() / 2)
5870 (void) chest_trap(otmp, FINGER, TRUE);
5875 You("
\89ð
\8f\9c\82µ
\82½
\81I");
5880 pline("That %s was not trapped.", xname(otmp));
5882 pline("
\82»
\82Ì%s
\82Éã©
\82Í
\82È
\82¢
\81D", xname(otmp));
5886 You("find no traps on %s.", the(xname(otmp)));
5888 pline("ã©
\82ð
\94
\8c©
\82Å
\82«
\82È
\82©
\82Á
\82½
\81D");
5894 You(trap_skipped ? "find no other traps here."
5895 : "know of no traps here.");
5897 You(trap_skipped ? "
\91¼
\82Ìã©
\82ð
\8c©
\82Â
\82¯
\82ç
\82ê
\82È
\82©
\82Á
\82½
\81D"
5898 : "
\82±
\82±
\82Éã©
\82ª
\82È
\82¢
\82±
\82Æ
\82ð
\92m
\82Á
\82Ä
\82¢
\82é
\81D");
5903 if (stumble_on_door_mimic(x, y))
5906 } /* deal_with_floor_trap */
5907 /* doors can be manipulated even while levitating/unskilled riding */
5909 if (!IS_DOOR(levl[x][y].typ)) {
5912 You("know of no traps there.");
5914 You("
\82»
\82±
\82Éã©
\82ª
\82È
\82¢
\82±
\82Æ
\82ð
\92m
\82Á
\82Ä
\82¢
\82é
\81D");
5918 switch (levl[x][y].doormask) {
5921 You("%s no door there.", Blind ? "feel" : "see");
5923 pline("
\82»
\82±
\82É
\82Í
\94à
\82ª
\82È
\82¢%s
\81D", Blind ? "
\82æ
\82¤
\82¾" : "
\82æ
\82¤
\82É
\8c©
\82¦
\82é");
5927 pline("This door is safely open.");
5929 pline("
\82»
\82Ì
\94à
\82Í
\88À
\91S
\82É
\8aJ
\82¢
\82Ä
\82¢
\82é
\81D");
5933 pline("This door is broken.");
5935 pline("
\82»
\82Ì
\94à
\82Í
\89ó
\82ê
\82Ä
\82¢
\82é
\81D");
5939 if (((levl[x][y].doormask & D_TRAPPED) != 0
5940 && (force || (!confused && rn2(MAXULEV - u.ulevel + 11) < 10)))
5941 || (!force && confused && !rn2(3))) {
5943 You("find a trap on the door!");
5945 pline("
\94à
\82Éã©
\82ð
\94
\8c©
\82µ
\82½
\81I");
5946 exercise(A_WIS, TRUE);
5948 if (ynq("Disarm it?") != 'y')
5950 if (ynq("
\89ð
\8f\9c\82µ
\82Ü
\82·
\82©
\81H") != 'y')
5952 if (levl[x][y].doormask & D_TRAPPED) {
5953 ch = 15 + (Role_if(PM_ROGUE) ? u.ulevel * 3 : u.ulevel);
5954 exercise(A_DEX, TRUE);
5955 if (!force && (confused || Fumbling
5956 || rnd(75 + level_difficulty() / 2) > ch)) {
5960 You("
\83X
\83C
\83b
\83`
\82ð
\93ü
\82ê
\82Ä
\82µ
\82Ü
\82Á
\82½
\81I");
5962 b_trapped("door", FINGER);
5964 b_trapped("
\94à", FINGER);
5965 levl[x][y].doormask = D_NODOOR;
5966 unblock_point(x, y);
5968 /* (probably ought to charge for this damage...) */
5969 if (*in_rooms(x, y, SHOPBASE))
5970 add_damage(x, y, 0L);
5975 You("
\89ð
\8f\9c\82µ
\82½
\81I");
5976 levl[x][y].doormask &= ~D_TRAPPED;
5980 pline("This door was not trapped.");
5982 pline("
\94à
\82Éã©
\82Í
\82È
\82©
\82Á
\82½
\81D");
5986 You("find no traps on the door.");
5988 pline("
\94à
\82Éã©
\82ð
\94
\8c©
\82Å
\82«
\82È
\82©
\82Á
\82½
\81D");
5993 /* for magic unlocking; returns true if targetted monster (which might
5994 be hero) gets untrapped; the trap remains intact */
5996 openholdingtrap(mon, noticed)
5998 boolean *noticed; /* set to true iff hero notices the effect; */
5999 { /* otherwise left with its previous value intact */
6001 char buf[BUFSZ], whichbuf[20];
6002 const char *trapdescr = 0, *which = 0;
6003 boolean ishero = (mon == &youmonst);
6007 if (mon == u.usteed)
6010 t = t_at(ishero ? u.ux : mon->mx, ishero ? u.uy : mon->my);
6012 if (ishero && u.utrap) { /* all u.utraptype values are holding traps */
6013 which = the_your[(!t || !t->tseen || !t->madeby_u) ? 0 : 1];
6014 switch (u.utraptype) {
6017 trapdescr = "molten lava";
6019 trapdescr = "
\82Ç
\82ë
\82Ç
\82ë
\82Ì
\97n
\8aâ";
6022 /* solidified lava, so not "floor" even if within a room */
6024 trapdescr = "ground";
6026 trapdescr = "
\92n
\96Ê";
6030 trapdescr = "your anchor";
6032 trapdescr = "
\82
\82³
\82Ñ";
6038 trapdescr = 0; /* use defsyms[].explanation */
6041 /* lint suppression in case 't' is unexpectedly Null
6042 or u.utraptype has new value we don't know about yet */
6050 /* if no trap here or it's not a holding trap, we're done */
6051 if (!t || (t->ttyp != BEAR_TRAP && t->ttyp != WEB))
6056 trapdescr = defsyms[trap_to_defsym(t->ttyp)].explanation;
6059 which = t->tseen ? the_your[t->madeby_u]
6060 : index(vowels, *trapdescr) ? "an" : "a";
6062 which = t->tseen ? set_you[t->madeby_u] : "";
6065 which = strcat(strcpy(whichbuf, which), " ");
6073 Sprintf(buf, "%s is", noit_Monnam(u.usteed));
6075 Strcpy(buf, noit_Monnam(u.usteed));
6078 Strcpy(buf, "You are");
6080 Strcpy(buf, "
\82 \82È
\82½");
6082 vision_full_recalc = 1; /* vision limits can change (pit escape) */
6084 pline("%s released from %s%s.", buf, which, trapdescr);
6086 pline("%s
\82Í%s%s
\82©
\82ç
\89ð
\95ú
\82³
\82ê
\82½
\81D", buf, which, trapdescr);
6091 if (canspotmon(mon)) {
6094 pline("%s is released from %s%s.", Monnam(mon), which,
6097 pline("%s
\82Í%s%s
\82©
\82ç
\89ð
\95ú
\82³
\82ê
\82½
\81D", Monnam(mon), which,
6100 } else if (cansee(t->tx, t->ty) && t->tseen) {
6104 pline("%s is released from %s%s.", Something, which,
6107 pline("
\89½
\8eÒ
\82©
\82Í%s%s
\82©
\82ç
\89ð
\95ú
\82³
\82ê
\82½
\81D", which,
6110 else /* BEAR_TRAP */
6112 pline("%s%s opens.", upstart(strcpy(buf, which)), trapdescr);
6114 pline("%s%s
\82Í
\8aJ
\82¢
\82½
\81D", which, trapdescr);
6116 /* might pacify monster if adjacent */
6117 if (rn2(2) && distu(mon->mx, mon->my) <= 2)
6118 reward_untrap(t, mon);
6123 /* for magic locking; returns true if targetted monster (which might
6124 be hero) gets hit by a trap (might avoid actually becoming trapped) */
6126 closeholdingtrap(mon, noticed)
6128 boolean *noticed; /* set to true iff hero notices the effect; */
6129 { /* otherwise left with its previous value intact */
6131 unsigned dotrapflags;
6132 boolean ishero = (mon == &youmonst), result;
6136 if (mon == u.usteed)
6138 t = t_at(ishero ? u.ux : mon->mx, ishero ? u.uy : mon->my);
6139 /* if no trap here or it's not a holding trap, we're done */
6140 if (!t || (t->ttyp != BEAR_TRAP && t->ttyp != WEB))
6145 return FALSE; /* already trapped */
6147 dotrapflags = FORCETRAP;
6148 /* dotrap calls mintrap when mounted hero encounters a web */
6150 dotrapflags |= NOWEBMSG;
6152 dotrap(t, dotrapflags);
6154 result = (u.utrap != 0);
6157 return FALSE; /* already trapped */
6158 /* you notice it if you see the trap close/tremble/whatever
6159 or if you sense the monster who becomes trapped */
6160 *noticed = cansee(t->tx, t->ty) || canspotmon(mon);
6162 result = (mintrap(mon) != 0);
6168 /* for magic unlocking; returns true if targetted monster (which might
6169 be hero) gets hit by a trap (target might avoid its effect) */
6171 openfallingtrap(mon, trapdoor_only, noticed)
6173 boolean trapdoor_only;
6174 boolean *noticed; /* set to true iff hero notices the effect; */
6175 { /* otherwise left with its previous value intact */
6177 boolean ishero = (mon == &youmonst), result;
6181 if (mon == u.usteed)
6183 t = t_at(ishero ? u.ux : mon->mx, ishero ? u.uy : mon->my);
6184 /* if no trap here or it's not a falling trap, we're done
6185 (note: falling rock traps have a trapdoor in the ceiling) */
6186 if (!t || ((t->ttyp != TRAPDOOR && t->ttyp != ROCKTRAP)
6187 && (trapdoor_only || (t->ttyp != HOLE && !is_pit(t->ttyp)))))
6192 return FALSE; /* already trapped */
6194 dotrap(t, FORCETRAP);
6195 result = (u.utrap != 0);
6198 return FALSE; /* already trapped */
6199 /* you notice it if you see the trap close/tremble/whatever
6200 or if you sense the monster who becomes trapped */
6201 *noticed = cansee(t->tx, t->ty) || canspotmon(mon);
6202 /* monster will be angered; mintrap doesn't handle that */
6205 result = (mintrap(mon) != 0);
6207 /* mon might now be on the migrating monsters list */
6212 /* only called when the player is doing something to the chest directly */
6214 chest_trap(obj, bodypart, disarm)
6215 register struct obj *obj;
6216 register int bodypart;
6219 register struct obj *otmp = obj, *otmp2;
6224 if (get_obj_location(obj, &cc.x, &cc.y, 0)) /* might be carried */
6225 obj->ox = cc.x, obj->oy = cc.y;
6227 otmp->otrapped = 0; /* trap is one-shot; clear flag first in case
6228 chest kills you and ends up in bones file */
6230 You(disarm ? "set it off!" : "trigger a trap!");
6232 You(disarm ? "
\83X
\83C
\83b
\83`
\82ð
\93ü
\82ê
\82Ä
\82µ
\82Ü
\82Á
\82½
\81I" : "ã©
\82É
\82Ð
\82Á
\82©
\82©
\82Á
\82½
\81I");
6233 display_nhwindow(WIN_MESSAGE, FALSE);
6234 if (Luck > -13 && rn2(13 + Luck) > 7) { /* saved by luck */
6235 /* trap went off, but good luck prevents damage */
6240 msg = "explosive charge is a dud";
6242 msg = "
\94\9a\94
\82Í
\95s
\94
\82¾
\82Á
\82½";
6247 msg = "electric charge is grounded";
6249 msg = "
\93d
\8c\82\82ª
\95ú
\8fo
\82³
\82ê
\82½
\82ª
\83A
\81[
\83X
\82³
\82ê
\82Ä
\82¢
\82½";
6254 msg = "flame fizzles out";
6256 msg = "
\89\8a\82Í
\83V
\83\85\81[
\82Á
\82Æ
\8fÁ
\82¦
\82½";
6262 msg = "poisoned needle misses";
6264 msg = "
\93Å
\90j
\82Í
\8eh
\82³
\82ç
\82È
\82©
\82Á
\82½";
6271 msg = "gas cloud blows away";
6273 msg = "
\83K
\83X
\89_
\82Í
\90\81\82«
\94ò
\82ñ
\82¾";
6276 impossible("chest disarm bug");
6282 pline("But luckily the %s!", msg);
6284 pline("
\82µ
\82©
\82µ
\89^
\82Ì
\82æ
\82¢
\82±
\82Æ
\82É%s
\81I", msg);
6286 switch (rn2(20) ? ((Luck >= 13) ? 0 : rn2(13 - Luck)) : rn2(26)) {
6292 struct monst *shkp = 0;
6294 boolean costly, insider;
6295 register xchar ox = obj->ox, oy = obj->oy;
6297 /* the obj location need not be that of player */
6298 costly = (costly_spot(ox, oy)
6299 && (shkp = shop_keeper(*in_rooms(ox, oy, SHOPBASE)))
6300 != (struct monst *) 0);
6301 insider = (*u.ushops && inside_shop(u.ux, u.uy)
6302 && *in_rooms(ox, oy, SHOPBASE) == *u.ushops);
6305 pline("%s!", Tobjnam(obj, "explode"));
6307 pline("%s
\82Í
\94\9a\94
\82µ
\82½
\81I", xname(obj));
6309 Sprintf(buf, "exploding %s", xname(obj));
6311 Sprintf(buf, "%s
\82Ì
\94\9a\94
\82Å", xname(obj));
6314 loss += stolen_value(obj, ox, oy, (boolean) shkp->mpeaceful,
6316 delete_contents(obj);
6317 /* unpunish() in advance if either ball or chain (or both)
6318 is going to be destroyed */
6319 if (Punished && ((uchain->ox == u.ux && uchain->oy == u.uy)
6320 || (uball->where == OBJ_FLOOR
6321 && uball->ox == u.ux && uball->oy == u.uy)))
6324 for (otmp = level.objects[u.ux][u.uy]; otmp; otmp = otmp2) {
6325 otmp2 = otmp->nexthere;
6327 loss += stolen_value(otmp, otmp->ox, otmp->oy,
6328 (boolean) shkp->mpeaceful, TRUE);
6332 losehp(Maybe_Half_Phys(d(6, 6)), buf, KILLED_BY_AN);
6333 exercise(A_STR, FALSE);
6334 if (costly && loss) {
6337 You("owe %ld %s for objects destroyed.", loss,
6340 You("
\8aí
\95¨
\94j
\91¹
\82Å%ld%s
\82Ì
\8eØ
\82è
\82ð
\82Â
\82
\82Á
\82½
\81D", loss,
6345 You("caused %ld %s worth of damage!", loss,
6348 You("%ld%s
\95ª
\82Ì
\91¹
\8aQ
\82ð
\88ø
\82«
\82¨
\82±
\82µ
\82½
\81I", loss,
6351 make_angry_shk(shkp, ox, oy);
6361 pline("A cloud of noxious gas billows from %s.", the(xname(obj)));
6363 pline("
\97L
\93Å
\83K
\83X
\82ª%s
\82©
\82ç
\89Q
\82Ü
\82¢
\82½
\81D", the(xname(obj)));
6365 poisoned("gas cloud", A_STR, "cloud of poison gas", 15, FALSE);
6367 poisoned("
\83K
\83X
\89_", A_STR, "
\83K
\83X
\89_", 15, FALSE);
6368 exercise(A_CON, FALSE);
6375 You_feel("a needle prick your %s.", body_part(bodypart));
6377 You("%s
\83`
\83N
\83b
\82Æ
\82¢
\82¤
\92É
\82Ý
\82ð
\8a´
\82¶
\82½
\81D", body_part(bodypart));
6379 poisoned("needle", A_CON, "poisoned needle", 10, FALSE);
6381 poisoned("
\90j", A_CON, "
\93Å
\90j", 10, FALSE);
6382 exercise(A_CON, FALSE);
6396 You("are jolted by a surge of electricity!");
6398 You("
\93d
\8bC
\83V
\83\87\83b
\83N
\82ð
\82
\82ç
\82Á
\82½
\81I");
6399 if (Shock_resistance) {
6400 shieldeff(u.ux, u.uy);
6402 You("don't seem to be affected.");
6404 pline("
\82µ
\82©
\82µ
\82 \82È
\82½
\82Í
\89e
\8b¿
\82ð
\8eó
\82¯
\82È
\82¢
\81D");
6408 destroy_item(RING_CLASS, AD_ELEC);
6409 destroy_item(WAND_CLASS, AD_ELEC);
6412 losehp(dmg, "electric shock", KILLED_BY_AN);
6414 losehp(dmg, "
\93d
\8bC
\83V
\83\87\83b
\83N
\82Å", KILLED_BY_AN);
6422 pline("Suddenly you are frozen in place!");
6424 pline("
\93Ë
\91R
\82»
\82Ì
\8fê
\82Å
\93®
\82¯
\82È
\82
\82È
\82Á
\82½
\81I");
6427 multi_reason = "frozen by a trap";
6429 multi_reason = "ã©
\82Å
\8dd
\92¼
\82µ
\82Ä
\82¢
\82é
\8e\9e\82É";
6430 exercise(A_DEX, FALSE);
6431 nomovemsg = You_can_move_again;
6434 You("momentarily stiffen.");
6436 You("
\88ê
\8fu
\8dd
\92¼
\82µ
\82½
\81D");
6442 pline("A cloud of %s gas billows from %s.",
6443 Blind ? blindgas[rn2(SIZE(blindgas))] : rndcolor(),
6446 pline("%s
\83K
\83X
\89_
\82ª%s
\82Ì
\92ê
\82Å
\89Q
\82Ü
\82¢
\82½
\81D",
6447 Blind ? blindgas[rn2(SIZE(blindgas))] :
6448 jconj_adj(rndcolor()), xname(obj));
6453 pline("What a groovy feeling!");
6455 pline("
\82È
\82ñ
\82Ä
\91f
\93G
\82È
\82ñ
\82¾
\81I");
6458 You("%s%s...", stagger(youmonst.data, "stagger"),
6459 Halluc_resistance ? ""
6460 : Blind ? " and get dizzy"
6461 : " and your vision blurs");
6463 You("
\82
\82ç
\82
\82ç
\82µ%s
\82½...",
6464 Halluc_resistance ? ""
6465 : Blind ? "
\81C
\82ß
\82Ü
\82¢
\82ª
\82µ"
6466 : "
\81C
\8ci
\90F
\82ª
\82Ú
\82â
\82¯
\82Ä
\82«");
6469 make_stunned((HStun & TIMEOUT) + (long) rn1(7, 16), FALSE);
6470 (void) make_hallucinated(
6471 (HHallucination & TIMEOUT) + (long) rn1(5, 16), FALSE, 0L);
6474 impossible("bad chest trap");
6477 bot(); /* to get immediate botl re-display */
6487 register struct trap *trap = ftrap;
6490 if (trap->tx == x && trap->ty == y)
6494 return (struct trap *) 0;
6499 register struct trap *trap;
6501 register struct trap *ttmp;
6503 clear_conjoined_pits(trap);
6504 if (trap == ftrap) {
6505 ftrap = ftrap->ntrap;
6507 for (ttmp = ftrap; ttmp; ttmp = ttmp->ntrap)
6508 if (ttmp->ntrap == trap)
6511 panic("deltrap: no preceding trap!");
6512 ttmp->ntrap = trap->ntrap;
6514 if (Sokoban && (trap->ttyp == PIT || trap->ttyp == HOLE))
6515 maybe_finish_sokoban();
6520 conjoined_pits(trap2, trap1, u_entering_trap2)
6521 struct trap *trap2, *trap1;
6522 boolean u_entering_trap2;
6524 int dx, dy, diridx, adjidx;
6526 if (!trap1 || !trap2)
6528 if (!isok(trap2->tx, trap2->ty) || !isok(trap1->tx, trap1->ty)
6529 || !is_pit(trap2->ttyp)
6530 || !is_pit(trap1->ttyp)
6531 || (u_entering_trap2 && !(u.utrap && u.utraptype == TT_PIT)))
6533 dx = sgn(trap2->tx - trap1->tx);
6534 dy = sgn(trap2->ty - trap1->ty);
6535 for (diridx = 0; diridx < 8; diridx++)
6536 if (xdir[diridx] == dx && ydir[diridx] == dy)
6538 /* diridx is valid if < 8 */
6540 adjidx = (diridx + 4) % 8;
6541 if ((trap1->conjoined & (1 << diridx))
6542 && (trap2->conjoined & (1 << adjidx)))
6549 clear_conjoined_pits(trap)
6552 int diridx, adjidx, x, y;
6555 if (trap && is_pit(trap->ttyp)) {
6556 for (diridx = 0; diridx < 8; ++diridx) {
6557 if (trap->conjoined & (1 << diridx)) {
6558 x = trap->tx + xdir[diridx];
6559 y = trap->ty + ydir[diridx];
6561 && (t = t_at(x, y)) != 0
6562 && is_pit(t->ttyp)) {
6563 adjidx = (diridx + 4) % 8;
6564 t->conjoined &= ~(1 << adjidx);
6566 trap->conjoined &= ~(1 << diridx);
6573 adj_nonconjoined_pit(adjtrap)
6574 struct trap *adjtrap;
6576 struct trap *trap_with_u = t_at(u.ux0, u.uy0);
6578 if (trap_with_u && adjtrap && u.utrap && u.utraptype == TT_PIT
6579 && is_pit(trap_with_u->ttyp) && is_pit(adjtrap->ttyp)) {
6582 for (idx = 0; idx < 8; idx++) {
6583 if (xdir[idx] == u.dx && ydir[idx] == u.dy)
6592 * Mark all neighboring pits as conjoined pits.
6593 * (currently not called from anywhere)
6596 join_adjacent_pits(trap)
6604 for (diridx = 0; diridx < 8; ++diridx) {
6605 x = trap->tx + xdir[diridx];
6606 y = trap->ty + ydir[diridx];
6608 if ((t = t_at(x, y)) != 0 && is_pit(t->ttyp)) {
6609 trap->conjoined |= (1 << diridx);
6610 join_adjacent_pits(t);
6612 trap->conjoined &= ~(1 << diridx);
6619 * Returns TRUE if you escaped a pit and are standing on the precipice.
6622 uteetering_at_seen_pit(trap)
6625 return (trap && is_pit(trap->ttyp) && trap->tseen
6626 && trap->tx == u.ux && trap->ty == u.uy
6627 && !(u.utrap && u.utraptype == TT_PIT));
6631 * Returns TRUE if you didn't fall through a hole or didn't
6632 * release a trap door
6635 uescaped_shaft(trap)
6638 return (trap && is_hole(trap->ttyp) && trap->tseen
6639 && trap->tx == u.ux && trap->ty == u.uy);
6642 /* Destroy a trap that emanates from the floor. */
6645 register struct trap *ttmp;
6647 /* some of these are arbitrary -dlc */
6648 if (ttmp && ((ttmp->ttyp == SQKY_BOARD) || (ttmp->ttyp == BEAR_TRAP)
6649 || (ttmp->ttyp == LANDMINE) || (ttmp->ttyp == FIRE_TRAP)
6650 || is_pit(ttmp->ttyp)
6651 || is_hole(ttmp->ttyp)
6652 || (ttmp->ttyp == TELEP_TRAP) || (ttmp->ttyp == LEVEL_TELEP)
6653 || (ttmp->ttyp == WEB) || (ttmp->ttyp == MAGIC_TRAP)
6654 || (ttmp->ttyp == ANTI_MAGIC))) {
6655 register struct monst *mtmp;
6657 if (ttmp->tx == u.ux && ttmp->ty == u.uy) {
6658 if (u.utraptype != TT_BURIEDBALL)
6660 } else if ((mtmp = m_at(ttmp->tx, ttmp->ty)) != 0) {
6669 /* used for doors (also tins). can be used for anything else that opens. */
6671 b_trapped(item, bodypart)
6675 int lvl = level_difficulty(),
6676 dmg = rnd(5 + (lvl < 5 ? lvl : 2 + lvl / 2));
6679 pline("KABOOM!! %s was booby-trapped!", The(item));
6681 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);
6684 losehp(Maybe_Half_Phys(dmg), "explosion", KILLED_BY_AN);
6686 losehp(Maybe_Half_Phys(dmg), "
\83u
\81[
\83r
\81[
\83g
\83\89\83b
\83v
\82Ì
\94\9a\94
\82Å", KILLED_BY_AN);
6687 exercise(A_STR, FALSE);
6689 exercise(A_CON, FALSE);
6690 make_stunned((HStun & TIMEOUT) + (long) dmg, TRUE);
6693 /* Monster is hit by trap. */
6694 /* Note: doesn't work if both obj and d_override are null */
6696 thitm(tlev, mon, obj, d_override, nocorpse)
6704 boolean trapkilled = FALSE;
6709 strike = (find_mac(mon) + tlev + obj->spe <= rnd(20));
6711 strike = (find_mac(mon) + tlev <= rnd(20));
6713 /* Actually more accurate than thitu, which doesn't take
6714 * obj->spe into account.
6717 if (obj && cansee(mon->mx, mon->my))
6719 pline("%s is almost hit by %s!", Monnam(mon), doname(obj));
6721 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));
6725 if (obj && cansee(mon->mx, mon->my))
6727 pline("%s is hit by %s!", Monnam(mon), doname(obj));
6729 pline("%s
\82ª%s
\82É
\96½
\92\86\82µ
\82½
\81I", doname(obj), Monnam(mon));
6733 dam = dmgval(obj, mon);
6738 if (DEADMONSTER(mon)) {
6739 int xx = mon->mx, yy = mon->my;
6741 monkilled(mon, "", nocorpse ? -AD_RBRE : AD_PHYS);
6742 if (DEADMONSTER(mon)) {
6748 if (obj && (!strike || d_override)) {
6749 place_object(obj, mon->mx, mon->my);
6764 return (boolean) (u.usleep
6766 && (!strncmp(nomovemsg, "You awake", 9)
6767 || !strncmp(nomovemsg, "You regain con", 14)
6768 || !strncmp(nomovemsg, "You are consci", 14))));
6770 /*JP 3.6.2
\82Å
\82Ì
\8fo
\8c»
\88Ê
\92u/
\89ñ
\90\94
6771 "You awake" : potion.c(1)
6772 "You regain con": eat.c(1)
6773 "You are consci": eat.c(1)
6775 return (boolean) (u.usleep
6777 && (!strncmp(nomovemsg, "
\96Ú
\82ª
\82³
\82ß
\82½
\82ª
\93ª
\92É", 18)
6778 || !strncmp(nomovemsg, "
\82 \82È
\82½
\82Í
\90³
\8bC
\82Ã
\82¢
\82½", 18)
6779 || !strncmp(nomovemsg, "
\82 \82È
\82½
\82Í
\82Ü
\82½
\90³
\8bC
\82Ã", 18))));
6784 static const char lava_killer[] = "molten lava";
6786 static const char lava_killer[] = "
\82Ç
\82ë
\82Ç
\82ë
\82Ì
\97n
\8aâ
\82Å";
6791 register struct obj *obj, *obj2;
6792 int dmg = d(6, 6); /* only applicable for water walking */
6793 boolean usurvive, boil_away;
6795 feel_newsym(u.ux, u.uy); /* in case Blind, map the lava here */
6797 if (likes_lava(youmonst.data))
6800 usurvive = Fire_resistance || (Wwalking && dmg < u.uhp);
6802 * A timely interrupt might manage to salvage your life
6803 * but not your gear. For scrolls and potions this
6804 * will destroy whole stacks, where fire resistant hero
6805 * survivor only loses partial stacks via destroy_item().
6807 * Flag items to be destroyed before any messages so
6808 * that player causing hangup at --More-- won't get an
6809 * emergency save file created before item destruction.
6812 for (obj = invent; obj; obj = obj->nobj)
6813 if ((is_organic(obj) || obj->oclass == POTION_CLASS)
6814 && !obj->oerodeproof
6815 && objects[obj->otyp].oc_oprop != FIRE_RES
6816 && obj->otyp != SCR_FIRE && obj->otyp != SPE_FIREBALL
6817 && !obj_resists(obj, 0, 0)) /* for invocation items */
6820 /* Check whether we should burn away boots *first* so we know whether to
6821 * make the player sink into the lava. Assumption: water walking only
6824 if (uarmf && is_organic(uarmf) && !uarmf->oerodeproof) {
6827 pline("%s into flame!", Yobjnam2(obj, "burst"));
6829 Your("%s
\82Í
\94R
\82¦
\82½
\81I", xname(obj));
6830 iflags.in_lava_effects++; /* (see above) */
6833 iflags.in_lava_effects--;
6836 if (!Fire_resistance) {
6839 pline_The("%s here burns you!", hliquid("lava"));
6841 pline("%s
\82ª
\82 \82È
\82½
\82ð
\8fÄ
\82«
\82Â
\82
\82µ
\82½
\81I", hliquid("
\97n
\8aâ"));
6843 losehp(dmg, lava_killer, KILLED_BY); /* lava damage */
6848 You("fall into the %s!", hliquid("lava"));
6850 You("%s
\82É
\97\8e\82¿
\82½
\81I", hliquid("
\97n
\8aâ"));
6852 usurvive = Lifesaved || discover;
6856 /* prevent remove_worn_item() -> Boots_off(WATER_WALKING_BOOTS) ->
6857 spoteffects() -> lava_effects() recursion which would
6858 successfully delete (via useupall) the no-longer-worn boots;
6859 once recursive call returned, we would try to delete them again
6860 here in the outer call (and access stale memory, probably panic) */
6861 iflags.in_lava_effects++;
6863 for (obj = invent; obj; obj = obj2) {
6865 /* above, we set in_use for objects which are to be destroyed */
6866 if (obj->otyp == SPE_BOOK_OF_THE_DEAD && !Blind) {
6869 pline("%s glows a strange %s, but remains intact.",
6870 The(xname(obj)), hcolor("dark red"));
6872 pline("%s
\82Í
\95s
\8ev
\8bc
\82É%s
\8bP
\82¢
\82½
\82ª
\81C
\96³
\8f\9d\82Ì
\82æ
\82¤
\82¾
\81D",
6873 xname(obj), jconj_adj(hcolor("
\88Ã
\90Ô
\90F
\82Ì")));
6875 } else if (obj->in_use) {
6876 if (obj->owornmask) {
6879 pline("%s into flame!", Yobjnam2(obj, "burst"));
6881 Your("%s
\82Í
\94R
\82¦
\82½
\81I", xname(obj));
6882 remove_worn_item(obj, TRUE);
6888 iflags.in_lava_effects--;
6891 boil_away = (u.umonnum == PM_WATER_ELEMENTAL
6892 || u.umonnum == PM_STEAM_VORTEX
6893 || u.umonnum == PM_FOG_CLOUD);
6896 /* killer format and name are reconstructed every iteration
6897 because lifesaving resets them */
6898 killer.format = KILLED_BY;
6899 Strcpy(killer.name, lava_killer);
6901 You("%s...", boil_away ? "boil away" : "burn to a crisp");
6903 You("%s
\81D
\81D
\81D", boil_away ? "
\95¦
\93«
\82µ
\82½" : "
\94R
\82¦
\82Ä
\83p
\83\8a\83p
\83\8a\82É
\82È
\82Á
\82½");
6905 if (safe_teleds(TRUE))
6906 break; /* successful life-save */
6907 /* nowhere safe to land; repeat burning loop */
6909 pline("You're still burning.");
6911 You("
\82Ü
\82¾
\94R
\82¦
\82Ä
\82¢
\82é
\81D");
6914 You("find yourself back on solid %s.", surface(u.ux, u.uy));
6916 You("
\82¢
\82Â
\82Ì
\82Ü
\82É
\82©
\8cÅ
\82¢%s
\82É
\96ß
\82Á
\82Ä
\82¢
\82½
\81D", surface(u.ux, u.uy));
6918 } else if (!Wwalking && (!u.utrap || u.utraptype != TT_LAVA)) {
6919 boil_away = !Fire_resistance;
6920 /* if not fire resistant, sink_into_lava() will quickly be fatal;
6921 hero needs to escape immediately */
6922 set_utrap((unsigned) (rn1(4, 4) + ((boil_away ? 2 : rn1(4, 12)) << 8)),
6925 You("sink into the %s%s!", hliquid("lava"),
6926 !boil_away ? ", but it only burns slightly"
6927 : " and are about to be immolated");
6929 You("%s
\82É
\92¾
\82ñ%s
\82¾
\81I", hliquid("
\97n
\8aâ"),
6930 !boil_away ? "
\82¾
\82ª
\81C
\82¿
\82å
\82Á
\82Æ
\8fÅ
\82°
\82½
\82¾
\82¯"
6931 : "
\82Å
\8fÄ
\82«
\8eE
\82³
\82ê
\82»
\82¤");
6934 losehp(!boil_away ? 1 : (u.uhp / 2), lava_killer,
6935 KILLED_BY); /* lava damage */
6939 destroy_item(SCROLL_CLASS, AD_FIRE);
6940 destroy_item(SPBOOK_CLASS, AD_FIRE);
6941 destroy_item(POTION_CLASS, AD_FIRE);
6945 /* called each turn when trapped in lava */
6950 static const char sink_deeper[] = "You sink deeper into the lava.";
6952 static const char sink_deeper[] = "
\82 \82È
\82½
\82Í
\82æ
\82è
\90[
\82
\97n
\8aâ
\82É
\92¾
\82ñ
\82¾
\81D";
6954 if (!u.utrap || u.utraptype != TT_LAVA) {
6955 ; /* do nothing; this usually won't happen but could after
6956 * polymorphing from a flier into a ceiling hider and then hiding;
6957 * allmain() only checks whether the hero is at a lava location,
6958 * not whether he or she is currently sinking */
6959 } else if (!is_lava(u.ux, u.uy)) {
6960 reset_utrap(FALSE); /* this shouldn't happen either */
6961 } else if (!u.uinvulnerable) {
6962 /* ordinarily we'd have to be fire resistant to survive long
6963 enough to become stuck in lava, but it can happen without
6964 resistance if water walking boots allow survival and then
6965 get burned up; u.utrap time will be quite short in that case */
6966 if (!Fire_resistance)
6967 u.uhp = (u.uhp + 2) / 3;
6969 u.utrap -= (1 << 8);
6970 if (u.utrap < (1 << 8)) {
6971 killer.format = KILLED_BY;
6973 Strcpy(killer.name, "molten lava");
6975 Strcpy(killer.name, "
\82Ç
\82ë
\82Ç
\82ë
\82Ì
\97n
\8aâ
\82Å");
6977 You("sink below the surface and die.");
6979 You("
\8a®
\91S
\82É
\97n
\8aâ
\82Ì
\92\86\82É
\92¾
\82ñ
\82Å
\81A
\8e\80\82É
\82Ü
\82µ
\82½
\81D
\81D
\81D");
6980 burn_away_slime(); /* add insult to injury? */
6982 /* can only get here via life-saving; try to get away from lava */
6984 /* levitation or flight have become unblocked, otherwise Tport */
6985 if (!Levitation && !Flying)
6986 (void) safe_teleds(TRUE);
6987 } else if (!u.umoved) {
6988 /* can't fully turn into slime while in lava, but might not
6989 have it be burned away until you've come awfully close */
6990 if (Slimed && rnd(10 - 1) >= (int) (Slimed & TIMEOUT)) {
7001 /* called when something has been done (breaking a boulder, for instance)
7002 which entails a luck penalty if performed on a sokoban level */
7008 /* TODO: issue some feedback so that player can learn that whatever
7009 he/she just did is a naughty thing to do in sokoban and should
7010 probably be avoided in future....
7011 Caveat: doing this might introduce message sequencing issues,
7012 depending upon feedback during the various actions which trigger
7013 Sokoban luck penalties. */
7017 /* called when a trap has been deleted or had its ttyp replaced */
7019 maybe_finish_sokoban()
7023 if (Sokoban && !in_mklev) {
7024 /* scan all remaining traps, ignoring any created by the hero;
7025 if this level has no more pits or holes, the current sokoban
7026 puzzle has been solved */
7027 for (t = ftrap; t; t = t->ntrap) {
7030 if (t->ttyp == PIT || t->ttyp == HOLE)
7034 /* we've passed the last trap without finding a pit or hole;
7035 clear the sokoban_rules flag so that luck penalties for
7036 things like breaking boulders or jumping will no longer
7037 be given, and restrictions on diagonal moves are lifted */
7038 Sokoban = 0; /* clear level.flags.sokoban_rules */
7039 /* TODO: give some feedback about solving the sokoban puzzle
7040 (perhaps say "congratulations" in Japanese?) */