1 /* NetHack 3.6 trap.c $NHDT-Date: 1448492213 2015/11/25 22:56:53 $ $NHDT-Branch: master $:$NHDT-Revision: 1.249 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /* NetHack may be freely redistributed. See license for details. */
5 /* JNetHack Copyright */
6 /* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000 */
7 /* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2016 */
8 /* JNetHack may be freely redistributed. See license for details. */
12 extern const char *const destroy_strings[][3]; /* from zap.c */
14 STATIC_DCL void FDECL(dofiretrap, (struct obj *));
15 STATIC_DCL void NDECL(domagictrap);
16 STATIC_DCL boolean FDECL(emergency_disrobe, (boolean *));
17 STATIC_DCL int FDECL(untrap_prob, (struct trap *));
18 STATIC_DCL void FDECL(move_into_trap, (struct trap *));
19 STATIC_DCL int FDECL(try_disarm, (struct trap *, BOOLEAN_P));
20 STATIC_DCL void FDECL(reward_untrap, (struct trap *, struct monst *));
21 STATIC_DCL int FDECL(disarm_holdingtrap, (struct trap *));
22 STATIC_DCL int FDECL(disarm_landmine, (struct trap *));
23 STATIC_DCL int FDECL(disarm_squeaky_board, (struct trap *));
24 STATIC_DCL int FDECL(disarm_shooting_trap, (struct trap *, int));
25 STATIC_DCL int FDECL(try_lift, (struct monst *, struct trap *, int,
27 STATIC_DCL int FDECL(help_monster_out, (struct monst *, struct trap *));
28 STATIC_DCL boolean FDECL(thitm, (int, struct monst *, struct obj *, int,
30 STATIC_DCL void FDECL(launch_drop_spot, (struct obj *, XCHAR_P, XCHAR_P));
31 STATIC_DCL int FDECL(mkroll_launch, (struct trap *, XCHAR_P, XCHAR_P,
33 STATIC_DCL boolean FDECL(isclearpath, (coord *, int, SCHAR_P, SCHAR_P));
34 STATIC_DCL char *FDECL(trapnote, (struct trap *, BOOLEAN_P));
36 STATIC_DCL void FDECL(join_adjacent_pits, (struct trap *));
38 STATIC_DCL void FDECL(clear_conjoined_pits, (struct trap *));
39 STATIC_DCL int FDECL(steedintrap, (struct trap *, struct obj *));
40 STATIC_DCL boolean FDECL(keep_saddle_with_steedcorpse, (unsigned,
43 STATIC_DCL void NDECL(maybe_finish_sokoban);
45 /* mintrap() should take a flags argument, but for time being we use this */
46 STATIC_VAR int force_mintrap = 0;
49 STATIC_VAR const char *const a_your[2] = { "a", "your" };
50 STATIC_VAR const char *const A_Your[2] = { "A", "Your" };
51 STATIC_VAR const char tower_of_flame[] = "tower of flame";
52 STATIC_VAR const char *const A_gush_of_water_hits = "A gush of water hits";
55 STATIC_VAR const char *const blindgas[6] = { "humid", "odorless",
56 "pungent", "chilling",
59 STATIC_VAR const char * const blindgas[6] = {
60 "
\82Þ
\82µ
\82Þ
\82µ
\82·
\82é", "
\96³
\8fL
\82Ì",
61 "
\8eh
\8c\83\8fL
\82Ì
\82·
\82é", "
\97â
\82½
\82¢",
62 "
\83c
\83\93\82Æ
\82µ
\82½
\82É
\82¨
\82¢
\82Ì", "
\82Ð
\82è
\82Ð
\82è
\82·
\82é"
66 const char *set_you[2] = { "", "
\82 \82È
\82½
\82Ì
\8ed
\8a|
\82¯
\82½" };
67 STATIC_VAR const char *dig_you[2] = { "", "
\82 \82È
\82½
\82ª
\8c@
\82Á
\82½" };
68 STATIC_VAR const char *web_you[2] = { "", "
\82 \82È
\82½
\82ª
\92£
\82Á
\82½" };
71 /* called when you're hit by fire (dofiretrap,buzz,zapyourself,explode);
72 returns TRUE if hit on torso */
84 hitting_u = (victim == &youmonst);
86 /* burning damage may dry wet towel */
87 item = hitting_u ? carrying(TOWEL) : m_carrying(victim, TOWEL);
89 if (is_wet_towel(item)) {
91 dry_a_towel(item, rn2(oldspe + 1), TRUE);
92 if (item->spe != oldspe)
93 break; /* stop once one towel has been affected */
98 #define burn_dmg(obj, descr) erode_obj(obj, descr, ERODE_BURN, EF_GREASE)
102 item = hitting_u ? uarmh : which_armor(victim, W_ARMH);
104 mat_idx = objects[item->otyp].oc_material;
106 Sprintf(buf, "%s %s", materialnm[mat_idx],
107 helm_simple_name(item));
109 Sprintf(buf, "%s
\82Ì%s", materialnm[mat_idx],
110 helm_simple_name(item));
114 if (!burn_dmg(item, item ? buf : "helmet"))
116 if (!burn_dmg(item, item ? buf : "
\8a\95"))
120 item = hitting_u ? uarmc : which_armor(victim, W_ARMC);
122 (void) burn_dmg(item, cloak_simple_name(item));
125 item = hitting_u ? uarm : which_armor(victim, W_ARM);
127 (void) burn_dmg(item, xname(item));
130 item = hitting_u ? uarmu : which_armor(victim, W_ARMU);
133 (void) burn_dmg(item, "shirt");
135 (void) burn_dmg(item, "
\83V
\83\83\83c");
138 item = hitting_u ? uarms : which_armor(victim, W_ARMS);
140 if (!burn_dmg(item, "wooden shield"))
142 if (!burn_dmg(item, "
\96Ø
\82Ì
\8f\82"))
146 item = hitting_u ? uarmg : which_armor(victim, W_ARMG);
148 if (!burn_dmg(item, "gloves"))
150 if (!burn_dmg(item, "
\8f¬
\8eè"))
154 item = hitting_u ? uarmf : which_armor(victim, W_ARMF);
156 if (!burn_dmg(item, "boots"))
158 if (!burn_dmg(item, "
\8cC"))
162 break; /* Out of while loop */
169 /* Generic erode-item function.
170 * "ostr", if non-null, is an alternate string to print instead of the
172 * "type" is an ERODE_* value for the erosion type
173 * "flags" is an or-ed list of EF_* flags
175 * Returns an erosion return value (ER_*)
178 erode_obj(otmp, ostr, type, ef_flags)
179 register struct obj *otmp;
185 static NEARDATA const char *const action[] = { "smoulder", "rust", "rot",
188 static NEARDATA const char * const action[] = {
189 "
\82
\82·
\82Ô
\82Á
\82½", "
\8eK
\82Ñ
\82½", "
\95\85\82Á
\82½", "
\95\85\90H
\82µ
\82½" };
192 static NEARDATA const char *const msg[] = { "burnt", "rusted", "rotten",
195 static NEARDATA const char * const msg[] = {
196 "
\8fÅ
\82°
\82½", "
\8eK
\82Ñ
\82½", "
\95\85\82Á
\82½", "
\95\85\90H
\82µ
\82½" };
198 boolean vulnerable = FALSE;
199 boolean is_primary = TRUE;
200 boolean check_grease = ef_flags & EF_GREASE;
201 boolean print = ef_flags & EF_VERBOSE;
203 struct monst *victim;
211 victim = carried(otmp) ? &youmonst : mcarried(otmp) ? otmp->ocarry : NULL;
212 vismon = victim && (victim != &youmonst) && canseemon(victim);
213 /* Is bhitpos correct here? Ugh. */
214 visobj = !victim && cansee(bhitpos.x, bhitpos.y);
218 vulnerable = is_flammable(otmp);
219 check_grease = FALSE;
220 cost_type = COST_BURN;
223 vulnerable = is_rustprone(otmp);
224 cost_type = COST_RUST;
227 vulnerable = is_rottable(otmp);
228 check_grease = FALSE;
230 cost_type = COST_ROT;
233 vulnerable = is_corrodeable(otmp);
235 cost_type = COST_CORRODE;
238 impossible("Invalid erosion type in erode_obj");
241 erosion = is_primary ? otmp->oeroded : otmp->oeroded2;
246 if (check_grease && otmp->greased) {
247 grease_protect(otmp, ostr, victim);
249 } else if (!vulnerable || (otmp->oerodeproof && otmp->rknown)) {
250 if (print && flags.verbose) {
251 if (victim == &youmonst)
253 Your("%s %s not affected.", ostr, vtense(ostr, "are"));
255 Your("%s
\82Í
\89e
\8b¿
\82ð
\8eó
\82¯
\82È
\82©
\82Á
\82½
\81D", ostr);
258 pline("%s %s %s not affected.", s_suffix(Monnam(victim)),
259 ostr, vtense(ostr, "are"));
261 pline("%s
\82Ì%s
\82Í
\89e
\8b¿
\82ð
\8eó
\82¯
\82È
\82©
\82Á
\82½
\81D", Monnam(victim),
266 } else if (otmp->oerodeproof || (otmp->blessed && !rnl(4))) {
267 if (flags.verbose && (print || otmp->oerodeproof)) {
268 if (victim == &youmonst)
270 pline("Somehow, your %s %s not affected.", ostr,
271 vtense(ostr, "are"));
273 pline("
\82È
\82º
\82©
\81C%s
\82Í
\89e
\8b¿
\82ð
\8eó
\82¯
\82È
\82©
\82Á
\82½
\81D",ostr);
277 pline("Somehow, %s %s %s not affected.",
278 s_suffix(mon_nam(victim)), ostr, vtense(ostr, "are"));
280 pline("
\82È
\82º
\82©
\81C%s
\82Ì%s
\82Í
\89e
\8b¿
\82ð
\8eó
\82¯
\82È
\82©
\82Á
\82½
\81D",
281 mon_nam(victim), ostr);
285 pline("Somehow, the %s %s not affected.", ostr,
286 vtense(ostr, "are"));
288 pline("
\82È
\82º
\82©
\81C%s
\82Í
\89e
\8b¿
\82ð
\8eó
\82¯
\82È
\82©
\82Á
\82½
\81D", ostr);
291 /* We assume here that if the object is protected because it
292 * is blessed, it still shows some minor signs of wear, and
293 * the hero can distinguish this from an object that is
294 * actually proof against damage. */
295 if (otmp->oerodeproof) {
297 if (victim == &youmonst)
302 } else if (erosion < MAX_ERODE) {
304 const char *adverb = (erosion + 1 == MAX_ERODE)
306 : erosion ? " further" : "";
308 const char *adverb = (erosion + 1 == MAX_ERODE)
310 : erosion ? "
\82³
\82ç
\82É" : "";
313 if (victim == &youmonst)
315 Your("%s %s%s!", ostr, vtense(ostr, action[type]), adverb);
317 pline("%s
\82Í%s%s
\81I", ostr, adverb, action[type]);
320 pline("%s %s %s%s!", s_suffix(Monnam(victim)), ostr,
321 vtense(ostr, action[type]), adverb);
323 pline("%s
\82Ì%s
\82Í%s%s
\81I", Monnam(victim), ostr,
324 adverb, action[type]);
328 pline("The %s %s%s!", ostr, vtense(ostr, action[type]), adverb);
330 pline("%s
\82Í%s%s
\81I", ostr, adverb, action[type]);
332 if (ef_flags & EF_PAY)
333 costly_alteration(otmp, cost_type);
340 if (victim == &youmonst)
344 } else if (ef_flags & EF_DESTROY) {
345 if (victim == &youmonst)
347 Your("%s %s away!", ostr, vtense(ostr, action[type]));
349 Your("%s
\82Í
\8a®
\91S
\82É%s
\81I", ostr, action[type]);
352 pline("%s %s %s away!", s_suffix(Monnam(victim)), ostr,
353 vtense(ostr, action[type]));
355 pline("%s
\82Ì%s
\82Í
\8a®
\91S
\82É%s
\81I", Monnam(victim), ostr,
360 pline("The %s %s away!", ostr, vtense(ostr, action[type]));
362 pline("%s
\82Í
\8a®
\91S
\82É%s
\81I", ostr, action[type]);
364 if (ef_flags & EF_PAY)
365 costly_alteration(otmp, cost_type);
371 if (flags.verbose && print) {
372 if (victim == &youmonst)
374 Your("%s %s completely %s.", ostr,
375 vtense(ostr, Blind ? "feel" : "look"), msg[type]);
377 Your("%s
\82Í
\8a®
\91S
\82É%s%s
\81D", ostr,
378 msg[type], Blind ? "
\82æ
\82¤
\82¾" : "");
382 pline("%s %s %s completely %s.", s_suffix(Monnam(victim)),
383 ostr, vtense(ostr, "look"), msg[type]);
385 pline("%s
\82Ì%s
\82Í
\8a®
\91S
\82É%s
\81D", Monnam(victim),
390 pline("The %s %s completely %s.", ostr, vtense(ostr, "look"),
393 pline("%s
\82Í
\8a®
\91S
\82É%s
\81D", ostr, msg[type]);
400 /* Protect an item from erosion with grease. Returns TRUE if the grease
404 grease_protect(otmp, ostr, victim)
405 register struct obj *otmp;
407 struct monst *victim;
410 static const char txt[] = "protected by the layer of grease!";
412 static const char txt[] = "
\96û
\82Ì
\93h
\82è
\82±
\82Ý
\82É
\82æ
\82Á
\82Ä
\8eç
\82ç
\82ê
\82Ä
\82¢
\82é
\81I";
413 boolean vismon = victim && (victim != &youmonst) && canseemon(victim);
416 if (victim == &youmonst)
418 Your("%s %s %s", ostr, vtense(ostr, "are"), txt);
420 Your("%s
\82Í%s", ostr, txt);
423 pline("%s's %s %s %s", Monnam(victim),
424 ostr, vtense(ostr, "are"), txt);
426 pline("%s
\82Ì%s
\82Í%s", Monnam(victim), ostr, txt);
428 } else if (victim == &youmonst || vismon) {
430 pline("%s %s", Yobjnam2(otmp, "are"), txt);
432 Your("%s
\82Í%s",xname(otmp), txt);
438 pline_The("grease dissolves.");
440 pline("
\96û
\82Í
\82Í
\82°
\82Ä
\82µ
\82Ü
\82Á
\82½
\81D");
450 register int x, y, typ;
452 static union vlaunchinfo zero_vl;
453 register struct trap *ttmp;
454 register struct rm *lev;
457 if ((ttmp = t_at(x, y)) != 0) {
458 if (ttmp->ttyp == MAGIC_PORTAL || ttmp->ttyp == VIBRATING_SQUARE)
459 return (struct trap *) 0;
461 if (u.utrap && x == u.ux && y == u.uy
462 && ((u.utraptype == TT_BEARTRAP && typ != BEAR_TRAP)
463 || (u.utraptype == TT_WEB && typ != WEB)
464 || (u.utraptype == TT_PIT && typ != PIT
465 && typ != SPIKED_PIT)))
467 /* old <tx,ty> remain valid */
468 } else if (IS_FURNITURE(levl[x][y].typ)) {
469 /* no trap on top of furniture (caller usually screens the
470 location to inhibit this, but wizard mode wishing doesn't) */
471 return (struct trap *) 0;
479 /* [re-]initialize all fields except ntrap (handled below) and <tx,ty> */
481 ttmp->launch.x = ttmp->launch.y = -1; /* force error if used before set */
482 ttmp->dst.dnum = ttmp->dst.dlevel = -1;
485 ttmp->tseen = (typ == HOLE); /* hide non-holes */
490 int tavail[12], tpick[12], tcnt = 0, k;
493 for (k = 0; k < 12; ++k)
494 tavail[k] = tpick[k] = 0;
495 for (t = ftrap; t; t = t->ntrap)
496 if (t->ttyp == SQKY_BOARD && t != ttmp)
497 tavail[t->tnote] = 1;
498 /* now populate tpick[] with the available indices */
499 for (k = 0; k < 12; ++k)
502 /* choose an unused note; if all are in use, pick a random one */
503 ttmp->tnote = (short) ((tcnt > 0) ? tpick[rn2(tcnt)] : rn2(12));
506 case STATUE_TRAP: { /* create a "living" statue */
508 struct obj *otmp, *statue;
509 struct permonst *mptr;
512 do { /* avoid ultimately hostile co-aligned unicorn */
513 mptr = &mons[rndmonnum()];
514 } while (--trycount > 0 && is_unicorn(mptr)
515 && sgn(u.ualign.type) == sgn(mptr->maligntyp));
516 statue = mkcorpstat(STATUE, (struct monst *) 0, mptr, x, y,
518 mtmp = makemon(&mons[statue->corpsenm], 0, 0, MM_NOCOUNTBIRTH);
520 break; /* should never happen */
521 while (mtmp->minvent) {
522 otmp = mtmp->minvent;
524 obj_extract_self(otmp);
525 (void) add_to_container(statue, otmp);
527 statue->owt = weight(statue);
531 case ROLLING_BOULDER_TRAP: /* boulder will roll towards trigger */
532 (void) mkroll_launch(ttmp, x, y, BOULDER, 1L);
541 if (*in_rooms(x, y, SHOPBASE)
542 && (typ == HOLE || typ == TRAPDOOR
543 || IS_DOOR(lev->typ) || IS_WALL(lev->typ)))
544 add_damage(x, y, /* schedule repair */
545 ((IS_DOOR(lev->typ) || IS_WALL(lev->typ))
546 && !context.mon_moving)
549 lev->doormask = 0; /* subsumes altarmask, icedpool... */
550 if (IS_ROOM(lev->typ)) /* && !IS_AIR(lev->typ) */
553 * some cases which can happen when digging
554 * down while phazing thru solid areas
556 else if (lev->typ == STONE || lev->typ == SCORR)
558 else if (IS_WALL(lev->typ) || lev->typ == SDOOR)
559 lev->typ = level.flags.is_maze_lev
561 : level.flags.is_cavernous_lev ? CORR : DOOR;
572 it shouldn't be possible to override a sokoban pit or hole
573 with some other trap, but we'll check just to be safe */
575 maybe_finish_sokoban();
582 boolean td; /* td == TRUE : trap door or hole */
586 const char *dont_fall = 0;
587 int newlevel, bottom;
589 /* we'll fall even while levitating in Sokoban; otherwise, if we
590 won't fall and won't be told that we aren't falling, give up now */
591 if (Blind && Levitation && !Sokoban)
594 bottom = dunlevs_in_dungeon(&u.uz);
595 /* when in the upper half of the quest, don't fall past the
596 middle "quest locate" level if hero hasn't been there yet */
597 if (In_quest(&u.uz)) {
598 int qlocate_depth = qlocate_level.dlevel;
600 /* deepest reached < qlocate implies current < qlocate */
601 if (dunlev_reached(&u.uz) < qlocate_depth)
602 bottom = qlocate_depth; /* early cut-off */
604 newlevel = dunlev(&u.uz); /* current level */
607 } while (!rn2(4) && newlevel < bottom);
610 struct trap *t = t_at(u.ux, u.uy);
614 if (t->ttyp == TRAPDOOR)
616 pline("A trap door opens up under you!");
618 pline("
\97\8e\82µ
\94à
\82ª
\82 \82È
\82½
\82Ì
\91«
\8c³
\82É
\8aJ
\82¢
\82½
\81I");
621 pline("There's a gaping hole under you!");
623 pline("
\82 \82È
\82½
\82Ì
\91«
\89º
\82É
\82Û
\82Á
\82©
\82è
\82Æ
\8c\8a\82ª
\8aJ
\82¢
\82Ä
\82¢
\82é
\81I");
627 pline_The("%s opens up under you!", surface(u.ux, u.uy));
629 pline("
\91«
\8c³
\82Ì%s
\82É
\8c\8a\82ª
\8aJ
\82¢
\82½
\81I", surface(u.ux,u.uy));
631 if (Sokoban && Can_fall_thru(&u.uz))
632 ; /* KMH -- You can't escape the Sokoban level traps */
633 else if (Levitation || u.ustuck
634 || (!Can_fall_thru(&u.uz) && !levl[u.ux][u.uy].candig) || Flying
635 || is_clinger(youmonst.data)
636 || (Inhell && !u.uevent.invoked && newlevel == bottom)) {
638 dont_fall = "don't fall in.";
640 dont_fall = "
\82µ
\82©
\82µ
\82 \82È
\82½
\82Í
\97\8e\82¿
\82È
\82©
\82Á
\82½
\81D";
641 } else if (youmonst.data->msize >= MZ_HUGE) {
643 dont_fall = "don't fit through.";
645 dont_fall = "
\92Ê
\82è
\94²
\82¯
\82é
\82É
\82Í
\83T
\83C
\83Y
\82ª
\8d\87\82í
\82È
\82¢
\81D";
646 } else if (!next_to_u()) {
648 dont_fall = "are jerked back by your pet!";
650 dont_fall = "
\82 \82È
\82½
\82Í
\83y
\83b
\83g
\82É
\82æ
\82Á
\82Ä
\88ø
\82Á
\82Ï
\82è
\82à
\82Ç
\82³
\82ê
\82½
\81I";
653 #if 0 /*JP*//*
\81u
\82 \82È
\82½
\82Í
\81v
\82Å
\8en
\82Ü
\82ç
\82È
\82¢
\82à
\82Ì
\82à
\82 \82é*/
658 /* hero didn't fall through, but any objects here might */
659 impact_drop((struct obj *) 0, u.ux, u.uy, 0);
661 display_nhwindow(WIN_MESSAGE, FALSE);
663 pline_The("opening under you closes up.");
665 pline_The("
\91«
\89º
\82É
\8aJ
\82¢
\82Ä
\82¢
\82½
\82à
\82Ì
\82Í
\95Â
\82¶
\82½
\81D");
672 if (Is_stronghold(&u.uz)) {
675 int dist = newlevel - dunlev(&u.uz);
676 dtmp.dnum = u.uz.dnum;
677 dtmp.dlevel = newlevel;
680 You("fall down a %s%sshaft!", dist > 3 ? "very " : "",
681 dist > 2 ? "deep " : "");
683 You("%s%s
\8c\8a\82Ì
\92\86\82ð
\97\8e\82¿
\82Ä
\82¢
\82Á
\82½
\81I", dist > 3 ? "
\82Æ
\82Ä
\82à" : "",
684 dist > 2 ? "
\90[
\82¢" : "");
689 Sprintf(msgbuf, "The hole in the %s above you closes up.",
691 Sprintf(msgbuf, "%s
\82É
\8aJ
\82¢
\82½
\8c\8a\82Í
\95Â
\82¶
\82½
\81D",
692 ceiling(u.ux, u.uy));
694 schedule_goto(&dtmp, FALSE, TRUE, 0, (char *) 0,
695 !td ? msgbuf : (char *) 0);
699 * Animate the given statue. May have been via shatter attempt, trap,
700 * or stone to flesh spell. Return a monster if successfully animated.
701 * If the monster is animated, the object is deleted. If fail_reason
702 * is non-null, then fill in the reason for failure (or success).
704 * The cause of animation is:
706 * ANIMATE_NORMAL - hero "finds" the monster
707 * ANIMATE_SHATTER - hero tries to destroy the statue
708 * ANIMATE_SPELL - stone to flesh spell hits the statue
710 * Perhaps x, y is not needed if we can use get_obj_location() to find
711 * the statue's location... ???
713 * Sequencing matters:
714 * create monster; if it fails, give up with statue intact;
715 * give "statue comes to life" message;
716 * if statue belongs to shop, have shk give "you owe" message;
717 * transfer statue contents to monster (after stolen_value());
719 * [This ordering means that if the statue ends up wearing a cloak of
720 * invisibility or a mummy wrapping, the visibility checks might be
721 * wrong, but to avoid that we'd have to clone the statue contents
722 * first in order to give them to the monster before checking their
723 * shop status--it's not worth the hassle.]
726 animate_statue(statue, x, y, cause, fail_reason)
732 int mnum = statue->corpsenm;
733 struct permonst *mptr = &mons[mnum];
734 struct monst *mon = 0, *shkp;
737 boolean historic = (Role_if(PM_ARCHEOLOGIST)
738 && (statue->spe & STATUE_HISTORIC) != 0),
739 golem_xform = FALSE, use_saved_traits;
740 const char *comes_to_life;
741 char statuename[BUFSZ], tmpbuf[BUFSZ];
742 static const char historic_statue_is_gone[] =
744 "that the historic statue is now gone";
746 "
\97ð
\8ej
\93I
\82È
\92¤
\91\9c\82ª
\82È
\82
\82È
\82Á
\82Ä
\82µ
\82Ü
\82Á
\82½
\82±
\82Æ";
747 if (cant_revive(&mnum, TRUE, statue)) {
748 /* mnum has changed; we won't be animating this statue as itself */
749 if (mnum != PM_DOPPELGANGER)
751 use_saved_traits = FALSE;
752 } else if (is_golem(mptr) && cause == ANIMATE_SPELL) {
753 /* statue of any golem hit by stone-to-flesh becomes flesh golem */
754 golem_xform = (mptr != &mons[PM_FLESH_GOLEM]);
755 mnum = PM_FLESH_GOLEM;
756 mptr = &mons[PM_FLESH_GOLEM];
757 use_saved_traits = (has_omonst(statue) && !golem_xform);
759 use_saved_traits = has_omonst(statue);
762 if (use_saved_traits) {
763 /* restore a petrified monster */
765 mon = montraits(statue, &cc);
766 if (mon && mon->mtame && !mon->isminion)
769 /* statues of unique monsters from bones or wishing end
770 up here (cant_revive() sets mnum to be doppelganger;
771 mptr reflects the original form for use by newcham()) */
772 if ((mnum == PM_DOPPELGANGER && mptr != &mons[PM_DOPPELGANGER])
773 /* block quest guards from other roles */
774 || (mptr->msound == MS_GUARDIAN
775 && quest_info(MS_GUARDIAN) != mnum)) {
776 mon = makemon(&mons[PM_DOPPELGANGER], x, y,
777 NO_MINVENT | MM_NOCOUNTBIRTH | MM_ADJACENTOK);
778 /* if hero has protection from shape changers, cham field will
779 be NON_PM; otherwise, set form to match the statue */
780 if (mon && mon->cham >= LOW_PM)
781 (void) newcham(mon, mptr, FALSE, FALSE);
783 mon = makemon(mptr, x, y, (cause == ANIMATE_SPELL)
784 ? (NO_MINVENT | MM_ADJACENTOK)
790 *fail_reason = unique_corpstat(&mons[statue->corpsenm])
793 return (struct monst *) 0;
796 /* a non-montraits() statue might specify gender */
797 if (statue->spe & STATUE_MALE)
799 else if (statue->spe & STATUE_FEMALE)
801 /* if statue has been named, give same name to the monster */
802 if (has_oname(statue))
803 mon = christen_monst(mon, ONAME(statue));
804 /* mimic statue becomes seen mimic; other hiders won't be hidden */
808 mon->mundetected = FALSE;
810 if (cause == ANIMATE_NORMAL || cause == ANIMATE_SHATTER) {
811 /* trap always releases hostile monster */
812 mon->mtame = 0; /* (might be petrified pet tossed onto trap) */
818 comes_to_life = !canspotmon(mon)
822 : (nonliving(mon->data) || is_vampshifter(mon))
826 comes_to_life = !canspotmon(mon)
829 ? "
\93÷
\91Ì
\82É
\96ß
\82Á"
830 : (nonliving(mon->data) || is_vampshifter(mon))
832 : "
\90¶
\96½
\82ð
\91Ñ
\82Ñ";
834 if ((x == u.ux && y == u.uy) || cause == ANIMATE_SPELL) {
835 /* "the|your|Manlobbi's statue [of a wombat]" */
836 shkp = shop_keeper(*in_rooms(mon->mx, mon->my, SHOPBASE));
838 Sprintf(statuename, "%s%s", shk_your(tmpbuf, statue),
839 (cause == ANIMATE_SPELL
840 /* avoid "of a shopkeeper" if it's Manlobbi himself
841 (if carried, it can't be unpaid--hence won't be
842 described as "Manlobbi's statue"--because there
843 wasn't any living shk when statue was picked up) */
844 && (mon != shkp || carried(statue)))
848 Sprintf(statuename, "%s%s", shk_your(tmpbuf, statue),
849 (cause == ANIMATE_SPELL
850 && (mon != shkp || carried(statue)))
855 pline("%s %s!", upstart(statuename), comes_to_life);
857 pline("%s
\82Í%s
\82½
\81I", upstart(statuename), comes_to_life);
858 } else if (Hallucination) { /* They don't know it's a statue */
860 pline_The("%s suddenly seems more animated.", rndmonnam((char *) 0));
862 pline_The("%s
\82Í
\93Ë
\91R
\82æ
\82è
\8a\88\93®
\93I
\82É
\82È
\82Á
\82½
\81D", rndmonnam((char *) 0));
863 } else if (cause == ANIMATE_SHATTER) {
865 Sprintf(statuename, "%s%s", shk_your(tmpbuf, statue),
869 Strcpy(statuename, "a statue");
871 Strcpy(statuename, "
\92¤
\91\9c");
873 pline("Instead of shattering, %s suddenly %s!", statuename,
876 pline("%s
\82Í
\8dÓ
\82¯
\82¸
\82É%s
\82½
\81I", statuename,
879 } else { /* cause == ANIMATE_NORMAL */
881 You("find %s posing as a statue.",
883 You("%s
\82ª
\92¤
\91\9c\82Ì
\82Ó
\82è
\82ð
\82µ
\82Ä
\82¢
\82é
\82Ì
\82ð
\8c©
\82Â
\82¯
\82½
\81D",
884 canspotmon(mon) ? a_monnam(mon) : something);
885 if (!canspotmon(mon) && Blind)
890 /* if this isn't caused by a monster using a wand of striking,
891 there might be consequences for the hero */
892 if (!context.mon_moving) {
893 /* if statue is owned by a shop, hero will have to pay for it;
894 stolen_value gives a message (about debt or use of credit)
895 which refers to "it" so needs to follow a message describing
896 the object ("the statue comes to life" one above) */
897 if (cause != ANIMATE_NORMAL && costly_spot(x, y)
898 && (shkp = shop_keeper(*in_rooms(x, y, SHOPBASE))) != 0
899 /* avoid charging for Manlobbi's statue of Manlobbi
900 if stone-to-flesh is used on petrified shopkeep */
902 (void) stolen_value(statue, x, y, (boolean) shkp->mpeaceful,
907 You_feel("guilty %s.", historic_statue_is_gone);
909 You_feel("%s
\82É
\8dß
\82ð
\8a´
\82¶
\82½
\81D", historic_statue_is_gone);
913 if (historic && cansee(x, y))
915 You_feel("regret %s.", historic_statue_is_gone);
917 You_feel("%s
\82ð
\8cã
\89÷
\82µ
\82½
\81D", historic_statue_is_gone);
918 /* no alignment penalty */
921 /* transfer any statue contents to monster's inventory */
922 while ((item = statue->cobj) != 0) {
923 obj_extract_self(item);
924 (void) mpickobj(mon, item);
927 /* in case statue is wielded and hero zaps stone-to-flesh at self */
928 if (statue->owornmask)
929 remove_worn_item(statue, TRUE);
930 /* statue no longer exists */
933 /* avoid hiding under nothing */
934 if (x == u.ux && y == u.uy && Upolyd && hides_under(youmonst.data)
939 *fail_reason = AS_OK;
944 * You've either stepped onto a statue trap's location or you've triggered a
945 * statue trap by searching next to it or by trying to break it with a wand
949 activate_statue_trap(trap, x, y, shatter)
954 struct monst *mtmp = (struct monst *) 0;
955 struct obj *otmp = sobj_at(STATUE, x, y);
959 * Try to animate the first valid statue. Stop the loop when we
960 * actually create something or the failure cause is not because
961 * the mon was unique.
965 mtmp = animate_statue(otmp, x, y,
966 shatter ? ANIMATE_SHATTER : ANIMATE_NORMAL,
968 if (mtmp || fail_reason != AS_MON_IS_UNIQUE)
971 otmp = nxtobj(otmp, STATUE, TRUE);
979 keep_saddle_with_steedcorpse(steed_mid, objchn, saddle)
981 struct obj *objchn, *saddle;
986 if (objchn->otyp == CORPSE && has_omonst(objchn)) {
987 struct monst *mtmp = OMONST(objchn);
989 if (mtmp->m_id == steed_mid) {
992 if (get_obj_location(objchn, &x, &y, 0)) {
993 obj_extract_self(saddle);
994 place_object(saddle, x, y);
1000 if (Has_contents(objchn)
1001 && keep_saddle_with_steedcorpse(steed_mid, objchn->cobj, saddle))
1003 objchn = objchn->nobj;
1009 dotrap(trap, trflags)
1010 register struct trap *trap;
1013 register int ttype = trap->ttyp;
1014 register struct obj *otmp;
1015 boolean already_seen = trap->tseen,
1016 forcetrap = (trflags & FORCETRAP) != 0,
1017 webmsgok = (trflags & NOWEBMSG) == 0,
1018 forcebungle = (trflags & FORCEBUNGLE) != 0,
1019 plunged = (trflags & TOOKPLUNGE) != 0,
1020 adj_pit = conjoined_pits(trap, t_at(u.ux0, u.uy0), TRUE);
1022 int steed_article = ARTICLE_THE;
1026 /* KMH -- You can't escape the Sokoban level traps */
1027 if (Sokoban && (ttype == PIT || ttype == SPIKED_PIT
1028 || ttype == HOLE || ttype == TRAPDOOR)) {
1029 /* The "air currents" message is still appropriate -- even when
1030 * the hero isn't flying or levitating -- because it conveys the
1031 * reason why the player cannot escape the trap with a dexterity
1032 * check, clinging to the ceiling, etc.
1035 pline("Air currents pull you down into %s %s!",
1036 a_your[trap->madeby_u],
1037 defsyms[trap_to_defsym(ttype)].explanation);
1039 pline("
\8bó
\8bC
\82Ì
\97¬
\82ê
\82ª
\82 \82È
\82½
\82ð%s
\82É
\88ø
\82«
\96ß
\82µ
\82½
\81I",
1040 defsyms[trap_to_defsym(ttype)].explanation);
1042 /* then proceed to normal trap effect */
1043 } else if (already_seen && !forcetrap) {
1044 if ((Levitation || (Flying && !plunged))
1045 && (ttype == PIT || ttype == SPIKED_PIT || ttype == HOLE
1046 || ttype == BEAR_TRAP)) {
1048 You("%s over %s %s.", Levitation ? "float" : "fly",
1049 a_your[trap->madeby_u],
1050 defsyms[trap_to_defsym(ttype)].explanation);
1052 You("%s%s
\82Ì
\8fã%s
\81D",
1053 set_you[trap->madeby_u],
1054 defsyms[trap_to_defsym(ttype)].explanation,
1055 Levitation ? "
\82ð
\8c©
\89º
\82ë
\82µ
\82½" : "
\82ð
\94ò
\82ñ
\82Å
\82¢
\82é");
1059 if (!Fumbling && ttype != MAGIC_PORTAL && ttype != VIBRATING_SQUARE
1060 && ttype != ANTI_MAGIC && !forcebungle && !plunged && !adj_pit
1061 && (!rn2(5) || ((ttype == PIT || ttype == SPIKED_PIT)
1062 && is_clinger(youmonst.data)))) {
1064 You("escape %s %s.", (ttype == ARROW_TRAP && !trap->madeby_u)
1066 : a_your[trap->madeby_u],
1067 defsyms[trap_to_defsym(ttype)].explanation);
1069 You("%s%s
\82ð
\82·
\82é
\82è
\82Æ
\94ð
\82¯
\82½
\81D",
1070 set_you[trap->madeby_u],
1071 defsyms[trap_to_defsym(ttype)].explanation);
1078 u.usteed->mtrapseen |= (1 << (ttype - 1));
1079 /* suppress article in various steed messages when using its
1080 name (which won't occur when hallucinating) */
1081 if (has_mname(u.usteed) && !Hallucination)
1082 steed_article = ARTICLE_NONE;
1087 if (trap->once && trap->tseen && !rn2(15)) {
1089 You_hear("a loud click!");
1091 You_hear("
\83K
\83`
\83\83\83b
\82Æ
\82¢
\82¤
\91å
\82«
\82È
\89¹
\82ð
\95·
\82¢
\82½
\81I");
1099 pline("An arrow shoots out at you!");
1101 pline("
\96î
\82ª
\94ò
\82ñ
\82Å
\82«
\82½
\81I");
1102 otmp = mksobj(ARROW, TRUE, FALSE);
1104 otmp->owt = weight(otmp);
1105 otmp->opoisoned = 0;
1106 if (u.usteed && !rn2(2) && steedintrap(trap, otmp)) { /* nothing */
1109 } else if (thitu(8, dmgval(otmp, &youmonst), otmp, "arrow")) {
1111 } else if (thitu(8, dmgval(otmp, &youmonst), otmp, "
\96î")) {
1112 obfree(otmp, (struct obj *) 0);
1114 place_object(otmp, u.ux, u.uy);
1123 if (trap->once && trap->tseen && !rn2(15)) {
1125 You_hear("a soft click.");
1127 You_hear("
\83J
\83`
\83b
\82Æ
\82¢
\82¤
\89¹
\82ð
\95·
\82¢
\82½
\81D");
1135 pline("A little dart shoots out at you!");
1137 pline("
\8f¬
\82³
\82È
\93\8a\82°
\96î
\82ª
\94ò
\82ñ
\82Å
\82«
\82½
\81I");
1138 otmp = mksobj(DART, TRUE, FALSE);
1140 otmp->owt = weight(otmp);
1142 otmp->opoisoned = 1;
1143 oldumort = u.umortality;
1144 if (u.usteed && !rn2(2) && steedintrap(trap, otmp)) { /* nothing */
1147 } else if (thitu(7, dmgval(otmp, &youmonst), otmp, "little dart")) {
1149 } else if (thitu(7, dmgval(otmp, &youmonst), otmp, "
\93\8a\82°
\96î")) {
1150 if (otmp->opoisoned)
1152 poisoned("dart", A_CON, "little dart",
1153 /* if damage triggered life-saving,
1154 poison is limited to attrib loss */
1155 (u.umortality > oldumort) ? 0 : 10, TRUE);
1157 poisoned("
\93\8a\82°
\96î", A_CON, "
\8f¬
\82³
\82È
\93\8a\82°
\96î",
1158 /* if damage triggered life-saving,
1159 poison is limited to attrib loss */
1160 (u.umortality > oldumort) ? 0 : 10, TRUE);
1162 obfree(otmp, (struct obj *) 0);
1164 place_object(otmp, u.ux, u.uy);
1173 if (trap->once && trap->tseen && !rn2(15)) {
1175 pline("A trap door in %s opens, but nothing falls out!",
1177 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",
1178 the(ceiling(u.ux, u.uy)));
1182 int dmg = d(2, 6); /* should be std ROCK dmg? */
1186 otmp = mksobj_at(ROCK, u.ux, u.uy, TRUE, FALSE);
1188 otmp->owt = weight(otmp);
1191 pline("A trap door in %s opens and %s falls on your %s!",
1192 the(ceiling(u.ux, u.uy)), an(xname(otmp)), body_part(HEAD));
1194 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",
1195 ceiling(u.ux,u.uy), xname(otmp), body_part(HEAD));
1199 if (is_metallic(uarmh)) {
1201 pline("Fortunately, you are wearing a hard helmet.");
1203 pline("
\8dK
\89^
\82É
\82à
\81C
\82 \82È
\82½
\82Í
\8cÅ
\82¢
\8a\95\82ð
\90g
\82É
\82Â
\82¯
\82Ä
\82¢
\82½
\81D");
1205 } else if (flags.verbose) {
1207 pline("%s does not protect you.", Yname2(uarmh));
1209 pline("%s
\82Å
\82Í
\96h
\82°
\82È
\82¢
\81D", xname(uarmh));
1216 newsym(u.ux, u.uy); /* map the rock */
1219 losehp(Maybe_Half_Phys(dmg), "falling rock", KILLED_BY_AN);
1221 losehp(Maybe_Half_Phys(dmg), "
\97\8e\8aâ
\82Å", KILLED_BY_AN);
1222 exercise(A_STR, FALSE);
1226 case SQKY_BOARD: /* stepped on a squeaky board */
1227 if ((Levitation || Flying) && !forcetrap) {
1232 You("notice a crease in the linoleum.");
1234 You("
\8f°
\82Ì
\8ed
\8fã
\8dÞ
\82Ì
\82µ
\82í
\82É
\8bC
\82ª
\82Â
\82¢
\82½
\81D");
1237 You("notice a loose board below you.");
1239 You("
\91«
\8c³
\82Ì
\8aÉ
\82ñ
\82¾
\94Â
\82É
\8bC
\82ª
\82Â
\82¢
\82½
\81D");
1244 pline("A board beneath you %s%s%s.",
1245 Deaf ? "vibrates" : "squeaks ",
1246 Deaf ? "" : trapnote(trap, 0), Deaf ? "" : " loudly");
1249 pline("
\91«
\8c³
\82Ì
\94Â
\82ª
\82ä
\82ê
\82½
\81D");
1251 pline("
\91«
\8c³
\82Ì
\94Â
\82ª
\91å
\82«
\82%s
\82Ì
\89¹
\82É
\82«
\82µ
\82ñ
\82¾
\81D", trapnote(trap, 0));
1261 if ((Levitation || Flying) && !forcetrap)
1264 if (amorphous(youmonst.data) || is_whirly(youmonst.data)
1265 || unsolid(youmonst.data)) {
1267 pline("%s bear trap closes harmlessly through you.",
1268 A_Your[trap->madeby_u]);
1270 pline("%s
\8cF
\82Ìã©
\82Í
\8a\9a\82Ý
\82Â
\82¢
\82½
\82ª
\81C
\82·
\82é
\82Á
\82Æ
\92Ê
\82è
\94²
\82¯
\82½
\81D",
1271 set_you[trap->madeby_u]);
1275 if (!u.usteed && youmonst.data->msize <= MZ_SMALL) {
1277 pline("%s bear trap closes harmlessly over you.",
1278 A_Your[trap->madeby_u]);
1280 pline("%s
\8cF
\82Ìã©
\82Í
\8a\9a\82Ý
\82Â
\82¢
\82½
\82ª
\81C
\97y
\82©
\8fã
\95û
\82¾
\82Á
\82½
\81D",
1281 set_you[trap->madeby_u]);
1285 u.utrap = rn1(4, 4);
1286 u.utraptype = TT_BEARTRAP;
1289 pline("%s bear trap closes on %s %s!", A_Your[trap->madeby_u],
1290 s_suffix(mon_nam(u.usteed)), mbodypart(u.usteed, FOOT));
1292 pline("%s
\8cF
\82Ìã©
\82Í%s
\82Ì%s
\82É
\8a\9a\82Ý
\82Â
\82¢
\82½
\81I", set_you[trap->madeby_u],
1293 mon_nam(u.usteed), mbodypart(u.usteed, FOOT));
1295 if (thitm(0, u.usteed, (struct obj *) 0, dmg, FALSE))
1296 u.utrap = 0; /* steed died, hero not trapped */
1299 pline("%s bear trap closes on your %s!", A_Your[trap->madeby_u],
1302 pline("%s
\8cF
\82Ìã©
\82ª
\82 \82È
\82½
\82Ì%s
\82É
\8a\9a\82Ý
\82Â
\82¢
\82½
\81I", set_you[trap->madeby_u],
1305 set_wounded_legs(rn2(2) ? RIGHT_SIDE : LEFT_SIDE, rn1(10, 10));
1306 if (u.umonnum == PM_OWLBEAR || u.umonnum == PM_BUGBEAR)
1308 You("howl in anger!");
1310 You("
\93{
\82è
\82Ì
\99ô
\9aK
\82ð
\82 \82°
\82½
\81I");
1312 losehp(Maybe_Half_Phys(dmg), "bear trap", KILLED_BY_AN);
1314 losehp(Maybe_Half_Phys(dmg), "
\8cF
\82Ìã©
\82Å", KILLED_BY_AN);
1316 exercise(A_DEX, FALSE);
1322 if (Sleep_resistance || breathless(youmonst.data)) {
1324 You("are enveloped in a cloud of gas!");
1326 You("
\83K
\83X
\89_
\82É
\82Â
\82Â
\82Ü
\82ê
\82½
\81I");
1329 pline("A cloud of gas puts you to sleep!");
1331 pline("
\82 \82È
\82½
\82Í
\83K
\83X
\89_
\82Å
\96°
\82Á
\82Ä
\82µ
\82Ü
\82Á
\82½
\81I");
1332 fall_asleep(-rnd(25), TRUE);
1334 (void) steedintrap(trap, (struct obj *) 0);
1340 /* Unlike monsters, traps cannot aim their rust attacks at
1341 * you, so instead of looping through and taking either the
1342 * first rustable one or the body, we take whatever we get,
1343 * even if it is not rustable.
1348 pline("%s you on the %s!", A_gush_of_water_hits, body_part(HEAD));
1350 pline("
\90\85\82ª
\95¬
\8fo
\82µ
\82Ä
\82 \82È
\82½
\82Ì%s
\82É
\96½
\92\86\82µ
\82½
\81I", body_part(HEAD));
1351 (void) water_damage(uarmh, helm_simple_name(uarmh), TRUE);
1355 pline("%s your left %s!", A_gush_of_water_hits, body_part(ARM));
1357 pline("
\90\85\82ª
\95¬
\8fo
\82µ
\82Ä
\82 \82È
\82½
\82Ì
\8d¶%s
\82É
\96½
\92\86\82µ
\82½
\81I", body_part(ARM));
1359 if (water_damage(uarms, "shield", TRUE) != ER_NOTHING)
1361 if (water_damage(uarms, "
\8f\82", TRUE) != ER_NOTHING)
1363 if (u.twoweap || (uwep && bimanual(uwep)))
1364 (void) water_damage(u.twoweap ? uswapwep : uwep, 0, TRUE);
1367 (void) water_damage(uarmg, "gauntlets", TRUE);
1369 (void) water_damage(uarmg, "
\8f¬
\8eè", TRUE);
1370 /* Not "metal gauntlets" since it gets called
1371 * even if it's leather for the message
1376 pline("%s your right %s!", A_gush_of_water_hits, body_part(ARM));
1378 pline("
\90\85\82ª
\95¬
\8fo
\82µ
\82Ä
\82 \82È
\82½
\82Ì
\89E%s
\82É
\96½
\92\86\82µ
\82½
\81I", body_part(ARM));
1379 (void) water_damage(uwep, 0, TRUE);
1383 pline("%s you!", A_gush_of_water_hits);
1385 pline("
\90\85\82ª
\95¬
\8fo
\82µ
\82Ä
\82 \82È
\82½
\82É
\96½
\92\86\82µ
\82½
\81I");
1386 for (otmp = invent; otmp; otmp = otmp->nobj)
1387 if (otmp->lamplit && otmp != uwep
1388 && (otmp != uswapwep || !u.twoweap))
1389 (void) snuff_lit(otmp);
1391 (void) water_damage(uarmc, cloak_simple_name(uarmc), TRUE);
1394 (void) water_damage(uarm, "armor", TRUE);
1396 (void) water_damage(uarm, "
\8aZ", TRUE);
1399 (void) water_damage(uarmu, "shirt", TRUE);
1401 (void) water_damage(uarmu, "
\83V
\83\83\83c", TRUE);
1405 if (u.umonnum == PM_IRON_GOLEM) {
1409 pline("%s you!", A_gush_of_water_hits);
1411 pline("
\90\85\82ª
\95¬
\8fo
\82µ
\82Ä
\82 \82È
\82½
\82É
\96½
\92\86\82µ
\82½
\81I");
1413 You("are covered with rust!");
1415 You("
\8eK
\82É
\95¢
\82í
\82ê
\82½
\81I");
1417 losehp(Maybe_Half_Phys(dam), "rusting away", KILLED_BY);
1419 losehp(Maybe_Half_Phys(dam), "
\8a®
\91S
\82É
\8eK
\82Ñ
\82Ä", KILLED_BY);
1420 } else if (u.umonnum == PM_GREMLIN && rn2(3)) {
1422 pline("%s you!", A_gush_of_water_hits);
1424 pline("
\90\85\82ª
\95¬
\8fo
\82µ
\82Ä
\82 \82È
\82½
\82É
\96½
\92\86\82µ
\82½
\81I");
1425 (void) split_mon(&youmonst, (struct monst *) 0);
1432 dofiretrap((struct obj *) 0);
1437 /* KMH -- You can't escape the Sokoban level traps */
1438 if (!Sokoban && (Levitation || (Flying && !plunged)))
1441 if (!Sokoban && is_clinger(youmonst.data) && !plunged) {
1444 You_see("%s %spit below you.", a_your[trap->madeby_u],
1445 ttype == SPIKED_PIT ? "spiked " : "");
1447 pline("
\91«
\8c³
\82É%s%s
\97\8e\82µ
\8c\8a\82ð
\94
\8c©
\82µ
\82½
\81D", dig_you[trap->madeby_u],
1448 ttype == SPIKED_PIT ? "
\83g
\83Q
\82¾
\82ç
\82¯
\82Ì" : "");
1452 pline("%s pit %sopens up under you!", A_Your[trap->madeby_u],
1453 ttype == SPIKED_PIT ? "full of spikes " : "");
1455 pline("%s%s
\97\8e\82µ
\8c\8a\82ª
\91«
\8c³
\82É
\8aJ
\82¢
\82½
\81I", dig_you[trap->madeby_u],
1456 ttype == SPIKED_PIT ? "
\83g
\83Q
\82¾
\82ç
\82¯
\82Ì" : "");
1459 You("don't fall in!");
1461 pline("
\82µ
\82©
\82µ
\81C
\82 \82È
\82½
\82Í
\97\8e\82¿
\82È
\82©
\82Á
\82½
\81I");
1466 char verbbuf[BUFSZ];
1469 if ((trflags & RECURSIVETRAP) != 0)
1471 Sprintf(verbbuf, "and %s fall",
1473 Sprintf(verbbuf, "
\82Æ%s",
1474 x_monnam(u.usteed, steed_article, (char *) 0,
1475 SUPPRESS_SADDLE, FALSE));
1478 Sprintf(verbbuf, "lead %s",
1479 x_monnam(u.usteed, steed_article, "poor",
1480 SUPPRESS_SADDLE, FALSE));
1482 Sprintf(verbbuf,"
\82Æ%s",
1483 x_monnam(u.usteed, steed_article, "
\82©
\82í
\82¢
\82»
\82¤
\82È",
1484 SUPPRESS_SADDLE, FALSE));
1486 } else if (adj_pit) {
1488 You("move into an adjacent pit.");
1490 You("
\97×
\82Ì
\97\8e\82µ
\8c\8a\82É
\88Ú
\93®
\82µ
\82½
\81D");
1494 !plunged ? "fall" : (Flying ? "dive" : "plunge"));
1497 !plunged ? "
\97\8e\82¿
\82½" : (Flying ? "
\94ò
\82Ñ
\8d\9e\82ñ
\82¾" : "
\93Ë
\93ü
\82µ
\82½"));
1500 You("%s into %s pit!", verbbuf, a_your[trap->madeby_u]);
1502 You("%s
\97\8e\82µ
\8c\8a\82É%s!", set_you[trap->madeby_u], verbbuf);
1505 /* wumpus reference */
1506 if (Role_if(PM_RANGER) && !trap->madeby_u && !trap->once
1507 && In_quest(&u.uz) && Is_qlocate(&u.uz)) {
1509 pline("Fortunately it has a bottom after all...");
1511 pline("
\8dK
\82¢
\81C
\8c\8b\8bÇ
\82Í
\92ê
\82ª
\82 \82Á
\82½
\81D
\81D
\81D");
1513 } else if (u.umonnum == PM_PIT_VIPER || u.umonnum == PM_PIT_FIEND) {
1515 pline("How pitiful. Isn't that the pits?");
1517 pline("
\82±
\82Ì
\97\8e\82µ
\8c\8a\82Í
\82¢
\82¢
\8ed
\8e\96\82ð
\82µ
\82Ä
\82¢
\82é
\81D");
1519 if (ttype == SPIKED_PIT) {
1521 const char *predicament = "on a set of sharp iron spikes";
1523 const char *predicament = "
\89s
\82¢
\93S
\82Ì
\83g
\83Q
\83g
\83Q
\82Ì
\8fã
\82É";
1528 upstart(x_monnam(u.usteed, steed_article, "poor",
1529 SUPPRESS_SADDLE, FALSE)),
1530 adj_pit ? "steps" : "lands", predicament);
1532 pline("%s
\82Í%s%s
\81I",
1533 upstart(x_monnam(u.usteed, steed_article, "
\82©
\82í
\82¢
\82»
\82¤
\82È",
1534 SUPPRESS_SADDLE, FALSE)),
1535 predicament, adj_pit ? "
\97\8e\82¿
\82½" : "
\8d~
\82è
\82½");
1539 You("%s %s!", adj_pit ? "step" : "land", predicament);
1541 You("%s%s
\81I", predicament, adj_pit ? "
\97\8e\82¿
\82½" : "
\8d~
\82è
\82½");
1544 u.utrap = rn1(6, 2);
1545 u.utraptype = TT_PIT;
1546 if (!steedintrap(trap, (struct obj *) 0)) {
1547 if (ttype == SPIKED_PIT) {
1548 oldumort = u.umortality;
1550 losehp(Maybe_Half_Phys(rnd(adj_pit ? 6 : 10)),
1552 ? "deliberately plunged into a pit of iron spikes"
1553 : adj_pit ? "stepped into a pit of iron spikes"
1554 : "fell into a pit of iron spikes",
1557 losehp(Maybe_Half_Phys(rnd(adj_pit ? 6 : 10)),
1559 ? "
\82í
\82´
\82í
\82´
\83g
\83Q
\82¾
\82ç
\82¯
\82Ì
\97\8e\82µ
\8c\8a\82É
\93Ë
\93ü
\82µ
\82Ä"
1560 : adj_pit ? "
\83g
\83Q
\82¾
\82ç
\82¯
\82Ì
\97\8e\82µ
\8c\8a\82É
\93¥
\82Ý
\8d\9e\82ñ
\82Å"
1561 : "
\83g
\83Q
\82¾
\82ç
\82¯
\82Ì
\97\8e\82µ
\8c\8a\82É
\97\8e\82¿
\82Ä",
1566 poisoned("spikes", A_STR,
1567 adj_pit ? "stepping on poison spikes"
1568 : "fall onto poison spikes",
1569 /* if damage triggered life-saving,
1570 poison is limited to attrib loss */
1571 (u.umortality > oldumort) ? 0 : 8, FALSE);
1573 poisoned("
\83g
\83Q", A_STR,
1574 adj_pit ? "
\93Å
\82Ì
\93h
\82ç
\82ê
\82½
\83g
\83Q
\82ð
\93¥
\82ñ
\82Å"
1575 : "
\93Å
\82Ì
\93h
\82ç
\82ê
\82½
\83g
\83Q
\82Ì
\8fã
\82É
\97\8e\82¿
\82Ä",
1576 /* if damage triggered life-saving,
1577 poison is limited to attrib loss */
1578 (u.umortality > oldumort) ? 0 : 8, FALSE);
1581 /* plunging flyers take spike damage but not pit damage */
1583 && !(plunged && (Flying || is_clinger(youmonst.data))))
1585 losehp(Maybe_Half_Phys(rnd(6)),
1586 plunged ? "deliberately plunged into a pit"
1587 : "fell into a pit",
1590 losehp(Maybe_Half_Phys(rnd(6)),
1591 plunged ? "
\82í
\82´
\82í
\82´
\97\8e\82µ
\8c\8a\82É
\93Ë
\93ü
\82µ
\82Ä"
1592 : "
\97\8e\82µ
\8c\8a\82É
\97\8e\82¿
\82Ä",
1596 if (Punished && !carried(uball)) {
1603 selftouch("Falling, you");
1605 selftouch("
\97\8e\89º
\92\86\81C
\82 \82È
\82½
\82Í");
1606 vision_full_recalc = 1; /* vision limits change */
1607 exercise(A_STR, FALSE);
1608 exercise(A_DEX, FALSE);
1614 if (!Can_fall_thru(&u.uz)) {
1615 seetrap(trap); /* normally done in fall_through */
1616 impossible("dotrap: %ss cannot exist on this level.",
1617 defsyms[trap_to_defsym(ttype)].explanation);
1618 break; /* don't activate it after all */
1630 level_tele_trap(trap);
1633 case WEB: /* Our luckless player has stumbled into a web. */
1635 if (amorphous(youmonst.data) || is_whirly(youmonst.data)
1636 || unsolid(youmonst.data)) {
1637 if (acidic(youmonst.data) || u.umonnum == PM_GELATINOUS_CUBE
1638 || u.umonnum == PM_FIRE_ELEMENTAL) {
1641 You("%s %s spider web!",
1642 (u.umonnum == PM_FIRE_ELEMENTAL) ? "burn"
1644 a_your[trap->madeby_u]);
1646 You("%s
\82
\82à
\82Ì
\91\83\82ð%s
\81I",
1647 web_you[trap->madeby_u],
1648 (u.umonnum == PM_FIRE_ELEMENTAL) ? "
\8fÄ
\82¢
\82½"
1649 : "
\82±
\82È
\82²
\82È
\82É
\82µ
\82½");
1657 You("flow through %s spider web.", a_your[trap->madeby_u]);
1659 You("%s
\82
\82à
\82Ì
\91\83\82ð
\82·
\82é
\82è
\82Æ
\92Ê
\82è
\94²
\82¯
\82½
\81D", web_you[trap->madeby_u]);
1662 if (webmaker(youmonst.data)) {
1665 pline(trap->madeby_u ? "You take a walk on your web."
1666 : "There is a spider web here.");
1668 pline(trap->madeby_u ? "
\8e©
\95ª
\82Å
\92£
\82Á
\82½
\82
\82à
\82Ì
\91\83\82Ì
\8fã
\82ð
\95à
\82¢
\82½
\81D"
1669 : "
\82±
\82±
\82É
\82Í
\82
\82à
\82Ì
\91\83\82ª
\82 \82é
\81D");
1674 char verbbuf[BUFSZ];
1678 Strcpy(verbbuf, "are caught by");
1679 } else if (u.usteed) {
1680 Sprintf(verbbuf, "lead %s into",
1681 x_monnam(u.usteed, steed_article, "poor",
1682 SUPPRESS_SADDLE, FALSE));
1684 Sprintf(verbbuf, "%s into",
1685 Levitation ? (const char *) "float"
1686 : locomotion(youmonst.data, "stumble"));
1688 You("%s %s spider web!", verbbuf, a_your[trap->madeby_u]);
1691 Strcpy(verbbuf, "
\82 \82È
\82½
\82Í");
1692 } else if (u.usteed) {
1693 Sprintf(verbbuf, "
\82 \82È
\82½
\82Æ%s",
1694 x_monnam(u.usteed, steed_article, "
\82©
\82í
\82¢
\82»
\82¤
\82È",
1695 SUPPRESS_SADDLE, FALSE));
1697 Sprintf(verbbuf, "
\82 \82È
\82½
\82Í%s",
1698 Levitation ? (const char *) "
\95\82\82«
\82È
\82ª
\82ç"
1699 : jconj(locomotion(youmonst.data, "
\82Â
\82Ü
\82¸
\82"), "
\82Ä"));
1701 pline("%s%s
\82
\82à
\82Ì
\91\83\82É
\82Ð
\82Á
\82©
\82©
\82Á
\82½
\81I", verbbuf, web_you[trap->madeby_u]);
1704 u.utraptype = TT_WEB;
1706 /* Time stuck in the web depends on your/steed strength. */
1708 register int str = ACURR(A_STR);
1710 /* If mounted, the steed gets trapped. Use mintrap
1711 * to do all the work. If mtrapped is set as a result,
1712 * unset it and set utrap instead. In the case of a
1713 * strongmonst and mintrap said it's trapped, use a
1714 * short but non-zero trap time. Otherwise, monsters
1715 * have no specific strength, so use player strength.
1716 * This gets skipped for webmsgok, which implies that
1717 * the steed isn't a factor.
1719 if (u.usteed && webmsgok) {
1720 /* mtmp location might not be up to date */
1721 u.usteed->mx = u.ux;
1722 u.usteed->my = u.uy;
1724 /* mintrap currently does not return 2(died) for webs */
1725 if (mintrap(u.usteed)) {
1726 u.usteed->mtrapped = 0;
1727 if (strongmonst(u.usteed->data))
1733 webmsgok = FALSE; /* mintrap printed the messages */
1736 u.utrap = rn1(6, 6);
1738 u.utrap = rn1(6, 4);
1740 u.utrap = rn1(4, 4);
1742 u.utrap = rn1(4, 2);
1744 u.utrap = rn1(2, 2);
1753 You("tear through %s web!", a_your[trap->madeby_u]);
1755 You("%s
\82
\82à
\82Ì
\91\83\82ð
\90Ø
\82è
\97ô
\82¢
\82½
\81I", web_you[trap->madeby_u]);
1757 newsym(u.ux, u.uy); /* get rid of trap symbol */
1763 (void) activate_statue_trap(trap, u.ux, u.uy, FALSE);
1766 case MAGIC_TRAP: /* A magic trap. */
1770 newsym(u.ux, u.uy); /* update position */
1772 You("are caught in a magical explosion!");
1774 You("
\96\82\96@
\82Ì
\94\9a\94
\82ð
\97\81\82Ñ
\82½
\81I");
1776 losehp(rnd(10), "magical explosion", KILLED_BY_AN);
1778 losehp(rnd(10), "
\96\82\96@
\82Ì
\94\9a\94
\82ð
\97\81\82Ñ
\82Ä", KILLED_BY_AN);
1780 Your("body absorbs some of the magical energy!");
1782 Your("
\91Ì
\82Í
\96\82\96@
\82Ì
\83G
\83l
\83\8b\83M
\81[
\82ð
\8f
\82µ
\8bz
\82¢
\82Æ
\82Á
\82½
\81I");
1783 u.uen = (u.uenmax += 2);
1788 (void) steedintrap(trap, (struct obj *) 0);
1793 /* hero without magic resistance loses spell energy,
1794 hero with magic resistance takes damage instead;
1795 possibly non-intuitive but useful for play balance */
1797 drain_en(rnd(u.ulevel) + 1);
1799 int dmgval2 = rnd(4), hp = Upolyd ? u.mh : u.uhp;
1801 /* Half_XXX_damage has opposite its usual effect (approx)
1802 but isn't cumulative if hero has more than one */
1803 if (Half_physical_damage || Half_spell_damage)
1805 /* give Magicbane wielder dose of own medicine */
1806 if (uwep && uwep->oartifact == ART_MAGICBANE)
1808 /* having an artifact--other than own quest one--which
1809 confers magic resistance simply by being carried
1810 also increases the effect */
1811 for (otmp = invent; otmp; otmp = otmp->nobj)
1812 if (otmp->oartifact && !is_quest_artifact(otmp)
1813 && defends_when_carried(AD_MAGM, otmp))
1818 dmgval2 = (dmgval2 + 3) / 4;
1821 You_feel((dmgval2 >= hp) ? "unbearably torpid!"
1822 : (dmgval2 >= hp / 4) ? "very lethargic."
1825 You_feel((dmgval2 >= hp) ? "
\91Ï
\82¦
\82ç
\82ê
\82È
\82¢
\82Ù
\82Ç
\96³
\8bC
\97Í
\82É
\82È
\82Á
\82½
\81I"
1826 : (dmgval2 >= hp / 4) ? "
\82Æ
\82Ä
\82à
\8bC
\82¾
\82é
\82
\82È
\82Á
\82½
\81D"
1827 : "
\82à
\82Ì
\82®
\82³
\82È
\8bC
\95ª
\82É
\82È
\82Á
\82½
\81D");
1829 /* opposite of magical explosion */
1831 losehp(dmgval2, "anti-magic implosion", KILLED_BY_AN);
1833 losehp(dmgval2, "
\94½
\96\82\96@
\82Ì
\93à
\95\94\94j
\97ô
\82Å", KILLED_BY_AN);
1838 char verbbuf[BUFSZ];
1843 Sprintf(verbbuf, "lead %s",
1845 Sprintf(verbbuf, "%s
\82Æ
\82Æ
\82à
\82É
\94ò
\82Ñ
\8d\9e\82ñ
\82¾",
1846 x_monnam(u.usteed, steed_article, (char *) 0,
1847 SUPPRESS_SADDLE, FALSE));
1850 Sprintf(verbbuf, "%s", Levitation
1851 ? (const char *) "float"
1852 : locomotion(youmonst.data, "step"));
1854 Sprintf(verbbuf,"%s",
1855 jpast(Levitation ? (const char *)"
\95\82\82«
\82È
\82ª
\82ç
\94ò
\82Ñ
\82±
\82Þ"
1856 : locomotion(youmonst.data, "
\93¥
\82Ý
\8d\9e\82Þ")));
1859 You("%s onto a polymorph trap!", verbbuf);
1861 You("
\95Ï
\89»
\82Ìã©
\82É%s
\81I", verbbuf);
1862 if (Antimagic || Unchanging) {
1863 shieldeff(u.ux, u.uy);
1865 You_feel("momentarily different.");
1867 You("
\88ê
\8fu
\88á
\82Á
\82½
\8a´
\82¶
\82ª
\82µ
\82½
\81D");
1868 /* Trap did nothing; don't remove it --KAA */
1870 (void) steedintrap(trap, (struct obj *) 0);
1871 deltrap(trap); /* delete trap before polymorph */
1872 newsym(u.ux, u.uy); /* get rid of trap symbol */
1874 You_feel("a change coming over you.");
1876 You("
\95Ï
\89»
\82ª
\96K
\82ê
\82½
\82æ
\82¤
\82È
\8bC
\82ª
\82µ
\82½
\81D");
1882 unsigned steed_mid = 0;
1883 struct obj *saddle = 0;
1885 if ((Levitation || Flying) && !forcetrap) {
1886 if (!already_seen && rn2(3))
1890 pline("%s %s in a pile of soil below you.",
1891 already_seen ? "There is" : "You discover",
1892 trap->madeby_u ? "the trigger of your mine" : "a trigger");
1895 pline("
\82±
\82±
\82É
\82Í%s
\92n
\97\8b\82Ì
\8bN
\94\9a\83X
\83C
\83b
\83`
\82ª
\82 \82é
\81D",
1896 set_you[trap->madeby_u]);
1898 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",
1899 set_you[trap->madeby_u]);
1901 if (already_seen && rn2(3))
1904 pline("KAABLAMM!!! %s %s%s off!",
1905 forcebungle ? "Your inept attempt sets"
1906 : "The air currents set",
1907 already_seen ? a_your[trap->madeby_u] : "",
1908 already_seen ? " land mine" : "it");
1910 pline("
\82¿
\82ã
\82Ç
\81[
\82ñ
\81I
\81I%s%s%s
\8bN
\94\9a\83X
\83C
\83b
\83`
\82ª
\94
\93®
\82µ
\82½
\81I",
1911 forcebungle ? "
\95s
\8aí
\97p
\82È
\82¹
\82¢
\82Å"
1912 : "
\8bó
\8bC
\82Ì
\97¬
\82ê
\82Å",
1913 already_seen ? set_you[trap->madeby_u] : "",
1914 already_seen ? "
\92n
\97\8b\82Ì" : "");
1917 /* prevent landmine from killing steed, throwing you to
1918 * the ground, and you being affected again by the same
1919 * mine because it hasn't been deleted yet
1921 static boolean recursive_mine = FALSE;
1927 pline("KAABLAMM!!! You triggered %s land mine!",
1928 a_your[trap->madeby_u]);
1930 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",
1931 set_you[trap->madeby_u]);
1934 steed_mid = u.usteed->m_id;
1935 recursive_mine = TRUE;
1936 (void) steedintrap(trap, (struct obj *) 0);
1937 recursive_mine = FALSE;
1938 saddle = sobj_at(SADDLE, u.ux, u.uy);
1939 set_wounded_legs(LEFT_SIDE, rn1(35, 41));
1940 set_wounded_legs(RIGHT_SIDE, rn1(35, 41));
1941 exercise(A_DEX, FALSE);
1943 blow_up_landmine(trap);
1944 if (steed_mid && saddle && !u.usteed)
1945 (void) keep_saddle_with_steedcorpse(steed_mid, fobj, saddle);
1946 newsym(u.ux, u.uy); /* update trap symbol */
1948 losehp(Maybe_Half_Phys(rnd(16)), "land mine", KILLED_BY_AN);
1950 losehp(Maybe_Half_Phys(rnd(16)), "
\92n
\97\8b\82ð
\93¥
\82ñ
\82Å", KILLED_BY_AN);
1951 /* fall recursively into the pit... */
1952 if ((trap = t_at(u.ux, u.uy)) != 0)
1953 dotrap(trap, RECURSIVETRAP);
1954 fill_pit(u.ux, u.uy);
1958 case ROLLING_BOULDER_TRAP: {
1959 int style = ROLL | (trap->tseen ? LAUNCH_KNOWN : 0);
1963 pline("Click! You trigger a rolling boulder trap!");
1965 pline("
\83J
\83`
\83b
\81I
\82 \82È
\82½
\82Í
\8b\90\8aâ
\82Ìã©
\82Ì
\83X
\83C
\83b
\83`
\82ð
\93¥
\82ñ
\82¾
\81I");
1966 if (!launch_obj(BOULDER, trap->launch.x, trap->launch.y,
1967 trap->launch2.x, trap->launch2.y, style)) {
1969 newsym(u.ux, u.uy); /* get rid of trap symbol */
1971 pline("Fortunately for you, no boulder was released.");
1973 pline("
\89^
\82Ì
\82æ
\82¢
\82±
\82Æ
\82É
\8aâ
\82Í
\93]
\82ª
\82Á
\82Ä
\82±
\82È
\82©
\82Á
\82½
\81D");
1980 domagicportal(trap);
1983 case VIBRATING_SQUARE:
1985 /* messages handled elsewhere; the trap symbol is merely to mark the
1986 * square for future reference */
1991 impossible("You hit a trap of type %u", trap->ttyp);
1996 trapnote(trap, noprefix)
2000 static char tnbuf[12];
2003 *tnnames[12] = { "C note", "D flat", "D note", "E flat",
2004 "E note", "F note", "F sharp", "G note",
2005 "G sharp", "A note", "B flat", "B note" };
2007 *tnnames[12] = { "
\83h", "
\83\8c\81ó", "
\83\8c", "
\83~
\81ó",
2008 "
\83~", "
\83t
\83@", "
\83t
\83@
\81ò", "
\83\",
2009 "
\83\
\81ò", "
\83\89", "
\83V
\81ó", "
\83V" };
2013 tn = tnnames[trap->tnote];
2016 Sprintf(tnbuf, "%s ",
2017 (*tn == 'A' || *tn == 'E' || *tn == 'F') ? "an" : "a");
2018 Sprintf(eos(tnbuf), "%s", tn);
2020 Sprintf(tnbuf, "%s
\82Ì
\89¹", tn);
2026 steedintrap(trap, otmp)
2030 struct monst *steed = u.usteed;
2032 boolean trapkilled, steedhit;
2034 if (!steed || !trap)
2039 trapkilled = steedhit = FALSE;
2044 impossible("steed hit by non-existant arrow?");
2047 trapkilled = thitm(8, steed, otmp, 0, FALSE);
2052 impossible("steed hit by non-existant dart?");
2055 trapkilled = thitm(7, steed, otmp, 0, FALSE);
2059 if (!resists_sleep(steed) && !breathless(steed->data)
2060 && !steed->msleeping && steed->mcanmove) {
2061 if (sleep_monst(steed, rnd(25), -1))
2062 /* no in_sight check here; you can feel it even if blind */
2064 pline("%s suddenly falls asleep!", Monnam(steed));
2066 pline("%s
\82Í
\82Æ
\82Â
\82º
\82ñ
\96°
\82Á
\82Ä
\82µ
\82Ü
\82Á
\82½
\81I", Monnam(steed));
2071 trapkilled = thitm(0, steed, (struct obj *) 0, rnd(16), FALSE);
2076 trapkilled = (steed->mhp <= 0
2077 || thitm(0, steed, (struct obj *) 0,
2078 rnd((tt == PIT) ? 6 : 10), FALSE));
2082 if (!resists_magm(steed) && !resist(steed, WAND_CLASS, 0, NOTELL)) {
2083 (void) newcham(steed, (struct permonst *) 0, FALSE, FALSE);
2084 if (!can_saddle(steed) || !can_ride(steed))
2085 dismount_steed(DISMOUNT_POLY);
2088 You("have to adjust yourself in the saddle on %s.",
2090 You("%s
\82Ì
\88Æ
\82Ì
\8fã
\82Å
\8dÀ
\82è
\82È
\82¨
\82µ
\82½
\81D",
2091 x_monnam(steed, ARTICLE_A, (char *) 0, SUPPRESS_SADDLE,
2101 dismount_steed(DISMOUNT_POLY);
2104 return steedhit ? 1 : 0;
2107 /* some actions common to both player and monsters for triggered landmine */
2109 blow_up_landmine(trap)
2112 int x = trap->tx, y = trap->ty, dbx, dby;
2113 struct rm *lev = &levl[x][y];
2115 (void) scatter(x, y, 4,
2116 MAY_DESTROY | MAY_HIT | MAY_FRACTURE | VIS_EFFECTS,
2119 wake_nearto(x, y, 400);
2120 if (IS_DOOR(lev->typ))
2121 lev->doormask = D_BROKEN;
2122 /* destroy drawbridge if present */
2123 if (lev->typ == DRAWBRIDGE_DOWN || is_drawbridge_wall(x, y) >= 0) {
2125 /* if under the portcullis, the bridge is adjacent */
2126 if (find_drawbridge(&dbx, &dby))
2127 destroy_drawbridge(dbx, dby);
2128 trap = t_at(x, y); /* expected to be null after destruction */
2130 /* convert landmine into pit */
2132 if (Is_waterlevel(&u.uz) || Is_airlevel(&u.uz)) {
2136 trap->ttyp = PIT; /* explosion creates a pit */
2137 trap->madeby_u = FALSE; /* resulting pit isn't yours */
2138 seetrap(trap); /* and it isn't concealed */
2144 * The following are used to track launched objects to
2145 * prevent them from vanishing if you are killed. They
2146 * will reappear at the launchplace in bones files.
2154 launch_drop_spot(obj, x, y)
2159 launchplace.obj = (struct obj *) 0;
2163 launchplace.obj = obj;
2170 launch_in_progress()
2172 if (launchplace.obj)
2178 force_launch_placement()
2180 if (launchplace.obj) {
2181 launchplace.obj->otrapped = 0;
2182 place_object(launchplace.obj, launchplace.x, launchplace.y);
2187 * Move obj from (x1,y1) to (x2,y2)
2189 * Return 0 if no object was launched.
2190 * 1 if an object was launched and placed somewhere.
2191 * 2 if an object was launched, but used up.
2194 launch_obj(otyp, x1, y1, x2, y2, style)
2196 register int x1, y1, x2, y2;
2199 register struct monst *mtmp;
2200 register struct obj *otmp, *otmp2;
2201 register int dx, dy;
2202 struct obj *singleobj;
2203 boolean used_up = FALSE;
2204 boolean otherside = FALSE;
2209 otmp = sobj_at(otyp, x1, y1);
2210 /* Try the other side too, for rolling boulder traps */
2211 if (!otmp && otyp == BOULDER) {
2213 otmp = sobj_at(otyp, x2, y2);
2217 if (otherside) { /* swap 'em */
2228 if (otmp->quan == 1L) {
2229 obj_extract_self(otmp);
2231 otmp = (struct obj *) 0;
2233 singleobj = splitobj(otmp, 1L);
2234 obj_extract_self(singleobj);
2237 /* in case you're using a pick-axe to chop the boulder that's being
2238 launched (perhaps a monster triggered it), destroy context so that
2239 next dig attempt never thinks you're resuming previous effort */
2240 if ((otyp == BOULDER || otyp == STATUE)
2241 && singleobj->ox == context.digging.pos.x
2242 && singleobj->oy == context.digging.pos.y)
2243 (void) memset((genericptr_t) &context.digging, 0,
2244 sizeof(struct dig_info));
2246 dist = distmin(x1, y1, x2, y2);
2252 case ROLL | LAUNCH_UNSEEN:
2253 if (otyp == BOULDER) {
2255 You_hear(Hallucination ? "someone bowling."
2256 : "rumbling in the distance.");
2258 You_hear(Hallucination ? "
\92N
\82©
\82ª
\83{
\81[
\83\8a\83\93\83O
\82ð
\82µ
\82Ä
\82¢
\82é
\89¹
\82ð
\95·
\82¢
\82½
\81D"
2259 : "
\89\93\82
\82Ì
\83S
\83\8d\83S
\83\8d\82Æ
\82¢
\82¤
\89¹
\82ð
\95·
\82¢
\82½
\81D");
2262 style &= ~LAUNCH_UNSEEN;
2264 case ROLL | LAUNCH_KNOWN:
2265 /* use otrapped as a flag to ohitmon */
2266 singleobj->otrapped = 1;
2267 style &= ~LAUNCH_KNOWN;
2276 if (!cansee(bhitpos.x, bhitpos.y))
2278 tmp_at(DISP_FLASH, obj_to_glyph(singleobj));
2279 tmp_at(bhitpos.x, bhitpos.y);
2281 /* Mark a spot to place object in bones files to prevent
2282 * loss of object. Use the starting spot to ensure that
2283 * a rolling boulder will still launch, which it wouldn't
2284 * do if left midstream. Unfortunately we can't use the
2285 * target resting spot, because there are some things/situations
2286 * that would prevent it from ever getting there (bars), and we
2287 * can't tell that yet.
2289 launch_drop_spot(singleobj, bhitpos.x, bhitpos.y);
2291 /* Set the object in motion */
2292 while (dist-- > 0 && !used_up) {
2294 tmp_at(bhitpos.x, bhitpos.y);
2297 /* dstage@u.washington.edu -- Delay only if hero sees it */
2298 if (cansee(bhitpos.x, bhitpos.y))
2304 t = t_at(bhitpos.x, bhitpos.y);
2306 if ((mtmp = m_at(bhitpos.x, bhitpos.y)) != 0) {
2307 if (otyp == BOULDER && throws_rocks(mtmp->data)) {
2310 pline("%s snatches the boulder.", Monnam(mtmp));
2312 pline("%s
\82Í
\8aâ
\82ð
\82Â
\82©
\82Ý
\8eæ
\82Á
\82½
\81D", Monnam(mtmp));
2313 singleobj->otrapped = 0;
2314 (void) mpickobj(mtmp, singleobj);
2316 launch_drop_spot((struct obj *) 0, 0, 0);
2320 if (ohitmon(mtmp, singleobj, (style == ROLL) ? -1 : dist,
2323 launch_drop_spot((struct obj *) 0, 0, 0);
2326 } else if (bhitpos.x == u.ux && bhitpos.y == u.uy) {
2329 if (thitu(9 + singleobj->spe, dmgval(singleobj, &youmonst),
2330 singleobj, (char *) 0))
2333 if (style == ROLL) {
2334 if (down_gate(bhitpos.x, bhitpos.y) != -1) {
2335 if (ship_object(singleobj, bhitpos.x, bhitpos.y, FALSE)) {
2337 launch_drop_spot((struct obj *) 0, 0, 0);
2341 if (t && otyp == BOULDER) {
2348 cansee(bhitpos.x, bhitpos.y)
2349 ? " The rolling boulder triggers a land mine."
2353 "
\82¿
\82ã
\82Ç
\81[
\82ñ
\81I
\81I%s",
2354 cansee(bhitpos.x, bhitpos.y)
2355 ? "
\93]
\82ª
\82Á
\82Ä
\82«
\82½
\8aâ
\82ª
\92n
\97\8b\82Ì
\8bN
\94\9a\83X
\83C
\83b
\83`
\82ð
\93¥
\82ñ
\82¾
\81D"
2359 del_engr_at(bhitpos.x, bhitpos.y);
2360 place_object(singleobj, bhitpos.x, bhitpos.y);
2361 singleobj->otrapped = 0;
2362 fracture_rock(singleobj);
2363 (void) scatter(bhitpos.x, bhitpos.y, 4,
2364 MAY_DESTROY | MAY_HIT | MAY_FRACTURE
2367 if (cansee(bhitpos.x, bhitpos.y))
2368 newsym(bhitpos.x, bhitpos.y);
2370 launch_drop_spot((struct obj *) 0, 0, 0);
2375 if (cansee(bhitpos.x, bhitpos.y))
2377 pline("Suddenly the rolling boulder disappears!");
2379 pline("
\93]
\82ª
\82Á
\82Ä
\82«
\82½
\8aâ
\82ª
\82Æ
\82Â
\82º
\82ñ
\8fÁ
\82¦
\82½
\81I");
2382 You_hear("a rumbling stop abruptly.");
2384 pline("
\83S
\83\8d\83S
\83\8d\82Æ
\82¢
\82¤
\89¹
\82ª
\93Ë
\91R
\8e~
\82Ü
\82Á
\82½
\81D");
2385 singleobj->otrapped = 0;
2386 if (t->ttyp == TELEP_TRAP)
2387 (void) rloco(singleobj);
2389 int newlev = random_teleport_level();
2392 if (newlev == depth(&u.uz) || In_endgame(&u.uz))
2394 add_to_migration(singleobj);
2395 get_level(&dest, newlev);
2396 singleobj->ox = dest.dnum;
2397 singleobj->oy = dest.dlevel;
2398 singleobj->owornmask = (long) MIGR_RANDOM;
2402 launch_drop_spot((struct obj *) 0, 0, 0);
2408 /* the boulder won't be used up if there is a
2409 monster in the trap; stop rolling anyway */
2410 x2 = bhitpos.x, y2 = bhitpos.y; /* stops here */
2412 if (flooreffects(singleobj, x2, y2, "fall")) {
2414 if (flooreffects(singleobj, x2, y2, "
\97\8e\82¿
\82é")) {
2416 launch_drop_spot((struct obj *) 0, 0, 0);
2418 dist = -1; /* stop rolling immediately */
2421 if (used_up || dist == -1)
2425 if (flooreffects(singleobj, bhitpos.x, bhitpos.y, "fall")) {
2427 if (flooreffects(singleobj, bhitpos.x, bhitpos.y, "
\97\8e\82¿
\82é")) {
2429 launch_drop_spot((struct obj *) 0, 0, 0);
2433 && (otmp2 = sobj_at(BOULDER, bhitpos.x, bhitpos.y)) != 0) {
2435 const char *bmsg = " as one boulder sets another in motion";
2437 const char *bmsg = "
\82Ð
\82Æ
\82Â
\82Ì
\8aâ
\82ª
\91¼
\82Ì
\8aâ
\82ð
\93®
\82©
\82µ
\82½
\82©
\82Ì
\82æ
\82¤
\82È
\81C";
2439 if (!isok(bhitpos.x + dx, bhitpos.y + dy) || !dist
2440 || IS_ROCK(levl[bhitpos.x + dx][bhitpos.y + dy].typ))
2442 bmsg = " as one boulder hits another";
2444 bmsg = "
\82Ð
\82Æ
\82Â
\82Ì
\8aâ
\82ª
\91¼
\82Ì
\8aâ
\82É
\93\96\82½
\82Á
\82½
\82æ
\82¤
\82È";
2447 You_hear("a loud crash%s!",
2449 You_hear("%s
\91å
\82«
\82È
\83S
\83\93\82Æ
\82¢
\82¤
\89¹
\82ð
\95·
\82¢
\82½
\81I",
2450 cansee(bhitpos.x, bhitpos.y) ? bmsg : "");
2451 obj_extract_self(otmp2);
2452 /* pass off the otrapped flag to the next boulder */
2453 otmp2->otrapped = singleobj->otrapped;
2454 singleobj->otrapped = 0;
2455 place_object(singleobj, bhitpos.x, bhitpos.y);
2457 otmp2 = (struct obj *) 0;
2458 wake_nearto(bhitpos.x, bhitpos.y, 10 * 10);
2461 if (otyp == BOULDER && closed_door(bhitpos.x, bhitpos.y)) {
2462 if (cansee(bhitpos.x, bhitpos.y))
2464 pline_The("boulder crashes through a door.");
2466 pline("
\8aâ
\82Í
\94à
\82ð
\94j
\89ó
\82µ
\82½
\81D");
2467 levl[bhitpos.x][bhitpos.y].doormask = D_BROKEN;
2469 unblock_point(bhitpos.x, bhitpos.y);
2472 /* if about to hit iron bars, do so now */
2473 if (dist > 0 && isok(bhitpos.x + dx, bhitpos.y + dy)
2474 && levl[bhitpos.x + dx][bhitpos.y + dy].typ == IRONBARS) {
2475 x2 = bhitpos.x, y2 = bhitpos.y; /* object stops here */
2476 if (hits_bars(&singleobj, x2, y2, !rn2(20), 0)) {
2479 launch_drop_spot((struct obj *) 0, 0, 0);
2485 tmp_at(DISP_END, 0);
2486 launch_drop_spot((struct obj *) 0, 0, 0);
2488 singleobj->otrapped = 0;
2489 place_object(singleobj, x2, y2);
2502 newsym(trap->tx, trap->ty);
2506 /* like seetrap() but overrides vision */
2513 /* in case it's beneath something, redisplay the something */
2514 newsym(trap->tx, trap->ty);
2518 mkroll_launch(ttmp, x, y, otyp, ocount)
2531 boolean success = FALSE;
2534 if (ttmp->ttyp == ROLLING_BOULDER_TRAP)
2536 distance = rn1(5, 4); /* 4..8 away */
2537 tmp = rn2(8); /* randomly pick a direction to try first */
2538 while (distance >= mindist) {
2543 /* Prevent boulder from being placed on water */
2544 if (ttmp->ttyp == ROLLING_BOULDER_TRAP
2545 && is_pool_or_lava(x + distance * dx, y + distance * dy))
2548 success = isclearpath(&cc, distance, dx, dy);
2549 if (ttmp->ttyp == ROLLING_BOULDER_TRAP) {
2550 boolean success_otherway;
2554 success_otherway = isclearpath(&bcc, distance, -(dx), -(dy));
2555 if (!success_otherway)
2562 if ((++trycount % 8) == 0)
2566 /* create the trap without any ammo, launch pt at trap location */
2570 otmp = mksobj(otyp, TRUE, FALSE);
2571 otmp->quan = ocount;
2572 otmp->owt = weight(otmp);
2573 place_object(otmp, cc.x, cc.y);
2576 ttmp->launch.x = cc.x;
2577 ttmp->launch.y = cc.y;
2578 if (ttmp->ttyp == ROLLING_BOULDER_TRAP) {
2579 ttmp->launch2.x = bcc.x;
2580 ttmp->launch2.y = bcc.y;
2582 ttmp->launch_otyp = otyp;
2583 newsym(ttmp->launch.x, ttmp->launch.y);
2588 isclearpath(cc, distance, dx, dy)
2598 while (distance-- > 0) {
2601 typ = levl[x][y].typ;
2602 if (!isok(x, y) || !ZAP_POS(typ) || closed_door(x, y))
2612 register struct monst *mtmp;
2614 register struct trap *trap = t_at(mtmp->mx, mtmp->my);
2615 boolean trapkilled = FALSE;
2616 struct permonst *mptr = mtmp->data;
2620 mtmp->mtrapped = 0; /* perhaps teleported? */
2621 } else if (mtmp->mtrapped) { /* is currently in the trap */
2622 if (!trap->tseen && cansee(mtmp->mx, mtmp->my) && canseemon(mtmp)
2623 && (trap->ttyp == SPIKED_PIT || trap->ttyp == BEAR_TRAP
2624 || trap->ttyp == HOLE || trap->ttyp == PIT
2625 || trap->ttyp == WEB)) {
2626 /* If you come upon an obviously trapped monster, then
2627 * you must be able to see the trap it's in too.
2633 if (sobj_at(BOULDER, mtmp->mx, mtmp->my)
2634 && (trap->ttyp == PIT || trap->ttyp == SPIKED_PIT)) {
2637 if (canseemon(mtmp))
2639 pline("%s pulls free...", Monnam(mtmp));
2641 pline("%s
\82Í
\8f\95\82¯
\8fã
\82°
\82ç
\82ê
\82½
\81D", Monnam(mtmp));
2642 fill_pit(mtmp->mx, mtmp->my);
2647 } else if (metallivorous(mptr)) {
2648 if (trap->ttyp == BEAR_TRAP) {
2649 if (canseemon(mtmp))
2651 pline("%s eats a bear trap!", Monnam(mtmp));
2653 pline("%s
\82Í
\8cF
\82Ìã©
\82ð
\90H
\82×
\82½
\81I", Monnam(mtmp));
2657 } else if (trap->ttyp == SPIKED_PIT) {
2658 if (canseemon(mtmp))
2660 pline("%s munches on some spikes!", Monnam(mtmp));
2662 pline("%s
\82Í
\83g
\83Q
\83g
\83Q
\82ð
\90H
\82×
\82½
\81I", Monnam(mtmp));
2668 register int tt = trap->ttyp;
2669 boolean in_sight, tear_web, see_it,
2670 inescapable = force_mintrap || ((tt == HOLE || tt == PIT)
2671 && Sokoban && !trap->madeby_u);
2672 const char *fallverb;
2674 /* true when called from dotrap, inescapable is not an option */
2675 if (mtmp == u.usteed)
2677 if (!inescapable && ((mtmp->mtrapseen & (1 << (tt - 1))) != 0
2678 || (tt == HOLE && !mindless(mptr)))) {
2679 /* it has been in such a trap - perhaps it escapes */
2683 mtmp->mtrapseen |= (1 << (tt - 1));
2685 /* Monster is aggravated by being trapped by you.
2686 Recognizing who made the trap isn't completely
2687 unreasonable; everybody has their own style. */
2688 if (trap->madeby_u && rnl(5))
2691 in_sight = canseemon(mtmp);
2692 see_it = cansee(mtmp->mx, mtmp->my);
2693 /* assume hero can tell what's going on for the steed */
2694 if (mtmp == u.usteed)
2698 if (trap->once && trap->tseen && !rn2(15)) {
2699 if (in_sight && see_it)
2701 pline("%s triggers a trap but nothing happens.",
2704 pline("%s
\82ª
\82í
\82È
\82ð
\8bN
\93®
\82³
\82¹
\82½
\82ª
\89½
\82à
\8bN
\82±
\82ç
\82È
\82©
\82Á
\82½
\81D",
2708 newsym(mtmp->mx, mtmp->my);
2712 otmp = mksobj(ARROW, TRUE, FALSE);
2714 otmp->owt = weight(otmp);
2715 otmp->opoisoned = 0;
2718 if (thitm(8, mtmp, otmp, 0, FALSE))
2722 if (trap->once && trap->tseen && !rn2(15)) {
2723 if (in_sight && see_it)
2725 pline("%s triggers a trap but nothing happens.",
2728 pline("%s
\82ª
\82í
\82È
\82ð
\8bN
\93®
\82³
\82¹
\82½
\82ª
\89½
\82à
\8bN
\82±
\82ç
\82È
\82©
\82Á
\82½
\81D",
2732 newsym(mtmp->mx, mtmp->my);
2736 otmp = mksobj(DART, TRUE, FALSE);
2738 otmp->owt = weight(otmp);
2740 otmp->opoisoned = 1;
2743 if (thitm(7, mtmp, otmp, 0, FALSE))
2747 if (trap->once && trap->tseen && !rn2(15)) {
2748 if (in_sight && see_it)
2751 "A trap door above %s opens, but nothing falls out!",
2753 "%s
\82Ì
\8fã
\82Ì
\94à
\82ª
\8aJ
\82¢
\82½
\82ª
\81C
\89½
\82à
\97\8e\82¿
\82Ä
\82±
\82È
\82©
\82Á
\82½
\81I",
2756 newsym(mtmp->mx, mtmp->my);
2760 otmp = mksobj(ROCK, TRUE, FALSE);
2762 otmp->owt = weight(otmp);
2765 if (thitm(0, mtmp, otmp, d(2, 6), FALSE))
2771 /* stepped on a squeaky board */
2775 pline("A board beneath %s squeaks %s loudly.",
2776 mon_nam(mtmp), trapnote(trap, 0));
2778 pline("%s
\82Ì
\91«
\8c³
\82Ì
\94Â
\82ª
\91å
\82«
\82%s
\82É
\82«
\82µ
\82ñ
\82¾
\81D",
2779 mon_nam(mtmp), trapnote(trap, 0));
2784 pline("%s stops momentarily and appears to cringe.",
2786 pline("%s
\82Í
\88ê
\8fu
\8e~
\82Ü
\82Á
\82Ä
\90g
\82ð
\82·
\82
\82ß
\82½
\82æ
\82¤
\82¾
\81D",
2791 You_hear("a distant %s squeak.", trapnote(trap, 1));
2793 You_hear("
\89\93\82
\82Å%s
\82Å
\82«
\82µ
\82Þ
\89¹
\82ð
\95·
\82¢
\82½
\81D", trapnote(trap, 1));
2794 /* wake up nearby monsters */
2795 wake_nearto(mtmp->mx, mtmp->my, 40);
2798 if (mptr->msize > MZ_SMALL && !amorphous(mptr) && !is_flyer(mptr)
2799 && !is_whirly(mptr) && !unsolid(mptr)) {
2803 pline("%s is caught in %s bear trap!", Monnam(mtmp),
2804 a_your[trap->madeby_u]);
2806 pline("%s
\82Í%s
\8cF
\82Ìã©
\82É
\82Â
\82©
\82Ü
\82Á
\82½
\81I", Monnam(mtmp),
2807 set_you[trap->madeby_u]);
2811 if (mptr == &mons[PM_OWLBEAR]
2812 || mptr == &mons[PM_BUGBEAR])
2814 You_hear("the roaring of an angry bear!");
2816 You_hear("
\93{
\82è
\82Ì
\99ô
\9aK
\82ð
\95·
\82¢
\82½
\81I");
2818 } else if (force_mintrap) {
2821 pline("%s evades %s bear trap!", Monnam(mtmp),
2822 a_your[trap->madeby_u]);
2824 pline("%s
\82Í%s
\8cF
\82Ìã©
\82ð
\82½
\82
\82Ý
\82É
\94ð
\82¯
\82½
\81I", Monnam(mtmp),
2825 set_you[trap->madeby_u]);
2831 trapkilled = thitm(0, mtmp, (struct obj *) 0, d(2, 4), FALSE);
2834 if (!resists_sleep(mtmp) && !breathless(mptr) && !mtmp->msleeping
2835 && mtmp->mcanmove) {
2836 if (sleep_monst(mtmp, rnd(25), -1) && in_sight) {
2838 pline("%s suddenly falls asleep!", Monnam(mtmp));
2840 pline("%s
\82Í
\93Ë
\91R
\96°
\82è
\82É
\97\8e\82¿
\82½
\81I", Monnam(mtmp));
2854 pline("%s %s on the %s!", A_gush_of_water_hits,
2855 mon_nam(mtmp), mbodypart(mtmp, HEAD));
2857 pline("
\90\85\82ª
\95¬
\8fo
\82µ
\82Ä
\81C%s
\82Ì%s
\82É
\96½
\92\86\82µ
\82½
\81I",
2858 mon_nam(mtmp), mbodypart(mtmp, HEAD));
2860 target = which_armor(mtmp, W_ARMH);
2861 (void) water_damage(target, helm_simple_name(target), TRUE);
2866 pline("%s %s's left %s!", A_gush_of_water_hits,
2867 mon_nam(mtmp), mbodypart(mtmp, ARM));
2869 pline("
\90\85\82ª
\95¬
\8fo
\82µ
\82Ä
\81C%s
\82Ì
\8d¶%s
\82É
\96½
\92\86\82µ
\82½
\81I",
2870 mon_nam(mtmp), mbodypart(mtmp, ARM));
2872 target = which_armor(mtmp, W_ARMS);
2874 if (water_damage(target, "shield", TRUE) != ER_NOTHING)
2876 if (water_damage(target, "
\8f\82", TRUE) != ER_NOTHING)
2878 target = MON_WEP(mtmp);
2879 if (target && bimanual(target))
2880 (void) water_damage(target, 0, TRUE);
2882 target = which_armor(mtmp, W_ARMG);
2884 (void) water_damage(target, "gauntlets", TRUE);
2886 (void) water_damage(target, "
\8f¬
\8eè", TRUE);
2891 pline("%s %s's right %s!", A_gush_of_water_hits,
2892 mon_nam(mtmp), mbodypart(mtmp, ARM));
2894 pline("
\90\85\82ª
\95¬
\8fo
\82µ
\82Ä
\81C%s
\82Ì
\89E%s
\82É
\96½
\92\86\82µ
\82½
\81I",
2895 mon_nam(mtmp), mbodypart(mtmp, ARM));
2897 (void) water_damage(MON_WEP(mtmp), 0, TRUE);
2902 pline("%s %s!", A_gush_of_water_hits, mon_nam(mtmp));
2904 pline("
\90\85\82ª
\95¬
\8fo
\82µ
\82Ä
\81C%s
\82É
\96½
\92\86\82µ
\82½
\81I", mon_nam(mtmp));
2905 for (otmp = mtmp->minvent; otmp; otmp = otmp->nobj)
2907 && (otmp->owornmask & (W_WEP | W_SWAPWEP)) == 0)
2908 (void) snuff_lit(otmp);
2909 if ((target = which_armor(mtmp, W_ARMC)) != 0)
2910 (void) water_damage(target, cloak_simple_name(target),
2912 else if ((target = which_armor(mtmp, W_ARM)) != 0)
2914 (void) water_damage(target, "armor", TRUE);
2916 (void) water_damage(target, "
\8aZ", TRUE);
2917 else if ((target = which_armor(mtmp, W_ARMU)) != 0)
2919 (void) water_damage(target, "shirt", TRUE);
2921 (void) water_damage(target, "
\83V
\83\83\83c", TRUE);
2924 if (mptr == &mons[PM_IRON_GOLEM]) {
2927 pline("%s falls to pieces!", Monnam(mtmp));
2929 pline("%s
\82Í
\82
\82¾
\82¯
\82¿
\82Á
\82½
\81I", Monnam(mtmp));
2930 else if (mtmp->mtame)
2932 pline("May %s rust in peace.", mon_nam(mtmp));
2934 pline("%s
\82æ
\81C
\88À
\82ç
\82©
\82É
\8eK
\82Ñ
\82ñ
\8e\96\82ð
\81D", mon_nam(mtmp));
2938 } else if (mptr == &mons[PM_GREMLIN] && rn2(3)) {
2939 (void) split_mon(mtmp, (struct monst *) 0);
2947 pline("A %s erupts from the %s under %s!", tower_of_flame,
2948 surface(mtmp->mx, mtmp->my), mon_nam(mtmp));
2950 pline("
\89Î
\92\8c\82ª%s
\82Ì
\91«
\8c³
\82Ì%s
\82©
\82ç
\97§
\82¿
\82Ì
\82Ú
\82Á
\82½
\81I",
2951 mon_nam(mtmp), surface(mtmp->mx,mtmp->my));
2953 else if (see_it) /* evidently `mtmp' is invisible */
2955 You_see("a %s erupt from the %s!", tower_of_flame,
2956 surface(mtmp->mx, mtmp->my));
2958 You("
\89Î
\92\8c\82ª%s
\82©
\82ç
\90¶
\82¶
\82é
\82Ì
\82ð
\8c©
\82½
\81I",
2959 surface(mtmp->mx,mtmp->my));
2962 if (resists_fire(mtmp)) {
2964 shieldeff(mtmp->mx, mtmp->my);
2966 pline("%s is uninjured.", Monnam(mtmp));
2968 pline("
\82ª
\81C%s
\82Í
\8f\9d\82Â
\82©
\82È
\82¢
\81D", Monnam(mtmp));
2971 int num = d(2, 4), alt;
2972 boolean immolate = FALSE;
2974 /* paper burns very fast, assume straw is tightly
2975 * packed and burns a bit slower */
2976 switch (monsndx(mptr)) {
2977 case PM_PAPER_GOLEM:
2981 case PM_STRAW_GOLEM:
2982 alt = mtmp->mhpmax / 2;
2985 alt = mtmp->mhpmax / 4;
2987 case PM_LEATHER_GOLEM:
2988 alt = mtmp->mhpmax / 8;
2997 if (thitm(0, mtmp, (struct obj *) 0, num, immolate))
3000 /* we know mhp is at least `num' below mhpmax,
3001 so no (mhp > mhpmax) check is needed here */
3002 mtmp->mhpmax -= rn2(num + 1);
3004 if (burnarmor(mtmp) || rn2(3)) {
3005 (void) destroy_mitem(mtmp, SCROLL_CLASS, AD_FIRE);
3006 (void) destroy_mitem(mtmp, SPBOOK_CLASS, AD_FIRE);
3007 (void) destroy_mitem(mtmp, POTION_CLASS, AD_FIRE);
3009 if (burn_floor_objects(mtmp->mx, mtmp->my, see_it, FALSE)
3010 && !see_it && distu(mtmp->mx, mtmp->my) <= 3 * 3)
3012 You("smell smoke.");
3014 pline("
\89\8c\82Ì
\93õ
\82¢
\82ª
\82µ
\82½
\81D");
3015 if (is_ice(mtmp->mx, mtmp->my))
3016 melt_ice(mtmp->mx, mtmp->my, (char *) 0);
3025 fallverb = "
\97\8e\82¿
\82½";
3026 if (is_flyer(mptr) || is_floater(mptr)
3027 || (mtmp->wormno && count_wsegs(mtmp) > 5)
3028 || is_clinger(mptr)) {
3029 if (force_mintrap && !Sokoban) {
3030 /* openfallingtrap; not inescapable here */
3034 pline("%s doesn't fall into the pit.", Monnam(mtmp));
3036 pline("%s
\82Í
\97\8e\82µ
\8c\8a\82É
\97\8e\82¿
\82È
\82©
\82Á
\82½
\81D", Monnam(mtmp));
3038 break; /* inescapable = FALSE; */
3041 break; /* avoids trap */
3043 fallverb = "is dragged"; /* sokoban pit */
3045 fallverb = "
\82¸
\82è
\97\8e\82¿
\82½"; /* sokoban pit */
3048 if (!passes_walls(mptr))
3052 pline("%s %s into %s pit!", Monnam(mtmp), fallverb,
3053 a_your[trap->madeby_u]);
3055 pline("%s
\82Í%s
\97\8e\82µ
\8c\8a\82É%s
\81I", Monnam(mtmp),
3056 set_you[trap->madeby_u], fallverb);
3058 if (mptr == &mons[PM_PIT_VIPER]
3059 || mptr == &mons[PM_PIT_FIEND])
3061 pline("How pitiful. Isn't that the pits?");
3063 pline("
\82±
\82Ì
\97\8e\82µ
\8c\8a\82Í
\82¢
\82¢
\8ed
\8e\96\82ð
\82µ
\82Ä
\82¢
\82é
\81D");
3067 mselftouch(mtmp, "Falling, ", FALSE);
3069 mselftouch(mtmp, "
\97\8e\89º
\92\86\81C", FALSE);
3070 if (mtmp->mhp <= 0 || thitm(0, mtmp, (struct obj *) 0,
3071 rnd((tt == PIT) ? 6 : 10), FALSE))
3076 if (!Can_fall_thru(&u.uz)) {
3077 impossible("mintrap: %ss cannot exist on this level.",
3078 defsyms[trap_to_defsym(tt)].explanation);
3079 break; /* don't activate it after all */
3081 if (is_flyer(mptr) || is_floater(mptr) || mptr == &mons[PM_WUMPUS]
3082 || (mtmp->wormno && count_wsegs(mtmp) > 5)
3083 || mptr->msize >= MZ_HUGE) {
3084 if (force_mintrap && !Sokoban) {
3085 /* openfallingtrap; not inescapable here */
3091 "A trap door opens, but %s doesn't fall through.",
3093 "
\97\8e\82µ
\94à
\82ª
\8aJ
\82¢
\82½
\82ª
\81C%s
\82Í
\97\8e\82¿
\82È
\82©
\82Á
\82½
\81D",
3095 else /* (tt == HOLE) */
3097 pline("%s doesn't fall through the hole.",
3099 pline("%s
\82Í
\8c\8a\82É
\97\8e\82¿
\82È
\82©
\82Á
\82½
\81D",
3102 break; /* inescapable = FALSE; */
3104 if (inescapable) { /* sokoban hole */
3107 pline("%s seems to be yanked down!", Monnam(mtmp));
3109 pline("%s
\82Í
\88ø
\82«
\97\8e\82³
\82ê
\82½
\82æ
\82¤
\82¾
\81I", Monnam(mtmp));
3110 /* suppress message in mlevel_tele_trap() */
3119 case MAGIC_PORTAL: {
3122 mlev_res = mlevel_tele_trap(mtmp, trap, inescapable, in_sight);
3128 mtele_trap(mtmp, trap, in_sight);
3131 /* Monster in a web. */
3134 if (amorphous(mptr) || is_whirly(mptr) || unsolid(mptr)) {
3135 if (acidic(mptr) || mptr == &mons[PM_GELATINOUS_CUBE]
3136 || mptr == &mons[PM_FIRE_ELEMENTAL]) {
3139 pline("%s %s %s spider web!", Monnam(mtmp),
3140 (mptr == &mons[PM_FIRE_ELEMENTAL])
3143 a_your[trap->madeby_u]);
3145 pline("%s%s
\82
\82à
\82Ì
\91\83\82ð%s
\81I",
3147 web_you[trap->madeby_u],
3148 (mptr == &mons[PM_FIRE_ELEMENTAL]) ?
3149 "
\8fÄ
\82¢
\82½" : "
\82±
\82È
\82²
\82È
\82É
\82µ
\82½");
3152 newsym(mtmp->mx, mtmp->my);
3157 pline("%s flows through %s spider web.", Monnam(mtmp),
3158 a_your[trap->madeby_u]);
3160 pline("%s
\82Í%s
\82
\82à
\82Ì
\91\83\82ð
\82·
\82é
\82è
\82Æ
\92Ê
\82è
\94²
\82¯
\82½
\81D", Monnam(mtmp),
3161 web_you[trap->madeby_u]);
3168 switch (monsndx(mptr)) {
3169 case PM_OWLBEAR: /* Eric Backus */
3173 You_hear("the roaring of a confused bear!");
3175 You_hear("
\8d¬
\97\90\82Ì
\99ô
\9aK
\82ð
\95·
\82¢
\82½
\81I");
3181 if (mptr->mlet == S_GIANT
3182 /* exclude baby dragons and relatively short worms */
3183 || (mptr->mlet == S_DRAGON && extra_nasty(mptr))
3184 || (mtmp->wormno && count_wsegs(mtmp) > 5)) {
3186 } else if (in_sight) {
3188 pline("%s is caught in %s spider web.", Monnam(mtmp),
3189 a_your[trap->madeby_u]);
3191 pline("%s
\82Í%s
\82
\82à
\82Ì
\91\83\82É
\82Â
\82©
\82Ü
\82Á
\82½
\81D", Monnam(mtmp),
3192 web_you[trap->madeby_u]);
3196 mtmp->mtrapped = tear_web ? 0 : 1;
3198 /* this list is fairly arbitrary; it deliberately
3199 excludes wumpus & giant/ettin zombies/mummies */
3200 case PM_TITANOTHERE:
3201 case PM_BALUCHITHERIUM:
3202 case PM_PURPLE_WORM:
3211 case PM_LORD_SURTUR:
3218 pline("%s tears through %s spider web!", Monnam(mtmp),
3219 a_your[trap->madeby_u]);
3221 pline("%s
\82Í%s
\82
\82à
\82Ì
\91\83\82ð
\88ø
\82«
\97ô
\82¢
\82½
\81I", Monnam(mtmp),
3222 web_you[trap->madeby_u]);
3225 newsym(mtmp->mx, mtmp->my);
3226 } else if (force_mintrap && !mtmp->mtrapped) {
3229 pline("%s avoids %s spider web!", Monnam(mtmp),
3230 a_your[trap->madeby_u]);
3232 pline("%s
\82Í%s
\82
\82à
\82Ì
\91\83\82ð
\94ð
\82¯
\82½
\81I", Monnam(mtmp),
3233 web_you[trap->madeby_u]);
3242 /* A magic trap. Monsters usually immune. */
3247 /* similar to hero's case, more or less */
3248 if (!resists_magm(mtmp)) { /* lose spell energy */
3249 if (!mtmp->mcan && (attacktype(mptr, AT_MAGC)
3250 || attacktype(mptr, AT_BREA))) {
3251 mtmp->mspec_used += d(2, 2);
3255 pline("%s seems lethargic.", Monnam(mtmp));
3257 pline("%s
\88ê
\8fu
\96³
\8bC
\97Í
\8a´
\82ð
\8a´
\82¶
\82½
\81D", Monnam(mtmp));
3260 } else { /* take some damage */
3261 int dmgval2 = rnd(4);
3263 if ((otmp = MON_WEP(mtmp)) != 0
3264 && otmp->oartifact == ART_MAGICBANE)
3266 for (otmp = mtmp->minvent; otmp; otmp = otmp->nobj)
3268 && defends_when_carried(AD_MAGM, otmp))
3272 if (passes_walls(mptr))
3273 dmgval2 = (dmgval2 + 3) / 4;
3277 if ((mtmp->mhp -= dmgval2) <= 0)
3281 ? "compression from an anti-magic field"
3283 ? "
\94½
\96\82\96@
\8bó
\8aÔ
\82Ì
\88³
\8fk"
3289 newsym(trap->tx, trap->ty);
3294 break; /* monsters usually don't set it off */
3295 if (is_flyer(mptr)) {
3296 boolean already_seen = trap->tseen;
3298 if (in_sight && !already_seen) {
3300 pline("A trigger appears in a pile of soil below %s.",
3302 pline("%s
\82Ì
\91«
\8c³
\82Ì
\93y
\82Ì
\8eR
\82É
\8bN
\94\9a\83X
\83C
\83b
\83`
\82ª
\8c»
\82í
\82ê
\82½
\81D",
3309 newsym(mtmp->mx, mtmp->my);
3311 pline_The("air currents set %s off!",
3312 already_seen ? "a land mine" : "it");
3314 pline("
\8bó
\8bC
\82Ì
\97¬
\82ê
\82Å
\83X
\83C
\83b
\83`
\82ª
\93ü
\82Á
\82½
\81I");
3317 } else if (in_sight) {
3318 newsym(mtmp->mx, mtmp->my);
3320 pline("KAABLAMM!!! %s triggers %s land mine!", Monnam(mtmp),
3321 a_your[trap->madeby_u]);
3323 pline("
\82¿
\82ã
\82Ç
\81[
\82ñ
\81I
\81I%s
\82Í%s
\92n
\97\8b\82Ì
\8bN
\94\9a\83X
\83C
\83b
\83`
\82ð
\93¥
\82ñ
\82¾
\81I", Monnam(mtmp),
3324 set_you[trap->madeby_u]);
3329 pline("Kaablamm! You hear an explosion in the distance!");
3331 pline("
\82¿
\82ã
\82Ç
\81[
\82ñ
\81I
\82 \82È
\82½
\82Í
\89\93\95û
\82Ì
\94\9a\94
\89¹
\82ð
\95·
\82¢
\82½
\81I");
3332 blow_up_landmine(trap);
3333 /* explosion might have destroyed a drawbridge; don't
3334 dish out more damage if monster is already dead */
3336 || thitm(0, mtmp, (struct obj *) 0, rnd(16), FALSE))
3339 /* monsters recursively fall into new pit */
3340 if (mintrap(mtmp) == 2)
3343 /* a boulder may fill the new pit, crushing monster */
3344 fill_pit(trap->tx, trap->ty);
3347 if (unconscious()) {
3350 nomovemsg = "The explosion awakens you!";
3352 nomovemsg = "
\94\9a\94
\82Å
\82 \82È
\82½
\82Í
\8bN
\82«
\82½
\81I";
3356 if (resists_magm(mtmp)) {
3357 shieldeff(mtmp->mx, mtmp->my);
3358 } else if (!resist(mtmp, WAND_CLASS, 0, NOTELL)) {
3359 if (newcham(mtmp, (struct permonst *) 0, FALSE, FALSE))
3360 /* we're done with mptr but keep it up to date */
3366 case ROLLING_BOULDER_TRAP:
3367 if (!is_flyer(mptr)) {
3368 int style = ROLL | (in_sight ? 0 : LAUNCH_UNSEEN);
3370 newsym(mtmp->mx, mtmp->my);
3373 pline("Click! %s triggers %s.", Monnam(mtmp),
3374 trap->tseen ? "a rolling boulder trap" : something);
3376 pline("
\83J
\83`
\83b
\81I%s
\82Í%s
\82Ì
\83X
\83C
\83b
\83`
\82ð
\93¥
\82ñ
\82¾
\81I", Monnam(mtmp),
3377 trap->tseen ? "
\97\8e\8aâ
\82Ìã©" : "
\89½
\82©");
3379 if (launch_obj(BOULDER, trap->launch.x, trap->launch.y,
3380 trap->launch2.x, trap->launch2.y, style)) {
3387 newsym(mtmp->mx, mtmp->my);
3391 case VIBRATING_SQUARE:
3392 if (see_it && !Blind) {
3395 pline("You see a strange vibration beneath %s %s.",
3396 s_suffix(mon_nam(mtmp)),
3397 makeplural(mbodypart(mtmp, FOOT)));
3399 pline("%s
\82Ì%s
\82ª
\95s
\8ev
\8bc
\82É
\90U
\93®
\82µ
\82Ä
\82¢
\82é
\82Ì
\82ð
\8c©
\82½
\81D",
3400 mon_nam(mtmp), mbodypart(mtmp, FOOT));
3404 pline("You see the ground vibrate in the distance.");
3406 pline("
\89\93\82
\82Å
\92n
\96Ê
\82ª
\90U
\93®
\82µ
\82Ä
\82¢
\82é
\82Ì
\82ð
\8c©
\82½
\81D");
3411 impossible("Some monster encountered a strange trap of type %d.",
3417 return mtmp->mtrapped;
3420 /* Combine cockatrice checks into single functions to avoid repeating code. */
3425 if (Stone_resistance)
3427 if (poly_when_stoned(youmonst.data) && polymon(PM_STONE_GOLEM))
3430 You("turn to stone...");
3432 You("
\90Î
\82É
\82È
\82Á
\82½
\81D
\81D
\81D");
3433 killer.format = KILLED_BY;
3434 if (str != killer.name)
3435 Strcpy(killer.name, str ? str : "");
3440 minstapetrify(mon, byplayer)
3444 if (resists_ston(mon))
3446 if (poly_when_stoned(mon->data)) {
3451 /* give a "<mon> is slowing down" message and also remove
3452 intrinsic speed (comparable to similar effect on the hero) */
3453 mon_adjust_speed(mon, -3, (struct obj *) 0);
3455 if (cansee(mon->mx, mon->my))
3457 pline("%s turns to stone.", Monnam(mon));
3459 pline("%s
\82Í
\90Î
\82É
\82È
\82Á
\82½
\81D", Monnam(mon));
3473 if (uwep && uwep->otyp == CORPSE && touch_petrifies(&mons[uwep->corpsenm])
3474 && !Stone_resistance) {
3476 pline("%s touch the %s corpse.", arg, mons[uwep->corpsenm].mname);
3478 pline("%s%s
\82Ì
\8e\80\91Ì
\82É
\90G
\82Á
\82½
\81D", arg, mons[uwep->corpsenm].mname);
3480 Sprintf(kbuf, "%s corpse", an(mons[uwep->corpsenm].mname));
3482 Sprintf(kbuf, "%s
\82Ì
\8e\80\91Ì
\82Å", mons[uwep->corpsenm].mname);
3484 /* life-saved; unwield the corpse if we can't handle it */
3485 if (!uarmg && !Stone_resistance)
3488 /* Or your secondary weapon, if wielded [hypothetical; we don't
3489 allow two-weapon combat when either weapon is a corpse] */
3490 if (u.twoweap && uswapwep && uswapwep->otyp == CORPSE
3491 && touch_petrifies(&mons[uswapwep->corpsenm]) && !Stone_resistance) {
3493 pline("%s touch the %s corpse.", arg, mons[uswapwep->corpsenm].mname);
3495 pline("%s%s
\82Ì
\8e\80\91Ì
\82É
\90G
\82Á
\82½
\81D", arg, mons[uswapwep->corpsenm].mname);
3497 Sprintf(kbuf, "%s corpse", an(mons[uswapwep->corpsenm].mname));
3499 Sprintf(kbuf, "%s
\82Ì
\8e\80\91Ì
\82Å", mons[uswapwep->corpsenm].mname);
3501 /* life-saved; unwield the corpse */
3502 if (!uarmg && !Stone_resistance)
3508 mselftouch(mon, arg, byplayer)
3513 struct obj *mwep = MON_WEP(mon);
3515 if (mwep && mwep->otyp == CORPSE && touch_petrifies(&mons[mwep->corpsenm])
3516 && !resists_ston(mon)) {
3517 if (cansee(mon->mx, mon->my)) {
3519 pline("%s%s touches %s.", arg ? arg : "",
3520 arg ? mon_nam(mon) : Monnam(mon),
3521 corpse_xname(mwep, (const char *) 0, CXN_PFX_THE));
3523 pline("%s%s
\82Í%s
\82Ì
\8e\80\91Ì
\82É
\90G
\82Á
\82½
\81D", arg ? arg : "",
3524 arg ? mon_nam(mon) : Monnam(mon),
3525 corpse_xname(mwep, (const char *) 0, CXN_PFX_THE));
3528 minstapetrify(mon, byplayer);
3529 /* if life-saved, might not be able to continue wielding */
3530 if (mon->mhp > 0 && !which_armor(mon, W_ARMG) && !resists_ston(mon))
3535 /* start levitating */
3540 if (u.utraptype == TT_PIT) {
3543 You("float up, out of the pit!");
3545 You("
\95\82\82«
\8fã
\82ª
\82Á
\82Ä
\81C
\97\8e\82µ
\8c\8a\82©
\82ç
\8fo
\82½
\81I");
3546 vision_full_recalc = 1; /* vision limits change */
3547 fill_pit(u.ux, u.uy);
3548 } else if (u.utraptype == TT_INFLOOR) {
3550 Your("body pulls upward, but your %s are still stuck.",
3552 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",
3553 makeplural(body_part(LEG)));
3556 You("float up, only your %s is still stuck.", body_part(LEG));
3558 You("
\95\82\82«
\8fo
\82½
\81D%s
\82¾
\82¯
\82ª
\82Í
\82Ü
\82Á
\82Ä
\82¢
\82é
\81D", body_part(LEG));
3561 } else if (Is_waterlevel(&u.uz)) {
3563 pline("It feels as though you've lost some weight.");
3565 You("
\82Ü
\82é
\82Å
\91Ì
\8fd
\82ª
\8c¸
\82Á
\82½
\82æ
\82¤
\82É
\8a´
\82¶
\82½
\81D");
3567 } else if (u.uinwater) {
3569 } else if (u.uswallow) {
3571 You(is_animal(u.ustuck->data) ? "float away from the %s."
3572 : "spiral up into %s.",
3573 is_animal(u.ustuck->data) ? surface(u.ux, u.uy)
3574 : mon_nam(u.ustuck));
3576 You(is_animal(u.ustuck->data) ? "%s
\82Ì
\92\86\82Å
\95\82\82¢
\82½
\81D"
3577 : "%s
\82Ì
\92\86\82Å
\82®
\82é
\82®
\82é
\89ñ
\93]
\82µ
\82½
\81D",
3578 is_animal(u.ustuck->data) ? surface(u.ux, u.uy)
3579 : mon_nam(u.ustuck));
3581 } else if (Hallucination) {
3583 pline("Up, up, and awaaaay! You're walking on air!");
3585 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");
3586 } else if (Is_airlevel(&u.uz)) {
3588 You("gain control over your movements.");
3590 You("
\82¤
\82Ü
\82
\93®
\82¯
\82é
\82æ
\82¤
\82É
\82È
\82Á
\82½
\81D");
3593 You("start to float in the air!");
3595 You("
\8bó
\92\86\82É
\95\82\82«
\82Í
\82¶
\82ß
\82½
\81I");
3597 if (u.usteed && !is_floater(u.usteed->data)
3598 && !is_flyer(u.usteed->data)) {
3601 pline("%s magically floats up!", Monnam(u.usteed));
3603 pline("%s
\82Í
\96\82\96@
\82Ì
\97Í
\82Å
\95\82\82¢
\82½
\81I", Monnam(u.usteed));
3606 You("cannot stay on %s.", mon_nam(u.usteed));
3608 You("%s
\82Ì
\8fã
\82É
\8fæ
\82Á
\82Ä
\82¢
\82ç
\82ê
\82È
\82¢
\81D", mon_nam(u.usteed));
3609 dismount_steed(DISMOUNT_GENERIC);
3614 You("are no longer able to control your flight.");
3616 You("
\8bó
\92\86\82Å
\82¤
\82Ü
\82
\93®
\82¯
\82È
\82
\82È
\82Á
\82½
\81D");
3617 BFlying |= I_SPECIAL;
3628 if ((t = t_at(x, y)) && ((t->ttyp == PIT) || (t->ttyp == SPIKED_PIT))
3629 && (otmp = sobj_at(BOULDER, x, y))) {
3630 obj_extract_self(otmp);
3632 (void) flooreffects(otmp, x, y, "settle");
3634 (void) flooreffects(otmp, x, y, "
\82Í
\82Ü
\82é");
3638 /* stop levitating */
3640 float_down(hmask, emask)
3641 long hmask, emask; /* might cancel timeout */
3643 register struct trap *trap = (struct trap *) 0;
3644 d_level current_dungeon_level;
3645 boolean no_msg = FALSE;
3647 HLevitation &= ~hmask;
3648 ELevitation &= ~emask;
3650 return 0; /* maybe another ring/potion/boots */
3652 /* Levitation is blocked, so hero is not actually floating
3653 hence shouldn't have float_down effects and feedback */
3654 float_vs_flight(); /* before nomul() rather than after */
3657 nomul(0); /* stop running or resting */
3659 /* controlled flight no longer overridden by levitation */
3660 BFlying &= ~I_SPECIAL;
3663 You("have stopped levitating and are now flying.");
3665 You("
\8bó
\92\86\95\82\97V
\82ð
\8e~
\82ß
\82Ä
\8bó
\82ð
\94ò
\82Ñ
\82Í
\82¶
\82ß
\82½
\81D");
3671 You("float down, but you are still %s.",
3672 is_animal(u.ustuck->data) ? "swallowed" : "engulfed");
3674 You("
\92\85\92n
\82µ
\82½
\82ª
\81C
\82Ü
\82¾
\88ù
\82Ý
\8d\9e\82Ü
\82ê
\82½
\82Ü
\82Ü
\82¾
\81D");
3679 if (Punished && !carried(uball)
3680 && (is_pool(uball->ox, uball->oy)
3681 || ((trap = t_at(uball->ox, uball->oy))
3682 && ((trap->ttyp == PIT) || (trap->ttyp == SPIKED_PIT)
3683 || (trap->ttyp == TRAPDOOR) || (trap->ttyp == HOLE))))) {
3688 movobj(uchain, uball->ox, uball->oy);
3689 newsym(u.ux0, u.uy0);
3690 vision_full_recalc = 1; /* in case the hero moved. */
3692 /* check for falling into pool - added by GAN 10/20/86 */
3694 if (!u.uswallow && u.ustuck) {
3695 if (sticks(youmonst.data))
3697 You("aren't able to maintain your hold on %s.",
3700 You("%s
\82ð
\82Â
\82©
\82Ü
\82¦
\91±
\82¯
\82Ä
\82¢
\82ç
\82ê
\82È
\82
\82È
\82Á
\82½
\81D",
3705 pline("Startled, %s can no longer hold you!",
3708 pline("%s
\82Í
\8bÁ
\82¢
\82Ä
\82 \82È
\82½
\82ð
\95ú
\82µ
\82Ä
\82µ
\82Ü
\82Á
\82½
\81I",
3714 * drown() and lava_effects() print various messages almost
3715 * every time they're called which conflict with the "fall
3716 * into" message below. Thus, we want to avoid printing
3717 * confusing, duplicate or out-of-order messages.
3718 * Use knowledge of the two routines as a hack -- this
3719 * should really be handled differently -dlc
3721 if (is_pool(u.ux, u.uy) && !Wwalking && !Swimming && !u.uinwater)
3724 if (is_lava(u.ux, u.uy)) {
3725 (void) lava_effects();
3730 trap = t_at(u.ux, u.uy);
3731 if (Is_airlevel(&u.uz)) {
3733 You("begin to tumble in place.");
3735 You("
\82»
\82Ì
\8fê
\82Å
\82Ð
\82Á
\82
\82è
\95Ô
\82è
\82Í
\82¶
\82ß
\82½
\81D");
3736 } else if (Is_waterlevel(&u.uz) && !no_msg) {
3738 You_feel("heavier.");
3740 You("
\8fd
\82
\82È
\82Á
\82½
\82æ
\82¤
\82È
\8bC
\82ª
\82µ
\82½
\81D");
3741 /* u.uinwater msgs already in spoteffects()/drown() */
3742 } else if (!u.uinwater && !no_msg) {
3743 if (!(emask & W_SADDLE)) {
3744 if (Sokoban && trap) {
3745 /* Justification elsewhere for Sokoban traps is based
3746 * on air currents. This is consistent with that.
3747 * The unexpected additional force of the air currents
3748 * once levitation ceases knocks you off your feet.
3752 pline("Bummer! You've crashed.");
3754 pline("
\82â
\82ß
\82Ä
\82¥
\81I
\82 \82È
\82½
\82Í
\92@
\82«
\82Â
\82¯
\82ç
\82ê
\82½
\81D");
3759 You("
\82Â
\82Ü
\82Ã
\82¢
\82½
\81D");
3761 losehp(rnd(2), "dangerous winds", KILLED_BY);
3763 losehp(rnd(2), "
\8aë
\8c¯
\82È
\95\97\82Å", KILLED_BY);
3765 dismount_steed(DISMOUNT_FELL);
3767 selftouch("As you fall, you");
3769 selftouch("
\97\8e\82¿
\82È
\82ª
\82ç
\81C
\82 \82È
\82½
\82Í");
3770 } else if (u.usteed && (is_floater(u.usteed->data)
3771 || is_flyer(u.usteed->data))) {
3773 You("settle more firmly in the saddle.");
3775 You("
\82æ
\82è
\82µ
\82Á
\82©
\82è
\82Æ
\88Æ
\82É
\94[
\82Ü
\82Á
\82½
\81D");
3776 } else if (Hallucination) {
3778 pline("Bummer! You've %s.",
3781 : "hit the ground");
3783 pline("
\82â
\82ß
\82Ä
\82¥
\81I
\82 \82È
\82½
\82Í%s
\82É
\92@
\82«
\82Â
\82¯
\82ç
\82ê
\82½
\81D",
3790 You("float gently to the %s.", surface(u.ux, u.uy));
3792 You("
\90Ã
\82©
\82É%s
\82Ü
\82Å
\92H
\82è
\82Â
\82¢
\82½
\81D", surface(u.ux, u.uy));
3798 /* can't rely on u.uz0 for detecting trap door-induced level change;
3799 it gets changed to reflect the new level before we can check it */
3800 assign_level(¤t_dungeon_level, &u.uz);
3802 switch (trap->ttyp) {
3807 if (!Can_fall_thru(&u.uz) || u.ustuck)
3811 if (!u.utrap) /* not already in the trap */
3815 if (!Is_airlevel(&u.uz) && !Is_waterlevel(&u.uz) && !u.uswallow
3816 /* falling through trap door calls goto_level,
3817 and goto_level does its own pickup() call */
3818 && on_level(&u.uz, ¤t_dungeon_level))
3823 /* shared code for climbing out of a pit */
3827 if (!u.utrap || u.utraptype != TT_PIT)
3831 /* marked as trapped so they can pick things up */
3833 You("ascend from the pit.");
3835 You("
\97\8e\82µ
\8c\8a\82ð
\8fã
\82Á
\82Ä
\82¢
\82Á
\82½
\81D");
3837 fill_pit(u.ux, u.uy);
3838 vision_full_recalc = 1; /* vision limits change */
3839 } else if (!rn2(2) && sobj_at(BOULDER, u.ux, u.uy)) {
3841 Your("%s gets stuck in a crevice.", body_part(LEG));
3843 Your("%s
\82Í
\8a\84\82ê
\96Ú
\82É
\82Í
\82Ü
\82Á
\82½
\81D", body_part(LEG));
3844 display_nhwindow(WIN_MESSAGE, FALSE);
3845 clear_nhwindow(WIN_MESSAGE);
3847 You("free your %s.", body_part(LEG));
3849 Your("%s
\82Í
\8e©
\97R
\82É
\82È
\82Á
\82½
\81D", body_part(LEG));
3850 } else if ((Flying || is_clinger(youmonst.data)) && !Sokoban) {
3851 /* eg fell in pit, then poly'd to a flying monster;
3852 or used '>' to deliberately enter it */
3854 You("%s from the pit.", Flying ? "fly" : "climb");
3856 You("
\97\8e\82µ
\8c\8a\82©
\82ç%s
\82¢
\82Á
\82½
\81D", Flying ? "
\8fã
\82Á
\82Ä" : "
\93o
\82Á
\82Ä");
3858 fill_pit(u.ux, u.uy);
3859 vision_full_recalc = 1; /* vision limits change */
3860 } else if (!(--u.utrap)) {
3862 You("%s to the edge of the pit.",
3863 (Sokoban && Levitation)
3864 ? "struggle against the air currents and float"
3865 : u.usteed ? "ride" : "crawl");
3867 You("%s
\97\8e\82µ
\8c\8a\82Ì
\92[
\82É
\82½
\82Ç
\82è
\92\85\82¢
\82½
\81D",
3868 (Sokoban && Levitation)
3869 ? "
\8bó
\8bC
\82Ì
\97¬
\82ê
\82Ì
\92\86\82Å
\82à
\82ª
\82«
\82È
\82ª
\82ç" : "");
3871 fill_pit(u.ux, u.uy);
3872 vision_full_recalc = 1; /* vision limits change */
3873 } else if (u.dz || flags.verbose) {
3876 Norep("%s is still in a pit.", upstart(y_monnam(u.usteed)));
3878 Norep("%s
\82Í
\82Ü
\82¾
\97\8e\82µ
\8c\8a\82Ì
\92\86\82É
\82¢
\82é
\81D", y_monnam(u.usteed));
3881 Norep((Hallucination && !rn2(5))
3882 ? "You've fallen, and you can't get up."
3883 : "You are still in a pit.");
3885 Norep((Hallucination && !rn2(5))
3886 ? "
\82 \82È
\82½
\82Í
\97\8e\82¿
\81C
\8fã
\82ª
\82ê
\82È
\82¢
\81D"
3887 : "
\82 \82È
\82½
\82Í
\82Ü
\82¾
\97\8e\82µ
\8c\8a\82Ì
\92\86\82É
\82¢
\82é
\81D");
3894 struct obj *box; /* null for floor trap */
3896 boolean see_it = !Blind;
3899 /* Bug: for box case, the equivalent of burn_floor_objects() ought
3900 * to be done upon its contents.
3903 if ((box && !carried(box)) ? is_pool(box->ox, box->oy) : Underwater) {
3905 pline("A cascade of steamy bubbles erupts from %s!",
3907 pline("
\8fö
\8bC
\82Ì
\96A
\82ª%s
\82©
\82ç
\82µ
\82ã
\81[
\82Á
\82Æ
\94
\90¶
\82µ
\82½
\81I",
3908 the(box ? xname(box) : surface(u.ux, u.uy)));
3909 if (Fire_resistance)
3911 You("are uninjured.");
3913 You("
\8f\9d\82Â
\82©
\82È
\82¢
\81D");
3916 losehp(rnd(3), "boiling water", KILLED_BY);
3918 losehp(rnd(3), "
\95¦
\93«
\82µ
\82½
\90\85\82Å", KILLED_BY);
3922 pline("A %s %s from %s!", tower_of_flame, box ? "bursts" : "erupts",
3923 the(box ? xname(box) : surface(u.ux, u.uy)));
3925 pline("
\89Î
\92\8c\82ª%s
\82©
\82ç%s
\81I", box ? xname(box) : surface(u.ux,u.uy),
3926 box ? "
\90\81\82«
\8fo
\82µ
\82½" : "
\97§
\82¿
\82Ì
\82Ú
\82Á
\82½");
3928 if (Fire_resistance) {
3929 shieldeff(u.ux, u.uy);
3931 } else if (Upolyd) {
3933 switch (u.umonnum) {
3934 case PM_PAPER_GOLEM:
3937 case PM_STRAW_GOLEM:
3943 case PM_LEATHER_GOLEM:
3952 if (u.mhmax > mons[u.umonnum].mlevel)
3953 u.mhmax -= rn2(min(u.mhmax, num + 1)), context.botl = 1;
3956 if (u.uhpmax > u.ulevel)
3957 u.uhpmax -= rn2(min(u.uhpmax, num + 1)), context.botl = 1;
3961 You("are uninjured.");
3963 You("
\8f\9d\82Â
\82©
\82È
\82¢
\81D");
3966 losehp(num, tower_of_flame, KILLED_BY_AN); /* fire damage */
3968 losehp(num, "
\89Î
\92\8c\82Å", KILLED_BY_AN); /* fire damage */
3972 if (burnarmor(&youmonst) || rn2(3)) {
3973 destroy_item(SCROLL_CLASS, AD_FIRE);
3974 destroy_item(SPBOOK_CLASS, AD_FIRE);
3975 destroy_item(POTION_CLASS, AD_FIRE);
3977 if (!box && burn_floor_objects(u.ux, u.uy, see_it, TRUE) && !see_it)
3979 You("smell paper burning.");
3981 You("
\8e\86\82Ì
\82±
\82°
\82é
\93õ
\82¢
\82ª
\82µ
\82½
\81D");
3982 if (is_ice(u.ux, u.uy))
3983 melt_ice(u.ux, u.uy, (char *) 0);
3989 register int fate = rnd(20);
3991 /* What happened to the poor sucker? */
3994 /* Most of the time, it creates some monsters. */
3995 register int cnt = rnd(4);
3997 if (!resists_blnd(&youmonst)) {
3999 You("are momentarily blinded by a flash of light!");
4001 You("
\82Ü
\82Î
\82ä
\82¢
\8cõ
\82Å
\88ê
\8fu
\96Ú
\82ª
\82
\82ç
\82ñ
\82¾
\81I");
4002 make_blinded((long) rn1(5, 10), FALSE);
4004 Your1(vision_clears);
4005 } else if (!Blind) {
4007 You_see("a flash of light!");
4009 You("
\82Ü
\82Î
\82ä
\82¢
\8cõ
\82ð
\97\81\82Ñ
\82½
\81I");
4012 You_hear("a deafening roar!");
4014 You_hear("
\8e¨
\82ð
\82Â
\82ñ
\82´
\82
\82æ
\82¤
\82È
\99ô
\9aK
\82ð
\95·
\82¢
\82½
\81I");
4015 incr_itimeout(&HDeaf, rn1(20, 30));
4017 (void) makemon((struct permonst *) 0, u.ux, u.uy, NO_MM_FLAGS);
4022 /* sometimes nothing happens */
4024 case 12: /* a flash of fire */
4025 dofiretrap((struct obj *) 0);
4031 pline("A shiver runs up and down your %s!", body_part(SPINE));
4033 pline("
\90k
\82¦
\82ª
\82 \82È
\82½
\82Ì%s
\82ð
\91\96\82Á
\82½
\81I", body_part(SPINE));
4037 You_hear(Hallucination ? "the moon howling at you."
4038 : "distant howling.");
4040 You_hear(Hallucination ? "
\8c\8e\82ª
\96i
\82¦
\82Ä
\82¢
\82é
\82Ì
\82ð
\95·
\82¢
\82½
\81D"
4041 : "
\89\93\95û
\82Ì
\89\93\96i
\82ð
\95·
\82¢
\82½
\81D");
4045 if (on_level(&u.uz, &qstart_level))
4048 "%slike the prodigal son.",
4049 (flags.female || (Upolyd && is_neuter(youmonst.data)))
4052 #else /*JP
\90¹
\8f\91\82Ì
\83\8b\83J
\93`
\82æ
\82è */
4053 You("%s
\95ú
\93 \91§
\8eq
\82Ì
\82æ
\82¤
\82É
\82È
\82Á
\82½
\82æ
\82¤
\82È
\8bC
\82ª
\82µ
\82½
\81D",
4054 (flags.female || (Upolyd && is_neuter(youmonst.data)))
4060 You("suddenly yearn for %s.",
4063 : (In_quest(&u.uz) || at_dgn_entrance("The Quest"))
4064 ? "your nearby homeland"
4065 : "your distant homeland");
4067 You("
\93Ë
\91R%s
\82ª
\97ö
\82µ
\82
\82È
\82Á
\82½
\81D",
4068 Hallucination ? "
\90Â
\90X"
4069 : (In_quest(&u.uz) || at_dgn_entrance("
\83N
\83G
\83X
\83g"))
4070 ? "
\82·
\82®
\82»
\82±
\82É
\82 \82é
\8cÌ
\8b½"
4071 : "
\82Í
\82é
\82©
\82©
\82È
\82½
\82Ì
\8cÌ
\8b½");
4076 Your("pack shakes violently!");
4078 Your("
\91Ü
\82Í
\8c\83\82µ
\82
\97h
\82ê
\82½
\81I");
4082 You(Hallucination ? "smell hamburgers." : "smell charred flesh.");
4084 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");
4090 You("
\94æ
\82ê
\82ð
\8a´
\82¶
\82½
\81D");
4093 /* very occasionally something nice happens. */
4094 case 19: { /* tame nearby monsters */
4098 (void) adjattrib(A_CHA, 1, FALSE);
4099 for (i = -1; i <= 1; i++)
4100 for (j = -1; j <= 1; j++) {
4101 if (!isok(u.ux + i, u.uy + j))
4103 mtmp = m_at(u.ux + i, u.uy + j);
4105 (void) tamedog(mtmp, (struct obj *) 0);
4109 case 20: { /* uncurse stuff */
4111 long save_conf = HConfusion;
4113 pseudo = zeroobj; /* neither cursed nor blessed,
4114 and zero out oextra */
4115 pseudo.otyp = SCR_REMOVE_CURSE;
4117 (void) seffects(&pseudo);
4118 HConfusion = save_conf;
4126 /* Set an item on fire.
4127 * "force" means not to roll a luck-based protection check for the
4129 * "x" and "y" are the coordinates to dump the contents of a
4130 * container, if it burns up.
4132 * Return whether the object was destroyed.
4135 fire_damage(obj, force, x, y)
4141 struct obj *otmp, *ncobj;
4142 int in_sight = !Blind && couldsee(x, y); /* Don't care if it's lit */
4145 /* object might light in a controlled manner */
4149 if (Is_container(obj)) {
4150 switch (obj->otyp) {
4152 return FALSE; /* Immune */
4163 if ((!force && (Luck + 5) > rn2(chance))
4164 || (is_flammable(obj) && obj->oerodeproof))
4166 /* Container is burnt up - dump contents out */
4169 pline("%s catches fire and burns.", Yname2(obj));
4171 pline("%s
\82Í
\89Î
\82ª
\82Â
\82¢
\82Ä
\94R
\82¦
\82½
\81D", Yname2(obj));
4172 if (Has_contents(obj)) {
4175 pline("Its contents fall out.");
4177 pline("
\92\86\90g
\82ª
\8fo
\82Ä
\82«
\82½
\81D");
4178 for (otmp = obj->cobj; otmp; otmp = ncobj) {
4180 obj_extract_self(otmp);
4181 if (!flooreffects(otmp, x, y, ""))
4182 place_object(otmp, x, y);
4188 } else if (!force && (Luck + 5) > rn2(20)) {
4189 /* chance per item of sustaining damage:
4190 * max luck (Luck==13): 10%
4191 * avg luck (Luck==0): 75%
4192 * awful luck (Luck<-4): 100%
4195 } else if (obj->oclass == SCROLL_CLASS || obj->oclass == SPBOOK_CLASS) {
4196 if (obj->otyp == SCR_FIRE || obj->otyp == SPE_FIREBALL)
4198 if (obj->otyp == SPE_BOOK_OF_THE_DEAD) {
4201 pline("Smoke rises from %s.", the(xname(obj)));
4203 pline("%s
\82©
\82ç
\89\8c\82ª
\82 \82ª
\82Á
\82½
\81D", the(xname(obj)));
4206 dindx = (obj->oclass == SCROLL_CLASS) ? 3 : 4;
4209 pline("%s %s.", Yname2(obj),
4210 destroy_strings[dindx][(obj->quan > 1L)]);
4212 pline("%s
\82Í%s
\81D", Yname2(obj),
4213 destroy_strings[dindx][(obj->quan > 1L)]);
4218 } else if (obj->oclass == POTION_CLASS) {
4219 dindx = (obj->otyp != POT_OIL) ? 1 : 2;
4222 pline("%s %s.", Yname2(obj),
4223 destroy_strings[dindx][(obj->quan > 1L)]);
4225 pline("%s
\82Í%s
\81D", Yname2(obj),
4226 destroy_strings[dindx][(obj->quan > 1L)]);
4231 } else if (erode_obj(obj, (char *) 0, ERODE_BURN, EF_DESTROY)
4239 * Apply fire_damage() to an entire chain.
4241 * Return number of objects destroyed. --ALI
4244 fire_damage_chain(chain, force, here, x, y)
4246 boolean force, here;
4249 struct obj *obj, *nobj;
4251 for (obj = chain; obj; obj = nobj) {
4252 nobj = here ? obj->nexthere : obj->nobj;
4253 if (fire_damage(obj, force, x, y))
4257 if (num && (Blind && !couldsee(x, y)))
4259 You("smell smoke.");
4261 You("
\89\8c\82Ì
\82É
\82¨
\82¢
\82ª
\82µ
\82½
\81D");
4269 /* Scrolls but not spellbooks can be erased by acid. */
4270 struct monst *victim;
4276 victim = carried(obj) ? &youmonst : mcarried(obj) ? obj->ocarry : NULL;
4277 vismon = victim && (victim != &youmonst) && canseemon(victim);
4280 grease_protect(obj, (char *) 0, victim);
4281 } else if (obj->oclass == SCROLL_CLASS && obj->otyp != SCR_BLANK_PAPER) {
4282 if (obj->otyp != SCR_BLANK_PAPER
4284 && obj->otyp != SCR_MAIL
4288 if (victim == &youmonst)
4290 pline("Your %s.", aobjnam(obj, "fade"));
4292 pline("%s
\82Ì
\95¶
\8e\9a\82Í
\94\96\82ê
\82½
\81D", xname(obj));
4295 pline("%s %s.", s_suffix(Monnam(victim)),
4296 aobjnam(obj, "fade"));
4298 pline("%s
\82Ì%s
\82Ì
\95¶
\8e\9a\82Í
\94\96\82ê
\82½
\81D", Monnam(victim),
4303 obj->otyp = SCR_BLANK_PAPER;
4307 erode_obj(obj, (char *) 0, ERODE_CORRODE, EF_GREASE | EF_VERBOSE);
4310 /* context for water_damage(), managed by water_damage_chain();
4311 when more than one stack of potions of acid explode while processing
4312 a chain of objects, use alternate phrasing after the first message */
4313 static struct h2o_ctx {
4314 int dkn_boom, unk_boom; /* track dknown, !dknown separately */
4316 } acid_ctx = { 0, 0, FALSE };
4318 /* Get an object wet and damage it appropriately.
4319 * "ostr", if present, is used instead of the object name in some
4321 * "force" means not to roll luck to protect some objects.
4322 * Returns an erosion return value (ER_*)
4325 water_damage(obj, ostr, force)
4339 if (obj->otyp == CAN_OF_GREASE && obj->spe > 0) {
4341 } else if (obj->otyp == TOWEL && obj->spe < 7) {
4342 wet_a_towel(obj, rnd(7), TRUE);
4344 } else if (obj->greased) {
4350 } else if (Is_container(obj) && !Is_box(obj)
4351 && (obj->otyp != OILSKIN_SACK || (obj->cursed && !rn2(3)))) {
4354 pline("Water gets into your %s!", ostr);
4356 pline("
\90\85\82ª%s
\82Ì
\92\86\82É
\93ü
\82Á
\82½
\81I", ostr);
4358 water_damage_chain(obj->cobj, FALSE);
4360 } else if (!force && (Luck + 5) > rn2(20)) {
4361 /* chance per item of sustaining damage:
4363 * avg luck (Luck==0): 75%
4364 * awful luck (Luck<-4): 100%
4367 } else if (obj->oclass == SCROLL_CLASS) {
4369 if (obj->otyp == SCR_MAIL)
4374 pline("Your %s %s.", ostr, vtense(ostr, "fade"));
4376 pline("%s
\82Ì
\95¶
\8e\9a\82Í
\94\96\82ê
\82½
\81D", ostr);
4378 obj->otyp = SCR_BLANK_PAPER;
4384 } else if (obj->oclass == SPBOOK_CLASS) {
4385 if (obj->otyp == SPE_BOOK_OF_THE_DEAD) {
4387 pline("Steam rises from %s.", the(xname(obj)));
4389 pline("
\8fö
\8bC
\82ª%s
\82©
\82ç
\97§
\82¿
\82Ì
\82Ú
\82Á
\82½
\81D", xname(obj));
4395 pline("Your %s %s.", ostr, vtense(ostr, "fade"));
4397 pline("%s
\82Ì
\95¶
\8e\9a\82Í
\94\96\82ê
\82½
\81D", ostr);
4399 if (obj->otyp == SPE_NOVEL) {
4404 obj->otyp = SPE_BLANK_PAPER;
4409 } else if (obj->oclass == POTION_CLASS) {
4410 if (obj->otyp == POT_ACID) {
4412 boolean one = (obj->quan == 1L), update = carried(obj),
4415 if (Blind && !carried(obj))
4417 if (acid_ctx.ctx_valid)
4418 exploded = ((obj->dknown ? acid_ctx.dkn_boom
4419 : acid_ctx.unk_boom) > 0);
4421 * "a [potion|<color> potion|potion of acid] explodes"
4422 * depending on obj->dknown (potion has been seen) and
4423 * objects[POT_ACID].oc_name_known (fully discovered),
4424 * or "some {plural version} explode" when relevant.
4425 * Second and subsequent messages for same chain and
4426 * matching dknown status are
4427 * "another [potion|<color> &c] explodes" or plural
4430 bufp = simpleonames(obj);
4432 pline("%s %s %s!", /* "A potion explodes!" */
4433 !exploded ? (one ? "A" : "Some")
4434 : (one ? "Another" : "More"),
4435 bufp, vtense(bufp, "explode"));
4437 pline("%s
\82Í
\94\9a\94
\82µ
\82½
\81I", bufp);
4439 if (acid_ctx.ctx_valid) {
4441 acid_ctx.dkn_boom++;
4443 acid_ctx.unk_boom++;
4449 return ER_DESTROYED;
4450 } else if (obj->odiluted) {
4453 pline("Your %s %s further.", ostr, vtense(ostr, "dilute"));
4455 pline("%s
\82Í
\82³
\82ç
\82É
\94\96\82Ü
\82Á
\82½
\81D", ostr);
4457 obj->otyp = POT_WATER;
4459 obj->blessed = obj->cursed = 0;
4464 } else if (obj->otyp != POT_WATER) {
4467 pline("Your %s %s.", ostr, vtense(ostr, "dilute"));
4469 pline("%s
\82Í
\94\96\82Ü
\82Á
\82½
\81D", ostr);
4477 return erode_obj(obj, ostr, ERODE_RUST, EF_NONE);
4483 water_damage_chain(obj, here)
4489 /* initialize acid context: so far, neither seen (dknown) potions of
4490 acid nor unseen have exploded during this water damage sequence */
4491 acid_ctx.dkn_boom = acid_ctx.unk_boom = 0;
4492 acid_ctx.ctx_valid = TRUE;
4494 for (; obj; obj = otmp) {
4495 otmp = here ? obj->nexthere : obj->nobj;
4496 water_damage(obj, (char *) 0, FALSE);
4499 /* reset acid context */
4500 acid_ctx.dkn_boom = acid_ctx.unk_boom = 0;
4501 acid_ctx.ctx_valid = FALSE;
4505 * This function is potentially expensive - rolling
4506 * inventory list multiple times. Luckily it's seldom needed.
4507 * Returns TRUE if disrobing made player unencumbered enough to
4508 * crawl out of the current predicament.
4511 emergency_disrobe(lostsome)
4514 int invc = inv_cnt(TRUE);
4516 while (near_capacity() > (Punished ? UNENCUMBERED : SLT_ENCUMBER)) {
4517 register struct obj *obj, *otmp = (struct obj *) 0;
4520 /* Pick a random object */
4523 for (obj = invent; obj; obj = obj->nobj) {
4525 * Undroppables are: body armor, boots, gloves,
4526 * amulets, and rings because of the time and effort
4527 * in removing them + loadstone and other cursed stuff
4528 * for obvious reasons.
4530 if (!((obj->otyp == LOADSTONE && obj->cursed) || obj == uamul
4531 || obj == uleft || obj == uright || obj == ublindf
4532 || obj == uarm || obj == uarmc || obj == uarmg
4533 || obj == uarmf || obj == uarmu
4534 || (obj->cursed && (obj == uarmh || obj == uarms))
4537 /* reached the mark and found some stuff to drop? */
4538 if (--i < 0 && otmp)
4545 return FALSE; /* nothing to drop! */
4546 if (otmp->owornmask)
4547 remove_worn_item(otmp, FALSE);
4556 /* return TRUE iff player relocated */
4560 const char *pool_of_water;
4561 boolean inpool_ok = FALSE, crawl_ok;
4564 /* happily wading in the same contiguous pool */
4565 if (u.uinwater && is_pool(u.ux - u.dx, u.uy - u.dy)
4566 && (Swimming || Amphibious)) {
4567 /* water effects on objects every now and then */
4576 You("%s into the water%c", Is_waterlevel(&u.uz) ? "plunge" : "fall",
4577 Amphibious || Swimming ? '.' : '!');
4579 You("
\90\85\82Ì
\92\86\82É%s%s", Is_waterlevel(&u.uz) ? "
\94ò
\82Ñ
\82±
\82ñ
\82¾" : "
\97\8e\82¿
\82½",
4580 Amphibious || Swimming ? "
\81D" : "
\81I");
4582 if (!Swimming && !Is_waterlevel(&u.uz))
4584 You("sink like %s.", Hallucination ? "the Titanic" : "a rock");
4586 You("%s
\82Ì
\82æ
\82¤
\82É
\92¾
\82ñ
\82¾
\81D", Hallucination ? "
\83^
\83C
\83^
\83j
\83b
\83N
\8d\86" : "
\8aâ");
4589 water_damage_chain(invent, FALSE);
4591 if (u.umonnum == PM_GREMLIN && rn2(3))
4592 (void) split_mon(&youmonst, (struct monst *) 0);
4593 else if (u.umonnum == PM_IRON_GOLEM) {
4597 You("
\8eK
\82Ñ
\82½
\81I");
4598 i = Maybe_Half_Phys(d(2, 6));
4602 losehp(i, "rusting away", KILLED_BY);
4604 losehp(i, "
\8a®
\91S
\82É
\8eK
\82Ñ
\82Ä", KILLED_BY);
4609 if ((i = number_leashed()) > 0) {
4611 pline_The("leash%s slip%s loose.", (i > 1) ? "es" : "",
4612 (i > 1) ? "" : "s");
4614 pline("
\95R
\82ª
\82ä
\82é
\82ñ
\82¾
\81D");
4619 if (Amphibious || Swimming) {
4623 pline("But you aren't drowning.");
4625 pline("
\82µ
\82©
\82µ
\81C
\82 \82È
\82½
\82Í
\93M
\82ê
\82È
\82©
\82Á
\82½
\81D");
4626 if (!Is_waterlevel(&u.uz)) {
4629 Your("keel hits the bottom.");
4631 You("
\92ê
\82É
\83j
\81[
\83h
\83\8d\83b
\83v
\82ð
\8c\88\82ß
\82½
\81D");
4634 You("touch bottom.");
4636 You("
\92ê
\82É
\82Â
\82¢
\82½
\81D");
4643 vision_recalc(2); /* unsee old position */
4646 vision_full_recalc = 1;
4649 if ((Teleportation || can_teleport(youmonst.data)) && !Unaware
4650 && (Teleport_control || rn2(3) < Luck + 2)) {
4652 You("attempt a teleport spell."); /* utcsri!carroll */
4654 You("
\8fu
\8aÔ
\88Ú
\93®
\82Ì
\8eô
\95¶
\82ð
\8f¥
\82¦
\82Ä
\82Ý
\82½
\81D");
4656 if (!level.flags.noteleport) {
4658 if (!is_pool(u.ux, u.uy))
4662 pline_The("attempted teleport spell fails.");
4664 pline("
\8fu
\8aÔ
\88Ú
\93®
\82Ì
\8eô
\95¶
\82Í
\8e¸
\94s
\82µ
\82½
\81D");
4667 dismount_steed(DISMOUNT_GENERIC);
4668 if (!is_pool(u.ux, u.uy))
4672 x = y = 0; /* lint suppression */
4673 /* if sleeping, wake up now so that we don't crawl out of water
4674 while still asleep; we can't do that the same way that waking
4675 due to combat is handled; note unmul() clears u.usleep */
4678 unmul("Suddenly you wake up!");
4680 unmul("
\93Ë
\91R
\82 \82È
\82½
\82Í
\96Ú
\82ª
\8ao
\82ß
\82½
\81I");
4681 /* being doused will revive from fainting */
4684 /* can't crawl if unable to move (crawl_ok flag stays false) */
4685 if (multi < 0 || (Upolyd && !youmonst.data->mmove))
4687 /* look around for a place to crawl to */
4688 for (i = 0; i < 100; i++) {
4689 x = rn1(3, u.ux - 1);
4690 y = rn1(3, u.uy - 1);
4691 if (crawl_destination(x, y)) {
4697 for (x = u.ux - 1; x <= u.ux + 1; x++)
4698 for (y = u.uy - 1; y <= u.uy + 1; y++)
4699 if (crawl_destination(x, y)) {
4705 boolean lost = FALSE;
4706 /* time to do some strip-tease... */
4707 boolean succ = Is_waterlevel(&u.uz) ? TRUE : emergency_disrobe(&lost);
4710 You("try to crawl out of the water.");
4712 You("
\90\85\82©
\82ç
\82Í
\82¢
\82 \82ª
\82ë
\82¤
\82Æ
\82µ
\82½
\81D");
4715 You("dump some of your gear to lose weight...");
4717 You("
\91Ì
\82ð
\8cy
\82
\82·
\82é
\82½
\82ß
\82¢
\82
\82Â
\82©
\95¨
\82ð
\93\8a\82°
\82·
\82Ä
\82½
\81D
\81D
\81D");
4720 pline("Pheew! That was close.");
4722 pline("
\83n
\83@
\83n
\83@
\81I
\82 \82Ô
\82È
\82©
\82Á
\82½
\81D");
4726 /* still too much weight */
4728 pline("But in vain.");
4730 pline("
\82ª
\81C
\96³
\91Ê
\82¾
\82Á
\82½
\81D");
4736 You("
\93M
\82ê
\82½
\81D");
4737 for (i = 0; i < 5; i++) { /* arbitrary number of loops */
4738 /* killer format and name are reconstructed every iteration
4739 because lifesaving resets them */
4740 pool_of_water = waterbody_name(u.ux, u.uy);
4741 killer.format = KILLED_BY_AN;
4743 /* avoid "drowned in [a] water" */
4744 if (!strcmp(pool_of_water, "water"))
4745 pool_of_water = "deep water", killer.format = KILLED_BY;
4747 Strcpy(killer.name, pool_of_water);
4749 /* oops, we're still alive. better get out of the water. */
4750 if (safe_teleds(TRUE))
4751 break; /* successful life-save */
4752 /* nowhere safe to land; repeat drowning loop... */
4754 pline("You're still drowning.");
4756 You("
\82Ü
\82¾
\93M
\82ê
\82Ä
\82¢
\82é
\81D");
4761 You("find yourself back %s.",
4762 Is_waterlevel(&u.uz) ? "in an air bubble" : "on land");
4764 You("
\82¢
\82Â
\82Ì
\82Ü
\82É
\82©%s
\82É
\82¢
\82é
\82Ì
\82É
\8bC
\82ª
\82Â
\82¢
\82½
\81D",
4765 Is_waterlevel(&u.uz) ? "
\8bó
\8bC
\82Ì
\96A
\82Ì
\92\86" : "
\92n
\96Ê");
4776 /* energy is completely gone */
4778 You_feel("momentarily lethargic.");
4780 You("
\88ê
\8fu
\96³
\8bC
\97Í
\8a´
\82ð
\8a´
\82¶
\82½
\81D");
4782 /* throttle further loss a bit when there's not much left to lose */
4783 if (n > u.uenmax || n > u.ulevel)
4787 You_feel("your magical energy drain away%c", (n > u.uen) ? '!' : '.');
4789 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");
4792 u.uenmax -= rnd(-u.uen);
4805 if (near_capacity() >= HVY_ENCUMBER) {
4807 pline("You're too strained to do that.");
4809 pline("ã©
\82ð
\89ð
\8f\9c\82µ
\82æ
\82¤
\82É
\82à
\95¨
\82ð
\8e\9d\82¿
\82·
\82¬
\82Ä
\82¢
\82é
\81D");
4812 if ((nohands(youmonst.data) && !webmaker(youmonst.data))
4813 || !youmonst.data->mmove) {
4815 pline("And just how do you expect to do that?");
4817 pline("
\82¢
\82Á
\82½
\82¢
\89½
\82ð
\8aú
\91Ò
\82µ
\82Ä
\82¢
\82é
\82ñ
\82¾
\82¢
\81H");
4819 } else if (u.ustuck && sticks(youmonst.data)) {
4821 pline("You'll have to let go of %s first.", mon_nam(u.ustuck));
4823 pline("%s
\82ð
\8eè
\97£
\82³
\82È
\82¢
\82±
\82Æ
\82É
\82Í
\82Å
\82«
\82È
\82¢
\81D", mon_nam(u.ustuck));
4826 if (u.ustuck || (welded(uwep) && bimanual(uwep))) {
4828 Your("%s seem to be too busy for that.", makeplural(body_part(HAND)));
4830 Your("
\82»
\82ñ
\82È
\82±
\82Æ
\82ð
\82·
\82é
\97]
\97T
\82È
\82ñ
\82Ä
\82È
\82¢
\81D");
4833 return untrap(FALSE);
4836 /* Probability of disabling a trap. Helge Hafting */
4843 /* Only spiders know how to deal with webs reliably */
4844 if (ttmp->ttyp == WEB && !webmaker(youmonst.data))
4846 if (Confusion || Hallucination)
4854 /* Your own traps are better known than others. */
4855 if (ttmp && ttmp->madeby_u)
4857 if (Role_if(PM_ROGUE)) {
4858 if (rn2(2 * MAXULEV) < u.ulevel)
4860 if (u.uhave.questart && chance > 1)
4862 } else if (Role_if(PM_RANGER) && chance > 1)
4867 /* Replace trap with object(s). Helge Hafting */
4869 cnv_trap_obj(otyp, cnt, ttmp, bury_it)
4875 struct obj *otmp = mksobj(otyp, TRUE, FALSE);
4878 otmp->owt = weight(otmp);
4879 /* Only dart traps are capable of being poisonous */
4881 otmp->opoisoned = 0;
4882 place_object(otmp, ttmp->tx, ttmp->ty);
4884 /* magical digging first disarms this trap, then will unearth it */
4885 (void) bury_an_obj(otmp, (boolean *) 0);
4887 /* Sell your own traps only... */
4889 sellobj(otmp, ttmp->tx, ttmp->ty);
4892 newsym(ttmp->tx, ttmp->ty);
4893 if (u.utrap && ttmp->tx == u.ux && ttmp->ty == u.uy)
4898 /* while attempting to disarm an adjacent trap, we've fallen into it */
4900 move_into_trap(ttmp)
4904 xchar x = ttmp->tx, y = ttmp->ty, bx, by, cx, cy;
4907 bx = by = cx = cy = 0; /* lint suppression */
4908 /* we know there's no monster in the way, and we're not trapped */
4910 || drag_ball(x, y, &bc, &bx, &by, &cx, &cy, &unused, TRUE)) {
4911 u.ux0 = u.ux, u.uy0 = u.uy;
4914 newsym(u.ux0, u.uy0);
4916 check_leash(u.ux0, u.uy0);
4918 move_bc(0, bc, bx, by, cx, cy);
4919 /* marking the trap unseen forces dotrap() to treat it like a new
4920 discovery and prevents pickup() -> look_here() -> check_here()
4921 from giving a redundant "there is a <trap> here" message when
4922 there are objects covering this trap */
4923 ttmp->tseen = 0; /* hack for check_here() */
4924 /* trigger the trap */
4925 spoteffects(TRUE); /* pickup() + dotrap() */
4926 exercise(A_WIS, FALSE);
4930 /* 0: doesn't even try
4931 * 1: tries and fails
4935 try_disarm(ttmp, force_failure)
4937 boolean force_failure;
4939 struct monst *mtmp = m_at(ttmp->tx, ttmp->ty);
4940 int ttype = ttmp->ttyp;
4941 boolean under_u = (!u.dx && !u.dy);
4942 boolean holdingtrap = (ttype == BEAR_TRAP || ttype == WEB);
4944 /* Test for monster first, monsters are displayed instead of trap. */
4945 if (mtmp && (!mtmp->mtrapped || !holdingtrap)) {
4947 pline("%s is in the way.", Monnam(mtmp));
4949 pline("
\82»
\82±
\82É
\82Í%s
\82ª
\82¢
\82é
\81D", Monnam(mtmp));
4952 /* We might be forced to move onto the trap's location. */
4953 if (sobj_at(BOULDER, ttmp->tx, ttmp->ty) && !Passes_walls && !under_u) {
4955 There("is a boulder in your way.");
4957 pline("
\82»
\82±
\82É
\82Í
\8aâ
\82ª
\82 \82é
\81D");
4960 /* duplicate tight-space checks from test_move */
4961 if (u.dx && u.dy && bad_rock(youmonst.data, u.ux, ttmp->ty)
4962 && bad_rock(youmonst.data, ttmp->tx, u.uy)) {
4963 if ((invent && (inv_weight() + weight_cap() > 600))
4964 || bigmonst(youmonst.data)) {
4965 /* don't allow untrap if they can't get thru to it */
4967 You("are unable to reach the %s!",
4968 defsyms[trap_to_defsym(ttype)].explanation);
4970 You("%s
\82É
\93Í
\82©
\82È
\82¢
\81I",
4971 defsyms[trap_to_defsym(ttype)].explanation);
4976 /* untrappable traps are located on the ground. */
4977 if (!can_reach_floor(TRUE)) {
4978 if (u.usteed && P_SKILL(P_RIDING) < P_BASIC)
4982 You("are unable to reach the %s!",
4983 defsyms[trap_to_defsym(ttype)].explanation);
4985 You("%s
\82É
\93Í
\82©
\82È
\82¢
\81I",
4986 defsyms[trap_to_defsym(ttype)].explanation);
4991 /* Will our hero succeed? */
4992 if (force_failure || untrap_prob(ttmp)) {
4997 pline("
\82¤
\82í
\82Á
\81D
\81D
\81D");
4998 if (mtmp) { /* must be a trap that holds monsters */
4999 if (ttype == BEAR_TRAP) {
5002 if ((mtmp->mhp -= rnd(4)) <= 0)
5004 } else if (ttype == WEB) {
5005 if (!webmaker(youmonst.data)) {
5006 struct trap *ttmp2 = maketrap(u.ux, u.uy, WEB);
5011 "webbing sticks to you. You're caught too!");
5013 "
\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");
5014 dotrap(ttmp2, NOWEBMSG);
5015 if (u.usteed && u.utrap) {
5016 /* you, not steed, are trapped */
5017 dismount_steed(DISMOUNT_FELL);
5022 pline("%s remains entangled.", Monnam(mtmp));
5024 pline("%s
\82Í
\82©
\82ç
\82Ü
\82Á
\82½
\82Ü
\82Ü
\82¾
\81D", Monnam(mtmp));
5026 } else if (under_u) {
5029 move_into_trap(ttmp);
5033 pline("%s %s is difficult to %s.",
5034 ttmp->madeby_u ? "Your" : under_u ? "This" : "That",
5035 defsyms[trap_to_defsym(ttype)].explanation,
5036 (ttype == WEB) ? "remove" : "disarm");
5038 pline("%s%s
\82ð
\89ð
\8f\9c\82·
\82é
\82Ì
\82Í
\8d¢
\93ï
\82¾
\81D",
5039 ttmp->madeby_u ? "
\82 \82È
\82½
\82Ì
\8ed
\8a|
\82¯
\82½" : under_u ? "
\82±
\82Ì" : "
\82»
\82Ì",
5040 defsyms[trap_to_defsym(ttype)].explanation);
5049 reward_untrap(ttmp, mtmp)
5053 if (!ttmp->madeby_u) {
5054 if (rnl(10) < 8 && !mtmp->mpeaceful && !mtmp->msleeping
5055 && !mtmp->mfrozen && !mindless(mtmp->data)
5056 && mtmp->data->mlet != S_HUMAN) {
5057 mtmp->mpeaceful = 1;
5058 set_malign(mtmp); /* reset alignment */
5060 pline("%s is grateful.", Monnam(mtmp));
5062 pline("%s
\82Í
\8aì
\82ñ
\82Å
\82¢
\82é
\81D", Monnam(mtmp));
5064 /* Helping someone out of a trap is a nice thing to do,
5065 * A lawful may be rewarded, but not too often. */
5066 if (!rn2(3) && !rnl(8) && u.ualign.type == A_LAWFUL) {
5069 You_feel("that you did the right thing.");
5071 You("
\90³
\82µ
\82¢
\82±
\82Æ
\82ð
\82µ
\82½
\82æ
\82¤
\82È
\8bC
\82ª
\82µ
\82½
\81D");
5077 disarm_holdingtrap(ttmp) /* Helge Hafting */
5081 int fails = try_disarm(ttmp, FALSE);
5086 /* ok, disarm it. */
5088 /* untrap the monster, if any.
5089 There's no need for a cockatrice test, only the trap is touched */
5090 if ((mtmp = m_at(ttmp->tx, ttmp->ty)) != 0) {
5093 You("remove %s %s from %s.", the_your[ttmp->madeby_u],
5094 (ttmp->ttyp == BEAR_TRAP) ? "bear trap" : "webbing",
5097 You("%s%s
\82ð%s
\82©
\82ç
\82Í
\82¸
\82µ
\82½
\81D", set_you[ttmp->madeby_u],
5098 (ttmp->ttyp == BEAR_TRAP) ? "
\8cF
\82Ìã©" : "
\82
\82à
\82Ì
\91\83",
5101 reward_untrap(ttmp, mtmp);
5103 if (ttmp->ttyp == BEAR_TRAP) {
5105 You("disarm %s bear trap.", the_your[ttmp->madeby_u]);
5107 You("%s
\8cF
\82Ìã©
\82ð
\89ð
\8f\9c\82µ
\82½
\81D", set_you[ttmp->madeby_u]);
5108 cnv_trap_obj(BEARTRAP, 1, ttmp, FALSE);
5109 } else /* if (ttmp->ttyp == WEB) */ {
5111 You("succeed in removing %s web.", the_your[ttmp->madeby_u]);
5113 You("%s
\82
\82à
\82Ì
\91\83\82ð
\8eæ
\82è
\8f\9c\82¢
\82½
\81D", set_you[ttmp->madeby_u]);
5117 newsym(u.ux + u.dx, u.uy + u.dy);
5122 disarm_landmine(ttmp) /* Helge Hafting */
5125 int fails = try_disarm(ttmp, FALSE);
5130 You("disarm %s land mine.", the_your[ttmp->madeby_u]);
5132 You("%s
\92n
\97\8b\82ð
\89ð
\8f\9c\82µ
\82½
\81D", set_you[ttmp->madeby_u]);
5133 cnv_trap_obj(LAND_MINE, 1, ttmp, FALSE);
5137 /* getobj will filter down to cans of grease and known potions of oil */
5138 static NEARDATA const char oil[] = { ALL_CLASSES, TOOL_CLASS, POTION_CLASS,
5141 /* it may not make much sense to use grease on floor boards, but so what? */
5143 disarm_squeaky_board(ttmp)
5150 obj = getobj(oil, "untrap with");
5154 bad_tool = (obj->cursed
5155 || ((obj->otyp != POT_OIL || obj->lamplit)
5156 && (obj->otyp != CAN_OF_GREASE || !obj->spe)));
5157 fails = try_disarm(ttmp, bad_tool);
5161 /* successfully used oil or grease to fix squeaky board */
5162 if (obj->otyp == CAN_OF_GREASE) {
5163 consume_obj_charge(obj, TRUE);
5165 useup(obj); /* oil */
5169 You("repair the squeaky board."); /* no madeby_u */
5171 You("
\82«
\82µ
\82Þ
\94Â
\82ð
\8fC
\97\9d\82µ
\82½
\81D"); /* no madeby_u */
5174 newsym(u.ux + u.dx, u.uy + u.dy);
5175 more_experienced(1, 5);
5180 /* removes traps that shoot arrows, darts, etc. */
5182 disarm_shooting_trap(ttmp, otyp)
5186 int fails = try_disarm(ttmp, FALSE);
5191 You("disarm %s trap.", the_your[ttmp->madeby_u]);
5193 pline("%sã©
\82ð
\89ð
\8f\9c\82µ
\82½
\81D", set_you[ttmp->madeby_u]);
5194 cnv_trap_obj(otyp, 50 - rnl(50), ttmp, FALSE);
5198 /* Is the weight too heavy?
5199 * Formula as in near_capacity() & check_capacity() */
5201 try_lift(mtmp, ttmp, wt, stuff)
5207 int wc = weight_cap();
5209 if (((wt * 2) / wc) >= HVY_ENCUMBER) {
5211 pline("%s is %s for you to lift.", Monnam(mtmp),
5212 stuff ? "carrying too much" : "too heavy");
5214 pline("%s
\82Í%s
\8e\9d\82¿
\82 \82°
\82é
\82±
\82Æ
\82ª
\82Å
\82«
\82È
\82¢
\81D", Monnam(mtmp),
5215 stuff ? "
\95¨
\82ð
\8e\9d\82¿
\82·
\82¬
\82Ä
\82¨
\82è" : "
\8fd
\82·
\82¬
\82Ä");
5217 if (!ttmp->madeby_u && !mtmp->mpeaceful && mtmp->mcanmove
5218 && !mindless(mtmp->data) && mtmp->data->mlet != S_HUMAN
5220 mtmp->mpeaceful = 1;
5221 set_malign(mtmp); /* reset alignment */
5223 pline("%s thinks it was nice of you to try.", Monnam(mtmp));
5225 pline("%s
\82Í
\82 \82È
\82½
\82Ì
\93w
\97Í
\82É
\8a´
\8eÓ
\82µ
\82Ä
\82¢
\82é
\82æ
\82¤
\82¾
\81D", Monnam(mtmp));
5232 /* Help trapped monster (out of a (spiked) pit) */
5234 help_monster_out(mtmp, ttmp)
5243 * This works when levitating too -- consistent with the ability
5244 * to hit monsters while levitating.
5246 * Should perhaps check that our hero has arms/hands at the
5247 * moment. Helping can also be done by engulfing...
5249 * Test the monster first - monsters are displayed before traps.
5251 if (!mtmp->mtrapped) {
5253 pline("%s isn't trapped.", Monnam(mtmp));
5255 pline("%s
\82Íã©
\82É
\82©
\82©
\82Á
\82Ä
\82¢
\82È
\82¢
\81D", Monnam(mtmp));
5258 /* Do you have the necessary capacity to lift anything? */
5259 if (check_capacity((char *) 0))
5262 /* Will our hero succeed? */
5263 if ((uprob = untrap_prob(ttmp)) && !mtmp->msleeping && mtmp->mcanmove) {
5265 You("try to reach out your %s, but %s backs away skeptically.",
5266 makeplural(body_part(ARM)), mon_nam(mtmp));
5268 You("%s
\82ð
\8d·
\82µ
\89\84\82×
\82æ
\82¤
\82Æ
\82µ
\82½
\82ª%s
\82Í
\8cx
\89ú
\82µ
\82Ä
\82¢
\82é
\81D",
5269 body_part(ARM), mon_nam(mtmp));
5274 /* is it a cockatrice?... */
5275 if (touch_petrifies(mtmp->data) && !uarmg && !Stone_resistance) {
5277 You("grab the trapped %s using your bare %s.", mtmp->data->mname,
5278 makeplural(body_part(HAND)));
5280 You("ã©
\82É
\82©
\82©
\82Á
\82Ä
\82¢
\82é%s
\82ð
\91f%s
\82Å
\92Í
\82ñ
\82¾
\81D", mtmp->data->mname,
5284 if (poly_when_stoned(youmonst.data) && polymon(PM_STONE_GOLEM)) {
5285 display_nhwindow(WIN_MESSAGE, FALSE);
5290 Sprintf(kbuf, "trying to help %s out of a pit",
5291 an(mtmp->data->mname));
5293 Sprintf(kbuf, "ã©
\82É
\82©
\82©
\82Á
\82Ä
\82¢
\82é%s
\82ð
\8f\95\82¯
\82æ
\82¤
\82Æ
\82µ
\82Ä",
5300 /* need to do cockatrice check first if sleeping or paralyzed */
5303 You("try to grab %s, but cannot get a firm grasp.", mon_nam(mtmp));
5305 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));
5306 if (mtmp->msleeping) {
5307 mtmp->msleeping = 0;
5309 pline("%s awakens.", Monnam(mtmp));
5311 pline("%s
\82Í
\96Ú
\82ð
\8ao
\82Ü
\82µ
\82½
\81D", Monnam(mtmp));
5317 You("reach out your %s and grab %s.", makeplural(body_part(ARM)),
5320 You("%s
\82ð
\90L
\82Î
\82µ
\82Ä%s
\82ð
\82Â
\82©
\82ñ
\82¾
\81D", body_part(ARM),
5324 if (mtmp->msleeping) {
5325 mtmp->msleeping = 0;
5327 pline("%s awakens.", Monnam(mtmp));
5329 pline("%s
\82Í
\96Ú
\82ð
\8ao
\82Ü
\82µ
\82½
\81D", Monnam(mtmp));
5330 } else if (mtmp->mfrozen && !rn2(mtmp->mfrozen)) {
5331 /* After such manhandling, perhaps the effect wears off */
5335 pline("%s stirs.", Monnam(mtmp));
5337 pline("%s
\82Í
\93®
\82«
\8en
\82ß
\82½
\81D", Monnam(mtmp));
5340 /* is the monster too heavy? */
5341 wt = inv_weight() + mtmp->data->cwt;
5342 if (!try_lift(mtmp, ttmp, wt, FALSE))
5345 /* is the monster with inventory too heavy? */
5346 for (otmp = mtmp->minvent; otmp; otmp = otmp->nobj)
5348 if (!try_lift(mtmp, ttmp, wt, TRUE))
5352 You("pull %s out of the pit.", mon_nam(mtmp));
5354 You("%s
\82ð
\97\8e\82µ
\8c\8a\82©
\82ç
\82Ð
\82Á
\82Ï
\82Á
\82½
\81D", mon_nam(mtmp));
5356 fill_pit(mtmp->mx, mtmp->my);
5357 reward_untrap(ttmp, mtmp);
5365 register struct obj *otmp;
5370 const char *trapdescr;
5371 boolean here, useplural, confused = (Confusion || Hallucination),
5372 trap_skipped = FALSE, deal_with_floor_trap;
5374 char the_trap[BUFSZ], qbuf[QBUFSZ];
5376 if (!getdir((char *) 0))
5382 pline_The("perils lurking there are beyond your grasp.");
5384 pline_The("
\82»
\82±
\82É
\82 \82é
\8aë
\8c¯
\82Í
\82 \82È
\82½
\82Ì
\8eè
\82É
\95\89\82¦
\82È
\82¢
\81D");
5388 if (ttmp && !ttmp->tseen)
5390 trapdescr = ttmp ? defsyms[trap_to_defsym(ttmp->ttyp)].explanation : 0;
5391 here = (x == u.ux && y == u.uy); /* !u.dx && !u.dy */
5393 if (here) /* are there are one or more containers here? */
5394 for (otmp = level.objects[x][y]; otmp; otmp = otmp->nexthere)
5400 deal_with_floor_trap = can_reach_floor(FALSE);
5401 if (!deal_with_floor_trap) {
5404 Strcat(the_trap, an(trapdescr));
5407 Strcat(the_trap, " and ");
5409 Strcat(the_trap, "
\82Æ");
5412 Strcat(the_trap, (boxcnt == 1) ? "a container" : "containers");
5414 Strcat(the_trap, "
\97e
\8aí");
5415 useplural = ((ttmp && boxcnt > 0) || boxcnt > 1);
5416 /* note: boxcnt and useplural will always be 0 for !here case */
5419 There("%s %s %s but you can't reach %s%s.",
5420 useplural ? "are" : "is", the_trap, here ? "here" : "there",
5421 useplural ? "them" : "it",
5422 u.usteed ? " while mounted" : "");
5424 pline("%s
\82ª
\82 \82é
\82ª
\81C%s
\93Í
\82©
\82È
\82¢
\81D",
5426 u.usteed ? "
\8fæ
\82Á
\82Ä
\82¢
\82é
\82Æ" : "");
5428 trap_skipped = (ttmp != 0);
5429 } else { /* deal_with_floor_trap */
5432 Strcpy(the_trap, the(trapdescr));
5434 if (ttmp->ttyp == PIT || ttmp->ttyp == SPIKED_PIT) {
5436 You_cant("do much about %s%s.", the_trap,
5437 u.utrap ? " that you're stuck in"
5438 : " while standing on the edge of it");
5440 pline("%s%s
\82É
\91Î
\82µ
\82Ä
\82Í
\82½
\82¢
\82µ
\82½
\82±
\82Æ
\82Í
\82Å
\82«
\82È
\82¢
\81D",
5441 u.utrap ? "
\8e©
\95ª
\82ª
\82Í
\82Ü
\82Á
\82Ä
\82¢
\82é"
5442 : "
\82·
\82®
\82»
\82Î
\82Ì",
5445 trap_skipped = TRUE;
5446 deal_with_floor_trap = FALSE;
5450 qbuf, "There %s and %s here. %s %s?",
5451 (boxcnt == 1) ? "is a container" : "are containers",
5453 (ttmp->ttyp == WEB) ? "Remove" : "Disarm", the_trap);
5456 qbuf, "
\94 \82Æ%s
\82ª
\82 \82é
\81D%s
\81H",
5458 (ttmp->ttyp == WEB) ? "
\8eæ
\82è
\8f\9c\82" : "
\89ð
\8f\9c\82·
\82é");
5460 switch (ynq(qbuf)) {
5464 trap_skipped = TRUE;
5465 deal_with_floor_trap = FALSE;
5470 if (deal_with_floor_trap) {
5473 You("cannot deal with %s while trapped%s!", the_trap,
5474 (x == u.ux && y == u.uy) ? " in it" : "");
5476 pline("ã©
\82É
\82©
\82©
\82Á
\82Ä
\82¢
\82é
\8aÔ
\82Íã©
\82ð
\89ð
\8f\9c\82Å
\82«
\82È
\82¢
\81I");
5480 if ((mtmp = m_at(x, y)) != 0
5481 && (mtmp->m_ap_type == M_AP_FURNITURE
5482 || mtmp->m_ap_type == M_AP_OBJECT)) {
5483 stumble_onto_mimic(mtmp);
5486 switch (ttmp->ttyp) {
5489 return disarm_holdingtrap(ttmp);
5491 return disarm_landmine(ttmp);
5493 return disarm_squeaky_board(ttmp);
5495 return disarm_shooting_trap(ttmp, DART);
5497 return disarm_shooting_trap(ttmp, ARROW);
5502 You("are already on the edge of the pit.");
5504 You("
\82à
\82¤
\97\8e\82µ
\8c\8a\82Ì
\92[
\82É
\82¢
\82é
\81D");
5509 pline("Try filling the pit instead.");
5511 pline("
\82È
\82ñ
\82Æ
\82©
\96\84\82ß
\82é
\82±
\82Æ
\82ð
\8dl
\82¦
\82Ä
\82Ý
\82½
\82ç
\81H");
5514 return help_monster_out(mtmp, ttmp);
5517 You("cannot disable %s trap.", !here ? "that" : "this");
5519 pline("%sã©
\82Í
\89ð
\8f\9c\82Å
\82«
\82È
\82¢
\81D", !here ? "
\82»
\82Ì" : "
\82±
\82Ì");
5526 for (otmp = level.objects[x][y]; otmp; otmp = otmp->nexthere)
5529 (void) safe_qbuf(qbuf, "There is ",
5530 " here. Check it for traps?", otmp,
5531 doname, ansimpleoname, "a box");
5533 (void) safe_qbuf(qbuf, "",
5534 "
\82ª
\82 \82é
\81Dã©
\82ð
\92²
\82×
\82Ü
\82·
\82©
\81H", otmp,
5535 doname, ansimpleoname, "
\94 ");
5537 switch (ynq(qbuf)) {
5545 && (force || (!confused
5546 && rn2(MAXULEV + 1 - u.ulevel) < 10)))
5547 || (!force && confused && !rn2(3))) {
5549 You("find a trap on %s!", the(xname(otmp)));
5551 pline("%s
\82Éã©
\82ð
\94
\8c©
\82µ
\82½
\81I", the(xname(otmp)));
5553 exercise(A_WIS, TRUE);
5556 switch (ynq("Disarm it?")) {
5558 switch (ynq("
\89ð
\8f\9c\82µ
\82Ü
\82·
\82©
\81H")) {
5562 trap_skipped = TRUE;
5566 if (otmp->otrapped) {
5567 exercise(A_DEX, TRUE);
5568 ch = ACURR(A_DEX) + u.ulevel;
5569 if (Role_if(PM_ROGUE))
5571 if (!force && (confused || Fumbling
5572 || rnd(75 + level_difficulty() / 2)
5574 (void) chest_trap(otmp, FINGER, TRUE);
5579 You("
\89ð
\8f\9c\82µ
\82½
\81I");
5584 pline("That %s was not trapped.", xname(otmp));
5586 pline("
\82»
\82Ì%s
\82Éã©
\82Í
\82È
\82¢
\81D", xname(otmp));
5590 You("find no traps on %s.", the(xname(otmp)));
5592 pline("ã©
\82ð
\94
\8c©
\82Å
\82«
\82È
\82©
\82Á
\82½
\81D");
5598 You(trap_skipped ? "find no other traps here."
5599 : "know of no traps here.");
5601 You(trap_skipped ? "
\91¼
\82Ìã©
\82ð
\8c©
\82Â
\82¯
\82ç
\82ê
\82È
\82©
\82Á
\82½
\81D"
5602 : "
\82±
\82±
\82Éã©
\82ª
\82È
\82¢
\82±
\82Æ
\82ð
\92m
\82Á
\82Ä
\82¢
\82é
\81D");
5607 if (stumble_on_door_mimic(x, y))
5610 } /* deal_with_floor_trap */
5611 /* doors can be manipulated even while levitating/unskilled riding */
5613 if (!IS_DOOR(levl[x][y].typ)) {
5616 You("know of no traps there.");
5618 You("
\82»
\82±
\82Éã©
\82ª
\82È
\82¢
\82±
\82Æ
\82ð
\92m
\82Á
\82Ä
\82¢
\82é
\81D");
5622 switch (levl[x][y].doormask) {
5625 You("%s no door there.", Blind ? "feel" : "see");
5627 pline("
\82»
\82±
\82É
\82Í
\94à
\82ª
\82È
\82¢%s
\81D", Blind ? "
\82æ
\82¤
\82¾" : "
\82æ
\82¤
\82É
\8c©
\82¦
\82é");
5631 pline("This door is safely open.");
5633 pline("
\82»
\82Ì
\94à
\82Í
\88À
\91S
\82É
\8aJ
\82¢
\82Ä
\82¢
\82é
\81D");
5637 pline("This door is broken.");
5639 pline("
\82»
\82Ì
\94à
\82Í
\89ó
\82ê
\82Ä
\82¢
\82é
\81D");
5643 if ((levl[x][y].doormask & D_TRAPPED
5644 && (force || (!confused && rn2(MAXULEV - u.ulevel + 11) < 10)))
5645 || (!force && confused && !rn2(3))) {
5647 You("find a trap on the door!");
5649 pline("
\94à
\82Éã©
\82ð
\94
\8c©
\82µ
\82½
\81I");
5650 exercise(A_WIS, TRUE);
5652 if (ynq("Disarm it?") != 'y')
5654 if (ynq("
\89ð
\8f\9c\82µ
\82Ü
\82·
\82©
\81H") != 'y')
5656 if (levl[x][y].doormask & D_TRAPPED) {
5657 ch = 15 + (Role_if(PM_ROGUE) ? u.ulevel * 3 : u.ulevel);
5658 exercise(A_DEX, TRUE);
5659 if (!force && (confused || Fumbling
5660 || rnd(75 + level_difficulty() / 2) > ch)) {
5664 You("
\83X
\83C
\83b
\83`
\82ð
\93ü
\82ê
\82Ä
\82µ
\82Ü
\82Á
\82½
\81I");
5666 b_trapped("door", FINGER);
5668 b_trapped("
\94à", FINGER);
5669 levl[x][y].doormask = D_NODOOR;
5670 unblock_point(x, y);
5672 /* (probably ought to charge for this damage...) */
5673 if (*in_rooms(x, y, SHOPBASE))
5674 add_damage(x, y, 0L);
5679 You("
\89ð
\8f\9c\82µ
\82½
\81I");
5680 levl[x][y].doormask &= ~D_TRAPPED;
5684 pline("This door was not trapped.");
5686 pline("
\94à
\82Éã©
\82Í
\82È
\82©
\82Á
\82½
\81D");
5690 You("find no traps on the door.");
5692 pline("
\94à
\82Éã©
\82ð
\94
\8c©
\82Å
\82«
\82È
\82©
\82Á
\82½
\81D");
5697 /* for magic unlocking; returns true if targetted monster (which might
5698 be hero) gets untrapped; the trap remains intact */
5700 openholdingtrap(mon, noticed)
5702 boolean *noticed; /* set to true iff hero notices the effect; */
5703 { /* otherwise left with its previous value intact */
5706 const char *trapdescr, *which;
5707 boolean ishero = (mon == &youmonst);
5709 if (mon == u.usteed)
5711 t = t_at(ishero ? u.ux : mon->mx, ishero ? u.uy : mon->my);
5712 /* if no trap here or it's not a holding trap, we're done */
5713 if (!t || (t->ttyp != BEAR_TRAP && t->ttyp != WEB))
5716 trapdescr = defsyms[trap_to_defsym(t->ttyp)].explanation;
5718 which = t->tseen ? the_your[t->madeby_u]
5719 : index(vowels, *trapdescr) ? "an" : "a";
5721 which = t->tseen ? set_you[t->madeby_u] : "";
5727 u.utrap = 0; /* released regardless of type */
5729 /* give message only if trap was the expected type */
5730 if (u.utraptype == TT_BEARTRAP || u.utraptype == TT_WEB) {
5733 Sprintf(buf, "%s is", noit_Monnam(u.usteed));
5735 Strcpy(buf, noit_Monnam(u.usteed));
5738 Strcpy(buf, "You are");
5740 Strcpy(buf, "
\82 \82È
\82½");
5742 pline("%s released from %s %s.", buf, which, trapdescr);
5744 pline("%s
\82Í%s%s
\82©
\82ç
\89ð
\95ú
\82³
\82ê
\82½
\81D", buf, which, trapdescr);
5750 if (canspotmon(mon)) {
5753 pline("%s is released from %s %s.", Monnam(mon), which,
5756 pline("%s
\82Í%s%s
\82©
\82ç
\89ð
\95ú
\82³
\82ê
\82½
\81D", Monnam(mon), which,
5759 } else if (cansee(t->tx, t->ty) && t->tseen) {
5763 pline("%s is released from %s %s.", Something, which,
5766 pline("
\89½
\8eÒ
\82©
\82Í%s%s
\82©
\82ç
\89ð
\95ú
\82³
\82ê
\82½
\81D", which,
5769 else /* BEAR_TRAP */
5771 pline("%s %s opens.", upstart(strcpy(buf, which)), trapdescr);
5773 pline("%s%s
\82Í
\8aJ
\82¢
\82½
\81D", which, trapdescr);
5775 /* might pacify monster if adjacent */
5776 if (rn2(2) && distu(mon->mx, mon->my) <= 2)
5777 reward_untrap(t, mon);
5782 /* for magic locking; returns true if targetted monster (which might
5783 be hero) gets hit by a trap (might avoid actually becoming trapped) */
5785 closeholdingtrap(mon, noticed)
5787 boolean *noticed; /* set to true iff hero notices the effect; */
5788 { /* otherwise left with its previous value intact */
5790 unsigned dotrapflags;
5791 boolean ishero = (mon == &youmonst), result;
5793 if (mon == u.usteed)
5795 t = t_at(ishero ? u.ux : mon->mx, ishero ? u.uy : mon->my);
5796 /* if no trap here or it's not a holding trap, we're done */
5797 if (!t || (t->ttyp != BEAR_TRAP && t->ttyp != WEB))
5802 return FALSE; /* already trapped */
5804 dotrapflags = FORCETRAP;
5805 /* dotrap calls mintrap when mounted hero encounters a web */
5807 dotrapflags |= NOWEBMSG;
5809 dotrap(t, dotrapflags);
5811 result = (u.utrap != 0);
5814 return FALSE; /* already trapped */
5815 /* you notice it if you see the trap close/tremble/whatever
5816 or if you sense the monster who becomes trapped */
5817 *noticed = cansee(t->tx, t->ty) || canspotmon(mon);
5819 result = (mintrap(mon) != 0);
5825 /* for magic unlocking; returns true if targetted monster (which might
5826 be hero) gets hit by a trap (target might avoid its effect) */
5828 openfallingtrap(mon, trapdoor_only, noticed)
5830 boolean trapdoor_only;
5831 boolean *noticed; /* set to true iff hero notices the effect; */
5832 { /* otherwise left with its previous value intact */
5834 boolean ishero = (mon == &youmonst), result;
5836 if (mon == u.usteed)
5838 t = t_at(ishero ? u.ux : mon->mx, ishero ? u.uy : mon->my);
5839 /* if no trap here or it's not a falling trap, we're done
5840 (note: falling rock traps have a trapdoor in the ceiling) */
5841 if (!t || ((t->ttyp != TRAPDOOR && t->ttyp != ROCKTRAP)
5842 && (trapdoor_only || (t->ttyp != HOLE && t->ttyp != PIT
5843 && t->ttyp != SPIKED_PIT))))
5848 return FALSE; /* already trapped */
5850 dotrap(t, FORCETRAP);
5851 result = (u.utrap != 0);
5854 return FALSE; /* already trapped */
5855 /* you notice it if you see the trap close/tremble/whatever
5856 or if you sense the monster who becomes trapped */
5857 *noticed = cansee(t->tx, t->ty) || canspotmon(mon);
5858 /* monster will be angered; mintrap doesn't handle that */
5861 result = (mintrap(mon) != 0);
5863 /* mon might now be on the migrating monsters list */
5868 /* only called when the player is doing something to the chest directly */
5870 chest_trap(obj, bodypart, disarm)
5871 register struct obj *obj;
5872 register int bodypart;
5875 register struct obj *otmp = obj, *otmp2;
5880 if (get_obj_location(obj, &cc.x, &cc.y, 0)) /* might be carried */
5881 obj->ox = cc.x, obj->oy = cc.y;
5883 otmp->otrapped = 0; /* trap is one-shot; clear flag first in case
5884 chest kills you and ends up in bones file */
5886 You(disarm ? "set it off!" : "trigger a trap!");
5888 You(disarm ? "
\83X
\83C
\83b
\83`
\82ð
\93ü
\82ê
\82Ä
\82µ
\82Ü
\82Á
\82½
\81I" : "ã©
\82É
\82Ð
\82Á
\82©
\82©
\82Á
\82½
\81I");
5889 display_nhwindow(WIN_MESSAGE, FALSE);
5890 if (Luck > -13 && rn2(13 + Luck) > 7) { /* saved by luck */
5891 /* trap went off, but good luck prevents damage */
5896 msg = "explosive charge is a dud";
5898 msg = "
\94\9a\94
\82Í
\95s
\94
\82¾
\82Á
\82½";
5903 msg = "electric charge is grounded";
5905 msg = "
\93d
\8c\82\82ª
\95ú
\8fo
\82³
\82ê
\82½
\82ª
\83A
\81[
\83X
\82³
\82ê
\82Ä
\82¢
\82½";
5910 msg = "flame fizzles out";
5912 msg = "
\89\8a\82Í
\83V
\83\85\81[
\82Á
\82Æ
\8fÁ
\82¦
\82½";
5918 msg = "poisoned needle misses";
5920 msg = "
\93Å
\90j
\82Í
\8eh
\82³
\82ç
\82È
\82©
\82Á
\82½";
5927 msg = "gas cloud blows away";
5929 msg = "
\83K
\83X
\89_
\82Í
\90\81\82«
\94ò
\82ñ
\82¾";
5932 impossible("chest disarm bug");
5938 pline("But luckily the %s!", msg);
5940 pline("
\82µ
\82©
\82µ
\89^
\82Ì
\82æ
\82¢
\82±
\82Æ
\82É%s
\81I", msg);
5942 switch (rn2(20) ? ((Luck >= 13) ? 0 : rn2(13 - Luck)) : rn2(26)) {
5948 struct monst *shkp = 0;
5950 boolean costly, insider;
5951 register xchar ox = obj->ox, oy = obj->oy;
5953 /* the obj location need not be that of player */
5954 costly = (costly_spot(ox, oy)
5955 && (shkp = shop_keeper(*in_rooms(ox, oy, SHOPBASE)))
5956 != (struct monst *) 0);
5957 insider = (*u.ushops && inside_shop(u.ux, u.uy)
5958 && *in_rooms(ox, oy, SHOPBASE) == *u.ushops);
5961 pline("%s!", Tobjnam(obj, "explode"));
5963 pline("%s
\82Í
\94\9a\94
\82µ
\82½
\81I", xname(obj));
5965 Sprintf(buf, "exploding %s", xname(obj));
5967 Sprintf(buf, "%s
\82Ì
\94\9a\94
\82Å", xname(obj));
5970 loss += stolen_value(obj, ox, oy, (boolean) shkp->mpeaceful,
5972 delete_contents(obj);
5973 /* we're about to delete all things at this location,
5974 * which could include the ball & chain.
5975 * If we attempt to call unpunish() in the
5976 * for-loop below we can end up with otmp2
5977 * being invalid once the chain is gone.
5978 * Deal with ball & chain right now instead.
5980 if (Punished && !carried(uball)
5981 && ((uchain->ox == u.ux && uchain->oy == u.uy)
5982 || (uball->ox == u.ux && uball->oy == u.uy)))
5985 for (otmp = level.objects[u.ux][u.uy]; otmp; otmp = otmp2) {
5986 otmp2 = otmp->nexthere;
5988 loss += stolen_value(otmp, otmp->ox, otmp->oy,
5989 (boolean) shkp->mpeaceful, TRUE);
5993 losehp(Maybe_Half_Phys(d(6, 6)), buf, KILLED_BY_AN);
5994 exercise(A_STR, FALSE);
5995 if (costly && loss) {
5998 You("owe %ld %s for objects destroyed.", loss,
6001 You("
\8aí
\95¨
\94j
\91¹
\82Å%ld%s
\82Ì
\8eØ
\82è
\82ð
\82Â
\82
\82Á
\82½
\81D", loss,
6006 You("caused %ld %s worth of damage!", loss,
6009 You("%ld%s
\95ª
\82Ì
\91¹
\8aQ
\82ð
\88ø
\82«
\82¨
\82±
\82µ
\82½
\81I", loss,
6012 make_angry_shk(shkp, ox, oy);
6022 pline("A cloud of noxious gas billows from %s.", the(xname(obj)));
6024 pline("
\97L
\93Å
\83K
\83X
\82ª%s
\82©
\82ç
\89Q
\82Ü
\82¢
\82½
\81D", the(xname(obj)));
6026 poisoned("gas cloud", A_STR, "cloud of poison gas", 15, FALSE);
6028 poisoned("
\83K
\83X
\89_", A_STR, "
\83K
\83X
\89_", 15, FALSE);
6029 exercise(A_CON, FALSE);
6036 You_feel("a needle prick your %s.", body_part(bodypart));
6038 You("%s
\83`
\83N
\83b
\82Æ
\82¢
\82¤
\92É
\82Ý
\82ð
\8a´
\82¶
\82½
\81D", body_part(bodypart));
6040 poisoned("needle", A_CON, "poisoned needle", 10, FALSE);
6042 poisoned("
\90j", A_CON, "
\93Å
\90j", 10, FALSE);
6043 exercise(A_CON, FALSE);
6057 You("are jolted by a surge of electricity!");
6059 You("
\93d
\8bC
\83V
\83\87\83b
\83N
\82ð
\82
\82ç
\82Á
\82½
\81I");
6060 if (Shock_resistance) {
6061 shieldeff(u.ux, u.uy);
6063 You("don't seem to be affected.");
6065 pline("
\82µ
\82©
\82µ
\82 \82È
\82½
\82Í
\89e
\8b¿
\82ð
\8eó
\82¯
\82È
\82¢
\81D");
6069 destroy_item(RING_CLASS, AD_ELEC);
6070 destroy_item(WAND_CLASS, AD_ELEC);
6073 losehp(dmg, "electric shock", KILLED_BY_AN);
6075 losehp(dmg, "
\93d
\8bC
\83V
\83\87\83b
\83N
\82Å", KILLED_BY_AN);
6083 pline("Suddenly you are frozen in place!");
6085 pline("
\93Ë
\91R
\82»
\82Ì
\8fê
\82Å
\93®
\82¯
\82È
\82
\82È
\82Á
\82½
\81I");
6088 multi_reason = "frozen by a trap";
6090 multi_reason = "ã©
\82Å
\8dd
\92¼
\82µ
\82Ä
\82¢
\82é
\8e\9e\82É";
6091 exercise(A_DEX, FALSE);
6092 nomovemsg = You_can_move_again;
6095 You("momentarily stiffen.");
6097 You("
\88ê
\8fu
\8dd
\92¼
\82µ
\82½
\81D");
6103 pline("A cloud of %s gas billows from %s.",
6104 Blind ? blindgas[rn2(SIZE(blindgas))] : rndcolor(),
6107 pline("%s
\83K
\83X
\89_
\82ª%s
\82Ì
\92ê
\82Å
\89Q
\82Ü
\82¢
\82½
\81D",
6108 Blind ? blindgas[rn2(SIZE(blindgas))] :
6109 jconj_adj(rndcolor()), xname(obj));
6114 pline("What a groovy feeling!");
6116 pline("
\82È
\82ñ
\82Ä
\91f
\93G
\82È
\82ñ
\82¾
\81I");
6119 You("%s%s...", stagger(youmonst.data, "stagger"),
6120 Halluc_resistance ? ""
6121 : Blind ? " and get dizzy"
6122 : " and your vision blurs");
6124 You("
\82
\82ç
\82
\82ç
\82µ%s
\82½...",
6125 Halluc_resistance ? ""
6126 : Blind ? "
\81C
\82ß
\82Ü
\82¢
\82ª
\82µ"
6127 : "
\81C
\8ci
\90F
\82ª
\82Ú
\82â
\82¯
\82Ä
\82«");
6130 make_stunned((HStun & TIMEOUT) + (long) rn1(7, 16), FALSE);
6131 (void) make_hallucinated(
6132 (HHallucination & TIMEOUT) + (long) rn1(5, 16), FALSE, 0L);
6135 impossible("bad chest trap");
6138 bot(); /* to get immediate botl re-display */
6148 register struct trap *trap = ftrap;
6151 if (trap->tx == x && trap->ty == y)
6155 return (struct trap *) 0;
6160 register struct trap *trap;
6162 register struct trap *ttmp;
6164 clear_conjoined_pits(trap);
6165 if (trap == ftrap) {
6166 ftrap = ftrap->ntrap;
6168 for (ttmp = ftrap; ttmp; ttmp = ttmp->ntrap)
6169 if (ttmp->ntrap == trap)
6172 panic("deltrap: no preceding trap!");
6173 ttmp->ntrap = trap->ntrap;
6175 if (Sokoban && (trap->ttyp == PIT || trap->ttyp == HOLE))
6176 maybe_finish_sokoban();
6181 conjoined_pits(trap2, trap1, u_entering_trap2)
6182 struct trap *trap2, *trap1;
6183 boolean u_entering_trap2;
6185 int dx, dy, diridx, adjidx;
6187 if (!trap1 || !trap2)
6189 if (!isok(trap2->tx, trap2->ty) || !isok(trap1->tx, trap1->ty)
6190 || !(trap2->ttyp == PIT || trap2->ttyp == SPIKED_PIT)
6191 || !(trap1->ttyp == PIT || trap1->ttyp == SPIKED_PIT)
6192 || (u_entering_trap2 && !(u.utrap && u.utraptype == TT_PIT)))
6194 dx = sgn(trap2->tx - trap1->tx);
6195 dy = sgn(trap2->ty - trap1->ty);
6196 for (diridx = 0; diridx < 8; diridx++)
6197 if (xdir[diridx] == dx && ydir[diridx] == dy)
6199 /* diridx is valid if < 8 */
6201 adjidx = (diridx + 4) % 8;
6202 if ((trap1->conjoined & (1 << diridx))
6203 && (trap2->conjoined & (1 << adjidx)))
6210 clear_conjoined_pits(trap)
6213 int diridx, adjidx, x, y;
6216 if (trap && (trap->ttyp == PIT || trap->ttyp == SPIKED_PIT)) {
6217 for (diridx = 0; diridx < 8; ++diridx) {
6218 if (trap->conjoined & (1 << diridx)) {
6219 x = trap->tx + xdir[diridx];
6220 y = trap->ty + ydir[diridx];
6222 && (t = t_at(x, y)) != 0
6223 && (t->ttyp == PIT || t->ttyp == SPIKED_PIT)) {
6224 adjidx = (diridx + 4) % 8;
6225 t->conjoined &= ~(1 << adjidx);
6227 trap->conjoined &= ~(1 << diridx);
6235 * Mark all neighboring pits as conjoined pits.
6236 * (currently not called from anywhere)
6239 join_adjacent_pits(trap)
6247 for (diridx = 0; diridx < 8; ++diridx) {
6248 x = trap->tx + xdir[diridx];
6249 y = trap->ty + ydir[diridx];
6251 if ((t = t_at(x, y)) != 0
6252 && (t->ttyp == PIT || t->ttyp == SPIKED_PIT)) {
6253 trap->conjoined |= (1 << diridx);
6254 join_adjacent_pits(t);
6256 trap->conjoined &= ~(1 << diridx);
6263 * Returns TRUE if you escaped a pit and are standing on the precipice.
6266 uteetering_at_seen_pit(trap)
6269 if (trap && trap->tseen && (!u.utrap || u.utraptype != TT_PIT)
6270 && (trap->ttyp == PIT || trap->ttyp == SPIKED_PIT))
6276 /* Destroy a trap that emanates from the floor. */
6279 register struct trap *ttmp;
6281 /* some of these are arbitrary -dlc */
6282 if (ttmp && ((ttmp->ttyp == SQKY_BOARD) || (ttmp->ttyp == BEAR_TRAP)
6283 || (ttmp->ttyp == LANDMINE) || (ttmp->ttyp == FIRE_TRAP)
6284 || (ttmp->ttyp == PIT) || (ttmp->ttyp == SPIKED_PIT)
6285 || (ttmp->ttyp == HOLE) || (ttmp->ttyp == TRAPDOOR)
6286 || (ttmp->ttyp == TELEP_TRAP) || (ttmp->ttyp == LEVEL_TELEP)
6287 || (ttmp->ttyp == WEB) || (ttmp->ttyp == MAGIC_TRAP)
6288 || (ttmp->ttyp == ANTI_MAGIC))) {
6289 register struct monst *mtmp;
6291 if (ttmp->tx == u.ux && ttmp->ty == u.uy) {
6294 } else if ((mtmp = m_at(ttmp->tx, ttmp->ty)) != 0) {
6303 /* used for doors (also tins). can be used for anything else that opens. */
6305 b_trapped(item, bodypart)
6309 int lvl = level_difficulty(),
6310 dmg = rnd(5 + (lvl < 5 ? lvl : 2 + lvl / 2));
6313 pline("KABOOM!! %s was booby-trapped!", The(item));
6315 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);
6318 losehp(Maybe_Half_Phys(dmg), "explosion", KILLED_BY_AN);
6320 losehp(Maybe_Half_Phys(dmg), "
\83u
\81[
\83r
\81[
\83g
\83\89\83b
\83v
\82Ì
\94\9a\94
\82Å", KILLED_BY_AN);
6321 exercise(A_STR, FALSE);
6323 exercise(A_CON, FALSE);
6324 make_stunned((HStun & TIMEOUT) + (long) dmg, TRUE);
6327 /* Monster is hit by trap. */
6328 /* Note: doesn't work if both obj and d_override are null */
6330 thitm(tlev, mon, obj, d_override, nocorpse)
6338 boolean trapkilled = FALSE;
6343 strike = (find_mac(mon) + tlev + obj->spe <= rnd(20));
6345 strike = (find_mac(mon) + tlev <= rnd(20));
6347 /* Actually more accurate than thitu, which doesn't take
6348 * obj->spe into account.
6351 if (obj && cansee(mon->mx, mon->my))
6353 pline("%s is almost hit by %s!", Monnam(mon), doname(obj));
6355 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));
6359 if (obj && cansee(mon->mx, mon->my))
6361 pline("%s is hit by %s!", Monnam(mon), doname(obj));
6363 pline("%s
\82ª%s
\82É
\96½
\92\86\82µ
\82½
\81I", doname(obj), Monnam(mon));
6367 dam = dmgval(obj, mon);
6371 if ((mon->mhp -= dam) <= 0) {
6375 monkilled(mon, "", nocorpse ? -AD_RBRE : AD_PHYS);
6376 if (mon->mhp <= 0) {
6382 if (obj && (!strike || d_override)) {
6383 place_object(obj, mon->mx, mon->my);
6398 return (boolean) (u.usleep
6400 && (!strncmp(nomovemsg, "You awake", 9)
6401 || !strncmp(nomovemsg, "You regain con", 14)
6402 || !strncmp(nomovemsg, "You are consci", 14))));
6404 /*JP 3.6.0
\82Å
\82Ì
\8fo
\8c»
\88Ê
\92u/
\89ñ
\90\94
6405 "You awake" : potion.c(1)
6406 "You regain con": eat.c(1)
6407 "You are consci": eat.c(1)
6409 return (boolean) (u.usleep
6411 && (!strncmp(nomovemsg, "
\96Ú
\82ª
\82³
\82ß
\82½
\82ª
\93ª
\92É", 18)
6412 || !strncmp(nomovemsg, "
\82 \82È
\82½
\82Í
\90³
\8bC
\82Ã
\82¢
\82½", 18)
6413 || !strncmp(nomovemsg, "
\82 \82È
\82½
\82Í
\82Ü
\82½
\90³
\8bC
\82Ã", 18))));
6418 static const char lava_killer[] = "molten lava";
6420 static const char lava_killer[] = "
\82Ç
\82ë
\82Ç
\82ë
\82Ì
\97n
\8aâ
\82Å";
6425 register struct obj *obj, *obj2;
6426 int dmg = d(6, 6); /* only applicable for water walking */
6427 boolean usurvive, boil_away;
6430 if (likes_lava(youmonst.data))
6433 usurvive = Fire_resistance || (Wwalking && dmg < u.uhp);
6435 * A timely interrupt might manage to salvage your life
6436 * but not your gear. For scrolls and potions this
6437 * will destroy whole stacks, where fire resistant hero
6438 * survivor only loses partial stacks via destroy_item().
6440 * Flag items to be destroyed before any messages so
6441 * that player causing hangup at --More-- won't get an
6442 * emergency save file created before item destruction.
6445 for (obj = invent; obj; obj = obj->nobj)
6446 if ((is_organic(obj) || obj->oclass == POTION_CLASS)
6447 && !obj->oerodeproof
6448 && objects[obj->otyp].oc_oprop != FIRE_RES
6449 && obj->otyp != SCR_FIRE && obj->otyp != SPE_FIREBALL
6450 && !obj_resists(obj, 0, 0)) /* for invocation items */
6453 /* Check whether we should burn away boots *first* so we know whether to
6454 * make the player sink into the lava. Assumption: water walking only
6457 if (Wwalking && uarmf && is_organic(uarmf) && !uarmf->oerodeproof) {
6460 pline("%s into flame!", Yobjnam2(obj, "burst"));
6462 Your("%s
\82Í
\94R
\82¦
\82½
\81I", xname(obj));
6463 iflags.in_lava_effects++; /* (see above) */
6466 iflags.in_lava_effects--;
6469 if (!Fire_resistance) {
6472 pline_The("lava here burns you!");
6474 pline("
\97n
\8aâ
\82ª
\82 \82È
\82½
\82ð
\8fÄ
\82«
\82Â
\82
\82µ
\82½
\81I");
6476 losehp(dmg, lava_killer, KILLED_BY); /* lava damage */
6481 You("fall into the lava!");
6483 You("
\97n
\8aâ
\82É
\97\8e\82¿
\82½
\81I");
6485 usurvive = Lifesaved || discover;
6489 /* prevent remove_worn_item() -> Boots_off(WATER_WALKING_BOOTS) ->
6490 spoteffects() -> lava_effects() recursion which would
6491 successfully delete (via useupall) the no-longer-worn boots;
6492 once recursive call returned, we would try to delete them again
6493 here in the outer call (and access stale memory, probably panic) */
6494 iflags.in_lava_effects++;
6496 for (obj = invent; obj; obj = obj2) {
6498 /* above, we set in_use for objects which are to be destroyed */
6499 if (obj->otyp == SPE_BOOK_OF_THE_DEAD && !Blind) {
6502 pline("%s glows a strange %s, but remains intact.",
6503 The(xname(obj)), hcolor("dark red"));
6505 pline("%s
\82Í
\95s
\8ev
\8bc
\82É%s
\8bP
\82¢
\82½
\82ª
\81C
\96³
\8f\9d\82Ì
\82æ
\82¤
\82¾
\81D",
6506 xname(obj), jconj_adj(hcolor("
\88Ã
\90Ô
\90F
\82Ì")));
6508 } else if (obj->in_use) {
6509 if (obj->owornmask) {
6512 pline("%s into flame!", Yobjnam2(obj, "burst"));
6514 Your("%s
\82Í
\94R
\82¦
\82½
\81I", xname(obj));
6515 remove_worn_item(obj, TRUE);
6521 iflags.in_lava_effects--;
6524 boil_away = (u.umonnum == PM_WATER_ELEMENTAL
6525 || u.umonnum == PM_STEAM_VORTEX
6526 || u.umonnum == PM_FOG_CLOUD);
6529 /* killer format and name are reconstructed every iteration
6530 because lifesaving resets them */
6531 killer.format = KILLED_BY;
6532 Strcpy(killer.name, lava_killer);
6534 You("%s...", boil_away ? "boil away" : "burn to a crisp");
6536 You("%s
\81D
\81D
\81D", boil_away ? "
\95¦
\93«
\82µ
\82½" : "
\94R
\82¦
\82Ä
\83p
\83\8a\83p
\83\8a\82É
\82È
\82Á
\82½");
6538 if (safe_teleds(TRUE))
6539 break; /* successful life-save */
6540 /* nowhere safe to land; repeat burning loop */
6542 pline("You're still burning.");
6544 You("
\82Ü
\82¾
\94R
\82¦
\82Ä
\82¢
\82é
\81D");
6547 You("find yourself back on solid %s.", surface(u.ux, u.uy));
6549 You("
\82¢
\82Â
\82Ì
\82Ü
\82É
\82©
\8cÅ
\82¢%s
\82É
\96ß
\82Á
\82Ä
\82¢
\82½
\81D", surface(u.ux, u.uy));
6551 } else if (!Wwalking && (!u.utrap || u.utraptype != TT_LAVA)) {
6552 boil_away = !Fire_resistance;
6553 /* if not fire resistant, sink_into_lava() will quickly be fatal;
6554 hero needs to escape immediately */
6555 u.utrap = rn1(4, 4) + ((boil_away ? 2 : rn1(4, 12)) << 8);
6556 u.utraptype = TT_LAVA;
6558 You("sink into the lava%s!", !boil_away
6559 ? ", but it only burns slightly"
6560 : " and are about to be immolated");
6562 You("
\97n
\8aâ
\82É
\92¾
\82ñ%s
\82¾
\81I", !boil_away
6563 ? "
\82¾
\82ª
\81C
\82¿
\82å
\82Á
\82Æ
\8fÅ
\82°
\82½
\82¾
\82¯"
6564 : "
\82Å
\8fÄ
\82«
\8eE
\82³
\82ê
\82»
\82¤");
6567 losehp(!boil_away ? 1 : (u.uhp / 2), lava_killer,
6568 KILLED_BY); /* lava damage */
6572 destroy_item(SCROLL_CLASS, AD_FIRE);
6573 destroy_item(SPBOOK_CLASS, AD_FIRE);
6574 destroy_item(POTION_CLASS, AD_FIRE);
6578 /* called each turn when trapped in lava */
6583 static const char sink_deeper[] = "You sink deeper into the lava.";
6585 static const char sink_deeper[] = "
\82 \82È
\82½
\82Í
\82æ
\82è
\90[
\82
\97n
\8aâ
\82É
\92¾
\82ñ
\82¾
\81D";
6587 if (!u.utrap || u.utraptype != TT_LAVA) {
6588 ; /* do nothing; this shouldn't happen */
6589 } else if (!is_lava(u.ux, u.uy)) {
6590 u.utrap = 0; /* this shouldn't happen either */
6591 } else if (!u.uinvulnerable) {
6592 /* ordinarily we'd have to be fire resistant to survive long
6593 enough to become stuck in lava, but it can happen without
6594 resistance if water walking boots allow survival and then
6595 get burned up; u.utrap time will be quite short in that case */
6596 if (!Fire_resistance)
6597 u.uhp = (u.uhp + 2) / 3;
6599 u.utrap -= (1 << 8);
6600 if (u.utrap < (1 << 8)) {
6601 killer.format = KILLED_BY;
6603 Strcpy(killer.name, "molten lava");
6605 Strcpy(killer.name, "
\82Ç
\82ë
\82Ç
\82ë
\82Ì
\97n
\8aâ
\82Å");
6607 You("sink below the surface and die.");
6609 You("
\8a®
\91S
\82É
\97n
\8aâ
\82Ì
\92\86\82É
\92¾
\82ñ
\82Å
\81A
\8e\80\82É
\82Ü
\82µ
\82½
\81D
\81D
\81D");
6610 burn_away_slime(); /* add insult to injury? */
6612 } else if (!u.umoved) {
6613 /* can't fully turn into slime while in lava, but might not
6614 have it be burned away until you've come awfully close */
6615 if (Slimed && rnd(10 - 1) >= (int) (Slimed & TIMEOUT)) {
6626 /* called when something has been done (breaking a boulder, for instance)
6627 which entails a luck penalty if performed on a sokoban level */
6633 /* TODO: issue some feedback so that player can learn that whatever
6634 he/she just did is a naughty thing to do in sokoban and should
6635 probably be avoided in future....
6636 Caveat: doing this might introduce message sequencing issues,
6637 depending upon feedback during the various actions which trigger
6638 Sokoban luck penalties. */
6642 /* called when a trap has been deleted or had its ttyp replaced */
6644 maybe_finish_sokoban()
6648 if (Sokoban && !in_mklev) {
6649 /* scan all remaining traps, ignoring any created by the hero;
6650 if this level has no more pits or holes, the current sokoban
6651 puzzle has been solved */
6652 for (t = ftrap; t; t = t->ntrap) {
6655 if (t->ttyp == PIT || t->ttyp == HOLE)
6659 /* we've passed the last trap without finding a pit or hole;
6660 clear the sokoban_rules flag so that luck penalties for
6661 things like breaking boulders or jumping will no longer
6662 be given, and restrictions on diagonal moves are lifted */
6663 Sokoban = 0; /* clear level.flags.sokoban_rules */
6664 /* TODO: give some feedback about solving the sokoban puzzle
6665 (perhaps say "congratulations" in Japanese?) */