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Æ";
748 if (cant_revive(&mnum, TRUE, statue)) {
749 /* mnum has changed; we won't be animating this statue as itself */
750 if (mnum != PM_DOPPELGANGER)
752 use_saved_traits = FALSE;
753 } else if (is_golem(mptr) && cause == ANIMATE_SPELL) {
754 /* statue of any golem hit by stone-to-flesh becomes flesh golem */
755 golem_xform = (mptr != &mons[PM_FLESH_GOLEM]);
756 mnum = PM_FLESH_GOLEM;
757 mptr = &mons[PM_FLESH_GOLEM];
758 use_saved_traits = (has_omonst(statue) && !golem_xform);
760 use_saved_traits = has_omonst(statue);
763 if (use_saved_traits) {
764 /* restore a petrified monster */
766 mon = montraits(statue, &cc);
767 if (mon && mon->mtame && !mon->isminion)
770 /* statues of unique monsters from bones or wishing end
771 up here (cant_revive() sets mnum to be doppelganger;
772 mptr reflects the original form for use by newcham()) */
773 if ((mnum == PM_DOPPELGANGER && mptr != &mons[PM_DOPPELGANGER])
774 /* block quest guards from other roles */
775 || (mptr->msound == MS_GUARDIAN
776 && quest_info(MS_GUARDIAN) != mnum)) {
777 mon = makemon(&mons[PM_DOPPELGANGER], x, y,
778 NO_MINVENT | MM_NOCOUNTBIRTH | MM_ADJACENTOK);
779 /* if hero has protection from shape changers, cham field will
780 be NON_PM; otherwise, set form to match the statue */
781 if (mon && mon->cham >= LOW_PM)
782 (void) newcham(mon, mptr, FALSE, FALSE);
784 mon = makemon(mptr, x, y, (cause == ANIMATE_SPELL)
785 ? (NO_MINVENT | MM_ADJACENTOK)
791 *fail_reason = unique_corpstat(&mons[statue->corpsenm])
794 return (struct monst *) 0;
797 /* a non-montraits() statue might specify gender */
798 if (statue->spe & STATUE_MALE)
800 else if (statue->spe & STATUE_FEMALE)
802 /* if statue has been named, give same name to the monster */
803 if (has_oname(statue))
804 mon = christen_monst(mon, ONAME(statue));
805 /* mimic statue becomes seen mimic; other hiders won't be hidden */
809 mon->mundetected = FALSE;
811 if (cause == ANIMATE_NORMAL || cause == ANIMATE_SHATTER) {
812 /* trap always releases hostile monster */
813 mon->mtame = 0; /* (might be petrified pet tossed onto trap) */
819 comes_to_life = !canspotmon(mon)
823 : (nonliving(mon->data) || is_vampshifter(mon))
827 comes_to_life = !canspotmon(mon)
830 ? "
\93÷
\91Ì
\82É
\96ß
\82Á"
831 : (nonliving(mon->data) || is_vampshifter(mon))
833 : "
\90¶
\96½
\82ð
\91Ñ
\82Ñ";
835 if ((x == u.ux && y == u.uy) || cause == ANIMATE_SPELL) {
836 /* "the|your|Manlobbi's statue [of a wombat]" */
837 shkp = shop_keeper(*in_rooms(mon->mx, mon->my, SHOPBASE));
839 Sprintf(statuename, "%s%s", shk_your(tmpbuf, statue),
840 (cause == ANIMATE_SPELL
841 /* avoid "of a shopkeeper" if it's Manlobbi himself
842 (if carried, it can't be unpaid--hence won't be
843 described as "Manlobbi's statue"--because there
844 wasn't any living shk when statue was picked up) */
845 && (mon != shkp || carried(statue)))
849 Sprintf(statuename, "%s%s", shk_your(tmpbuf, statue),
850 (cause == ANIMATE_SPELL
851 && (mon != shkp || carried(statue)))
856 pline("%s %s!", upstart(statuename), comes_to_life);
858 pline("%s
\82Í%s
\82½
\81I", upstart(statuename), comes_to_life);
859 } else if (Hallucination) { /* They don't know it's a statue */
861 pline_The("%s suddenly seems more animated.", rndmonnam((char *) 0));
863 pline_The("%s
\82Í
\93Ë
\91R
\82æ
\82è
\8a\88\93®
\93I
\82É
\82È
\82Á
\82½
\81D", rndmonnam((char *) 0));
864 } else if (cause == ANIMATE_SHATTER) {
866 Sprintf(statuename, "%s%s", shk_your(tmpbuf, statue),
870 Strcpy(statuename, "a statue");
872 Strcpy(statuename, "
\92¤
\91\9c");
874 pline("Instead of shattering, %s suddenly %s!", statuename,
877 pline("%s
\82Í
\8dÓ
\82¯
\82¸
\82É%s
\82½
\81I", statuename,
880 } else { /* cause == ANIMATE_NORMAL */
882 You("find %s posing as a statue.",
884 You("%s
\82ª
\92¤
\91\9c\82Ì
\82Ó
\82è
\82ð
\82µ
\82Ä
\82¢
\82é
\82Ì
\82ð
\8c©
\82Â
\82¯
\82½
\81D",
885 canspotmon(mon) ? a_monnam(mon) : something);
886 if (!canspotmon(mon) && Blind)
891 /* if this isn't caused by a monster using a wand of striking,
892 there might be consequences for the hero */
893 if (!context.mon_moving) {
894 /* if statue is owned by a shop, hero will have to pay for it;
895 stolen_value gives a message (about debt or use of credit)
896 which refers to "it" so needs to follow a message describing
897 the object ("the statue comes to life" one above) */
898 if (cause != ANIMATE_NORMAL && costly_spot(x, y)
899 && (shkp = shop_keeper(*in_rooms(x, y, SHOPBASE))) != 0
900 /* avoid charging for Manlobbi's statue of Manlobbi
901 if stone-to-flesh is used on petrified shopkeep */
903 (void) stolen_value(statue, x, y, (boolean) shkp->mpeaceful,
908 You_feel("guilty %s.", historic_statue_is_gone);
910 You_feel("%s
\82É
\8dß
\82ð
\8a´
\82¶
\82½
\81D", historic_statue_is_gone);
914 if (historic && cansee(x, y))
916 You_feel("regret %s.", historic_statue_is_gone);
918 You_feel("%s
\82ð
\8cã
\89÷
\82µ
\82½
\81D", historic_statue_is_gone);
919 /* no alignment penalty */
922 /* transfer any statue contents to monster's inventory */
923 while ((item = statue->cobj) != 0) {
924 obj_extract_self(item);
925 (void) mpickobj(mon, item);
928 /* in case statue is wielded and hero zaps stone-to-flesh at self */
929 if (statue->owornmask)
930 remove_worn_item(statue, TRUE);
931 /* statue no longer exists */
934 /* avoid hiding under nothing */
935 if (x == u.ux && y == u.uy && Upolyd && hides_under(youmonst.data)
940 *fail_reason = AS_OK;
945 * You've either stepped onto a statue trap's location or you've triggered a
946 * statue trap by searching next to it or by trying to break it with a wand
950 activate_statue_trap(trap, x, y, shatter)
955 struct monst *mtmp = (struct monst *) 0;
956 struct obj *otmp = sobj_at(STATUE, x, y);
960 * Try to animate the first valid statue. Stop the loop when we
961 * actually create something or the failure cause is not because
962 * the mon was unique.
966 mtmp = animate_statue(otmp, x, y,
967 shatter ? ANIMATE_SHATTER : ANIMATE_NORMAL,
969 if (mtmp || fail_reason != AS_MON_IS_UNIQUE)
972 otmp = nxtobj(otmp, STATUE, TRUE);
980 keep_saddle_with_steedcorpse(steed_mid, objchn, saddle)
982 struct obj *objchn, *saddle;
987 if (objchn->otyp == CORPSE && has_omonst(objchn)) {
988 struct monst *mtmp = OMONST(objchn);
990 if (mtmp->m_id == steed_mid) {
993 if (get_obj_location(objchn, &x, &y, 0)) {
994 obj_extract_self(saddle);
995 place_object(saddle, x, y);
1001 if (Has_contents(objchn)
1002 && keep_saddle_with_steedcorpse(steed_mid, objchn->cobj, saddle))
1004 objchn = objchn->nobj;
1010 dotrap(trap, trflags)
1011 register struct trap *trap;
1014 register int ttype = trap->ttyp;
1015 register struct obj *otmp;
1016 boolean already_seen = trap->tseen,
1017 forcetrap = (trflags & FORCETRAP) != 0,
1018 webmsgok = (trflags & NOWEBMSG) == 0,
1019 forcebungle = (trflags & FORCEBUNGLE) != 0,
1020 plunged = (trflags & TOOKPLUNGE) != 0,
1021 adj_pit = conjoined_pits(trap, t_at(u.ux0, u.uy0), TRUE);
1023 int steed_article = ARTICLE_THE;
1027 /* KMH -- You can't escape the Sokoban level traps */
1028 if (Sokoban && (ttype == PIT || ttype == SPIKED_PIT
1029 || ttype == HOLE || ttype == TRAPDOOR)) {
1030 /* The "air currents" message is still appropriate -- even when
1031 * the hero isn't flying or levitating -- because it conveys the
1032 * reason why the player cannot escape the trap with a dexterity
1033 * check, clinging to the ceiling, etc.
1036 pline("Air currents pull you down into %s %s!",
1037 a_your[trap->madeby_u],
1038 defsyms[trap_to_defsym(ttype)].explanation);
1040 pline("
\8bó
\8bC
\82Ì
\97¬
\82ê
\82ª
\82 \82È
\82½
\82ð%s
\82É
\88ø
\82«
\96ß
\82µ
\82½
\81I",
1041 defsyms[trap_to_defsym(ttype)].explanation);
1043 /* then proceed to normal trap effect */
1044 } else if (already_seen && !forcetrap) {
1045 if ((Levitation || (Flying && !plunged))
1046 && (ttype == PIT || ttype == SPIKED_PIT || ttype == HOLE
1047 || ttype == BEAR_TRAP)) {
1049 You("%s over %s %s.", Levitation ? "float" : "fly",
1050 a_your[trap->madeby_u],
1051 defsyms[trap_to_defsym(ttype)].explanation);
1053 You("%s%s
\82Ì
\8fã%s
\81D",
1054 set_you[trap->madeby_u],
1055 defsyms[trap_to_defsym(ttype)].explanation,
1056 Levitation ? "
\82ð
\8c©
\89º
\82ë
\82µ
\82½" : "
\82ð
\94ò
\82ñ
\82Å
\82¢
\82é");
1060 if (!Fumbling && ttype != MAGIC_PORTAL && ttype != VIBRATING_SQUARE
1061 && ttype != ANTI_MAGIC && !forcebungle && !plunged && !adj_pit
1062 && (!rn2(5) || ((ttype == PIT || ttype == SPIKED_PIT)
1063 && is_clinger(youmonst.data)))) {
1065 You("escape %s %s.", (ttype == ARROW_TRAP && !trap->madeby_u)
1067 : a_your[trap->madeby_u],
1068 defsyms[trap_to_defsym(ttype)].explanation);
1070 You("%s%s
\82ð
\82·
\82é
\82è
\82Æ
\94ð
\82¯
\82½
\81D",
1071 set_you[trap->madeby_u],
1072 defsyms[trap_to_defsym(ttype)].explanation);
1079 u.usteed->mtrapseen |= (1 << (ttype - 1));
1080 /* suppress article in various steed messages when using its
1081 name (which won't occur when hallucinating) */
1082 if (has_mname(u.usteed) && !Hallucination)
1083 steed_article = ARTICLE_NONE;
1088 if (trap->once && trap->tseen && !rn2(15)) {
1090 You_hear("a loud click!");
1092 You_hear("
\83K
\83`
\83\83\83b
\82Æ
\82¢
\82¤
\91å
\82«
\82È
\89¹
\82ð
\95·
\82¢
\82½
\81I");
1100 pline("An arrow shoots out at you!");
1102 pline("
\96î
\82ª
\94ò
\82ñ
\82Å
\82«
\82½
\81I");
1103 otmp = mksobj(ARROW, TRUE, FALSE);
1105 otmp->owt = weight(otmp);
1106 otmp->opoisoned = 0;
1107 if (u.usteed && !rn2(2) && steedintrap(trap, otmp)) { /* nothing */
1110 } else if (thitu(8, dmgval(otmp, &youmonst), otmp, "arrow")) {
1112 } else if (thitu(8, dmgval(otmp, &youmonst), otmp, "
\96î")) {
1113 obfree(otmp, (struct obj *) 0);
1115 place_object(otmp, u.ux, u.uy);
1124 if (trap->once && trap->tseen && !rn2(15)) {
1126 You_hear("a soft click.");
1128 You_hear("
\83J
\83`
\83b
\82Æ
\82¢
\82¤
\89¹
\82ð
\95·
\82¢
\82½
\81D");
1136 pline("A little dart shoots out at you!");
1138 pline("
\8f¬
\82³
\82È
\93\8a\82°
\96î
\82ª
\94ò
\82ñ
\82Å
\82«
\82½
\81I");
1139 otmp = mksobj(DART, TRUE, FALSE);
1141 otmp->owt = weight(otmp);
1143 otmp->opoisoned = 1;
1144 oldumort = u.umortality;
1145 if (u.usteed && !rn2(2) && steedintrap(trap, otmp)) { /* nothing */
1148 } else if (thitu(7, dmgval(otmp, &youmonst), otmp, "little dart")) {
1150 } else if (thitu(7, dmgval(otmp, &youmonst), otmp, "
\93\8a\82°
\96î")) {
1151 if (otmp->opoisoned)
1153 poisoned("dart", A_CON, "little dart",
1154 /* if damage triggered life-saving,
1155 poison is limited to attrib loss */
1156 (u.umortality > oldumort) ? 0 : 10, TRUE);
1158 poisoned("
\93\8a\82°
\96î", A_CON, "
\8f¬
\82³
\82È
\93\8a\82°
\96î",
1159 /* if damage triggered life-saving,
1160 poison is limited to attrib loss */
1161 (u.umortality > oldumort) ? 0 : 10, TRUE);
1163 obfree(otmp, (struct obj *) 0);
1165 place_object(otmp, u.ux, u.uy);
1174 if (trap->once && trap->tseen && !rn2(15)) {
1176 pline("A trap door in %s opens, but nothing falls out!",
1178 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",
1179 the(ceiling(u.ux, u.uy)));
1183 int dmg = d(2, 6); /* should be std ROCK dmg? */
1187 otmp = mksobj_at(ROCK, u.ux, u.uy, TRUE, FALSE);
1189 otmp->owt = weight(otmp);
1192 pline("A trap door in %s opens and %s falls on your %s!",
1193 the(ceiling(u.ux, u.uy)), an(xname(otmp)), body_part(HEAD));
1195 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",
1196 ceiling(u.ux,u.uy), xname(otmp), body_part(HEAD));
1200 if (is_metallic(uarmh)) {
1202 pline("Fortunately, you are wearing a hard helmet.");
1204 pline("
\8dK
\89^
\82É
\82à
\81C
\82 \82È
\82½
\82Í
\8cÅ
\82¢
\8a\95\82ð
\90g
\82É
\82Â
\82¯
\82Ä
\82¢
\82½
\81D");
1206 } else if (flags.verbose) {
1208 pline("%s does not protect you.", Yname2(uarmh));
1210 pline("%s
\82Å
\82Í
\96h
\82°
\82È
\82¢
\81D", xname(uarmh));
1217 newsym(u.ux, u.uy); /* map the rock */
1220 losehp(Maybe_Half_Phys(dmg), "falling rock", KILLED_BY_AN);
1222 losehp(Maybe_Half_Phys(dmg), "
\97\8e\8aâ
\82Å", KILLED_BY_AN);
1223 exercise(A_STR, FALSE);
1227 case SQKY_BOARD: /* stepped on a squeaky board */
1228 if ((Levitation || Flying) && !forcetrap) {
1233 You("notice a crease in the linoleum.");
1235 You("
\8f°
\82Ì
\8ed
\8fã
\8dÞ
\82Ì
\82µ
\82í
\82É
\8bC
\82ª
\82Â
\82¢
\82½
\81D");
1238 You("notice a loose board below you.");
1240 You("
\91«
\8c³
\82Ì
\8aÉ
\82ñ
\82¾
\94Â
\82É
\8bC
\82ª
\82Â
\82¢
\82½
\81D");
1245 pline("A board beneath you %s%s%s.",
1246 Deaf ? "vibrates" : "squeaks ",
1247 Deaf ? "" : trapnote(trap, 0), Deaf ? "" : " loudly");
1250 pline("
\91«
\8c³
\82Ì
\94Â
\82ª
\82ä
\82ê
\82½
\81D");
1252 pline("
\91«
\8c³
\82Ì
\94Â
\82ª
\91å
\82«
\82%s
\82Ì
\89¹
\82É
\82«
\82µ
\82ñ
\82¾
\81D", trapnote(trap, 0));
1262 if ((Levitation || Flying) && !forcetrap)
1265 if (amorphous(youmonst.data) || is_whirly(youmonst.data)
1266 || unsolid(youmonst.data)) {
1268 pline("%s bear trap closes harmlessly through you.",
1269 A_Your[trap->madeby_u]);
1271 pline("%s
\8cF
\82Ìã©
\82Í
\8a\9a\82Ý
\82Â
\82¢
\82½
\82ª
\81C
\82·
\82é
\82Á
\82Æ
\92Ê
\82è
\94²
\82¯
\82½
\81D",
1272 set_you[trap->madeby_u]);
1276 if (!u.usteed && youmonst.data->msize <= MZ_SMALL) {
1278 pline("%s bear trap closes harmlessly over you.",
1279 A_Your[trap->madeby_u]);
1281 pline("%s
\8cF
\82Ìã©
\82Í
\8a\9a\82Ý
\82Â
\82¢
\82½
\82ª
\81C
\97y
\82©
\8fã
\95û
\82¾
\82Á
\82½
\81D",
1282 set_you[trap->madeby_u]);
1286 u.utrap = rn1(4, 4);
1287 u.utraptype = TT_BEARTRAP;
1290 pline("%s bear trap closes on %s %s!", A_Your[trap->madeby_u],
1291 s_suffix(mon_nam(u.usteed)), mbodypart(u.usteed, FOOT));
1293 pline("%s
\8cF
\82Ìã©
\82Í%s
\82Ì%s
\82É
\8a\9a\82Ý
\82Â
\82¢
\82½
\81I", set_you[trap->madeby_u],
1294 mon_nam(u.usteed), mbodypart(u.usteed, FOOT));
1296 if (thitm(0, u.usteed, (struct obj *) 0, dmg, FALSE))
1297 u.utrap = 0; /* steed died, hero not trapped */
1300 pline("%s bear trap closes on your %s!", A_Your[trap->madeby_u],
1303 pline("%s
\8cF
\82Ìã©
\82ª
\82 \82È
\82½
\82Ì%s
\82É
\8a\9a\82Ý
\82Â
\82¢
\82½
\81I", set_you[trap->madeby_u],
1306 set_wounded_legs(rn2(2) ? RIGHT_SIDE : LEFT_SIDE, rn1(10, 10));
1307 if (u.umonnum == PM_OWLBEAR || u.umonnum == PM_BUGBEAR)
1309 You("howl in anger!");
1311 You("
\93{
\82è
\82Ì
\99ô
\9aK
\82ð
\82 \82°
\82½
\81I");
1313 losehp(Maybe_Half_Phys(dmg), "bear trap", KILLED_BY_AN);
1315 losehp(Maybe_Half_Phys(dmg), "
\8cF
\82Ìã©
\82Å", KILLED_BY_AN);
1317 exercise(A_DEX, FALSE);
1323 if (Sleep_resistance || breathless(youmonst.data)) {
1325 You("are enveloped in a cloud of gas!");
1327 You("
\83K
\83X
\89_
\82É
\82Â
\82Â
\82Ü
\82ê
\82½
\81I");
1330 pline("A cloud of gas puts you to sleep!");
1332 pline("
\82 \82È
\82½
\82Í
\83K
\83X
\89_
\82Å
\96°
\82Á
\82Ä
\82µ
\82Ü
\82Á
\82½
\81I");
1333 fall_asleep(-rnd(25), TRUE);
1335 (void) steedintrap(trap, (struct obj *) 0);
1341 /* Unlike monsters, traps cannot aim their rust attacks at
1342 * you, so instead of looping through and taking either the
1343 * first rustable one or the body, we take whatever we get,
1344 * even if it is not rustable.
1349 pline("%s you on the %s!", A_gush_of_water_hits, body_part(HEAD));
1351 pline("
\90\85\82ª
\95¬
\8fo
\82µ
\82Ä
\82 \82È
\82½
\82Ì%s
\82É
\96½
\92\86\82µ
\82½
\81I", body_part(HEAD));
1352 (void) water_damage(uarmh, helm_simple_name(uarmh), TRUE);
1356 pline("%s your left %s!", A_gush_of_water_hits, body_part(ARM));
1358 pline("
\90\85\82ª
\95¬
\8fo
\82µ
\82Ä
\82 \82È
\82½
\82Ì
\8d¶%s
\82É
\96½
\92\86\82µ
\82½
\81I", body_part(ARM));
1360 if (water_damage(uarms, "shield", TRUE) != ER_NOTHING)
1362 if (water_damage(uarms, "
\8f\82", TRUE) != ER_NOTHING)
1364 if (u.twoweap || (uwep && bimanual(uwep)))
1365 (void) water_damage(u.twoweap ? uswapwep : uwep, 0, TRUE);
1368 (void) water_damage(uarmg, "gauntlets", TRUE);
1370 (void) water_damage(uarmg, "
\8f¬
\8eè", TRUE);
1371 /* Not "metal gauntlets" since it gets called
1372 * even if it's leather for the message
1377 pline("%s your right %s!", A_gush_of_water_hits, body_part(ARM));
1379 pline("
\90\85\82ª
\95¬
\8fo
\82µ
\82Ä
\82 \82È
\82½
\82Ì
\89E%s
\82É
\96½
\92\86\82µ
\82½
\81I", body_part(ARM));
1380 (void) water_damage(uwep, 0, TRUE);
1384 pline("%s you!", A_gush_of_water_hits);
1386 pline("
\90\85\82ª
\95¬
\8fo
\82µ
\82Ä
\82 \82È
\82½
\82É
\96½
\92\86\82µ
\82½
\81I");
1387 for (otmp = invent; otmp; otmp = otmp->nobj)
1388 if (otmp->lamplit && otmp != uwep
1389 && (otmp != uswapwep || !u.twoweap))
1390 (void) snuff_lit(otmp);
1392 (void) water_damage(uarmc, cloak_simple_name(uarmc), TRUE);
1395 (void) water_damage(uarm, "armor", TRUE);
1397 (void) water_damage(uarm, "
\8aZ", TRUE);
1400 (void) water_damage(uarmu, "shirt", TRUE);
1402 (void) water_damage(uarmu, "
\83V
\83\83\83c", TRUE);
1406 if (u.umonnum == PM_IRON_GOLEM) {
1410 pline("%s you!", A_gush_of_water_hits);
1412 pline("
\90\85\82ª
\95¬
\8fo
\82µ
\82Ä
\82 \82È
\82½
\82É
\96½
\92\86\82µ
\82½
\81I");
1414 You("are covered with rust!");
1416 You("
\8eK
\82É
\95¢
\82í
\82ê
\82½
\81I");
1418 losehp(Maybe_Half_Phys(dam), "rusting away", KILLED_BY);
1420 losehp(Maybe_Half_Phys(dam), "
\8a®
\91S
\82É
\8eK
\82Ñ
\82Ä", KILLED_BY);
1421 } else if (u.umonnum == PM_GREMLIN && rn2(3)) {
1423 pline("%s you!", A_gush_of_water_hits);
1425 pline("
\90\85\82ª
\95¬
\8fo
\82µ
\82Ä
\82 \82È
\82½
\82É
\96½
\92\86\82µ
\82½
\81I");
1426 (void) split_mon(&youmonst, (struct monst *) 0);
1433 dofiretrap((struct obj *) 0);
1438 /* KMH -- You can't escape the Sokoban level traps */
1439 if (!Sokoban && (Levitation || (Flying && !plunged)))
1442 if (!Sokoban && is_clinger(youmonst.data) && !plunged) {
1445 You_see("%s %spit below you.", a_your[trap->madeby_u],
1446 ttype == SPIKED_PIT ? "spiked " : "");
1448 pline("
\91«
\8c³
\82É%s%s
\97\8e\82µ
\8c\8a\82ð
\94
\8c©
\82µ
\82½
\81D", dig_you[trap->madeby_u],
1449 ttype == SPIKED_PIT ? "
\83g
\83Q
\82¾
\82ç
\82¯
\82Ì" : "");
1453 pline("%s pit %sopens up under you!", A_Your[trap->madeby_u],
1454 ttype == SPIKED_PIT ? "full of spikes " : "");
1456 pline("%s%s
\97\8e\82µ
\8c\8a\82ª
\91«
\8c³
\82É
\8aJ
\82¢
\82½
\81I", dig_you[trap->madeby_u],
1457 ttype == SPIKED_PIT ? "
\83g
\83Q
\82¾
\82ç
\82¯
\82Ì" : "");
1460 You("don't fall in!");
1462 pline("
\82µ
\82©
\82µ
\81C
\82 \82È
\82½
\82Í
\97\8e\82¿
\82È
\82©
\82Á
\82½
\81I");
1467 char verbbuf[BUFSZ];
1470 if ((trflags & RECURSIVETRAP) != 0)
1472 Sprintf(verbbuf, "and %s fall",
1474 Sprintf(verbbuf, "
\82Æ%s",
1475 x_monnam(u.usteed, steed_article, (char *) 0,
1476 SUPPRESS_SADDLE, FALSE));
1479 Sprintf(verbbuf, "lead %s",
1480 x_monnam(u.usteed, steed_article, "poor",
1481 SUPPRESS_SADDLE, FALSE));
1483 Sprintf(verbbuf,"
\82Æ%s",
1484 x_monnam(u.usteed, steed_article, "
\82©
\82í
\82¢
\82»
\82¤
\82È",
1485 SUPPRESS_SADDLE, FALSE));
1487 } else if (adj_pit) {
1489 You("move into an adjacent pit.");
1491 You("
\97×
\82Ì
\97\8e\82µ
\8c\8a\82É
\88Ú
\93®
\82µ
\82½
\81D");
1495 !plunged ? "fall" : (Flying ? "dive" : "plunge"));
1498 !plunged ? "
\97\8e\82¿
\82½" : (Flying ? "
\94ò
\82Ñ
\8d\9e\82ñ
\82¾" : "
\93Ë
\93ü
\82µ
\82½"));
1501 You("%s into %s pit!", verbbuf, a_your[trap->madeby_u]);
1503 You("%s
\97\8e\82µ
\8c\8a\82É%s!", set_you[trap->madeby_u], verbbuf);
1506 /* wumpus reference */
1507 if (Role_if(PM_RANGER) && !trap->madeby_u && !trap->once
1508 && In_quest(&u.uz) && Is_qlocate(&u.uz)) {
1510 pline("Fortunately it has a bottom after all...");
1512 pline("
\8dK
\82¢
\81C
\8c\8b\8bÇ
\82Í
\92ê
\82ª
\82 \82Á
\82½
\81D
\81D
\81D");
1514 } else if (u.umonnum == PM_PIT_VIPER || u.umonnum == PM_PIT_FIEND) {
1516 pline("How pitiful. Isn't that the pits?");
1518 pline("
\82±
\82Ì
\97\8e\82µ
\8c\8a\82Í
\82¢
\82¢
\8ed
\8e\96\82ð
\82µ
\82Ä
\82¢
\82é
\81D");
1520 if (ttype == SPIKED_PIT) {
1522 const char *predicament = "on a set of sharp iron spikes";
1524 const char *predicament = "
\89s
\82¢
\93S
\82Ì
\83g
\83Q
\83g
\83Q
\82Ì
\8fã
\82É";
1529 upstart(x_monnam(u.usteed, steed_article, "poor",
1530 SUPPRESS_SADDLE, FALSE)),
1531 adj_pit ? "steps" : "lands", predicament);
1533 pline("%s
\82Í%s%s
\81I",
1534 upstart(x_monnam(u.usteed, steed_article, "
\82©
\82í
\82¢
\82»
\82¤
\82È",
1535 SUPPRESS_SADDLE, FALSE)),
1536 predicament, adj_pit ? "
\97\8e\82¿
\82½" : "
\8d~
\82è
\82½");
1540 You("%s %s!", adj_pit ? "step" : "land", predicament);
1542 You("%s%s
\81I", predicament, adj_pit ? "
\97\8e\82¿
\82½" : "
\8d~
\82è
\82½");
1545 u.utrap = rn1(6, 2);
1546 u.utraptype = TT_PIT;
1547 if (!steedintrap(trap, (struct obj *) 0)) {
1548 if (ttype == SPIKED_PIT) {
1549 oldumort = u.umortality;
1551 losehp(Maybe_Half_Phys(rnd(adj_pit ? 6 : 10)),
1553 ? "deliberately plunged into a pit of iron spikes"
1554 : adj_pit ? "stepped into a pit of iron spikes"
1555 : "fell into a pit of iron spikes",
1558 losehp(Maybe_Half_Phys(rnd(adj_pit ? 6 : 10)),
1560 ? "
\82í
\82´
\82í
\82´
\83g
\83Q
\82¾
\82ç
\82¯
\82Ì
\97\8e\82µ
\8c\8a\82É
\93Ë
\93ü
\82µ
\82Ä"
1561 : adj_pit ? "
\83g
\83Q
\82¾
\82ç
\82¯
\82Ì
\97\8e\82µ
\8c\8a\82É
\93¥
\82Ý
\8d\9e\82ñ
\82Å"
1562 : "
\83g
\83Q
\82¾
\82ç
\82¯
\82Ì
\97\8e\82µ
\8c\8a\82É
\97\8e\82¿
\82Ä",
1567 poisoned("spikes", A_STR,
1568 adj_pit ? "stepping on poison spikes"
1569 : "fall onto poison spikes",
1570 /* if damage triggered life-saving,
1571 poison is limited to attrib loss */
1572 (u.umortality > oldumort) ? 0 : 8, FALSE);
1574 poisoned("
\83g
\83Q", A_STR,
1575 adj_pit ? "
\93Å
\82Ì
\93h
\82ç
\82ê
\82½
\83g
\83Q
\82ð
\93¥
\82ñ
\82Å"
1576 : "
\93Å
\82Ì
\93h
\82ç
\82ê
\82½
\83g
\83Q
\82Ì
\8fã
\82É
\97\8e\82¿
\82Ä",
1577 /* if damage triggered life-saving,
1578 poison is limited to attrib loss */
1579 (u.umortality > oldumort) ? 0 : 8, FALSE);
1582 /* plunging flyers take spike damage but not pit damage */
1584 && !(plunged && (Flying || is_clinger(youmonst.data))))
1586 losehp(Maybe_Half_Phys(rnd(6)),
1587 plunged ? "deliberately plunged into a pit"
1588 : "fell into a pit",
1591 losehp(Maybe_Half_Phys(rnd(6)),
1592 plunged ? "
\82í
\82´
\82í
\82´
\97\8e\82µ
\8c\8a\82É
\93Ë
\93ü
\82µ
\82Ä"
1593 : "
\97\8e\82µ
\8c\8a\82É
\97\8e\82¿
\82Ä",
1597 if (Punished && !carried(uball)) {
1604 selftouch("Falling, you");
1606 selftouch("
\97\8e\89º
\92\86\81C
\82 \82È
\82½
\82Í");
1607 vision_full_recalc = 1; /* vision limits change */
1608 exercise(A_STR, FALSE);
1609 exercise(A_DEX, FALSE);
1615 if (!Can_fall_thru(&u.uz)) {
1616 seetrap(trap); /* normally done in fall_through */
1617 impossible("dotrap: %ss cannot exist on this level.",
1618 defsyms[trap_to_defsym(ttype)].explanation);
1619 break; /* don't activate it after all */
1631 level_tele_trap(trap);
1634 case WEB: /* Our luckless player has stumbled into a web. */
1636 if (amorphous(youmonst.data) || is_whirly(youmonst.data)
1637 || unsolid(youmonst.data)) {
1638 if (acidic(youmonst.data) || u.umonnum == PM_GELATINOUS_CUBE
1639 || u.umonnum == PM_FIRE_ELEMENTAL) {
1642 You("%s %s spider web!",
1643 (u.umonnum == PM_FIRE_ELEMENTAL) ? "burn"
1645 a_your[trap->madeby_u]);
1647 You("%s
\82
\82à
\82Ì
\91\83\82ð%s
\81I",
1648 web_you[trap->madeby_u],
1649 (u.umonnum == PM_FIRE_ELEMENTAL) ? "
\8fÄ
\82¢
\82½"
1650 : "
\82±
\82È
\82²
\82È
\82É
\82µ
\82½");
1658 You("flow through %s spider web.", a_your[trap->madeby_u]);
1660 You("%s
\82
\82à
\82Ì
\91\83\82ð
\82·
\82é
\82è
\82Æ
\92Ê
\82è
\94²
\82¯
\82½
\81D", web_you[trap->madeby_u]);
1663 if (webmaker(youmonst.data)) {
1666 pline(trap->madeby_u ? "You take a walk on your web."
1667 : "There is a spider web here.");
1669 pline(trap->madeby_u ? "
\8e©
\95ª
\82Å
\92£
\82Á
\82½
\82
\82à
\82Ì
\91\83\82Ì
\8fã
\82ð
\95à
\82¢
\82½
\81D"
1670 : "
\82±
\82±
\82É
\82Í
\82
\82à
\82Ì
\91\83\82ª
\82 \82é
\81D");
1675 char verbbuf[BUFSZ];
1679 Strcpy(verbbuf, "are caught by");
1680 } else if (u.usteed) {
1681 Sprintf(verbbuf, "lead %s into",
1682 x_monnam(u.usteed, steed_article, "poor",
1683 SUPPRESS_SADDLE, FALSE));
1685 Sprintf(verbbuf, "%s into",
1686 Levitation ? (const char *) "float"
1687 : locomotion(youmonst.data, "stumble"));
1689 You("%s %s spider web!", verbbuf, a_your[trap->madeby_u]);
1692 Strcpy(verbbuf, "
\82 \82È
\82½
\82Í");
1693 } else if (u.usteed) {
1694 Sprintf(verbbuf, "
\82 \82È
\82½
\82Æ%s",
1695 x_monnam(u.usteed, steed_article, "
\82©
\82í
\82¢
\82»
\82¤
\82È",
1696 SUPPRESS_SADDLE, FALSE));
1698 Sprintf(verbbuf, "
\82 \82È
\82½
\82Í%s",
1699 Levitation ? (const char *) "
\95\82\82«
\82È
\82ª
\82ç"
1700 : jconj(locomotion(youmonst.data, "
\82Â
\82Ü
\82¸
\82"), "
\82Ä"));
1702 pline("%s%s
\82
\82à
\82Ì
\91\83\82É
\82Ð
\82Á
\82©
\82©
\82Á
\82½
\81I", verbbuf, web_you[trap->madeby_u]);
1705 u.utraptype = TT_WEB;
1707 /* Time stuck in the web depends on your/steed strength. */
1709 register int str = ACURR(A_STR);
1711 /* If mounted, the steed gets trapped. Use mintrap
1712 * to do all the work. If mtrapped is set as a result,
1713 * unset it and set utrap instead. In the case of a
1714 * strongmonst and mintrap said it's trapped, use a
1715 * short but non-zero trap time. Otherwise, monsters
1716 * have no specific strength, so use player strength.
1717 * This gets skipped for webmsgok, which implies that
1718 * the steed isn't a factor.
1720 if (u.usteed && webmsgok) {
1721 /* mtmp location might not be up to date */
1722 u.usteed->mx = u.ux;
1723 u.usteed->my = u.uy;
1725 /* mintrap currently does not return 2(died) for webs */
1726 if (mintrap(u.usteed)) {
1727 u.usteed->mtrapped = 0;
1728 if (strongmonst(u.usteed->data))
1734 webmsgok = FALSE; /* mintrap printed the messages */
1737 u.utrap = rn1(6, 6);
1739 u.utrap = rn1(6, 4);
1741 u.utrap = rn1(4, 4);
1743 u.utrap = rn1(4, 2);
1745 u.utrap = rn1(2, 2);
1754 You("tear through %s web!", a_your[trap->madeby_u]);
1756 You("%s
\82
\82à
\82Ì
\91\83\82ð
\90Ø
\82è
\97ô
\82¢
\82½
\81I", web_you[trap->madeby_u]);
1758 newsym(u.ux, u.uy); /* get rid of trap symbol */
1764 (void) activate_statue_trap(trap, u.ux, u.uy, FALSE);
1767 case MAGIC_TRAP: /* A magic trap. */
1771 newsym(u.ux, u.uy); /* update position */
1773 You("are caught in a magical explosion!");
1775 You("
\96\82\96@
\82Ì
\94\9a\94
\82ð
\97\81\82Ñ
\82½
\81I");
1777 losehp(rnd(10), "magical explosion", KILLED_BY_AN);
1779 losehp(rnd(10), "
\96\82\96@
\82Ì
\94\9a\94
\82ð
\97\81\82Ñ
\82Ä", KILLED_BY_AN);
1781 Your("body absorbs some of the magical energy!");
1783 Your("
\91Ì
\82Í
\96\82\96@
\82Ì
\83G
\83l
\83\8b\83M
\81[
\82ð
\8f
\82µ
\8bz
\82¢
\82Æ
\82Á
\82½
\81I");
1784 u.uen = (u.uenmax += 2);
1789 (void) steedintrap(trap, (struct obj *) 0);
1794 /* hero without magic resistance loses spell energy,
1795 hero with magic resistance takes damage instead;
1796 possibly non-intuitive but useful for play balance */
1798 drain_en(rnd(u.ulevel) + 1);
1800 int dmgval2 = rnd(4), hp = Upolyd ? u.mh : u.uhp;
1802 /* Half_XXX_damage has opposite its usual effect (approx)
1803 but isn't cumulative if hero has more than one */
1804 if (Half_physical_damage || Half_spell_damage)
1806 /* give Magicbane wielder dose of own medicine */
1807 if (uwep && uwep->oartifact == ART_MAGICBANE)
1809 /* having an artifact--other than own quest one--which
1810 confers magic resistance simply by being carried
1811 also increases the effect */
1812 for (otmp = invent; otmp; otmp = otmp->nobj)
1813 if (otmp->oartifact && !is_quest_artifact(otmp)
1814 && defends_when_carried(AD_MAGM, otmp))
1819 dmgval2 = (dmgval2 + 3) / 4;
1822 You_feel((dmgval2 >= hp) ? "unbearably torpid!"
1823 : (dmgval2 >= hp / 4) ? "very lethargic."
1826 You_feel((dmgval2 >= hp) ? "
\91Ï
\82¦
\82ç
\82ê
\82È
\82¢
\82Ù
\82Ç
\96³
\8bC
\97Í
\82É
\82È
\82Á
\82½
\81I"
1827 : (dmgval2 >= hp / 4) ? "
\82Æ
\82Ä
\82à
\8bC
\82¾
\82é
\82
\82È
\82Á
\82½
\81D"
1828 : "
\82à
\82Ì
\82®
\82³
\82È
\8bC
\95ª
\82É
\82È
\82Á
\82½
\81D");
1830 /* opposite of magical explosion */
1832 losehp(dmgval2, "anti-magic implosion", KILLED_BY_AN);
1834 losehp(dmgval2, "
\94½
\96\82\96@
\82Ì
\93à
\95\94\94j
\97ô
\82Å", KILLED_BY_AN);
1839 char verbbuf[BUFSZ];
1844 Sprintf(verbbuf, "lead %s",
1846 Sprintf(verbbuf, "%s
\82Æ
\82Æ
\82à
\82É
\94ò
\82Ñ
\8d\9e\82ñ
\82¾",
1847 x_monnam(u.usteed, steed_article, (char *) 0,
1848 SUPPRESS_SADDLE, FALSE));
1851 Sprintf(verbbuf, "%s", Levitation
1852 ? (const char *) "float"
1853 : locomotion(youmonst.data, "step"));
1855 Sprintf(verbbuf,"%s",
1856 jpast(Levitation ? (const char *)"
\95\82\82«
\82È
\82ª
\82ç
\94ò
\82Ñ
\82±
\82Þ"
1857 : locomotion(youmonst.data, "
\93¥
\82Ý
\8d\9e\82Þ")));
1860 You("%s onto a polymorph trap!", verbbuf);
1862 You("
\95Ï
\89»
\82Ìã©
\82É%s
\81I", verbbuf);
1863 if (Antimagic || Unchanging) {
1864 shieldeff(u.ux, u.uy);
1866 You_feel("momentarily different.");
1868 You("
\88ê
\8fu
\88á
\82Á
\82½
\8a´
\82¶
\82ª
\82µ
\82½
\81D");
1869 /* Trap did nothing; don't remove it --KAA */
1871 (void) steedintrap(trap, (struct obj *) 0);
1872 deltrap(trap); /* delete trap before polymorph */
1873 newsym(u.ux, u.uy); /* get rid of trap symbol */
1875 You_feel("a change coming over you.");
1877 You("
\95Ï
\89»
\82ª
\96K
\82ê
\82½
\82æ
\82¤
\82È
\8bC
\82ª
\82µ
\82½
\81D");
1883 unsigned steed_mid = 0;
1884 struct obj *saddle = 0;
1886 if ((Levitation || Flying) && !forcetrap) {
1887 if (!already_seen && rn2(3))
1891 pline("%s %s in a pile of soil below you.",
1892 already_seen ? "There is" : "You discover",
1893 trap->madeby_u ? "the trigger of your mine" : "a trigger");
1896 pline("
\82±
\82±
\82É
\82Í%s
\92n
\97\8b\82Ì
\8bN
\94\9a\83X
\83C
\83b
\83`
\82ª
\82 \82é
\81D",
1897 set_you[trap->madeby_u]);
1899 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",
1900 set_you[trap->madeby_u]);
1902 if (already_seen && rn2(3))
1905 pline("KAABLAMM!!! %s %s%s off!",
1906 forcebungle ? "Your inept attempt sets"
1907 : "The air currents set",
1908 already_seen ? a_your[trap->madeby_u] : "",
1909 already_seen ? " land mine" : "it");
1911 pline("
\82¿
\82ã
\82Ç
\81[
\82ñ
\81I
\81I%s%s%s
\8bN
\94\9a\83X
\83C
\83b
\83`
\82ª
\94
\93®
\82µ
\82½
\81I",
1912 forcebungle ? "
\95s
\8aí
\97p
\82È
\82¹
\82¢
\82Å"
1913 : "
\8bó
\8bC
\82Ì
\97¬
\82ê
\82Å",
1914 already_seen ? set_you[trap->madeby_u] : "",
1915 already_seen ? "
\92n
\97\8b\82Ì" : "");
1918 /* prevent landmine from killing steed, throwing you to
1919 * the ground, and you being affected again by the same
1920 * mine because it hasn't been deleted yet
1922 static boolean recursive_mine = FALSE;
1928 pline("KAABLAMM!!! You triggered %s land mine!",
1929 a_your[trap->madeby_u]);
1931 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",
1932 set_you[trap->madeby_u]);
1935 steed_mid = u.usteed->m_id;
1936 recursive_mine = TRUE;
1937 (void) steedintrap(trap, (struct obj *) 0);
1938 recursive_mine = FALSE;
1939 saddle = sobj_at(SADDLE, u.ux, u.uy);
1940 set_wounded_legs(LEFT_SIDE, rn1(35, 41));
1941 set_wounded_legs(RIGHT_SIDE, rn1(35, 41));
1942 exercise(A_DEX, FALSE);
1944 blow_up_landmine(trap);
1945 if (steed_mid && saddle && !u.usteed)
1946 (void) keep_saddle_with_steedcorpse(steed_mid, fobj, saddle);
1947 newsym(u.ux, u.uy); /* update trap symbol */
1949 losehp(Maybe_Half_Phys(rnd(16)), "land mine", KILLED_BY_AN);
1951 losehp(Maybe_Half_Phys(rnd(16)), "
\92n
\97\8b\82ð
\93¥
\82ñ
\82Å", KILLED_BY_AN);
1952 /* fall recursively into the pit... */
1953 if ((trap = t_at(u.ux, u.uy)) != 0)
1954 dotrap(trap, RECURSIVETRAP);
1955 fill_pit(u.ux, u.uy);
1959 case ROLLING_BOULDER_TRAP: {
1960 int style = ROLL | (trap->tseen ? LAUNCH_KNOWN : 0);
1964 pline("Click! You trigger a rolling boulder trap!");
1966 pline("
\83J
\83`
\83b
\81I
\82 \82È
\82½
\82Í
\8b\90\8aâ
\82Ìã©
\82Ì
\83X
\83C
\83b
\83`
\82ð
\93¥
\82ñ
\82¾
\81I");
1967 if (!launch_obj(BOULDER, trap->launch.x, trap->launch.y,
1968 trap->launch2.x, trap->launch2.y, style)) {
1970 newsym(u.ux, u.uy); /* get rid of trap symbol */
1972 pline("Fortunately for you, no boulder was released.");
1974 pline("
\89^
\82Ì
\82æ
\82¢
\82±
\82Æ
\82É
\8aâ
\82Í
\93]
\82ª
\82Á
\82Ä
\82±
\82È
\82©
\82Á
\82½
\81D");
1981 domagicportal(trap);
1984 case VIBRATING_SQUARE:
1986 /* messages handled elsewhere; the trap symbol is merely to mark the
1987 * square for future reference */
1992 impossible("You hit a trap of type %u", trap->ttyp);
1997 trapnote(trap, noprefix)
2001 static char tnbuf[12];
2004 *tnnames[12] = { "C note", "D flat", "D note", "E flat",
2005 "E note", "F note", "F sharp", "G note",
2006 "G sharp", "A note", "B flat", "B note" };
2008 *tnnames[12] = { "
\83h", "
\83\8c\81ó", "
\83\8c", "
\83~
\81ó",
2009 "
\83~", "
\83t
\83@", "
\83t
\83@
\81ò", "
\83\",
2010 "
\83\
\81ò", "
\83\89", "
\83V
\81ó", "
\83V" };
2014 tn = tnnames[trap->tnote];
2017 Sprintf(tnbuf, "%s ",
2018 (*tn == 'A' || *tn == 'E' || *tn == 'F') ? "an" : "a");
2019 Sprintf(eos(tnbuf), "%s", tn);
2021 Sprintf(tnbuf, "%s
\82Ì
\89¹", tn);
2027 steedintrap(trap, otmp)
2031 struct monst *steed = u.usteed;
2033 boolean trapkilled, steedhit;
2035 if (!steed || !trap)
2040 trapkilled = steedhit = FALSE;
2045 impossible("steed hit by non-existant arrow?");
2048 trapkilled = thitm(8, steed, otmp, 0, FALSE);
2053 impossible("steed hit by non-existant dart?");
2056 trapkilled = thitm(7, steed, otmp, 0, FALSE);
2060 if (!resists_sleep(steed) && !breathless(steed->data)
2061 && !steed->msleeping && steed->mcanmove) {
2062 if (sleep_monst(steed, rnd(25), -1))
2063 /* no in_sight check here; you can feel it even if blind */
2065 pline("%s suddenly falls asleep!", Monnam(steed));
2067 pline("%s
\82Í
\82Æ
\82Â
\82º
\82ñ
\96°
\82Á
\82Ä
\82µ
\82Ü
\82Á
\82½
\81I", Monnam(steed));
2072 trapkilled = thitm(0, steed, (struct obj *) 0, rnd(16), FALSE);
2077 trapkilled = (steed->mhp <= 0
2078 || thitm(0, steed, (struct obj *) 0,
2079 rnd((tt == PIT) ? 6 : 10), FALSE));
2083 if (!resists_magm(steed) && !resist(steed, WAND_CLASS, 0, NOTELL)) {
2084 (void) newcham(steed, (struct permonst *) 0, FALSE, FALSE);
2085 if (!can_saddle(steed) || !can_ride(steed))
2086 dismount_steed(DISMOUNT_POLY);
2089 You("have to adjust yourself in the saddle on %s.",
2091 You("%s
\82Ì
\88Æ
\82Ì
\8fã
\82Å
\8dÀ
\82è
\82È
\82¨
\82µ
\82½
\81D",
2092 x_monnam(steed, ARTICLE_A, (char *) 0, SUPPRESS_SADDLE,
2102 dismount_steed(DISMOUNT_POLY);
2105 return steedhit ? 1 : 0;
2108 /* some actions common to both player and monsters for triggered landmine */
2110 blow_up_landmine(trap)
2113 int x = trap->tx, y = trap->ty, dbx, dby;
2114 struct rm *lev = &levl[x][y];
2116 (void) scatter(x, y, 4,
2117 MAY_DESTROY | MAY_HIT | MAY_FRACTURE | VIS_EFFECTS,
2120 wake_nearto(x, y, 400);
2121 if (IS_DOOR(lev->typ))
2122 lev->doormask = D_BROKEN;
2123 /* destroy drawbridge if present */
2124 if (lev->typ == DRAWBRIDGE_DOWN || is_drawbridge_wall(x, y) >= 0) {
2126 /* if under the portcullis, the bridge is adjacent */
2127 if (find_drawbridge(&dbx, &dby))
2128 destroy_drawbridge(dbx, dby);
2129 trap = t_at(x, y); /* expected to be null after destruction */
2131 /* convert landmine into pit */
2133 if (Is_waterlevel(&u.uz) || Is_airlevel(&u.uz)) {
2137 trap->ttyp = PIT; /* explosion creates a pit */
2138 trap->madeby_u = FALSE; /* resulting pit isn't yours */
2139 seetrap(trap); /* and it isn't concealed */
2145 * The following are used to track launched objects to
2146 * prevent them from vanishing if you are killed. They
2147 * will reappear at the launchplace in bones files.
2155 launch_drop_spot(obj, x, y)
2160 launchplace.obj = (struct obj *) 0;
2164 launchplace.obj = obj;
2171 launch_in_progress()
2173 if (launchplace.obj)
2179 force_launch_placement()
2181 if (launchplace.obj) {
2182 launchplace.obj->otrapped = 0;
2183 place_object(launchplace.obj, launchplace.x, launchplace.y);
2188 * Move obj from (x1,y1) to (x2,y2)
2190 * Return 0 if no object was launched.
2191 * 1 if an object was launched and placed somewhere.
2192 * 2 if an object was launched, but used up.
2195 launch_obj(otyp, x1, y1, x2, y2, style)
2197 register int x1, y1, x2, y2;
2200 register struct monst *mtmp;
2201 register struct obj *otmp, *otmp2;
2202 register int dx, dy;
2203 struct obj *singleobj;
2204 boolean used_up = FALSE;
2205 boolean otherside = FALSE;
2210 otmp = sobj_at(otyp, x1, y1);
2211 /* Try the other side too, for rolling boulder traps */
2212 if (!otmp && otyp == BOULDER) {
2214 otmp = sobj_at(otyp, x2, y2);
2218 if (otherside) { /* swap 'em */
2229 if (otmp->quan == 1L) {
2230 obj_extract_self(otmp);
2232 otmp = (struct obj *) 0;
2234 singleobj = splitobj(otmp, 1L);
2235 obj_extract_self(singleobj);
2238 /* in case you're using a pick-axe to chop the boulder that's being
2239 launched (perhaps a monster triggered it), destroy context so that
2240 next dig attempt never thinks you're resuming previous effort */
2241 if ((otyp == BOULDER || otyp == STATUE)
2242 && singleobj->ox == context.digging.pos.x
2243 && singleobj->oy == context.digging.pos.y)
2244 (void) memset((genericptr_t) &context.digging, 0,
2245 sizeof(struct dig_info));
2247 dist = distmin(x1, y1, x2, y2);
2253 case ROLL | LAUNCH_UNSEEN:
2254 if (otyp == BOULDER) {
2256 You_hear(Hallucination ? "someone bowling."
2257 : "rumbling in the distance.");
2259 You_hear(Hallucination ? "
\92N
\82©
\82ª
\83{
\81[
\83\8a\83\93\83O
\82ð
\82µ
\82Ä
\82¢
\82é
\89¹
\82ð
\95·
\82¢
\82½
\81D"
2260 : "
\89\93\82
\82Ì
\83S
\83\8d\83S
\83\8d\82Æ
\82¢
\82¤
\89¹
\82ð
\95·
\82¢
\82½
\81D");
2263 style &= ~LAUNCH_UNSEEN;
2265 case ROLL | LAUNCH_KNOWN:
2266 /* use otrapped as a flag to ohitmon */
2267 singleobj->otrapped = 1;
2268 style &= ~LAUNCH_KNOWN;
2277 if (!cansee(bhitpos.x, bhitpos.y))
2279 tmp_at(DISP_FLASH, obj_to_glyph(singleobj));
2280 tmp_at(bhitpos.x, bhitpos.y);
2282 /* Mark a spot to place object in bones files to prevent
2283 * loss of object. Use the starting spot to ensure that
2284 * a rolling boulder will still launch, which it wouldn't
2285 * do if left midstream. Unfortunately we can't use the
2286 * target resting spot, because there are some things/situations
2287 * that would prevent it from ever getting there (bars), and we
2288 * can't tell that yet.
2290 launch_drop_spot(singleobj, bhitpos.x, bhitpos.y);
2292 /* Set the object in motion */
2293 while (dist-- > 0 && !used_up) {
2295 tmp_at(bhitpos.x, bhitpos.y);
2298 /* dstage@u.washington.edu -- Delay only if hero sees it */
2299 if (cansee(bhitpos.x, bhitpos.y))
2305 t = t_at(bhitpos.x, bhitpos.y);
2307 if ((mtmp = m_at(bhitpos.x, bhitpos.y)) != 0) {
2308 if (otyp == BOULDER && throws_rocks(mtmp->data)) {
2311 pline("%s snatches the boulder.", Monnam(mtmp));
2313 pline("%s
\82Í
\8aâ
\82ð
\82Â
\82©
\82Ý
\8eæ
\82Á
\82½
\81D", Monnam(mtmp));
2314 singleobj->otrapped = 0;
2315 (void) mpickobj(mtmp, singleobj);
2317 launch_drop_spot((struct obj *) 0, 0, 0);
2321 if (ohitmon(mtmp, singleobj, (style == ROLL) ? -1 : dist,
2324 launch_drop_spot((struct obj *) 0, 0, 0);
2327 } else if (bhitpos.x == u.ux && bhitpos.y == u.uy) {
2330 if (thitu(9 + singleobj->spe, dmgval(singleobj, &youmonst),
2331 singleobj, (char *) 0))
2334 if (style == ROLL) {
2335 if (down_gate(bhitpos.x, bhitpos.y) != -1) {
2336 if (ship_object(singleobj, bhitpos.x, bhitpos.y, FALSE)) {
2338 launch_drop_spot((struct obj *) 0, 0, 0);
2342 if (t && otyp == BOULDER) {
2349 cansee(bhitpos.x, bhitpos.y)
2350 ? " The rolling boulder triggers a land mine."
2354 "
\82¿
\82ã
\82Ç
\81[
\82ñ
\81I
\81I%s",
2355 cansee(bhitpos.x, bhitpos.y)
2356 ? "
\93]
\82ª
\82Á
\82Ä
\82«
\82½
\8aâ
\82ª
\92n
\97\8b\82Ì
\8bN
\94\9a\83X
\83C
\83b
\83`
\82ð
\93¥
\82ñ
\82¾
\81D"
2360 del_engr_at(bhitpos.x, bhitpos.y);
2361 place_object(singleobj, bhitpos.x, bhitpos.y);
2362 singleobj->otrapped = 0;
2363 fracture_rock(singleobj);
2364 (void) scatter(bhitpos.x, bhitpos.y, 4,
2365 MAY_DESTROY | MAY_HIT | MAY_FRACTURE
2368 if (cansee(bhitpos.x, bhitpos.y))
2369 newsym(bhitpos.x, bhitpos.y);
2371 launch_drop_spot((struct obj *) 0, 0, 0);
2376 if (cansee(bhitpos.x, bhitpos.y))
2378 pline("Suddenly the rolling boulder disappears!");
2380 pline("
\93]
\82ª
\82Á
\82Ä
\82«
\82½
\8aâ
\82ª
\82Æ
\82Â
\82º
\82ñ
\8fÁ
\82¦
\82½
\81I");
2383 You_hear("a rumbling stop abruptly.");
2385 pline("
\83S
\83\8d\83S
\83\8d\82Æ
\82¢
\82¤
\89¹
\82ª
\93Ë
\91R
\8e~
\82Ü
\82Á
\82½
\81D");
2386 singleobj->otrapped = 0;
2387 if (t->ttyp == TELEP_TRAP)
2388 (void) rloco(singleobj);
2390 int newlev = random_teleport_level();
2393 if (newlev == depth(&u.uz) || In_endgame(&u.uz))
2395 add_to_migration(singleobj);
2396 get_level(&dest, newlev);
2397 singleobj->ox = dest.dnum;
2398 singleobj->oy = dest.dlevel;
2399 singleobj->owornmask = (long) MIGR_RANDOM;
2403 launch_drop_spot((struct obj *) 0, 0, 0);
2409 /* the boulder won't be used up if there is a
2410 monster in the trap; stop rolling anyway */
2411 x2 = bhitpos.x, y2 = bhitpos.y; /* stops here */
2413 if (flooreffects(singleobj, x2, y2, "fall")) {
2415 if (flooreffects(singleobj, x2, y2, "
\97\8e\82¿
\82é")) {
2417 launch_drop_spot((struct obj *) 0, 0, 0);
2419 dist = -1; /* stop rolling immediately */
2422 if (used_up || dist == -1)
2426 if (flooreffects(singleobj, bhitpos.x, bhitpos.y, "fall")) {
2428 if (flooreffects(singleobj, bhitpos.x, bhitpos.y, "
\97\8e\82¿
\82é")) {
2430 launch_drop_spot((struct obj *) 0, 0, 0);
2434 && (otmp2 = sobj_at(BOULDER, bhitpos.x, bhitpos.y)) != 0) {
2436 const char *bmsg = " as one boulder sets another in motion";
2438 const char *bmsg = "
\82Ð
\82Æ
\82Â
\82Ì
\8aâ
\82ª
\91¼
\82Ì
\8aâ
\82ð
\93®
\82©
\82µ
\82½
\82©
\82Ì
\82æ
\82¤
\82È
\81C";
2440 if (!isok(bhitpos.x + dx, bhitpos.y + dy) || !dist
2441 || IS_ROCK(levl[bhitpos.x + dx][bhitpos.y + dy].typ))
2443 bmsg = " as one boulder hits another";
2445 bmsg = "
\82Ð
\82Æ
\82Â
\82Ì
\8aâ
\82ª
\91¼
\82Ì
\8aâ
\82É
\93\96\82½
\82Á
\82½
\82æ
\82¤
\82È";
2448 You_hear("a loud crash%s!",
2450 You_hear("%s
\91å
\82«
\82È
\83S
\83\93\82Æ
\82¢
\82¤
\89¹
\82ð
\95·
\82¢
\82½
\81I",
2451 cansee(bhitpos.x, bhitpos.y) ? bmsg : "");
2452 obj_extract_self(otmp2);
2453 /* pass off the otrapped flag to the next boulder */
2454 otmp2->otrapped = singleobj->otrapped;
2455 singleobj->otrapped = 0;
2456 place_object(singleobj, bhitpos.x, bhitpos.y);
2458 otmp2 = (struct obj *) 0;
2459 wake_nearto(bhitpos.x, bhitpos.y, 10 * 10);
2462 if (otyp == BOULDER && closed_door(bhitpos.x, bhitpos.y)) {
2463 if (cansee(bhitpos.x, bhitpos.y))
2465 pline_The("boulder crashes through a door.");
2467 pline("
\8aâ
\82Í
\94à
\82ð
\94j
\89ó
\82µ
\82½
\81D");
2468 levl[bhitpos.x][bhitpos.y].doormask = D_BROKEN;
2470 unblock_point(bhitpos.x, bhitpos.y);
2473 /* if about to hit iron bars, do so now */
2474 if (dist > 0 && isok(bhitpos.x + dx, bhitpos.y + dy)
2475 && levl[bhitpos.x + dx][bhitpos.y + dy].typ == IRONBARS) {
2476 x2 = bhitpos.x, y2 = bhitpos.y; /* object stops here */
2477 if (hits_bars(&singleobj, x2, y2, !rn2(20), 0)) {
2480 launch_drop_spot((struct obj *) 0, 0, 0);
2486 tmp_at(DISP_END, 0);
2487 launch_drop_spot((struct obj *) 0, 0, 0);
2489 singleobj->otrapped = 0;
2490 place_object(singleobj, x2, y2);
2503 newsym(trap->tx, trap->ty);
2507 /* like seetrap() but overrides vision */
2514 /* in case it's beneath something, redisplay the something */
2515 newsym(trap->tx, trap->ty);
2519 mkroll_launch(ttmp, x, y, otyp, ocount)
2532 boolean success = FALSE;
2535 if (ttmp->ttyp == ROLLING_BOULDER_TRAP)
2537 distance = rn1(5, 4); /* 4..8 away */
2538 tmp = rn2(8); /* randomly pick a direction to try first */
2539 while (distance >= mindist) {
2544 /* Prevent boulder from being placed on water */
2545 if (ttmp->ttyp == ROLLING_BOULDER_TRAP
2546 && is_pool_or_lava(x + distance * dx, y + distance * dy))
2549 success = isclearpath(&cc, distance, dx, dy);
2550 if (ttmp->ttyp == ROLLING_BOULDER_TRAP) {
2551 boolean success_otherway;
2555 success_otherway = isclearpath(&bcc, distance, -(dx), -(dy));
2556 if (!success_otherway)
2563 if ((++trycount % 8) == 0)
2567 /* create the trap without any ammo, launch pt at trap location */
2571 otmp = mksobj(otyp, TRUE, FALSE);
2572 otmp->quan = ocount;
2573 otmp->owt = weight(otmp);
2574 place_object(otmp, cc.x, cc.y);
2577 ttmp->launch.x = cc.x;
2578 ttmp->launch.y = cc.y;
2579 if (ttmp->ttyp == ROLLING_BOULDER_TRAP) {
2580 ttmp->launch2.x = bcc.x;
2581 ttmp->launch2.y = bcc.y;
2583 ttmp->launch_otyp = otyp;
2584 newsym(ttmp->launch.x, ttmp->launch.y);
2589 isclearpath(cc, distance, dx, dy)
2599 while (distance-- > 0) {
2602 typ = levl[x][y].typ;
2603 if (!isok(x, y) || !ZAP_POS(typ) || closed_door(x, y))
2613 register struct monst *mtmp;
2615 register struct trap *trap = t_at(mtmp->mx, mtmp->my);
2616 boolean trapkilled = FALSE;
2617 struct permonst *mptr = mtmp->data;
2621 mtmp->mtrapped = 0; /* perhaps teleported? */
2622 } else if (mtmp->mtrapped) { /* is currently in the trap */
2623 if (!trap->tseen && cansee(mtmp->mx, mtmp->my) && canseemon(mtmp)
2624 && (trap->ttyp == SPIKED_PIT || trap->ttyp == BEAR_TRAP
2625 || trap->ttyp == HOLE || trap->ttyp == PIT
2626 || trap->ttyp == WEB)) {
2627 /* If you come upon an obviously trapped monster, then
2628 * you must be able to see the trap it's in too.
2634 if (sobj_at(BOULDER, mtmp->mx, mtmp->my)
2635 && (trap->ttyp == PIT || trap->ttyp == SPIKED_PIT)) {
2638 if (canseemon(mtmp))
2640 pline("%s pulls free...", Monnam(mtmp));
2642 pline("%s
\82Í
\8f\95\82¯
\8fã
\82°
\82ç
\82ê
\82½
\81D", Monnam(mtmp));
2643 fill_pit(mtmp->mx, mtmp->my);
2648 } else if (metallivorous(mptr)) {
2649 if (trap->ttyp == BEAR_TRAP) {
2650 if (canseemon(mtmp))
2652 pline("%s eats a bear trap!", Monnam(mtmp));
2654 pline("%s
\82Í
\8cF
\82Ìã©
\82ð
\90H
\82×
\82½
\81I", Monnam(mtmp));
2658 } else if (trap->ttyp == SPIKED_PIT) {
2659 if (canseemon(mtmp))
2661 pline("%s munches on some spikes!", Monnam(mtmp));
2663 pline("%s
\82Í
\83g
\83Q
\83g
\83Q
\82ð
\90H
\82×
\82½
\81I", Monnam(mtmp));
2669 register int tt = trap->ttyp;
2670 boolean in_sight, tear_web, see_it,
2671 inescapable = force_mintrap || ((tt == HOLE || tt == PIT)
2672 && Sokoban && !trap->madeby_u);
2673 const char *fallverb;
2675 /* true when called from dotrap, inescapable is not an option */
2676 if (mtmp == u.usteed)
2678 if (!inescapable && ((mtmp->mtrapseen & (1 << (tt - 1))) != 0
2679 || (tt == HOLE && !mindless(mptr)))) {
2680 /* it has been in such a trap - perhaps it escapes */
2684 mtmp->mtrapseen |= (1 << (tt - 1));
2686 /* Monster is aggravated by being trapped by you.
2687 Recognizing who made the trap isn't completely
2688 unreasonable; everybody has their own style. */
2689 if (trap->madeby_u && rnl(5))
2692 in_sight = canseemon(mtmp);
2693 see_it = cansee(mtmp->mx, mtmp->my);
2694 /* assume hero can tell what's going on for the steed */
2695 if (mtmp == u.usteed)
2699 if (trap->once && trap->tseen && !rn2(15)) {
2700 if (in_sight && see_it)
2702 pline("%s triggers a trap but nothing happens.",
2705 pline("%s
\82ª
\82í
\82È
\82ð
\8bN
\93®
\82³
\82¹
\82½
\82ª
\89½
\82à
\8bN
\82±
\82ç
\82È
\82©
\82Á
\82½
\81D",
2709 newsym(mtmp->mx, mtmp->my);
2713 otmp = mksobj(ARROW, TRUE, FALSE);
2715 otmp->owt = weight(otmp);
2716 otmp->opoisoned = 0;
2719 if (thitm(8, mtmp, otmp, 0, FALSE))
2723 if (trap->once && trap->tseen && !rn2(15)) {
2724 if (in_sight && see_it)
2726 pline("%s triggers a trap but nothing happens.",
2729 pline("%s
\82ª
\82í
\82È
\82ð
\8bN
\93®
\82³
\82¹
\82½
\82ª
\89½
\82à
\8bN
\82±
\82ç
\82È
\82©
\82Á
\82½
\81D",
2733 newsym(mtmp->mx, mtmp->my);
2737 otmp = mksobj(DART, TRUE, FALSE);
2739 otmp->owt = weight(otmp);
2741 otmp->opoisoned = 1;
2744 if (thitm(7, mtmp, otmp, 0, FALSE))
2748 if (trap->once && trap->tseen && !rn2(15)) {
2749 if (in_sight && see_it)
2752 "A trap door above %s opens, but nothing falls out!",
2754 "%s
\82Ì
\8fã
\82Ì
\94à
\82ª
\8aJ
\82¢
\82½
\82ª
\81C
\89½
\82à
\97\8e\82¿
\82Ä
\82±
\82È
\82©
\82Á
\82½
\81I",
2757 newsym(mtmp->mx, mtmp->my);
2761 otmp = mksobj(ROCK, TRUE, FALSE);
2763 otmp->owt = weight(otmp);
2766 if (thitm(0, mtmp, otmp, d(2, 6), FALSE))
2772 /* stepped on a squeaky board */
2776 pline("A board beneath %s squeaks %s loudly.",
2777 mon_nam(mtmp), trapnote(trap, 0));
2779 pline("%s
\82Ì
\91«
\8c³
\82Ì
\94Â
\82ª
\91å
\82«
\82%s
\82É
\82«
\82µ
\82ñ
\82¾
\81D",
2780 mon_nam(mtmp), trapnote(trap, 0));
2785 pline("%s stops momentarily and appears to cringe.",
2787 pline("%s
\82Í
\88ê
\8fu
\8e~
\82Ü
\82Á
\82Ä
\90g
\82ð
\82·
\82
\82ß
\82½
\82æ
\82¤
\82¾
\81D",
2792 You_hear("a distant %s squeak.", trapnote(trap, 1));
2794 You_hear("
\89\93\82
\82Å%s
\82Å
\82«
\82µ
\82Þ
\89¹
\82ð
\95·
\82¢
\82½
\81D", trapnote(trap, 1));
2795 /* wake up nearby monsters */
2796 wake_nearto(mtmp->mx, mtmp->my, 40);
2799 if (mptr->msize > MZ_SMALL && !amorphous(mptr) && !is_flyer(mptr)
2800 && !is_whirly(mptr) && !unsolid(mptr)) {
2804 pline("%s is caught in %s bear trap!", Monnam(mtmp),
2805 a_your[trap->madeby_u]);
2807 pline("%s
\82Í%s
\8cF
\82Ìã©
\82É
\82Â
\82©
\82Ü
\82Á
\82½
\81I", Monnam(mtmp),
2808 set_you[trap->madeby_u]);
2812 if (mptr == &mons[PM_OWLBEAR]
2813 || mptr == &mons[PM_BUGBEAR])
2815 You_hear("the roaring of an angry bear!");
2817 You_hear("
\93{
\82è
\82Ì
\99ô
\9aK
\82ð
\95·
\82¢
\82½
\81I");
2819 } else if (force_mintrap) {
2822 pline("%s evades %s bear trap!", Monnam(mtmp),
2823 a_your[trap->madeby_u]);
2825 pline("%s
\82Í%s
\8cF
\82Ìã©
\82ð
\82½
\82
\82Ý
\82É
\94ð
\82¯
\82½
\81I", Monnam(mtmp),
2826 set_you[trap->madeby_u]);
2832 trapkilled = thitm(0, mtmp, (struct obj *) 0, d(2, 4), FALSE);
2835 if (!resists_sleep(mtmp) && !breathless(mptr) && !mtmp->msleeping
2836 && mtmp->mcanmove) {
2837 if (sleep_monst(mtmp, rnd(25), -1) && in_sight) {
2839 pline("%s suddenly falls asleep!", Monnam(mtmp));
2841 pline("%s
\82Í
\93Ë
\91R
\96°
\82è
\82É
\97\8e\82¿
\82½
\81I", Monnam(mtmp));
2855 pline("%s %s on the %s!", A_gush_of_water_hits,
2856 mon_nam(mtmp), mbodypart(mtmp, HEAD));
2858 pline("
\90\85\82ª
\95¬
\8fo
\82µ
\82Ä
\81C%s
\82Ì%s
\82É
\96½
\92\86\82µ
\82½
\81I",
2859 mon_nam(mtmp), mbodypart(mtmp, HEAD));
2861 target = which_armor(mtmp, W_ARMH);
2862 (void) water_damage(target, helm_simple_name(target), TRUE);
2867 pline("%s %s's left %s!", A_gush_of_water_hits,
2868 mon_nam(mtmp), mbodypart(mtmp, ARM));
2870 pline("
\90\85\82ª
\95¬
\8fo
\82µ
\82Ä
\81C%s
\82Ì
\8d¶%s
\82É
\96½
\92\86\82µ
\82½
\81I",
2871 mon_nam(mtmp), mbodypart(mtmp, ARM));
2873 target = which_armor(mtmp, W_ARMS);
2875 if (water_damage(target, "shield", TRUE) != ER_NOTHING)
2877 if (water_damage(target, "
\8f\82", TRUE) != ER_NOTHING)
2879 target = MON_WEP(mtmp);
2880 if (target && bimanual(target))
2881 (void) water_damage(target, 0, TRUE);
2883 target = which_armor(mtmp, W_ARMG);
2885 (void) water_damage(target, "gauntlets", TRUE);
2887 (void) water_damage(target, "
\8f¬
\8eè", TRUE);
2892 pline("%s %s's right %s!", A_gush_of_water_hits,
2893 mon_nam(mtmp), mbodypart(mtmp, ARM));
2895 pline("
\90\85\82ª
\95¬
\8fo
\82µ
\82Ä
\81C%s
\82Ì
\89E%s
\82É
\96½
\92\86\82µ
\82½
\81I",
2896 mon_nam(mtmp), mbodypart(mtmp, ARM));
2898 (void) water_damage(MON_WEP(mtmp), 0, TRUE);
2903 pline("%s %s!", A_gush_of_water_hits, mon_nam(mtmp));
2905 pline("
\90\85\82ª
\95¬
\8fo
\82µ
\82Ä
\81C%s
\82É
\96½
\92\86\82µ
\82½
\81I", mon_nam(mtmp));
2906 for (otmp = mtmp->minvent; otmp; otmp = otmp->nobj)
2908 && (otmp->owornmask & (W_WEP | W_SWAPWEP)) == 0)
2909 (void) snuff_lit(otmp);
2910 if ((target = which_armor(mtmp, W_ARMC)) != 0)
2911 (void) water_damage(target, cloak_simple_name(target),
2913 else if ((target = which_armor(mtmp, W_ARM)) != 0)
2915 (void) water_damage(target, "armor", TRUE);
2917 (void) water_damage(target, "
\8aZ", TRUE);
2918 else if ((target = which_armor(mtmp, W_ARMU)) != 0)
2920 (void) water_damage(target, "shirt", TRUE);
2922 (void) water_damage(target, "
\83V
\83\83\83c", TRUE);
2925 if (mptr == &mons[PM_IRON_GOLEM]) {
2928 pline("%s falls to pieces!", Monnam(mtmp));
2930 pline("%s
\82Í
\82
\82¾
\82¯
\82¿
\82Á
\82½
\81I", Monnam(mtmp));
2931 else if (mtmp->mtame)
2933 pline("May %s rust in peace.", mon_nam(mtmp));
2935 pline("%s
\82æ
\81C
\88À
\82ç
\82©
\82É
\8eK
\82Ñ
\82ñ
\8e\96\82ð
\81D", mon_nam(mtmp));
2939 } else if (mptr == &mons[PM_GREMLIN] && rn2(3)) {
2940 (void) split_mon(mtmp, (struct monst *) 0);
2948 pline("A %s erupts from the %s under %s!", tower_of_flame,
2949 surface(mtmp->mx, mtmp->my), mon_nam(mtmp));
2951 pline("
\89Î
\92\8c\82ª%s
\82Ì
\91«
\8c³
\82Ì%s
\82©
\82ç
\97§
\82¿
\82Ì
\82Ú
\82Á
\82½
\81I",
2952 mon_nam(mtmp), surface(mtmp->mx,mtmp->my));
2954 else if (see_it) /* evidently `mtmp' is invisible */
2956 You_see("a %s erupt from the %s!", tower_of_flame,
2957 surface(mtmp->mx, mtmp->my));
2959 You("
\89Î
\92\8c\82ª%s
\82©
\82ç
\90¶
\82¶
\82é
\82Ì
\82ð
\8c©
\82½
\81I",
2960 surface(mtmp->mx,mtmp->my));
2963 if (resists_fire(mtmp)) {
2965 shieldeff(mtmp->mx, mtmp->my);
2967 pline("%s is uninjured.", Monnam(mtmp));
2969 pline("
\82ª
\81C%s
\82Í
\8f\9d\82Â
\82©
\82È
\82¢
\81D", Monnam(mtmp));
2972 int num = d(2, 4), alt;
2973 boolean immolate = FALSE;
2975 /* paper burns very fast, assume straw is tightly
2976 * packed and burns a bit slower */
2977 switch (monsndx(mptr)) {
2978 case PM_PAPER_GOLEM:
2982 case PM_STRAW_GOLEM:
2983 alt = mtmp->mhpmax / 2;
2986 alt = mtmp->mhpmax / 4;
2988 case PM_LEATHER_GOLEM:
2989 alt = mtmp->mhpmax / 8;
2998 if (thitm(0, mtmp, (struct obj *) 0, num, immolate))
3001 /* we know mhp is at least `num' below mhpmax,
3002 so no (mhp > mhpmax) check is needed here */
3003 mtmp->mhpmax -= rn2(num + 1);
3005 if (burnarmor(mtmp) || rn2(3)) {
3006 (void) destroy_mitem(mtmp, SCROLL_CLASS, AD_FIRE);
3007 (void) destroy_mitem(mtmp, SPBOOK_CLASS, AD_FIRE);
3008 (void) destroy_mitem(mtmp, POTION_CLASS, AD_FIRE);
3010 if (burn_floor_objects(mtmp->mx, mtmp->my, see_it, FALSE)
3011 && !see_it && distu(mtmp->mx, mtmp->my) <= 3 * 3)
3013 You("smell smoke.");
3015 pline("
\89\8c\82Ì
\93õ
\82¢
\82ª
\82µ
\82½
\81D");
3016 if (is_ice(mtmp->mx, mtmp->my))
3017 melt_ice(mtmp->mx, mtmp->my, (char *) 0);
3026 fallverb = "
\97\8e\82¿
\82½";
3027 if (is_flyer(mptr) || is_floater(mptr)
3028 || (mtmp->wormno && count_wsegs(mtmp) > 5)
3029 || is_clinger(mptr)) {
3030 if (force_mintrap && !Sokoban) {
3031 /* openfallingtrap; not inescapable here */
3035 pline("%s doesn't fall into the pit.", Monnam(mtmp));
3037 pline("%s
\82Í
\97\8e\82µ
\8c\8a\82É
\97\8e\82¿
\82È
\82©
\82Á
\82½
\81D", Monnam(mtmp));
3039 break; /* inescapable = FALSE; */
3042 break; /* avoids trap */
3044 fallverb = "is dragged"; /* sokoban pit */
3046 fallverb = "
\82¸
\82è
\97\8e\82¿
\82½"; /* sokoban pit */
3049 if (!passes_walls(mptr))
3053 pline("%s %s into %s pit!", Monnam(mtmp), fallverb,
3054 a_your[trap->madeby_u]);
3056 pline("%s
\82Í%s
\97\8e\82µ
\8c\8a\82É%s
\81I", Monnam(mtmp),
3057 set_you[trap->madeby_u], fallverb);
3059 if (mptr == &mons[PM_PIT_VIPER]
3060 || mptr == &mons[PM_PIT_FIEND])
3062 pline("How pitiful. Isn't that the pits?");
3064 pline("
\82±
\82Ì
\97\8e\82µ
\8c\8a\82Í
\82¢
\82¢
\8ed
\8e\96\82ð
\82µ
\82Ä
\82¢
\82é
\81D");
3068 mselftouch(mtmp, "Falling, ", FALSE);
3070 mselftouch(mtmp, "
\97\8e\89º
\92\86\81C", FALSE);
3071 if (mtmp->mhp <= 0 || thitm(0, mtmp, (struct obj *) 0,
3072 rnd((tt == PIT) ? 6 : 10), FALSE))
3077 if (!Can_fall_thru(&u.uz)) {
3078 impossible("mintrap: %ss cannot exist on this level.",
3079 defsyms[trap_to_defsym(tt)].explanation);
3080 break; /* don't activate it after all */
3082 if (is_flyer(mptr) || is_floater(mptr) || mptr == &mons[PM_WUMPUS]
3083 || (mtmp->wormno && count_wsegs(mtmp) > 5)
3084 || mptr->msize >= MZ_HUGE) {
3085 if (force_mintrap && !Sokoban) {
3086 /* openfallingtrap; not inescapable here */
3092 "A trap door opens, but %s doesn't fall through.",
3094 "
\97\8e\82µ
\94à
\82ª
\8aJ
\82¢
\82½
\82ª
\81C%s
\82Í
\97\8e\82¿
\82È
\82©
\82Á
\82½
\81D",
3096 else /* (tt == HOLE) */
3098 pline("%s doesn't fall through the hole.",
3100 pline("%s
\82Í
\8c\8a\82É
\97\8e\82¿
\82È
\82©
\82Á
\82½
\81D",
3103 break; /* inescapable = FALSE; */
3105 if (inescapable) { /* sokoban hole */
3108 pline("%s seems to be yanked down!", Monnam(mtmp));
3110 pline("%s
\82Í
\88ø
\82«
\97\8e\82³
\82ê
\82½
\82æ
\82¤
\82¾
\81I", Monnam(mtmp));
3111 /* suppress message in mlevel_tele_trap() */
3120 case MAGIC_PORTAL: {
3123 mlev_res = mlevel_tele_trap(mtmp, trap, inescapable, in_sight);
3129 mtele_trap(mtmp, trap, in_sight);
3132 /* Monster in a web. */
3135 if (amorphous(mptr) || is_whirly(mptr) || unsolid(mptr)) {
3136 if (acidic(mptr) || mptr == &mons[PM_GELATINOUS_CUBE]
3137 || mptr == &mons[PM_FIRE_ELEMENTAL]) {
3140 pline("%s %s %s spider web!", Monnam(mtmp),
3141 (mptr == &mons[PM_FIRE_ELEMENTAL])
3144 a_your[trap->madeby_u]);
3146 pline("%s%s
\82
\82à
\82Ì
\91\83\82ð%s
\81I",
3148 web_you[trap->madeby_u],
3149 (mptr == &mons[PM_FIRE_ELEMENTAL]) ?
3150 "
\8fÄ
\82¢
\82½" : "
\82±
\82È
\82²
\82È
\82É
\82µ
\82½");
3153 newsym(mtmp->mx, mtmp->my);
3158 pline("%s flows through %s spider web.", Monnam(mtmp),
3159 a_your[trap->madeby_u]);
3161 pline("%s
\82Í%s
\82
\82à
\82Ì
\91\83\82ð
\82·
\82é
\82è
\82Æ
\92Ê
\82è
\94²
\82¯
\82½
\81D", Monnam(mtmp),
3162 web_you[trap->madeby_u]);
3169 switch (monsndx(mptr)) {
3170 case PM_OWLBEAR: /* Eric Backus */
3174 You_hear("the roaring of a confused bear!");
3176 You_hear("
\8d¬
\97\90\82Ì
\99ô
\9aK
\82ð
\95·
\82¢
\82½
\81I");
3182 if (mptr->mlet == S_GIANT
3183 /* exclude baby dragons and relatively short worms */
3184 || (mptr->mlet == S_DRAGON && extra_nasty(mptr))
3185 || (mtmp->wormno && count_wsegs(mtmp) > 5)) {
3187 } else if (in_sight) {
3189 pline("%s is caught in %s spider web.", Monnam(mtmp),
3190 a_your[trap->madeby_u]);
3192 pline("%s
\82Í%s
\82
\82à
\82Ì
\91\83\82É
\82Â
\82©
\82Ü
\82Á
\82½
\81D", Monnam(mtmp),
3193 web_you[trap->madeby_u]);
3197 mtmp->mtrapped = tear_web ? 0 : 1;
3199 /* this list is fairly arbitrary; it deliberately
3200 excludes wumpus & giant/ettin zombies/mummies */
3201 case PM_TITANOTHERE:
3202 case PM_BALUCHITHERIUM:
3203 case PM_PURPLE_WORM:
3212 case PM_LORD_SURTUR:
3219 pline("%s tears through %s spider web!", Monnam(mtmp),
3220 a_your[trap->madeby_u]);
3222 pline("%s
\82Í%s
\82
\82à
\82Ì
\91\83\82ð
\88ø
\82«
\97ô
\82¢
\82½
\81I", Monnam(mtmp),
3223 web_you[trap->madeby_u]);
3226 newsym(mtmp->mx, mtmp->my);
3227 } else if (force_mintrap && !mtmp->mtrapped) {
3230 pline("%s avoids %s spider web!", Monnam(mtmp),
3231 a_your[trap->madeby_u]);
3233 pline("%s
\82Í%s
\82
\82à
\82Ì
\91\83\82ð
\94ð
\82¯
\82½
\81I", Monnam(mtmp),
3234 web_you[trap->madeby_u]);
3243 /* A magic trap. Monsters usually immune. */
3248 /* similar to hero's case, more or less */
3249 if (!resists_magm(mtmp)) { /* lose spell energy */
3250 if (!mtmp->mcan && (attacktype(mptr, AT_MAGC)
3251 || attacktype(mptr, AT_BREA))) {
3252 mtmp->mspec_used += d(2, 2);
3256 pline("%s seems lethargic.", Monnam(mtmp));
3258 pline("%s
\88ê
\8fu
\96³
\8bC
\97Í
\8a´
\82ð
\8a´
\82¶
\82½
\81D", Monnam(mtmp));
3261 } else { /* take some damage */
3262 int dmgval2 = rnd(4);
3264 if ((otmp = MON_WEP(mtmp)) != 0
3265 && otmp->oartifact == ART_MAGICBANE)
3267 for (otmp = mtmp->minvent; otmp; otmp = otmp->nobj)
3269 && defends_when_carried(AD_MAGM, otmp))
3273 if (passes_walls(mptr))
3274 dmgval2 = (dmgval2 + 3) / 4;
3278 if ((mtmp->mhp -= dmgval2) <= 0)
3282 ? "compression from an anti-magic field"
3284 ? "
\94½
\96\82\96@
\8bó
\8aÔ
\82Ì
\88³
\8fk"
3290 newsym(trap->tx, trap->ty);
3295 break; /* monsters usually don't set it off */
3296 if (is_flyer(mptr)) {
3297 boolean already_seen = trap->tseen;
3299 if (in_sight && !already_seen) {
3301 pline("A trigger appears in a pile of soil below %s.",
3303 pline("%s
\82Ì
\91«
\8c³
\82Ì
\93y
\82Ì
\8eR
\82É
\8bN
\94\9a\83X
\83C
\83b
\83`
\82ª
\8c»
\82í
\82ê
\82½
\81D",
3310 newsym(mtmp->mx, mtmp->my);
3312 pline_The("air currents set %s off!",
3313 already_seen ? "a land mine" : "it");
3315 pline("
\8bó
\8bC
\82Ì
\97¬
\82ê
\82Å
\83X
\83C
\83b
\83`
\82ª
\93ü
\82Á
\82½
\81I");
3318 } else if (in_sight) {
3319 newsym(mtmp->mx, mtmp->my);
3321 pline("KAABLAMM!!! %s triggers %s land mine!", Monnam(mtmp),
3322 a_your[trap->madeby_u]);
3324 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),
3325 set_you[trap->madeby_u]);
3330 pline("Kaablamm! You hear an explosion in the distance!");
3332 pline("
\82¿
\82ã
\82Ç
\81[
\82ñ
\81I
\82 \82È
\82½
\82Í
\89\93\95û
\82Ì
\94\9a\94
\89¹
\82ð
\95·
\82¢
\82½
\81I");
3333 blow_up_landmine(trap);
3334 /* explosion might have destroyed a drawbridge; don't
3335 dish out more damage if monster is already dead */
3337 || thitm(0, mtmp, (struct obj *) 0, rnd(16), FALSE))
3340 /* monsters recursively fall into new pit */
3341 if (mintrap(mtmp) == 2)
3344 /* a boulder may fill the new pit, crushing monster */
3345 fill_pit(trap->tx, trap->ty);
3348 if (unconscious()) {
3351 nomovemsg = "The explosion awakens you!";
3353 nomovemsg = "
\94\9a\94
\82Å
\82 \82È
\82½
\82Í
\8bN
\82«
\82½
\81I";
3357 if (resists_magm(mtmp)) {
3358 shieldeff(mtmp->mx, mtmp->my);
3359 } else if (!resist(mtmp, WAND_CLASS, 0, NOTELL)) {
3360 if (newcham(mtmp, (struct permonst *) 0, FALSE, FALSE))
3361 /* we're done with mptr but keep it up to date */
3367 case ROLLING_BOULDER_TRAP:
3368 if (!is_flyer(mptr)) {
3369 int style = ROLL | (in_sight ? 0 : LAUNCH_UNSEEN);
3371 newsym(mtmp->mx, mtmp->my);
3374 pline("Click! %s triggers %s.", Monnam(mtmp),
3375 trap->tseen ? "a rolling boulder trap" : something);
3377 pline("
\83J
\83`
\83b
\81I%s
\82Í%s
\82Ì
\83X
\83C
\83b
\83`
\82ð
\93¥
\82ñ
\82¾
\81I", Monnam(mtmp),
3378 trap->tseen ? "
\97\8e\8aâ
\82Ìã©" : "
\89½
\82©");
3380 if (launch_obj(BOULDER, trap->launch.x, trap->launch.y,
3381 trap->launch2.x, trap->launch2.y, style)) {
3388 newsym(mtmp->mx, mtmp->my);
3392 case VIBRATING_SQUARE:
3393 if (see_it && !Blind) {
3396 pline("You see a strange vibration beneath %s %s.",
3397 s_suffix(mon_nam(mtmp)),
3398 makeplural(mbodypart(mtmp, FOOT)));
3400 pline("%s
\82Ì%s
\82ª
\95s
\8ev
\8bc
\82É
\90U
\93®
\82µ
\82Ä
\82¢
\82é
\82Ì
\82ð
\8c©
\82½
\81D",
3401 mon_nam(mtmp), mbodypart(mtmp, FOOT));
3405 pline("You see the ground vibrate in the distance.");
3407 pline("
\89\93\82
\82Å
\92n
\96Ê
\82ª
\90U
\93®
\82µ
\82Ä
\82¢
\82é
\82Ì
\82ð
\8c©
\82½
\81D");
3412 impossible("Some monster encountered a strange trap of type %d.",
3418 return mtmp->mtrapped;
3421 /* Combine cockatrice checks into single functions to avoid repeating code. */
3426 if (Stone_resistance)
3428 if (poly_when_stoned(youmonst.data) && polymon(PM_STONE_GOLEM))
3431 You("turn to stone...");
3433 You("
\90Î
\82É
\82È
\82Á
\82½
\81D
\81D
\81D");
3434 killer.format = KILLED_BY;
3435 if (str != killer.name)
3436 Strcpy(killer.name, str ? str : "");
3441 minstapetrify(mon, byplayer)
3445 if (resists_ston(mon))
3447 if (poly_when_stoned(mon->data)) {
3452 /* give a "<mon> is slowing down" message and also remove
3453 intrinsic speed (comparable to similar effect on the hero) */
3454 mon_adjust_speed(mon, -3, (struct obj *) 0);
3456 if (cansee(mon->mx, mon->my))
3458 pline("%s turns to stone.", Monnam(mon));
3460 pline("%s
\82Í
\90Î
\82É
\82È
\82Á
\82½
\81D", Monnam(mon));
3474 if (uwep && uwep->otyp == CORPSE && touch_petrifies(&mons[uwep->corpsenm])
3475 && !Stone_resistance) {
3477 pline("%s touch the %s corpse.", arg, mons[uwep->corpsenm].mname);
3479 pline("%s%s
\82Ì
\8e\80\91Ì
\82É
\90G
\82Á
\82½
\81D", arg, mons[uwep->corpsenm].mname);
3481 Sprintf(kbuf, "%s corpse", an(mons[uwep->corpsenm].mname));
3483 Sprintf(kbuf, "%s
\82Ì
\8e\80\91Ì
\82Å", mons[uwep->corpsenm].mname);
3485 /* life-saved; unwield the corpse if we can't handle it */
3486 if (!uarmg && !Stone_resistance)
3489 /* Or your secondary weapon, if wielded [hypothetical; we don't
3490 allow two-weapon combat when either weapon is a corpse] */
3491 if (u.twoweap && uswapwep && uswapwep->otyp == CORPSE
3492 && touch_petrifies(&mons[uswapwep->corpsenm]) && !Stone_resistance) {
3494 pline("%s touch the %s corpse.", arg, mons[uswapwep->corpsenm].mname);
3496 pline("%s%s
\82Ì
\8e\80\91Ì
\82É
\90G
\82Á
\82½
\81D", arg, mons[uswapwep->corpsenm].mname);
3498 Sprintf(kbuf, "%s corpse", an(mons[uswapwep->corpsenm].mname));
3500 Sprintf(kbuf, "%s
\82Ì
\8e\80\91Ì
\82Å", mons[uswapwep->corpsenm].mname);
3502 /* life-saved; unwield the corpse */
3503 if (!uarmg && !Stone_resistance)
3509 mselftouch(mon, arg, byplayer)
3514 struct obj *mwep = MON_WEP(mon);
3516 if (mwep && mwep->otyp == CORPSE && touch_petrifies(&mons[mwep->corpsenm])
3517 && !resists_ston(mon)) {
3518 if (cansee(mon->mx, mon->my)) {
3520 pline("%s%s touches %s.", arg ? arg : "",
3521 arg ? mon_nam(mon) : Monnam(mon),
3522 corpse_xname(mwep, (const char *) 0, CXN_PFX_THE));
3524 pline("%s%s
\82Í%s
\82Ì
\8e\80\91Ì
\82É
\90G
\82Á
\82½
\81D", arg ? arg : "",
3525 arg ? mon_nam(mon) : Monnam(mon),
3526 corpse_xname(mwep, (const char *) 0, CXN_PFX_THE));
3529 minstapetrify(mon, byplayer);
3530 /* if life-saved, might not be able to continue wielding */
3531 if (mon->mhp > 0 && !which_armor(mon, W_ARMG) && !resists_ston(mon))
3536 /* start levitating */
3541 if (u.utraptype == TT_PIT) {
3544 You("float up, out of the pit!");
3546 You("
\95\82\82«
\8fã
\82ª
\82Á
\82Ä
\81C
\97\8e\82µ
\8c\8a\82©
\82ç
\8fo
\82½
\81I");
3547 vision_full_recalc = 1; /* vision limits change */
3548 fill_pit(u.ux, u.uy);
3549 } else if (u.utraptype == TT_INFLOOR) {
3551 Your("body pulls upward, but your %s are still stuck.",
3553 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",
3554 makeplural(body_part(LEG)));
3557 You("float up, only your %s is still stuck.", body_part(LEG));
3559 You("
\95\82\82«
\8fo
\82½
\81D%s
\82¾
\82¯
\82ª
\82Í
\82Ü
\82Á
\82Ä
\82¢
\82é
\81D", body_part(LEG));
3562 } else if (Is_waterlevel(&u.uz)) {
3564 pline("It feels as though you've lost some weight.");
3566 You("
\82Ü
\82é
\82Å
\91Ì
\8fd
\82ª
\8c¸
\82Á
\82½
\82æ
\82¤
\82É
\8a´
\82¶
\82½
\81D");
3568 } else if (u.uinwater) {
3570 } else if (u.uswallow) {
3572 You(is_animal(u.ustuck->data) ? "float away from the %s."
3573 : "spiral up into %s.",
3574 is_animal(u.ustuck->data) ? surface(u.ux, u.uy)
3575 : mon_nam(u.ustuck));
3577 You(is_animal(u.ustuck->data) ? "%s
\82Ì
\92\86\82Å
\95\82\82¢
\82½
\81D"
3578 : "%s
\82Ì
\92\86\82Å
\82®
\82é
\82®
\82é
\89ñ
\93]
\82µ
\82½
\81D",
3579 is_animal(u.ustuck->data) ? surface(u.ux, u.uy)
3580 : mon_nam(u.ustuck));
3582 } else if (Hallucination) {
3584 pline("Up, up, and awaaaay! You're walking on air!");
3586 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");
3587 } else if (Is_airlevel(&u.uz)) {
3589 You("gain control over your movements.");
3591 You("
\82¤
\82Ü
\82
\93®
\82¯
\82é
\82æ
\82¤
\82É
\82È
\82Á
\82½
\81D");
3594 You("start to float in the air!");
3596 You("
\8bó
\92\86\82É
\95\82\82«
\82Í
\82¶
\82ß
\82½
\81I");
3598 if (u.usteed && !is_floater(u.usteed->data)
3599 && !is_flyer(u.usteed->data)) {
3602 pline("%s magically floats up!", Monnam(u.usteed));
3604 pline("%s
\82Í
\96\82\96@
\82Ì
\97Í
\82Å
\95\82\82¢
\82½
\81I", Monnam(u.usteed));
3607 You("cannot stay on %s.", mon_nam(u.usteed));
3609 You("%s
\82Ì
\8fã
\82É
\8fæ
\82Á
\82Ä
\82¢
\82ç
\82ê
\82È
\82¢
\81D", mon_nam(u.usteed));
3610 dismount_steed(DISMOUNT_GENERIC);
3615 You("are no longer able to control your flight.");
3617 You("
\8bó
\92\86\82Å
\82¤
\82Ü
\82
\93®
\82¯
\82È
\82
\82È
\82Á
\82½
\81D");
3618 BFlying |= I_SPECIAL;
3629 if ((t = t_at(x, y)) && ((t->ttyp == PIT) || (t->ttyp == SPIKED_PIT))
3630 && (otmp = sobj_at(BOULDER, x, y))) {
3631 obj_extract_self(otmp);
3633 (void) flooreffects(otmp, x, y, "settle");
3635 (void) flooreffects(otmp, x, y, "
\82Í
\82Ü
\82é");
3639 /* stop levitating */
3641 float_down(hmask, emask)
3642 long hmask, emask; /* might cancel timeout */
3644 register struct trap *trap = (struct trap *) 0;
3645 d_level current_dungeon_level;
3646 boolean no_msg = FALSE;
3648 HLevitation &= ~hmask;
3649 ELevitation &= ~emask;
3651 return 0; /* maybe another ring/potion/boots */
3653 /* Levitation is blocked, so hero is not actually floating
3654 hence shouldn't have float_down effects and feedback */
3655 float_vs_flight(); /* before nomul() rather than after */
3658 nomul(0); /* stop running or resting */
3660 /* controlled flight no longer overridden by levitation */
3661 BFlying &= ~I_SPECIAL;
3664 You("have stopped levitating and are now flying.");
3666 You("
\8bó
\92\86\95\82\97V
\82ð
\8e~
\82ß
\82Ä
\8bó
\82ð
\94ò
\82Ñ
\82Í
\82¶
\82ß
\82½
\81D");
3672 You("float down, but you are still %s.",
3673 is_animal(u.ustuck->data) ? "swallowed" : "engulfed");
3675 You("
\92\85\92n
\82µ
\82½
\82ª
\81C
\82Ü
\82¾
\88ù
\82Ý
\8d\9e\82Ü
\82ê
\82½
\82Ü
\82Ü
\82¾
\81D");
3680 if (Punished && !carried(uball)
3681 && (is_pool(uball->ox, uball->oy)
3682 || ((trap = t_at(uball->ox, uball->oy))
3683 && ((trap->ttyp == PIT) || (trap->ttyp == SPIKED_PIT)
3684 || (trap->ttyp == TRAPDOOR) || (trap->ttyp == HOLE))))) {
3689 movobj(uchain, uball->ox, uball->oy);
3690 newsym(u.ux0, u.uy0);
3691 vision_full_recalc = 1; /* in case the hero moved. */
3693 /* check for falling into pool - added by GAN 10/20/86 */
3695 if (!u.uswallow && u.ustuck) {
3696 if (sticks(youmonst.data))
3698 You("aren't able to maintain your hold on %s.",
3701 You("%s
\82ð
\82Â
\82©
\82Ü
\82¦
\91±
\82¯
\82Ä
\82¢
\82ç
\82ê
\82È
\82
\82È
\82Á
\82½
\81D",
3706 pline("Startled, %s can no longer hold you!",
3709 pline("%s
\82Í
\8bÁ
\82¢
\82Ä
\82 \82È
\82½
\82ð
\95ú
\82µ
\82Ä
\82µ
\82Ü
\82Á
\82½
\81I",
3715 * drown() and lava_effects() print various messages almost
3716 * every time they're called which conflict with the "fall
3717 * into" message below. Thus, we want to avoid printing
3718 * confusing, duplicate or out-of-order messages.
3719 * Use knowledge of the two routines as a hack -- this
3720 * should really be handled differently -dlc
3722 if (is_pool(u.ux, u.uy) && !Wwalking && !Swimming && !u.uinwater)
3725 if (is_lava(u.ux, u.uy)) {
3726 (void) lava_effects();
3731 trap = t_at(u.ux, u.uy);
3732 if (Is_airlevel(&u.uz)) {
3734 You("begin to tumble in place.");
3736 You("
\82»
\82Ì
\8fê
\82Å
\82Ð
\82Á
\82
\82è
\95Ô
\82è
\82Í
\82¶
\82ß
\82½
\81D");
3737 } else if (Is_waterlevel(&u.uz) && !no_msg) {
3739 You_feel("heavier.");
3741 You("
\8fd
\82
\82È
\82Á
\82½
\82æ
\82¤
\82È
\8bC
\82ª
\82µ
\82½
\81D");
3742 /* u.uinwater msgs already in spoteffects()/drown() */
3743 } else if (!u.uinwater && !no_msg) {
3744 if (!(emask & W_SADDLE)) {
3745 if (Sokoban && trap) {
3746 /* Justification elsewhere for Sokoban traps is based
3747 * on air currents. This is consistent with that.
3748 * The unexpected additional force of the air currents
3749 * once levitation ceases knocks you off your feet.
3753 pline("Bummer! You've crashed.");
3755 pline("
\82â
\82ß
\82Ä
\82¥
\81I
\82 \82È
\82½
\82Í
\92@
\82«
\82Â
\82¯
\82ç
\82ê
\82½
\81D");
3760 You("
\82Â
\82Ü
\82Ã
\82¢
\82½
\81D");
3762 losehp(rnd(2), "dangerous winds", KILLED_BY);
3764 losehp(rnd(2), "
\8aë
\8c¯
\82È
\95\97\82Å", KILLED_BY);
3766 dismount_steed(DISMOUNT_FELL);
3768 selftouch("As you fall, you");
3770 selftouch("
\97\8e\82¿
\82È
\82ª
\82ç
\81C
\82 \82È
\82½
\82Í");
3771 } else if (u.usteed && (is_floater(u.usteed->data)
3772 || is_flyer(u.usteed->data))) {
3774 You("settle more firmly in the saddle.");
3776 You("
\82æ
\82è
\82µ
\82Á
\82©
\82è
\82Æ
\88Æ
\82É
\94[
\82Ü
\82Á
\82½
\81D");
3777 } else if (Hallucination) {
3779 pline("Bummer! You've %s.",
3782 : "hit the ground");
3784 pline("
\82â
\82ß
\82Ä
\82¥
\81I
\82 \82È
\82½
\82Í%s
\82É
\92@
\82«
\82Â
\82¯
\82ç
\82ê
\82½
\81D",
3791 You("float gently to the %s.", surface(u.ux, u.uy));
3793 You("
\90Ã
\82©
\82É%s
\82Ü
\82Å
\92H
\82è
\82Â
\82¢
\82½
\81D", surface(u.ux, u.uy));
3799 /* can't rely on u.uz0 for detecting trap door-induced level change;
3800 it gets changed to reflect the new level before we can check it */
3801 assign_level(¤t_dungeon_level, &u.uz);
3803 switch (trap->ttyp) {
3808 if (!Can_fall_thru(&u.uz) || u.ustuck)
3812 if (!u.utrap) /* not already in the trap */
3816 if (!Is_airlevel(&u.uz) && !Is_waterlevel(&u.uz) && !u.uswallow
3817 /* falling through trap door calls goto_level,
3818 and goto_level does its own pickup() call */
3819 && on_level(&u.uz, ¤t_dungeon_level))
3824 /* shared code for climbing out of a pit */
3828 if (!u.utrap || u.utraptype != TT_PIT)
3832 /* marked as trapped so they can pick things up */
3834 You("ascend from the pit.");
3836 You("
\97\8e\82µ
\8c\8a\82ð
\8fã
\82Á
\82Ä
\82¢
\82Á
\82½
\81D");
3838 fill_pit(u.ux, u.uy);
3839 vision_full_recalc = 1; /* vision limits change */
3840 } else if (!rn2(2) && sobj_at(BOULDER, u.ux, u.uy)) {
3842 Your("%s gets stuck in a crevice.", body_part(LEG));
3844 Your("%s
\82Í
\8a\84\82ê
\96Ú
\82É
\82Í
\82Ü
\82Á
\82½
\81D", body_part(LEG));
3845 display_nhwindow(WIN_MESSAGE, FALSE);
3846 clear_nhwindow(WIN_MESSAGE);
3848 You("free your %s.", body_part(LEG));
3850 Your("%s
\82Í
\8e©
\97R
\82É
\82È
\82Á
\82½
\81D", body_part(LEG));
3851 } else if ((Flying || is_clinger(youmonst.data)) && !Sokoban) {
3852 /* eg fell in pit, then poly'd to a flying monster;
3853 or used '>' to deliberately enter it */
3855 You("%s from the pit.", Flying ? "fly" : "climb");
3857 You("
\97\8e\82µ
\8c\8a\82©
\82ç%s
\82¢
\82Á
\82½
\81D", Flying ? "
\8fã
\82Á
\82Ä" : "
\93o
\82Á
\82Ä");
3859 fill_pit(u.ux, u.uy);
3860 vision_full_recalc = 1; /* vision limits change */
3861 } else if (!(--u.utrap)) {
3863 You("%s to the edge of the pit.",
3864 (Sokoban && Levitation)
3865 ? "struggle against the air currents and float"
3866 : u.usteed ? "ride" : "crawl");
3868 You("%s
\97\8e\82µ
\8c\8a\82Ì
\92[
\82É
\82½
\82Ç
\82è
\92\85\82¢
\82½
\81D",
3869 (Sokoban && Levitation)
3870 ? "
\8bó
\8bC
\82Ì
\97¬
\82ê
\82Ì
\92\86\82Å
\82à
\82ª
\82«
\82È
\82ª
\82ç" : "");
3872 fill_pit(u.ux, u.uy);
3873 vision_full_recalc = 1; /* vision limits change */
3874 } else if (u.dz || flags.verbose) {
3877 Norep("%s is still in a pit.", upstart(y_monnam(u.usteed)));
3879 Norep("%s
\82Í
\82Ü
\82¾
\97\8e\82µ
\8c\8a\82Ì
\92\86\82É
\82¢
\82é
\81D", y_monnam(u.usteed));
3882 Norep((Hallucination && !rn2(5))
3883 ? "You've fallen, and you can't get up."
3884 : "You are still in a pit.");
3886 Norep((Hallucination && !rn2(5))
3887 ? "
\82 \82È
\82½
\82Í
\97\8e\82¿
\81C
\8fã
\82ª
\82ê
\82È
\82¢
\81D"
3888 : "
\82 \82È
\82½
\82Í
\82Ü
\82¾
\97\8e\82µ
\8c\8a\82Ì
\92\86\82É
\82¢
\82é
\81D");
3895 struct obj *box; /* null for floor trap */
3897 boolean see_it = !Blind;
3900 /* Bug: for box case, the equivalent of burn_floor_objects() ought
3901 * to be done upon its contents.
3904 if ((box && !carried(box)) ? is_pool(box->ox, box->oy) : Underwater) {
3906 pline("A cascade of steamy bubbles erupts from %s!",
3908 pline("
\8fö
\8bC
\82Ì
\96A
\82ª%s
\82©
\82ç
\82µ
\82ã
\81[
\82Á
\82Æ
\94
\90¶
\82µ
\82½
\81I",
3909 the(box ? xname(box) : surface(u.ux, u.uy)));
3910 if (Fire_resistance)
3912 You("are uninjured.");
3914 You("
\8f\9d\82Â
\82©
\82È
\82¢
\81D");
3917 losehp(rnd(3), "boiling water", KILLED_BY);
3919 losehp(rnd(3), "
\95¦
\93«
\82µ
\82½
\90\85\82Å", KILLED_BY);
3923 pline("A %s %s from %s!", tower_of_flame, box ? "bursts" : "erupts",
3924 the(box ? xname(box) : surface(u.ux, u.uy)));
3926 pline("
\89Î
\92\8c\82ª%s
\82©
\82ç%s
\81I", box ? xname(box) : surface(u.ux,u.uy),
3927 box ? "
\90\81\82«
\8fo
\82µ
\82½" : "
\97§
\82¿
\82Ì
\82Ú
\82Á
\82½");
3929 if (Fire_resistance) {
3930 shieldeff(u.ux, u.uy);
3932 } else if (Upolyd) {
3934 switch (u.umonnum) {
3935 case PM_PAPER_GOLEM:
3938 case PM_STRAW_GOLEM:
3944 case PM_LEATHER_GOLEM:
3953 if (u.mhmax > mons[u.umonnum].mlevel)
3954 u.mhmax -= rn2(min(u.mhmax, num + 1)), context.botl = 1;
3957 if (u.uhpmax > u.ulevel)
3958 u.uhpmax -= rn2(min(u.uhpmax, num + 1)), context.botl = 1;
3962 You("are uninjured.");
3964 You("
\8f\9d\82Â
\82©
\82È
\82¢
\81D");
3967 losehp(num, tower_of_flame, KILLED_BY_AN); /* fire damage */
3969 losehp(num, "
\89Î
\92\8c\82Å", KILLED_BY_AN); /* fire damage */
3973 if (burnarmor(&youmonst) || rn2(3)) {
3974 destroy_item(SCROLL_CLASS, AD_FIRE);
3975 destroy_item(SPBOOK_CLASS, AD_FIRE);
3976 destroy_item(POTION_CLASS, AD_FIRE);
3978 if (!box && burn_floor_objects(u.ux, u.uy, see_it, TRUE) && !see_it)
3980 You("smell paper burning.");
3982 You("
\8e\86\82Ì
\82±
\82°
\82é
\93õ
\82¢
\82ª
\82µ
\82½
\81D");
3983 if (is_ice(u.ux, u.uy))
3984 melt_ice(u.ux, u.uy, (char *) 0);
3990 register int fate = rnd(20);
3992 /* What happened to the poor sucker? */
3995 /* Most of the time, it creates some monsters. */
3996 register int cnt = rnd(4);
3998 if (!resists_blnd(&youmonst)) {
4000 You("are momentarily blinded by a flash of light!");
4002 You("
\82Ü
\82Î
\82ä
\82¢
\8cõ
\82Å
\88ê
\8fu
\96Ú
\82ª
\82
\82ç
\82ñ
\82¾
\81I");
4003 make_blinded((long) rn1(5, 10), FALSE);
4005 Your1(vision_clears);
4006 } else if (!Blind) {
4008 You_see("a flash of light!");
4010 You("
\82Ü
\82Î
\82ä
\82¢
\8cõ
\82ð
\97\81\82Ñ
\82½
\81I");
4013 You_hear("a deafening roar!");
4015 You_hear("
\8e¨
\82ð
\82Â
\82ñ
\82´
\82
\82æ
\82¤
\82È
\99ô
\9aK
\82ð
\95·
\82¢
\82½
\81I");
4016 incr_itimeout(&HDeaf, rn1(20, 30));
4018 (void) makemon((struct permonst *) 0, u.ux, u.uy, NO_MM_FLAGS);
4023 /* sometimes nothing happens */
4025 case 12: /* a flash of fire */
4026 dofiretrap((struct obj *) 0);
4032 pline("A shiver runs up and down your %s!", body_part(SPINE));
4034 pline("
\90k
\82¦
\82ª
\82 \82È
\82½
\82Ì%s
\82ð
\91\96\82Á
\82½
\81I", body_part(SPINE));
4038 You_hear(Hallucination ? "the moon howling at you."
4039 : "distant howling.");
4041 You_hear(Hallucination ? "
\8c\8e\82ª
\96i
\82¦
\82Ä
\82¢
\82é
\82Ì
\82ð
\95·
\82¢
\82½
\81D"
4042 : "
\89\93\95û
\82Ì
\89\93\96i
\82ð
\95·
\82¢
\82½
\81D");
4046 if (on_level(&u.uz, &qstart_level))
4049 "%slike the prodigal son.",
4050 (flags.female || (Upolyd && is_neuter(youmonst.data)))
4053 #else /*JP
\90¹
\8f\91\82Ì
\83\8b\83J
\93`
\82æ
\82è */
4054 You("%s
\95ú
\93 \91§
\8eq
\82Ì
\82æ
\82¤
\82É
\82È
\82Á
\82½
\82æ
\82¤
\82È
\8bC
\82ª
\82µ
\82½
\81D",
4055 (flags.female || (Upolyd && is_neuter(youmonst.data)))
4061 You("suddenly yearn for %s.",
4064 : (In_quest(&u.uz) || at_dgn_entrance("The Quest"))
4065 ? "your nearby homeland"
4066 : "your distant homeland");
4068 You("
\93Ë
\91R%s
\82ª
\97ö
\82µ
\82
\82È
\82Á
\82½
\81D",
4069 Hallucination ? "
\90Â
\90X"
4070 : (In_quest(&u.uz) || at_dgn_entrance("
\83N
\83G
\83X
\83g"))
4071 ? "
\82·
\82®
\82»
\82±
\82É
\82 \82é
\8cÌ
\8b½"
4072 : "
\82Í
\82é
\82©
\82©
\82È
\82½
\82Ì
\8cÌ
\8b½");
4077 Your("pack shakes violently!");
4079 Your("
\91Ü
\82Í
\8c\83\82µ
\82
\97h
\82ê
\82½
\81I");
4083 You(Hallucination ? "smell hamburgers." : "smell charred flesh.");
4085 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");
4091 You("
\94æ
\82ê
\82ð
\8a´
\82¶
\82½
\81D");
4094 /* very occasionally something nice happens. */
4095 case 19: { /* tame nearby monsters */
4099 (void) adjattrib(A_CHA, 1, FALSE);
4100 for (i = -1; i <= 1; i++)
4101 for (j = -1; j <= 1; j++) {
4102 if (!isok(u.ux + i, u.uy + j))
4104 mtmp = m_at(u.ux + i, u.uy + j);
4106 (void) tamedog(mtmp, (struct obj *) 0);
4110 case 20: { /* uncurse stuff */
4112 long save_conf = HConfusion;
4114 pseudo = zeroobj; /* neither cursed nor blessed,
4115 and zero out oextra */
4116 pseudo.otyp = SCR_REMOVE_CURSE;
4118 (void) seffects(&pseudo);
4119 HConfusion = save_conf;
4127 /* Set an item on fire.
4128 * "force" means not to roll a luck-based protection check for the
4130 * "x" and "y" are the coordinates to dump the contents of a
4131 * container, if it burns up.
4133 * Return whether the object was destroyed.
4136 fire_damage(obj, force, x, y)
4142 struct obj *otmp, *ncobj;
4143 int in_sight = !Blind && couldsee(x, y); /* Don't care if it's lit */
4146 /* object might light in a controlled manner */
4150 if (Is_container(obj)) {
4151 switch (obj->otyp) {
4153 return FALSE; /* Immune */
4164 if ((!force && (Luck + 5) > rn2(chance))
4165 || (is_flammable(obj) && obj->oerodeproof))
4167 /* Container is burnt up - dump contents out */
4170 pline("%s catches fire and burns.", Yname2(obj));
4172 pline("%s
\82Í
\89Î
\82ª
\82Â
\82¢
\82Ä
\94R
\82¦
\82½
\81D", Yname2(obj));
4173 if (Has_contents(obj)) {
4176 pline("Its contents fall out.");
4178 pline("
\92\86\90g
\82ª
\8fo
\82Ä
\82«
\82½
\81D");
4179 for (otmp = obj->cobj; otmp; otmp = ncobj) {
4181 obj_extract_self(otmp);
4182 if (!flooreffects(otmp, x, y, ""))
4183 place_object(otmp, x, y);
4189 } else if (!force && (Luck + 5) > rn2(20)) {
4190 /* chance per item of sustaining damage:
4191 * max luck (Luck==13): 10%
4192 * avg luck (Luck==0): 75%
4193 * awful luck (Luck<-4): 100%
4196 } else if (obj->oclass == SCROLL_CLASS || obj->oclass == SPBOOK_CLASS) {
4197 if (obj->otyp == SCR_FIRE || obj->otyp == SPE_FIREBALL)
4199 if (obj->otyp == SPE_BOOK_OF_THE_DEAD) {
4202 pline("Smoke rises from %s.", the(xname(obj)));
4204 pline("%s
\82©
\82ç
\89\8c\82ª
\82 \82ª
\82Á
\82½
\81D", the(xname(obj)));
4207 dindx = (obj->oclass == SCROLL_CLASS) ? 3 : 4;
4210 pline("%s %s.", Yname2(obj),
4211 destroy_strings[dindx][(obj->quan > 1L)]);
4213 pline("%s
\82Í%s
\81D", Yname2(obj),
4214 destroy_strings[dindx][(obj->quan > 1L)]);
4219 } else if (obj->oclass == POTION_CLASS) {
4220 dindx = (obj->otyp != POT_OIL) ? 1 : 2;
4223 pline("%s %s.", Yname2(obj),
4224 destroy_strings[dindx][(obj->quan > 1L)]);
4226 pline("%s
\82Í%s
\81D", Yname2(obj),
4227 destroy_strings[dindx][(obj->quan > 1L)]);
4232 } else if (erode_obj(obj, (char *) 0, ERODE_BURN, EF_DESTROY)
4240 * Apply fire_damage() to an entire chain.
4242 * Return number of objects destroyed. --ALI
4245 fire_damage_chain(chain, force, here, x, y)
4247 boolean force, here;
4250 struct obj *obj, *nobj;
4252 for (obj = chain; obj; obj = nobj) {
4253 nobj = here ? obj->nexthere : obj->nobj;
4254 if (fire_damage(obj, force, x, y))
4258 if (num && (Blind && !couldsee(x, y)))
4260 You("smell smoke.");
4262 You("
\89\8c\82Ì
\82É
\82¨
\82¢
\82ª
\82µ
\82½
\81D");
4270 /* Scrolls but not spellbooks can be erased by acid. */
4271 struct monst *victim;
4277 victim = carried(obj) ? &youmonst : mcarried(obj) ? obj->ocarry : NULL;
4278 vismon = victim && (victim != &youmonst) && canseemon(victim);
4281 grease_protect(obj, (char *) 0, victim);
4282 } else if (obj->oclass == SCROLL_CLASS && obj->otyp != SCR_BLANK_PAPER) {
4283 if (obj->otyp != SCR_BLANK_PAPER
4285 && obj->otyp != SCR_MAIL
4289 if (victim == &youmonst)
4291 pline("Your %s.", aobjnam(obj, "fade"));
4293 pline("%s
\82Ì
\95¶
\8e\9a\82Í
\94\96\82ê
\82½
\81D", xname(obj));
4296 pline("%s %s.", s_suffix(Monnam(victim)),
4297 aobjnam(obj, "fade"));
4299 pline("%s
\82Ì%s
\82Ì
\95¶
\8e\9a\82Í
\94\96\82ê
\82½
\81D", Monnam(victim),
4304 obj->otyp = SCR_BLANK_PAPER;
4308 erode_obj(obj, (char *) 0, ERODE_CORRODE, EF_GREASE | EF_VERBOSE);
4311 /* context for water_damage(), managed by water_damage_chain();
4312 when more than one stack of potions of acid explode while processing
4313 a chain of objects, use alternate phrasing after the first message */
4314 static struct h2o_ctx {
4315 int dkn_boom, unk_boom; /* track dknown, !dknown separately */
4317 } acid_ctx = { 0, 0, FALSE };
4319 /* Get an object wet and damage it appropriately.
4320 * "ostr", if present, is used instead of the object name in some
4322 * "force" means not to roll luck to protect some objects.
4323 * Returns an erosion return value (ER_*)
4326 water_damage(obj, ostr, force)
4340 if (obj->otyp == CAN_OF_GREASE && obj->spe > 0) {
4342 } else if (obj->otyp == TOWEL && obj->spe < 7) {
4343 wet_a_towel(obj, rnd(7), TRUE);
4345 } else if (obj->greased) {
4351 } else if (Is_container(obj) && !Is_box(obj)
4352 && (obj->otyp != OILSKIN_SACK || (obj->cursed && !rn2(3)))) {
4355 pline("Water gets into your %s!", ostr);
4357 pline("
\90\85\82ª%s
\82Ì
\92\86\82É
\93ü
\82Á
\82½
\81I", ostr);
4359 water_damage_chain(obj->cobj, FALSE);
4361 } else if (!force && (Luck + 5) > rn2(20)) {
4362 /* chance per item of sustaining damage:
4364 * avg luck (Luck==0): 75%
4365 * awful luck (Luck<-4): 100%
4368 } else if (obj->oclass == SCROLL_CLASS) {
4370 if (obj->otyp == SCR_MAIL)
4375 pline("Your %s %s.", ostr, vtense(ostr, "fade"));
4377 pline("%s
\82Ì
\95¶
\8e\9a\82Í
\94\96\82ê
\82½
\81D", ostr);
4379 obj->otyp = SCR_BLANK_PAPER;
4385 } else if (obj->oclass == SPBOOK_CLASS) {
4386 if (obj->otyp == SPE_BOOK_OF_THE_DEAD) {
4388 pline("Steam rises from %s.", the(xname(obj)));
4390 pline("
\8fö
\8bC
\82ª%s
\82©
\82ç
\97§
\82¿
\82Ì
\82Ú
\82Á
\82½
\81D", xname(obj));
4396 pline("Your %s %s.", ostr, vtense(ostr, "fade"));
4398 pline("%s
\82Ì
\95¶
\8e\9a\82Í
\94\96\82ê
\82½
\81D", ostr);
4400 if (obj->otyp == SPE_NOVEL) {
4405 obj->otyp = SPE_BLANK_PAPER;
4410 } else if (obj->oclass == POTION_CLASS) {
4411 if (obj->otyp == POT_ACID) {
4413 boolean one = (obj->quan == 1L), update = carried(obj),
4416 if (Blind && !carried(obj))
4418 if (acid_ctx.ctx_valid)
4419 exploded = ((obj->dknown ? acid_ctx.dkn_boom
4420 : acid_ctx.unk_boom) > 0);
4422 * "a [potion|<color> potion|potion of acid] explodes"
4423 * depending on obj->dknown (potion has been seen) and
4424 * objects[POT_ACID].oc_name_known (fully discovered),
4425 * or "some {plural version} explode" when relevant.
4426 * Second and subsequent messages for same chain and
4427 * matching dknown status are
4428 * "another [potion|<color> &c] explodes" or plural
4431 bufp = simpleonames(obj);
4433 pline("%s %s %s!", /* "A potion explodes!" */
4434 !exploded ? (one ? "A" : "Some")
4435 : (one ? "Another" : "More"),
4436 bufp, vtense(bufp, "explode"));
4438 pline("%s
\82Í
\94\9a\94
\82µ
\82½
\81I", bufp);
4440 if (acid_ctx.ctx_valid) {
4442 acid_ctx.dkn_boom++;
4444 acid_ctx.unk_boom++;
4450 return ER_DESTROYED;
4451 } else if (obj->odiluted) {
4454 pline("Your %s %s further.", ostr, vtense(ostr, "dilute"));
4456 pline("%s
\82Í
\82³
\82ç
\82É
\94\96\82Ü
\82Á
\82½
\81D", ostr);
4458 obj->otyp = POT_WATER;
4460 obj->blessed = obj->cursed = 0;
4465 } else if (obj->otyp != POT_WATER) {
4468 pline("Your %s %s.", ostr, vtense(ostr, "dilute"));
4470 pline("%s
\82Í
\94\96\82Ü
\82Á
\82½
\81D", ostr);
4478 return erode_obj(obj, ostr, ERODE_RUST, EF_NONE);
4484 water_damage_chain(obj, here)
4490 /* initialize acid context: so far, neither seen (dknown) potions of
4491 acid nor unseen have exploded during this water damage sequence */
4492 acid_ctx.dkn_boom = acid_ctx.unk_boom = 0;
4493 acid_ctx.ctx_valid = TRUE;
4495 for (; obj; obj = otmp) {
4496 otmp = here ? obj->nexthere : obj->nobj;
4497 water_damage(obj, (char *) 0, FALSE);
4500 /* reset acid context */
4501 acid_ctx.dkn_boom = acid_ctx.unk_boom = 0;
4502 acid_ctx.ctx_valid = FALSE;
4506 * This function is potentially expensive - rolling
4507 * inventory list multiple times. Luckily it's seldom needed.
4508 * Returns TRUE if disrobing made player unencumbered enough to
4509 * crawl out of the current predicament.
4512 emergency_disrobe(lostsome)
4515 int invc = inv_cnt(TRUE);
4517 while (near_capacity() > (Punished ? UNENCUMBERED : SLT_ENCUMBER)) {
4518 register struct obj *obj, *otmp = (struct obj *) 0;
4521 /* Pick a random object */
4524 for (obj = invent; obj; obj = obj->nobj) {
4526 * Undroppables are: body armor, boots, gloves,
4527 * amulets, and rings because of the time and effort
4528 * in removing them + loadstone and other cursed stuff
4529 * for obvious reasons.
4531 if (!((obj->otyp == LOADSTONE && obj->cursed) || obj == uamul
4532 || obj == uleft || obj == uright || obj == ublindf
4533 || obj == uarm || obj == uarmc || obj == uarmg
4534 || obj == uarmf || obj == uarmu
4535 || (obj->cursed && (obj == uarmh || obj == uarms))
4538 /* reached the mark and found some stuff to drop? */
4539 if (--i < 0 && otmp)
4546 return FALSE; /* nothing to drop! */
4547 if (otmp->owornmask)
4548 remove_worn_item(otmp, FALSE);
4557 /* return TRUE iff player relocated */
4561 const char *pool_of_water;
4562 boolean inpool_ok = FALSE, crawl_ok;
4565 /* happily wading in the same contiguous pool */
4566 if (u.uinwater && is_pool(u.ux - u.dx, u.uy - u.dy)
4567 && (Swimming || Amphibious)) {
4568 /* water effects on objects every now and then */
4577 You("%s into the water%c", Is_waterlevel(&u.uz) ? "plunge" : "fall",
4578 Amphibious || Swimming ? '.' : '!');
4580 You("
\90\85\82Ì
\92\86\82É%s%s", Is_waterlevel(&u.uz) ? "
\94ò
\82Ñ
\82±
\82ñ
\82¾" : "
\97\8e\82¿
\82½",
4581 Amphibious || Swimming ? "
\81D" : "
\81I");
4583 if (!Swimming && !Is_waterlevel(&u.uz))
4585 You("sink like %s.", Hallucination ? "the Titanic" : "a rock");
4587 You("%s
\82Ì
\82æ
\82¤
\82É
\92¾
\82ñ
\82¾
\81D", Hallucination ? "
\83^
\83C
\83^
\83j
\83b
\83N
\8d\86" : "
\8aâ");
4590 water_damage_chain(invent, FALSE);
4592 if (u.umonnum == PM_GREMLIN && rn2(3))
4593 (void) split_mon(&youmonst, (struct monst *) 0);
4594 else if (u.umonnum == PM_IRON_GOLEM) {
4598 You("
\8eK
\82Ñ
\82½
\81I");
4599 i = Maybe_Half_Phys(d(2, 6));
4603 losehp(i, "rusting away", KILLED_BY);
4605 losehp(i, "
\8a®
\91S
\82É
\8eK
\82Ñ
\82Ä", KILLED_BY);
4610 if ((i = number_leashed()) > 0) {
4612 pline_The("leash%s slip%s loose.", (i > 1) ? "es" : "",
4613 (i > 1) ? "" : "s");
4615 pline("
\95R
\82ª
\82ä
\82é
\82ñ
\82¾
\81D");
4620 if (Amphibious || Swimming) {
4624 pline("But you aren't drowning.");
4626 pline("
\82µ
\82©
\82µ
\81C
\82 \82È
\82½
\82Í
\93M
\82ê
\82È
\82©
\82Á
\82½
\81D");
4627 if (!Is_waterlevel(&u.uz)) {
4630 Your("keel hits the bottom.");
4632 You("
\92ê
\82É
\83j
\81[
\83h
\83\8d\83b
\83v
\82ð
\8c\88\82ß
\82½
\81D");
4635 You("touch bottom.");
4637 You("
\92ê
\82É
\82Â
\82¢
\82½
\81D");
4644 vision_recalc(2); /* unsee old position */
4647 vision_full_recalc = 1;
4650 if ((Teleportation || can_teleport(youmonst.data)) && !Unaware
4651 && (Teleport_control || rn2(3) < Luck + 2)) {
4653 You("attempt a teleport spell."); /* utcsri!carroll */
4655 You("
\8fu
\8aÔ
\88Ú
\93®
\82Ì
\8eô
\95¶
\82ð
\8f¥
\82¦
\82Ä
\82Ý
\82½
\81D");
4657 if (!level.flags.noteleport) {
4659 if (!is_pool(u.ux, u.uy))
4663 pline_The("attempted teleport spell fails.");
4665 pline("
\8fu
\8aÔ
\88Ú
\93®
\82Ì
\8eô
\95¶
\82Í
\8e¸
\94s
\82µ
\82½
\81D");
4668 dismount_steed(DISMOUNT_GENERIC);
4669 if (!is_pool(u.ux, u.uy))
4673 x = y = 0; /* lint suppression */
4674 /* if sleeping, wake up now so that we don't crawl out of water
4675 while still asleep; we can't do that the same way that waking
4676 due to combat is handled; note unmul() clears u.usleep */
4679 unmul("Suddenly you wake up!");
4681 unmul("
\93Ë
\91R
\82 \82È
\82½
\82Í
\96Ú
\82ª
\8ao
\82ß
\82½
\81I");
4682 /* being doused will revive from fainting */
4685 /* can't crawl if unable to move (crawl_ok flag stays false) */
4686 if (multi < 0 || (Upolyd && !youmonst.data->mmove))
4688 /* look around for a place to crawl to */
4689 for (i = 0; i < 100; i++) {
4690 x = rn1(3, u.ux - 1);
4691 y = rn1(3, u.uy - 1);
4692 if (crawl_destination(x, y)) {
4698 for (x = u.ux - 1; x <= u.ux + 1; x++)
4699 for (y = u.uy - 1; y <= u.uy + 1; y++)
4700 if (crawl_destination(x, y)) {
4706 boolean lost = FALSE;
4707 /* time to do some strip-tease... */
4708 boolean succ = Is_waterlevel(&u.uz) ? TRUE : emergency_disrobe(&lost);
4711 You("try to crawl out of the water.");
4713 You("
\90\85\82©
\82ç
\82Í
\82¢
\82 \82ª
\82ë
\82¤
\82Æ
\82µ
\82½
\81D");
4716 You("dump some of your gear to lose weight...");
4718 You("
\91Ì
\82ð
\8cy
\82
\82·
\82é
\82½
\82ß
\82¢
\82
\82Â
\82©
\95¨
\82ð
\93\8a\82°
\82·
\82Ä
\82½
\81D
\81D
\81D");
4721 pline("Pheew! That was close.");
4723 pline("
\83n
\83@
\83n
\83@
\81I
\82 \82Ô
\82È
\82©
\82Á
\82½
\81D");
4727 /* still too much weight */
4729 pline("But in vain.");
4731 pline("
\82ª
\81C
\96³
\91Ê
\82¾
\82Á
\82½
\81D");
4737 You("
\93M
\82ê
\82½
\81D");
4738 for (i = 0; i < 5; i++) { /* arbitrary number of loops */
4739 /* killer format and name are reconstructed every iteration
4740 because lifesaving resets them */
4741 pool_of_water = waterbody_name(u.ux, u.uy);
4742 killer.format = KILLED_BY_AN;
4744 /* avoid "drowned in [a] water" */
4745 if (!strcmp(pool_of_water, "water"))
4746 pool_of_water = "deep water", killer.format = KILLED_BY;
4748 Strcpy(killer.name, pool_of_water);
4750 /* oops, we're still alive. better get out of the water. */
4751 if (safe_teleds(TRUE))
4752 break; /* successful life-save */
4753 /* nowhere safe to land; repeat drowning loop... */
4755 pline("You're still drowning.");
4757 You("
\82Ü
\82¾
\93M
\82ê
\82Ä
\82¢
\82é
\81D");
4762 You("find yourself back %s.",
4763 Is_waterlevel(&u.uz) ? "in an air bubble" : "on land");
4765 You("
\82¢
\82Â
\82Ì
\82Ü
\82É
\82©%s
\82É
\82¢
\82é
\82Ì
\82É
\8bC
\82ª
\82Â
\82¢
\82½
\81D",
4766 Is_waterlevel(&u.uz) ? "
\8bó
\8bC
\82Ì
\96A
\82Ì
\92\86" : "
\92n
\96Ê");
4777 /* energy is completely gone */
4779 You_feel("momentarily lethargic.");
4781 You("
\88ê
\8fu
\96³
\8bC
\97Í
\8a´
\82ð
\8a´
\82¶
\82½
\81D");
4783 /* throttle further loss a bit when there's not much left to lose */
4784 if (n > u.uenmax || n > u.ulevel)
4788 You_feel("your magical energy drain away%c", (n > u.uen) ? '!' : '.');
4790 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");
4793 u.uenmax -= rnd(-u.uen);
4806 if (near_capacity() >= HVY_ENCUMBER) {
4808 pline("You're too strained to do that.");
4810 pline("ã©
\82ð
\89ð
\8f\9c\82µ
\82æ
\82¤
\82É
\82à
\95¨
\82ð
\8e\9d\82¿
\82·
\82¬
\82Ä
\82¢
\82é
\81D");
4813 if ((nohands(youmonst.data) && !webmaker(youmonst.data))
4814 || !youmonst.data->mmove) {
4816 pline("And just how do you expect to do that?");
4818 pline("
\82¢
\82Á
\82½
\82¢
\89½
\82ð
\8aú
\91Ò
\82µ
\82Ä
\82¢
\82é
\82ñ
\82¾
\82¢
\81H");
4820 } else if (u.ustuck && sticks(youmonst.data)) {
4822 pline("You'll have to let go of %s first.", mon_nam(u.ustuck));
4824 pline("%s
\82ð
\8eè
\97£
\82³
\82È
\82¢
\82±
\82Æ
\82É
\82Í
\82Å
\82«
\82È
\82¢
\81D", mon_nam(u.ustuck));
4827 if (u.ustuck || (welded(uwep) && bimanual(uwep))) {
4829 Your("%s seem to be too busy for that.", makeplural(body_part(HAND)));
4831 Your("
\82»
\82ñ
\82È
\82±
\82Æ
\82ð
\82·
\82é
\97]
\97T
\82È
\82ñ
\82Ä
\82È
\82¢
\81D");
4834 return untrap(FALSE);
4837 /* Probability of disabling a trap. Helge Hafting */
4844 /* Only spiders know how to deal with webs reliably */
4845 if (ttmp->ttyp == WEB && !webmaker(youmonst.data))
4847 if (Confusion || Hallucination)
4855 /* Your own traps are better known than others. */
4856 if (ttmp && ttmp->madeby_u)
4858 if (Role_if(PM_ROGUE)) {
4859 if (rn2(2 * MAXULEV) < u.ulevel)
4861 if (u.uhave.questart && chance > 1)
4863 } else if (Role_if(PM_RANGER) && chance > 1)
4868 /* Replace trap with object(s). Helge Hafting */
4870 cnv_trap_obj(otyp, cnt, ttmp, bury_it)
4876 struct obj *otmp = mksobj(otyp, TRUE, FALSE);
4879 otmp->owt = weight(otmp);
4880 /* Only dart traps are capable of being poisonous */
4882 otmp->opoisoned = 0;
4883 place_object(otmp, ttmp->tx, ttmp->ty);
4885 /* magical digging first disarms this trap, then will unearth it */
4886 (void) bury_an_obj(otmp, (boolean *) 0);
4888 /* Sell your own traps only... */
4890 sellobj(otmp, ttmp->tx, ttmp->ty);
4893 newsym(ttmp->tx, ttmp->ty);
4894 if (u.utrap && ttmp->tx == u.ux && ttmp->ty == u.uy)
4899 /* while attempting to disarm an adjacent trap, we've fallen into it */
4901 move_into_trap(ttmp)
4905 xchar x = ttmp->tx, y = ttmp->ty, bx, by, cx, cy;
4908 bx = by = cx = cy = 0; /* lint suppression */
4909 /* we know there's no monster in the way, and we're not trapped */
4911 || drag_ball(x, y, &bc, &bx, &by, &cx, &cy, &unused, TRUE)) {
4912 u.ux0 = u.ux, u.uy0 = u.uy;
4915 newsym(u.ux0, u.uy0);
4917 check_leash(u.ux0, u.uy0);
4919 move_bc(0, bc, bx, by, cx, cy);
4920 /* marking the trap unseen forces dotrap() to treat it like a new
4921 discovery and prevents pickup() -> look_here() -> check_here()
4922 from giving a redundant "there is a <trap> here" message when
4923 there are objects covering this trap */
4924 ttmp->tseen = 0; /* hack for check_here() */
4925 /* trigger the trap */
4926 spoteffects(TRUE); /* pickup() + dotrap() */
4927 exercise(A_WIS, FALSE);
4931 /* 0: doesn't even try
4932 * 1: tries and fails
4936 try_disarm(ttmp, force_failure)
4938 boolean force_failure;
4940 struct monst *mtmp = m_at(ttmp->tx, ttmp->ty);
4941 int ttype = ttmp->ttyp;
4942 boolean under_u = (!u.dx && !u.dy);
4943 boolean holdingtrap = (ttype == BEAR_TRAP || ttype == WEB);
4945 /* Test for monster first, monsters are displayed instead of trap. */
4946 if (mtmp && (!mtmp->mtrapped || !holdingtrap)) {
4948 pline("%s is in the way.", Monnam(mtmp));
4950 pline("
\82»
\82±
\82É
\82Í%s
\82ª
\82¢
\82é
\81D", Monnam(mtmp));
4953 /* We might be forced to move onto the trap's location. */
4954 if (sobj_at(BOULDER, ttmp->tx, ttmp->ty) && !Passes_walls && !under_u) {
4956 There("is a boulder in your way.");
4958 pline("
\82»
\82±
\82É
\82Í
\8aâ
\82ª
\82 \82é
\81D");
4961 /* duplicate tight-space checks from test_move */
4962 if (u.dx && u.dy && bad_rock(youmonst.data, u.ux, ttmp->ty)
4963 && bad_rock(youmonst.data, ttmp->tx, u.uy)) {
4964 if ((invent && (inv_weight() + weight_cap() > 600))
4965 || bigmonst(youmonst.data)) {
4966 /* don't allow untrap if they can't get thru to it */
4968 You("are unable to reach the %s!",
4969 defsyms[trap_to_defsym(ttype)].explanation);
4971 You("%s
\82É
\93Í
\82©
\82È
\82¢
\81I",
4972 defsyms[trap_to_defsym(ttype)].explanation);
4977 /* untrappable traps are located on the ground. */
4978 if (!can_reach_floor(TRUE)) {
4979 if (u.usteed && P_SKILL(P_RIDING) < P_BASIC)
4983 You("are unable to reach the %s!",
4984 defsyms[trap_to_defsym(ttype)].explanation);
4986 You("%s
\82É
\93Í
\82©
\82È
\82¢
\81I",
4987 defsyms[trap_to_defsym(ttype)].explanation);
4992 /* Will our hero succeed? */
4993 if (force_failure || untrap_prob(ttmp)) {
4998 pline("
\82¤
\82í
\82Á
\81D
\81D
\81D");
4999 if (mtmp) { /* must be a trap that holds monsters */
5000 if (ttype == BEAR_TRAP) {
5003 if ((mtmp->mhp -= rnd(4)) <= 0)
5005 } else if (ttype == WEB) {
5006 if (!webmaker(youmonst.data)) {
5007 struct trap *ttmp2 = maketrap(u.ux, u.uy, WEB);
5012 "webbing sticks to you. You're caught too!");
5014 "
\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");
5015 dotrap(ttmp2, NOWEBMSG);
5016 if (u.usteed && u.utrap) {
5017 /* you, not steed, are trapped */
5018 dismount_steed(DISMOUNT_FELL);
5023 pline("%s remains entangled.", Monnam(mtmp));
5025 pline("%s
\82Í
\82©
\82ç
\82Ü
\82Á
\82½
\82Ü
\82Ü
\82¾
\81D", Monnam(mtmp));
5027 } else if (under_u) {
5030 move_into_trap(ttmp);
5034 pline("%s %s is difficult to %s.",
5035 ttmp->madeby_u ? "Your" : under_u ? "This" : "That",
5036 defsyms[trap_to_defsym(ttype)].explanation,
5037 (ttype == WEB) ? "remove" : "disarm");
5039 pline("%s%s
\82ð
\89ð
\8f\9c\82·
\82é
\82Ì
\82Í
\8d¢
\93ï
\82¾
\81D",
5040 ttmp->madeby_u ? "
\82 \82È
\82½
\82Ì
\8ed
\8a|
\82¯
\82½" : under_u ? "
\82±
\82Ì" : "
\82»
\82Ì",
5041 defsyms[trap_to_defsym(ttype)].explanation);
5050 reward_untrap(ttmp, mtmp)
5054 if (!ttmp->madeby_u) {
5055 if (rnl(10) < 8 && !mtmp->mpeaceful && !mtmp->msleeping
5056 && !mtmp->mfrozen && !mindless(mtmp->data)
5057 && mtmp->data->mlet != S_HUMAN) {
5058 mtmp->mpeaceful = 1;
5059 set_malign(mtmp); /* reset alignment */
5061 pline("%s is grateful.", Monnam(mtmp));
5063 pline("%s
\82Í
\8aì
\82ñ
\82Å
\82¢
\82é
\81D", Monnam(mtmp));
5065 /* Helping someone out of a trap is a nice thing to do,
5066 * A lawful may be rewarded, but not too often. */
5067 if (!rn2(3) && !rnl(8) && u.ualign.type == A_LAWFUL) {
5070 You_feel("that you did the right thing.");
5072 You("
\90³
\82µ
\82¢
\82±
\82Æ
\82ð
\82µ
\82½
\82æ
\82¤
\82È
\8bC
\82ª
\82µ
\82½
\81D");
5078 disarm_holdingtrap(ttmp) /* Helge Hafting */
5082 int fails = try_disarm(ttmp, FALSE);
5087 /* ok, disarm it. */
5089 /* untrap the monster, if any.
5090 There's no need for a cockatrice test, only the trap is touched */
5091 if ((mtmp = m_at(ttmp->tx, ttmp->ty)) != 0) {
5094 You("remove %s %s from %s.", the_your[ttmp->madeby_u],
5095 (ttmp->ttyp == BEAR_TRAP) ? "bear trap" : "webbing",
5098 You("%s%s
\82ð%s
\82©
\82ç
\82Í
\82¸
\82µ
\82½
\81D", set_you[ttmp->madeby_u],
5099 (ttmp->ttyp == BEAR_TRAP) ? "
\8cF
\82Ìã©" : "
\82
\82à
\82Ì
\91\83",
5102 reward_untrap(ttmp, mtmp);
5104 if (ttmp->ttyp == BEAR_TRAP) {
5106 You("disarm %s bear trap.", the_your[ttmp->madeby_u]);
5108 You("%s
\8cF
\82Ìã©
\82ð
\89ð
\8f\9c\82µ
\82½
\81D", set_you[ttmp->madeby_u]);
5109 cnv_trap_obj(BEARTRAP, 1, ttmp, FALSE);
5110 } else /* if (ttmp->ttyp == WEB) */ {
5112 You("succeed in removing %s web.", the_your[ttmp->madeby_u]);
5114 You("%s
\82
\82à
\82Ì
\91\83\82ð
\8eæ
\82è
\8f\9c\82¢
\82½
\81D", set_you[ttmp->madeby_u]);
5118 newsym(u.ux + u.dx, u.uy + u.dy);
5123 disarm_landmine(ttmp) /* Helge Hafting */
5126 int fails = try_disarm(ttmp, FALSE);
5131 You("disarm %s land mine.", the_your[ttmp->madeby_u]);
5133 You("%s
\92n
\97\8b\82ð
\89ð
\8f\9c\82µ
\82½
\81D", set_you[ttmp->madeby_u]);
5134 cnv_trap_obj(LAND_MINE, 1, ttmp, FALSE);
5138 /* getobj will filter down to cans of grease and known potions of oil */
5139 static NEARDATA const char oil[] = { ALL_CLASSES, TOOL_CLASS, POTION_CLASS,
5142 /* it may not make much sense to use grease on floor boards, but so what? */
5144 disarm_squeaky_board(ttmp)
5151 obj = getobj(oil, "untrap with");
5155 bad_tool = (obj->cursed
5156 || ((obj->otyp != POT_OIL || obj->lamplit)
5157 && (obj->otyp != CAN_OF_GREASE || !obj->spe)));
5158 fails = try_disarm(ttmp, bad_tool);
5162 /* successfully used oil or grease to fix squeaky board */
5163 if (obj->otyp == CAN_OF_GREASE) {
5164 consume_obj_charge(obj, TRUE);
5166 useup(obj); /* oil */
5170 You("repair the squeaky board."); /* no madeby_u */
5172 You("
\82«
\82µ
\82Þ
\94Â
\82ð
\8fC
\97\9d\82µ
\82½
\81D"); /* no madeby_u */
5175 newsym(u.ux + u.dx, u.uy + u.dy);
5176 more_experienced(1, 5);
5181 /* removes traps that shoot arrows, darts, etc. */
5183 disarm_shooting_trap(ttmp, otyp)
5187 int fails = try_disarm(ttmp, FALSE);
5192 You("disarm %s trap.", the_your[ttmp->madeby_u]);
5194 pline("%sã©
\82ð
\89ð
\8f\9c\82µ
\82½
\81D", set_you[ttmp->madeby_u]);
5195 cnv_trap_obj(otyp, 50 - rnl(50), ttmp, FALSE);
5199 /* Is the weight too heavy?
5200 * Formula as in near_capacity() & check_capacity() */
5202 try_lift(mtmp, ttmp, wt, stuff)
5208 int wc = weight_cap();
5210 if (((wt * 2) / wc) >= HVY_ENCUMBER) {
5212 pline("%s is %s for you to lift.", Monnam(mtmp),
5213 stuff ? "carrying too much" : "too heavy");
5215 pline("%s
\82Í%s
\8e\9d\82¿
\82 \82°
\82é
\82±
\82Æ
\82ª
\82Å
\82«
\82È
\82¢
\81D", Monnam(mtmp),
5216 stuff ? "
\95¨
\82ð
\8e\9d\82¿
\82·
\82¬
\82Ä
\82¨
\82è" : "
\8fd
\82·
\82¬
\82Ä");
5218 if (!ttmp->madeby_u && !mtmp->mpeaceful && mtmp->mcanmove
5219 && !mindless(mtmp->data) && mtmp->data->mlet != S_HUMAN
5221 mtmp->mpeaceful = 1;
5222 set_malign(mtmp); /* reset alignment */
5224 pline("%s thinks it was nice of you to try.", Monnam(mtmp));
5226 pline("%s
\82Í
\82 \82È
\82½
\82Ì
\93w
\97Í
\82É
\8a´
\8eÓ
\82µ
\82Ä
\82¢
\82é
\82æ
\82¤
\82¾
\81D", Monnam(mtmp));
5233 /* Help trapped monster (out of a (spiked) pit) */
5235 help_monster_out(mtmp, ttmp)
5244 * This works when levitating too -- consistent with the ability
5245 * to hit monsters while levitating.
5247 * Should perhaps check that our hero has arms/hands at the
5248 * moment. Helping can also be done by engulfing...
5250 * Test the monster first - monsters are displayed before traps.
5252 if (!mtmp->mtrapped) {
5254 pline("%s isn't trapped.", Monnam(mtmp));
5256 pline("%s
\82Íã©
\82É
\82©
\82©
\82Á
\82Ä
\82¢
\82È
\82¢
\81D", Monnam(mtmp));
5259 /* Do you have the necessary capacity to lift anything? */
5260 if (check_capacity((char *) 0))
5263 /* Will our hero succeed? */
5264 if ((uprob = untrap_prob(ttmp)) && !mtmp->msleeping && mtmp->mcanmove) {
5266 You("try to reach out your %s, but %s backs away skeptically.",
5267 makeplural(body_part(ARM)), mon_nam(mtmp));
5269 You("%s
\82ð
\8d·
\82µ
\89\84\82×
\82æ
\82¤
\82Æ
\82µ
\82½
\82ª%s
\82Í
\8cx
\89ú
\82µ
\82Ä
\82¢
\82é
\81D",
5270 body_part(ARM), mon_nam(mtmp));
5275 /* is it a cockatrice?... */
5276 if (touch_petrifies(mtmp->data) && !uarmg && !Stone_resistance) {
5278 You("grab the trapped %s using your bare %s.", mtmp->data->mname,
5279 makeplural(body_part(HAND)));
5281 You("ã©
\82É
\82©
\82©
\82Á
\82Ä
\82¢
\82é%s
\82ð
\91f%s
\82Å
\92Í
\82ñ
\82¾
\81D", mtmp->data->mname,
5285 if (poly_when_stoned(youmonst.data) && polymon(PM_STONE_GOLEM)) {
5286 display_nhwindow(WIN_MESSAGE, FALSE);
5291 Sprintf(kbuf, "trying to help %s out of a pit",
5292 an(mtmp->data->mname));
5294 Sprintf(kbuf, "ã©
\82É
\82©
\82©
\82Á
\82Ä
\82¢
\82é%s
\82ð
\8f\95\82¯
\82æ
\82¤
\82Æ
\82µ
\82Ä",
5301 /* need to do cockatrice check first if sleeping or paralyzed */
5304 You("try to grab %s, but cannot get a firm grasp.", mon_nam(mtmp));
5306 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));
5307 if (mtmp->msleeping) {
5308 mtmp->msleeping = 0;
5310 pline("%s awakens.", Monnam(mtmp));
5312 pline("%s
\82Í
\96Ú
\82ð
\8ao
\82Ü
\82µ
\82½
\81D", Monnam(mtmp));
5318 You("reach out your %s and grab %s.", makeplural(body_part(ARM)),
5321 You("%s
\82ð
\90L
\82Î
\82µ
\82Ä%s
\82ð
\82Â
\82©
\82ñ
\82¾
\81D", body_part(ARM),
5325 if (mtmp->msleeping) {
5326 mtmp->msleeping = 0;
5328 pline("%s awakens.", Monnam(mtmp));
5330 pline("%s
\82Í
\96Ú
\82ð
\8ao
\82Ü
\82µ
\82½
\81D", Monnam(mtmp));
5331 } else if (mtmp->mfrozen && !rn2(mtmp->mfrozen)) {
5332 /* After such manhandling, perhaps the effect wears off */
5336 pline("%s stirs.", Monnam(mtmp));
5338 pline("%s
\82Í
\93®
\82«
\8en
\82ß
\82½
\81D", Monnam(mtmp));
5341 /* is the monster too heavy? */
5342 wt = inv_weight() + mtmp->data->cwt;
5343 if (!try_lift(mtmp, ttmp, wt, FALSE))
5346 /* is the monster with inventory too heavy? */
5347 for (otmp = mtmp->minvent; otmp; otmp = otmp->nobj)
5349 if (!try_lift(mtmp, ttmp, wt, TRUE))
5353 You("pull %s out of the pit.", mon_nam(mtmp));
5355 You("%s
\82ð
\97\8e\82µ
\8c\8a\82©
\82ç
\82Ð
\82Á
\82Ï
\82Á
\82½
\81D", mon_nam(mtmp));
5357 fill_pit(mtmp->mx, mtmp->my);
5358 reward_untrap(ttmp, mtmp);
5366 register struct obj *otmp;
5371 const char *trapdescr;
5372 boolean here, useplural, confused = (Confusion || Hallucination),
5373 trap_skipped = FALSE, deal_with_floor_trap;
5375 char the_trap[BUFSZ], qbuf[QBUFSZ];
5377 if (!getdir((char *) 0))
5383 pline_The("perils lurking there are beyond your grasp.");
5385 pline_The("
\82»
\82±
\82É
\82 \82é
\8aë
\8c¯
\82Í
\82 \82È
\82½
\82Ì
\8eè
\82É
\95\89\82¦
\82È
\82¢
\81D");
5389 if (ttmp && !ttmp->tseen)
5391 trapdescr = ttmp ? defsyms[trap_to_defsym(ttmp->ttyp)].explanation : 0;
5392 here = (x == u.ux && y == u.uy); /* !u.dx && !u.dy */
5394 if (here) /* are there are one or more containers here? */
5395 for (otmp = level.objects[x][y]; otmp; otmp = otmp->nexthere)
5401 deal_with_floor_trap = can_reach_floor(FALSE);
5402 if (!deal_with_floor_trap) {
5405 Strcat(the_trap, an(trapdescr));
5408 Strcat(the_trap, " and ");
5410 Strcat(the_trap, "
\82Æ");
5413 Strcat(the_trap, (boxcnt == 1) ? "a container" : "containers");
5415 Strcat(the_trap, "
\97e
\8aí");
5416 useplural = ((ttmp && boxcnt > 0) || boxcnt > 1);
5417 /* note: boxcnt and useplural will always be 0 for !here case */
5420 There("%s %s %s but you can't reach %s%s.",
5421 useplural ? "are" : "is", the_trap, here ? "here" : "there",
5422 useplural ? "them" : "it",
5423 u.usteed ? " while mounted" : "");
5425 pline("%s
\82ª
\82 \82é
\82ª
\81C%s
\93Í
\82©
\82È
\82¢
\81D",
5427 u.usteed ? "
\8fæ
\82Á
\82Ä
\82¢
\82é
\82Æ" : "");
5429 trap_skipped = (ttmp != 0);
5430 } else { /* deal_with_floor_trap */
5433 Strcpy(the_trap, the(trapdescr));
5435 if (ttmp->ttyp == PIT || ttmp->ttyp == SPIKED_PIT) {
5437 You_cant("do much about %s%s.", the_trap,
5438 u.utrap ? " that you're stuck in"
5439 : " while standing on the edge of it");
5441 pline("%s%s
\82É
\91Î
\82µ
\82Ä
\82Í
\82½
\82¢
\82µ
\82½
\82±
\82Æ
\82Í
\82Å
\82«
\82È
\82¢
\81D",
5442 u.utrap ? "
\8e©
\95ª
\82ª
\82Í
\82Ü
\82Á
\82Ä
\82¢
\82é"
5443 : "
\82·
\82®
\82»
\82Î
\82Ì",
5446 trap_skipped = TRUE;
5447 deal_with_floor_trap = FALSE;
5451 qbuf, "There %s and %s here. %s %s?",
5452 (boxcnt == 1) ? "is a container" : "are containers",
5454 (ttmp->ttyp == WEB) ? "Remove" : "Disarm", the_trap);
5457 qbuf, "
\94 \82Æ%s
\82ª
\82 \82é
\81D%s
\81H",
5459 (ttmp->ttyp == WEB) ? "
\8eæ
\82è
\8f\9c\82" : "
\89ð
\8f\9c\82·
\82é");
5461 switch (ynq(qbuf)) {
5465 trap_skipped = TRUE;
5466 deal_with_floor_trap = FALSE;
5471 if (deal_with_floor_trap) {
5474 You("cannot deal with %s while trapped%s!", the_trap,
5475 (x == u.ux && y == u.uy) ? " in it" : "");
5477 pline("ã©
\82É
\82©
\82©
\82Á
\82Ä
\82¢
\82é
\8aÔ
\82Íã©
\82ð
\89ð
\8f\9c\82Å
\82«
\82È
\82¢
\81I");
5481 if ((mtmp = m_at(x, y)) != 0
5482 && (mtmp->m_ap_type == M_AP_FURNITURE
5483 || mtmp->m_ap_type == M_AP_OBJECT)) {
5484 stumble_onto_mimic(mtmp);
5487 switch (ttmp->ttyp) {
5490 return disarm_holdingtrap(ttmp);
5492 return disarm_landmine(ttmp);
5494 return disarm_squeaky_board(ttmp);
5496 return disarm_shooting_trap(ttmp, DART);
5498 return disarm_shooting_trap(ttmp, ARROW);
5503 You("are already on the edge of the pit.");
5505 You("
\82à
\82¤
\97\8e\82µ
\8c\8a\82Ì
\92[
\82É
\82¢
\82é
\81D");
5510 pline("Try filling the pit instead.");
5512 pline("
\82È
\82ñ
\82Æ
\82©
\96\84\82ß
\82é
\82±
\82Æ
\82ð
\8dl
\82¦
\82Ä
\82Ý
\82½
\82ç
\81H");
5515 return help_monster_out(mtmp, ttmp);
5518 You("cannot disable %s trap.", !here ? "that" : "this");
5520 pline("%sã©
\82Í
\89ð
\8f\9c\82Å
\82«
\82È
\82¢
\81D", !here ? "
\82»
\82Ì" : "
\82±
\82Ì");
5527 for (otmp = level.objects[x][y]; otmp; otmp = otmp->nexthere)
5530 (void) safe_qbuf(qbuf, "There is ",
5531 " here. Check it for traps?", otmp,
5532 doname, ansimpleoname, "a box");
5534 (void) safe_qbuf(qbuf, "",
5535 "
\82ª
\82 \82é
\81Dã©
\82ð
\92²
\82×
\82Ü
\82·
\82©
\81H", otmp,
5536 doname, ansimpleoname, "
\94 ");
5538 switch (ynq(qbuf)) {
5546 && (force || (!confused
5547 && rn2(MAXULEV + 1 - u.ulevel) < 10)))
5548 || (!force && confused && !rn2(3))) {
5550 You("find a trap on %s!", the(xname(otmp)));
5552 pline("%s
\82Éã©
\82ð
\94
\8c©
\82µ
\82½
\81I", the(xname(otmp)));
5554 exercise(A_WIS, TRUE);
5557 switch (ynq("Disarm it?")) {
5559 switch (ynq("
\89ð
\8f\9c\82µ
\82Ü
\82·
\82©
\81H")) {
5563 trap_skipped = TRUE;
5567 if (otmp->otrapped) {
5568 exercise(A_DEX, TRUE);
5569 ch = ACURR(A_DEX) + u.ulevel;
5570 if (Role_if(PM_ROGUE))
5572 if (!force && (confused || Fumbling
5573 || rnd(75 + level_difficulty() / 2)
5575 (void) chest_trap(otmp, FINGER, TRUE);
5580 You("
\89ð
\8f\9c\82µ
\82½
\81I");
5585 pline("That %s was not trapped.", xname(otmp));
5587 pline("
\82»
\82Ì%s
\82Éã©
\82Í
\82È
\82¢
\81D", xname(otmp));
5591 You("find no traps on %s.", the(xname(otmp)));
5593 pline("ã©
\82ð
\94
\8c©
\82Å
\82«
\82È
\82©
\82Á
\82½
\81D");
5599 You(trap_skipped ? "find no other traps here."
5600 : "know of no traps here.");
5602 You(trap_skipped ? "
\91¼
\82Ìã©
\82ð
\8c©
\82Â
\82¯
\82ç
\82ê
\82È
\82©
\82Á
\82½
\81D"
5603 : "
\82±
\82±
\82Éã©
\82ª
\82È
\82¢
\82±
\82Æ
\82ð
\92m
\82Á
\82Ä
\82¢
\82é
\81D");
5608 if (stumble_on_door_mimic(x, y))
5611 } /* deal_with_floor_trap */
5612 /* doors can be manipulated even while levitating/unskilled riding */
5614 if (!IS_DOOR(levl[x][y].typ)) {
5617 You("know of no traps there.");
5619 You("
\82»
\82±
\82Éã©
\82ª
\82È
\82¢
\82±
\82Æ
\82ð
\92m
\82Á
\82Ä
\82¢
\82é
\81D");
5623 switch (levl[x][y].doormask) {
5626 You("%s no door there.", Blind ? "feel" : "see");
5628 pline("
\82»
\82±
\82É
\82Í
\94à
\82ª
\82È
\82¢%s
\81D", Blind ? "
\82æ
\82¤
\82¾" : "
\82æ
\82¤
\82É
\8c©
\82¦
\82é");
5632 pline("This door is safely open.");
5634 pline("
\82»
\82Ì
\94à
\82Í
\88À
\91S
\82É
\8aJ
\82¢
\82Ä
\82¢
\82é
\81D");
5638 pline("This door is broken.");
5640 pline("
\82»
\82Ì
\94à
\82Í
\89ó
\82ê
\82Ä
\82¢
\82é
\81D");
5644 if ((levl[x][y].doormask & D_TRAPPED
5645 && (force || (!confused && rn2(MAXULEV - u.ulevel + 11) < 10)))
5646 || (!force && confused && !rn2(3))) {
5648 You("find a trap on the door!");
5650 pline("
\94à
\82Éã©
\82ð
\94
\8c©
\82µ
\82½
\81I");
5651 exercise(A_WIS, TRUE);
5653 if (ynq("Disarm it?") != 'y')
5655 if (ynq("
\89ð
\8f\9c\82µ
\82Ü
\82·
\82©
\81H") != 'y')
5657 if (levl[x][y].doormask & D_TRAPPED) {
5658 ch = 15 + (Role_if(PM_ROGUE) ? u.ulevel * 3 : u.ulevel);
5659 exercise(A_DEX, TRUE);
5660 if (!force && (confused || Fumbling
5661 || rnd(75 + level_difficulty() / 2) > ch)) {
5665 You("
\83X
\83C
\83b
\83`
\82ð
\93ü
\82ê
\82Ä
\82µ
\82Ü
\82Á
\82½
\81I");
5667 b_trapped("door", FINGER);
5669 b_trapped("
\94à", FINGER);
5670 levl[x][y].doormask = D_NODOOR;
5671 unblock_point(x, y);
5673 /* (probably ought to charge for this damage...) */
5674 if (*in_rooms(x, y, SHOPBASE))
5675 add_damage(x, y, 0L);
5680 You("
\89ð
\8f\9c\82µ
\82½
\81I");
5681 levl[x][y].doormask &= ~D_TRAPPED;
5685 pline("This door was not trapped.");
5687 pline("
\94à
\82Éã©
\82Í
\82È
\82©
\82Á
\82½
\81D");
5691 You("find no traps on the door.");
5693 pline("
\94à
\82Éã©
\82ð
\94
\8c©
\82Å
\82«
\82È
\82©
\82Á
\82½
\81D");
5698 /* for magic unlocking; returns true if targetted monster (which might
5699 be hero) gets untrapped; the trap remains intact */
5701 openholdingtrap(mon, noticed)
5703 boolean *noticed; /* set to true iff hero notices the effect; */
5704 { /* otherwise left with its previous value intact */
5707 const char *trapdescr, *which;
5708 boolean ishero = (mon == &youmonst);
5710 if (mon == u.usteed)
5712 t = t_at(ishero ? u.ux : mon->mx, ishero ? u.uy : mon->my);
5713 /* if no trap here or it's not a holding trap, we're done */
5714 if (!t || (t->ttyp != BEAR_TRAP && t->ttyp != WEB))
5717 trapdescr = defsyms[trap_to_defsym(t->ttyp)].explanation;
5719 which = t->tseen ? the_your[t->madeby_u]
5720 : index(vowels, *trapdescr) ? "an" : "a";
5722 which = t->tseen ? set_you[t->madeby_u] : "";
5728 u.utrap = 0; /* released regardless of type */
5730 /* give message only if trap was the expected type */
5731 if (u.utraptype == TT_BEARTRAP || u.utraptype == TT_WEB) {
5734 Sprintf(buf, "%s is", noit_Monnam(u.usteed));
5736 Strcpy(buf, noit_Monnam(u.usteed));
5739 Strcpy(buf, "You are");
5741 Strcpy(buf, "
\82 \82È
\82½");
5743 pline("%s released from %s %s.", buf, which, trapdescr);
5745 pline("%s
\82Í%s%s
\82©
\82ç
\89ð
\95ú
\82³
\82ê
\82½
\81D", buf, which, trapdescr);
5751 if (canspotmon(mon)) {
5754 pline("%s is released from %s %s.", Monnam(mon), which,
5757 pline("%s
\82Í%s%s
\82©
\82ç
\89ð
\95ú
\82³
\82ê
\82½
\81D", Monnam(mon), which,
5760 } else if (cansee(t->tx, t->ty) && t->tseen) {
5764 pline("%s is released from %s %s.", Something, which,
5767 pline("
\89½
\8eÒ
\82©
\82Í%s%s
\82©
\82ç
\89ð
\95ú
\82³
\82ê
\82½
\81D", which,
5770 else /* BEAR_TRAP */
5772 pline("%s %s opens.", upstart(strcpy(buf, which)), trapdescr);
5774 pline("%s%s
\82Í
\8aJ
\82¢
\82½
\81D", which, trapdescr);
5776 /* might pacify monster if adjacent */
5777 if (rn2(2) && distu(mon->mx, mon->my) <= 2)
5778 reward_untrap(t, mon);
5783 /* for magic locking; returns true if targetted monster (which might
5784 be hero) gets hit by a trap (might avoid actually becoming trapped) */
5786 closeholdingtrap(mon, noticed)
5788 boolean *noticed; /* set to true iff hero notices the effect; */
5789 { /* otherwise left with its previous value intact */
5791 unsigned dotrapflags;
5792 boolean ishero = (mon == &youmonst), result;
5794 if (mon == u.usteed)
5796 t = t_at(ishero ? u.ux : mon->mx, ishero ? u.uy : mon->my);
5797 /* if no trap here or it's not a holding trap, we're done */
5798 if (!t || (t->ttyp != BEAR_TRAP && t->ttyp != WEB))
5803 return FALSE; /* already trapped */
5805 dotrapflags = FORCETRAP;
5806 /* dotrap calls mintrap when mounted hero encounters a web */
5808 dotrapflags |= NOWEBMSG;
5810 dotrap(t, dotrapflags);
5812 result = (u.utrap != 0);
5815 return FALSE; /* already trapped */
5816 /* you notice it if you see the trap close/tremble/whatever
5817 or if you sense the monster who becomes trapped */
5818 *noticed = cansee(t->tx, t->ty) || canspotmon(mon);
5820 result = (mintrap(mon) != 0);
5826 /* for magic unlocking; returns true if targetted monster (which might
5827 be hero) gets hit by a trap (target might avoid its effect) */
5829 openfallingtrap(mon, trapdoor_only, noticed)
5831 boolean trapdoor_only;
5832 boolean *noticed; /* set to true iff hero notices the effect; */
5833 { /* otherwise left with its previous value intact */
5835 boolean ishero = (mon == &youmonst), result;
5837 if (mon == u.usteed)
5839 t = t_at(ishero ? u.ux : mon->mx, ishero ? u.uy : mon->my);
5840 /* if no trap here or it's not a falling trap, we're done
5841 (note: falling rock traps have a trapdoor in the ceiling) */
5842 if (!t || ((t->ttyp != TRAPDOOR && t->ttyp != ROCKTRAP)
5843 && (trapdoor_only || (t->ttyp != HOLE && t->ttyp != PIT
5844 && t->ttyp != SPIKED_PIT))))
5849 return FALSE; /* already trapped */
5851 dotrap(t, FORCETRAP);
5852 result = (u.utrap != 0);
5855 return FALSE; /* already trapped */
5856 /* you notice it if you see the trap close/tremble/whatever
5857 or if you sense the monster who becomes trapped */
5858 *noticed = cansee(t->tx, t->ty) || canspotmon(mon);
5859 /* monster will be angered; mintrap doesn't handle that */
5862 result = (mintrap(mon) != 0);
5864 /* mon might now be on the migrating monsters list */
5869 /* only called when the player is doing something to the chest directly */
5871 chest_trap(obj, bodypart, disarm)
5872 register struct obj *obj;
5873 register int bodypart;
5876 register struct obj *otmp = obj, *otmp2;
5881 if (get_obj_location(obj, &cc.x, &cc.y, 0)) /* might be carried */
5882 obj->ox = cc.x, obj->oy = cc.y;
5884 otmp->otrapped = 0; /* trap is one-shot; clear flag first in case
5885 chest kills you and ends up in bones file */
5887 You(disarm ? "set it off!" : "trigger a trap!");
5889 You(disarm ? "
\83X
\83C
\83b
\83`
\82ð
\93ü
\82ê
\82Ä
\82µ
\82Ü
\82Á
\82½
\81I" : "ã©
\82É
\82Ð
\82Á
\82©
\82©
\82Á
\82½
\81I");
5890 display_nhwindow(WIN_MESSAGE, FALSE);
5891 if (Luck > -13 && rn2(13 + Luck) > 7) { /* saved by luck */
5892 /* trap went off, but good luck prevents damage */
5897 msg = "explosive charge is a dud";
5899 msg = "
\94\9a\94
\82Í
\95s
\94
\82¾
\82Á
\82½";
5904 msg = "electric charge is grounded";
5906 msg = "
\93d
\8c\82\82ª
\95ú
\8fo
\82³
\82ê
\82½
\82ª
\83A
\81[
\83X
\82³
\82ê
\82Ä
\82¢
\82½";
5911 msg = "flame fizzles out";
5913 msg = "
\89\8a\82Í
\83V
\83\85\81[
\82Á
\82Æ
\8fÁ
\82¦
\82½";
5919 msg = "poisoned needle misses";
5921 msg = "
\93Å
\90j
\82Í
\8eh
\82³
\82ç
\82È
\82©
\82Á
\82½";
5928 msg = "gas cloud blows away";
5930 msg = "
\83K
\83X
\89_
\82Í
\90\81\82«
\94ò
\82ñ
\82¾";
5933 impossible("chest disarm bug");
5939 pline("But luckily the %s!", msg);
5941 pline("
\82µ
\82©
\82µ
\89^
\82Ì
\82æ
\82¢
\82±
\82Æ
\82É%s
\81I", msg);
5943 switch (rn2(20) ? ((Luck >= 13) ? 0 : rn2(13 - Luck)) : rn2(26)) {
5949 struct monst *shkp = 0;
5951 boolean costly, insider;
5952 register xchar ox = obj->ox, oy = obj->oy;
5954 /* the obj location need not be that of player */
5955 costly = (costly_spot(ox, oy)
5956 && (shkp = shop_keeper(*in_rooms(ox, oy, SHOPBASE)))
5957 != (struct monst *) 0);
5958 insider = (*u.ushops && inside_shop(u.ux, u.uy)
5959 && *in_rooms(ox, oy, SHOPBASE) == *u.ushops);
5962 pline("%s!", Tobjnam(obj, "explode"));
5964 pline("%s
\82Í
\94\9a\94
\82µ
\82½
\81I", xname(obj));
5966 Sprintf(buf, "exploding %s", xname(obj));
5968 Sprintf(buf, "%s
\82Ì
\94\9a\94
\82Å", xname(obj));
5971 loss += stolen_value(obj, ox, oy, (boolean) shkp->mpeaceful,
5973 delete_contents(obj);
5974 /* we're about to delete all things at this location,
5975 * which could include the ball & chain.
5976 * If we attempt to call unpunish() in the
5977 * for-loop below we can end up with otmp2
5978 * being invalid once the chain is gone.
5979 * Deal with ball & chain right now instead.
5981 if (Punished && !carried(uball)
5982 && ((uchain->ox == u.ux && uchain->oy == u.uy)
5983 || (uball->ox == u.ux && uball->oy == u.uy)))
5986 for (otmp = level.objects[u.ux][u.uy]; otmp; otmp = otmp2) {
5987 otmp2 = otmp->nexthere;
5989 loss += stolen_value(otmp, otmp->ox, otmp->oy,
5990 (boolean) shkp->mpeaceful, TRUE);
5994 losehp(Maybe_Half_Phys(d(6, 6)), buf, KILLED_BY_AN);
5995 exercise(A_STR, FALSE);
5996 if (costly && loss) {
5999 You("owe %ld %s for objects destroyed.", loss,
6002 You("
\8aí
\95¨
\94j
\91¹
\82Å%ld%s
\82Ì
\8eØ
\82è
\82ð
\82Â
\82
\82Á
\82½
\81D", loss,
6007 You("caused %ld %s worth of damage!", loss,
6010 You("%ld%s
\95ª
\82Ì
\91¹
\8aQ
\82ð
\88ø
\82«
\82¨
\82±
\82µ
\82½
\81I", loss,
6013 make_angry_shk(shkp, ox, oy);
6023 pline("A cloud of noxious gas billows from %s.", the(xname(obj)));
6025 pline("
\97L
\93Å
\83K
\83X
\82ª%s
\82©
\82ç
\89Q
\82Ü
\82¢
\82½
\81D", the(xname(obj)));
6027 poisoned("gas cloud", A_STR, "cloud of poison gas", 15, FALSE);
6029 poisoned("
\83K
\83X
\89_", A_STR, "
\83K
\83X
\89_", 15, FALSE);
6030 exercise(A_CON, FALSE);
6037 You_feel("a needle prick your %s.", body_part(bodypart));
6039 You("%s
\83`
\83N
\83b
\82Æ
\82¢
\82¤
\92É
\82Ý
\82ð
\8a´
\82¶
\82½
\81D", body_part(bodypart));
6041 poisoned("needle", A_CON, "poisoned needle", 10, FALSE);
6043 poisoned("
\90j", A_CON, "
\93Å
\90j", 10, FALSE);
6044 exercise(A_CON, FALSE);
6058 You("are jolted by a surge of electricity!");
6060 You("
\93d
\8bC
\83V
\83\87\83b
\83N
\82ð
\82
\82ç
\82Á
\82½
\81I");
6061 if (Shock_resistance) {
6062 shieldeff(u.ux, u.uy);
6064 You("don't seem to be affected.");
6066 pline("
\82µ
\82©
\82µ
\82 \82È
\82½
\82Í
\89e
\8b¿
\82ð
\8eó
\82¯
\82È
\82¢
\81D");
6070 destroy_item(RING_CLASS, AD_ELEC);
6071 destroy_item(WAND_CLASS, AD_ELEC);
6074 losehp(dmg, "electric shock", KILLED_BY_AN);
6076 losehp(dmg, "
\93d
\8bC
\83V
\83\87\83b
\83N
\82Å", KILLED_BY_AN);
6084 pline("Suddenly you are frozen in place!");
6086 pline("
\93Ë
\91R
\82»
\82Ì
\8fê
\82Å
\93®
\82¯
\82È
\82
\82È
\82Á
\82½
\81I");
6089 multi_reason = "frozen by a trap";
6091 multi_reason = "ã©
\82Å
\8dd
\92¼
\82µ
\82Ä
\82¢
\82é
\8e\9e\82É";
6092 exercise(A_DEX, FALSE);
6093 nomovemsg = You_can_move_again;
6096 You("momentarily stiffen.");
6098 You("
\88ê
\8fu
\8dd
\92¼
\82µ
\82½
\81D");
6104 pline("A cloud of %s gas billows from %s.",
6105 Blind ? blindgas[rn2(SIZE(blindgas))] : rndcolor(),
6108 pline("%s
\83K
\83X
\89_
\82ª%s
\82Ì
\92ê
\82Å
\89Q
\82Ü
\82¢
\82½
\81D",
6109 Blind ? blindgas[rn2(SIZE(blindgas))] :
6110 jconj_adj(rndcolor()), xname(obj));
6115 pline("What a groovy feeling!");
6117 pline("
\82È
\82ñ
\82Ä
\91f
\93G
\82È
\82ñ
\82¾
\81I");
6120 You("%s%s...", stagger(youmonst.data, "stagger"),
6121 Halluc_resistance ? ""
6122 : Blind ? " and get dizzy"
6123 : " and your vision blurs");
6125 You("
\82
\82ç
\82
\82ç
\82µ%s
\82½...",
6126 Halluc_resistance ? ""
6127 : Blind ? "
\81C
\82ß
\82Ü
\82¢
\82ª
\82µ"
6128 : "
\81C
\8ci
\90F
\82ª
\82Ú
\82â
\82¯
\82Ä
\82«");
6131 make_stunned((HStun & TIMEOUT) + (long) rn1(7, 16), FALSE);
6132 (void) make_hallucinated(
6133 (HHallucination & TIMEOUT) + (long) rn1(5, 16), FALSE, 0L);
6136 impossible("bad chest trap");
6139 bot(); /* to get immediate botl re-display */
6149 register struct trap *trap = ftrap;
6152 if (trap->tx == x && trap->ty == y)
6156 return (struct trap *) 0;
6161 register struct trap *trap;
6163 register struct trap *ttmp;
6165 clear_conjoined_pits(trap);
6166 if (trap == ftrap) {
6167 ftrap = ftrap->ntrap;
6169 for (ttmp = ftrap; ttmp; ttmp = ttmp->ntrap)
6170 if (ttmp->ntrap == trap)
6173 panic("deltrap: no preceding trap!");
6174 ttmp->ntrap = trap->ntrap;
6176 if (Sokoban && (trap->ttyp == PIT || trap->ttyp == HOLE))
6177 maybe_finish_sokoban();
6182 conjoined_pits(trap2, trap1, u_entering_trap2)
6183 struct trap *trap2, *trap1;
6184 boolean u_entering_trap2;
6186 int dx, dy, diridx, adjidx;
6188 if (!trap1 || !trap2)
6190 if (!isok(trap2->tx, trap2->ty) || !isok(trap1->tx, trap1->ty)
6191 || !(trap2->ttyp == PIT || trap2->ttyp == SPIKED_PIT)
6192 || !(trap1->ttyp == PIT || trap1->ttyp == SPIKED_PIT)
6193 || (u_entering_trap2 && !(u.utrap && u.utraptype == TT_PIT)))
6195 dx = sgn(trap2->tx - trap1->tx);
6196 dy = sgn(trap2->ty - trap1->ty);
6197 for (diridx = 0; diridx < 8; diridx++)
6198 if (xdir[diridx] == dx && ydir[diridx] == dy)
6200 /* diridx is valid if < 8 */
6202 adjidx = (diridx + 4) % 8;
6203 if ((trap1->conjoined & (1 << diridx))
6204 && (trap2->conjoined & (1 << adjidx)))
6211 clear_conjoined_pits(trap)
6214 int diridx, adjidx, x, y;
6217 if (trap && (trap->ttyp == PIT || trap->ttyp == SPIKED_PIT)) {
6218 for (diridx = 0; diridx < 8; ++diridx) {
6219 if (trap->conjoined & (1 << diridx)) {
6220 x = trap->tx + xdir[diridx];
6221 y = trap->ty + ydir[diridx];
6223 && (t = t_at(x, y)) != 0
6224 && (t->ttyp == PIT || t->ttyp == SPIKED_PIT)) {
6225 adjidx = (diridx + 4) % 8;
6226 t->conjoined &= ~(1 << adjidx);
6228 trap->conjoined &= ~(1 << diridx);
6236 * Mark all neighboring pits as conjoined pits.
6237 * (currently not called from anywhere)
6240 join_adjacent_pits(trap)
6248 for (diridx = 0; diridx < 8; ++diridx) {
6249 x = trap->tx + xdir[diridx];
6250 y = trap->ty + ydir[diridx];
6252 if ((t = t_at(x, y)) != 0
6253 && (t->ttyp == PIT || t->ttyp == SPIKED_PIT)) {
6254 trap->conjoined |= (1 << diridx);
6255 join_adjacent_pits(t);
6257 trap->conjoined &= ~(1 << diridx);
6264 * Returns TRUE if you escaped a pit and are standing on the precipice.
6267 uteetering_at_seen_pit(trap)
6270 if (trap && trap->tseen && (!u.utrap || u.utraptype != TT_PIT)
6271 && (trap->ttyp == PIT || trap->ttyp == SPIKED_PIT))
6277 /* Destroy a trap that emanates from the floor. */
6280 register struct trap *ttmp;
6282 /* some of these are arbitrary -dlc */
6283 if (ttmp && ((ttmp->ttyp == SQKY_BOARD) || (ttmp->ttyp == BEAR_TRAP)
6284 || (ttmp->ttyp == LANDMINE) || (ttmp->ttyp == FIRE_TRAP)
6285 || (ttmp->ttyp == PIT) || (ttmp->ttyp == SPIKED_PIT)
6286 || (ttmp->ttyp == HOLE) || (ttmp->ttyp == TRAPDOOR)
6287 || (ttmp->ttyp == TELEP_TRAP) || (ttmp->ttyp == LEVEL_TELEP)
6288 || (ttmp->ttyp == WEB) || (ttmp->ttyp == MAGIC_TRAP)
6289 || (ttmp->ttyp == ANTI_MAGIC))) {
6290 register struct monst *mtmp;
6292 if (ttmp->tx == u.ux && ttmp->ty == u.uy) {
6295 } else if ((mtmp = m_at(ttmp->tx, ttmp->ty)) != 0) {
6304 /* used for doors (also tins). can be used for anything else that opens. */
6306 b_trapped(item, bodypart)
6310 int lvl = level_difficulty(),
6311 dmg = rnd(5 + (lvl < 5 ? lvl : 2 + lvl / 2));
6314 pline("KABOOM!! %s was booby-trapped!", The(item));
6316 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);
6319 losehp(Maybe_Half_Phys(dmg), "explosion", KILLED_BY_AN);
6321 losehp(Maybe_Half_Phys(dmg), "
\83u
\81[
\83r
\81[
\83g
\83\89\83b
\83v
\82Ì
\94\9a\94
\82Å", KILLED_BY_AN);
6322 exercise(A_STR, FALSE);
6324 exercise(A_CON, FALSE);
6325 make_stunned((HStun & TIMEOUT) + (long) dmg, TRUE);
6328 /* Monster is hit by trap. */
6329 /* Note: doesn't work if both obj and d_override are null */
6331 thitm(tlev, mon, obj, d_override, nocorpse)
6339 boolean trapkilled = FALSE;
6344 strike = (find_mac(mon) + tlev + obj->spe <= rnd(20));
6346 strike = (find_mac(mon) + tlev <= rnd(20));
6348 /* Actually more accurate than thitu, which doesn't take
6349 * obj->spe into account.
6352 if (obj && cansee(mon->mx, mon->my))
6354 pline("%s is almost hit by %s!", Monnam(mon), doname(obj));
6356 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));
6360 if (obj && cansee(mon->mx, mon->my))
6362 pline("%s is hit by %s!", Monnam(mon), doname(obj));
6364 pline("%s
\82ª%s
\82É
\96½
\92\86\82µ
\82½
\81I", doname(obj), Monnam(mon));
6368 dam = dmgval(obj, mon);
6372 if ((mon->mhp -= dam) <= 0) {
6376 monkilled(mon, "", nocorpse ? -AD_RBRE : AD_PHYS);
6377 if (mon->mhp <= 0) {
6383 if (obj && (!strike || d_override)) {
6384 place_object(obj, mon->mx, mon->my);
6399 return (boolean) (u.usleep
6401 && (!strncmp(nomovemsg, "You awake", 9)
6402 || !strncmp(nomovemsg, "You regain con", 14)
6403 || !strncmp(nomovemsg, "You are consci", 14))));
6405 /*JP 3.6.0
\82Å
\82Ì
\8fo
\8c»
\88Ê
\92u/
\89ñ
\90\94
6406 "You awake" : potion.c(1)
6407 "You regain con": eat.c(1)
6408 "You are consci": eat.c(1)
6410 return (boolean) (u.usleep
6412 && (!strncmp(nomovemsg, "
\96Ú
\82ª
\82³
\82ß
\82½
\82ª
\93ª
\92É", 18)
6413 || !strncmp(nomovemsg, "
\82 \82È
\82½
\82Í
\90³
\8bC
\82Ã
\82¢
\82½", 18)
6414 || !strncmp(nomovemsg, "
\82 \82È
\82½
\82Í
\82Ü
\82½
\90³
\8bC
\82Ã", 18))));
6419 static const char lava_killer[] = "molten lava";
6421 static const char lava_killer[] = "
\82Ç
\82ë
\82Ç
\82ë
\82Ì
\97n
\8aâ
\82Å";
6426 register struct obj *obj, *obj2;
6427 int dmg = d(6, 6); /* only applicable for water walking */
6428 boolean usurvive, boil_away;
6431 if (likes_lava(youmonst.data))
6434 usurvive = Fire_resistance || (Wwalking && dmg < u.uhp);
6436 * A timely interrupt might manage to salvage your life
6437 * but not your gear. For scrolls and potions this
6438 * will destroy whole stacks, where fire resistant hero
6439 * survivor only loses partial stacks via destroy_item().
6441 * Flag items to be destroyed before any messages so
6442 * that player causing hangup at --More-- won't get an
6443 * emergency save file created before item destruction.
6446 for (obj = invent; obj; obj = obj->nobj)
6447 if ((is_organic(obj) || obj->oclass == POTION_CLASS)
6448 && !obj->oerodeproof
6449 && objects[obj->otyp].oc_oprop != FIRE_RES
6450 && obj->otyp != SCR_FIRE && obj->otyp != SPE_FIREBALL
6451 && !obj_resists(obj, 0, 0)) /* for invocation items */
6454 /* Check whether we should burn away boots *first* so we know whether to
6455 * make the player sink into the lava. Assumption: water walking only
6458 if (Wwalking && uarmf && is_organic(uarmf) && !uarmf->oerodeproof) {
6461 pline("%s into flame!", Yobjnam2(obj, "burst"));
6463 Your("%s
\82Í
\94R
\82¦
\82½
\81I", xname(obj));
6464 iflags.in_lava_effects++; /* (see above) */
6467 iflags.in_lava_effects--;
6470 if (!Fire_resistance) {
6473 pline_The("lava here burns you!");
6475 pline("
\97n
\8aâ
\82ª
\82 \82È
\82½
\82ð
\8fÄ
\82«
\82Â
\82
\82µ
\82½
\81I");
6477 losehp(dmg, lava_killer, KILLED_BY); /* lava damage */
6482 You("fall into the lava!");
6484 You("
\97n
\8aâ
\82É
\97\8e\82¿
\82½
\81I");
6486 usurvive = Lifesaved || discover;
6490 /* prevent remove_worn_item() -> Boots_off(WATER_WALKING_BOOTS) ->
6491 spoteffects() -> lava_effects() recursion which would
6492 successfully delete (via useupall) the no-longer-worn boots;
6493 once recursive call returned, we would try to delete them again
6494 here in the outer call (and access stale memory, probably panic) */
6495 iflags.in_lava_effects++;
6497 for (obj = invent; obj; obj = obj2) {
6499 /* above, we set in_use for objects which are to be destroyed */
6500 if (obj->otyp == SPE_BOOK_OF_THE_DEAD && !Blind) {
6503 pline("%s glows a strange %s, but remains intact.",
6504 The(xname(obj)), hcolor("dark red"));
6506 pline("%s
\82Í
\95s
\8ev
\8bc
\82É%s
\8bP
\82¢
\82½
\82ª
\81C
\96³
\8f\9d\82Ì
\82æ
\82¤
\82¾
\81D",
6507 xname(obj), jconj_adj(hcolor("
\88Ã
\90Ô
\90F
\82Ì")));
6509 } else if (obj->in_use) {
6510 if (obj->owornmask) {
6513 pline("%s into flame!", Yobjnam2(obj, "burst"));
6515 Your("%s
\82Í
\94R
\82¦
\82½
\81I", xname(obj));
6516 remove_worn_item(obj, TRUE);
6522 iflags.in_lava_effects--;
6525 boil_away = (u.umonnum == PM_WATER_ELEMENTAL
6526 || u.umonnum == PM_STEAM_VORTEX
6527 || u.umonnum == PM_FOG_CLOUD);
6530 /* killer format and name are reconstructed every iteration
6531 because lifesaving resets them */
6532 killer.format = KILLED_BY;
6533 Strcpy(killer.name, lava_killer);
6535 You("%s...", boil_away ? "boil away" : "burn to a crisp");
6537 You("%s
\81D
\81D
\81D", boil_away ? "
\95¦
\93«
\82µ
\82½" : "
\94R
\82¦
\82Ä
\83p
\83\8a\83p
\83\8a\82É
\82È
\82Á
\82½");
6539 if (safe_teleds(TRUE))
6540 break; /* successful life-save */
6541 /* nowhere safe to land; repeat burning loop */
6543 pline("You're still burning.");
6545 You("
\82Ü
\82¾
\94R
\82¦
\82Ä
\82¢
\82é
\81D");
6548 You("find yourself back on solid %s.", surface(u.ux, u.uy));
6550 You("
\82¢
\82Â
\82Ì
\82Ü
\82É
\82©
\8cÅ
\82¢%s
\82É
\96ß
\82Á
\82Ä
\82¢
\82½
\81D", surface(u.ux, u.uy));
6552 } else if (!Wwalking && (!u.utrap || u.utraptype != TT_LAVA)) {
6553 boil_away = !Fire_resistance;
6554 /* if not fire resistant, sink_into_lava() will quickly be fatal;
6555 hero needs to escape immediately */
6556 u.utrap = rn1(4, 4) + ((boil_away ? 2 : rn1(4, 12)) << 8);
6557 u.utraptype = TT_LAVA;
6559 You("sink into the lava%s!", !boil_away
6560 ? ", but it only burns slightly"
6561 : " and are about to be immolated");
6563 You("
\97n
\8aâ
\82É
\92¾
\82ñ%s
\82¾
\81I", !boil_away
6564 ? "
\82¾
\82ª
\81C
\82¿
\82å
\82Á
\82Æ
\8fÅ
\82°
\82½
\82¾
\82¯"
6565 : "
\82Å
\8fÄ
\82«
\8eE
\82³
\82ê
\82»
\82¤");
6568 losehp(!boil_away ? 1 : (u.uhp / 2), lava_killer,
6569 KILLED_BY); /* lava damage */
6573 destroy_item(SCROLL_CLASS, AD_FIRE);
6574 destroy_item(SPBOOK_CLASS, AD_FIRE);
6575 destroy_item(POTION_CLASS, AD_FIRE);
6579 /* called each turn when trapped in lava */
6584 static const char sink_deeper[] = "You sink deeper into the lava.";
6586 static const char sink_deeper[] = "
\82 \82È
\82½
\82Í
\82æ
\82è
\90[
\82
\97n
\8aâ
\82É
\92¾
\82ñ
\82¾
\81D";
6588 if (!u.utrap || u.utraptype != TT_LAVA) {
6589 ; /* do nothing; this shouldn't happen */
6590 } else if (!is_lava(u.ux, u.uy)) {
6591 u.utrap = 0; /* this shouldn't happen either */
6592 } else if (!u.uinvulnerable) {
6593 /* ordinarily we'd have to be fire resistant to survive long
6594 enough to become stuck in lava, but it can happen without
6595 resistance if water walking boots allow survival and then
6596 get burned up; u.utrap time will be quite short in that case */
6597 if (!Fire_resistance)
6598 u.uhp = (u.uhp + 2) / 3;
6600 u.utrap -= (1 << 8);
6601 if (u.utrap < (1 << 8)) {
6602 killer.format = KILLED_BY;
6604 Strcpy(killer.name, "molten lava");
6606 Strcpy(killer.name, "
\82Ç
\82ë
\82Ç
\82ë
\82Ì
\97n
\8aâ
\82Å");
6608 You("sink below the surface and die.");
6610 You("
\8a®
\91S
\82É
\97n
\8aâ
\82Ì
\92\86\82É
\92¾
\82ñ
\82Å
\81A
\8e\80\82É
\82Ü
\82µ
\82½
\81D
\81D
\81D");
6611 burn_away_slime(); /* add insult to injury? */
6613 } else if (!u.umoved) {
6614 /* can't fully turn into slime while in lava, but might not
6615 have it be burned away until you've come awfully close */
6616 if (Slimed && rnd(10 - 1) >= (int) (Slimed & TIMEOUT)) {
6627 /* called when something has been done (breaking a boulder, for instance)
6628 which entails a luck penalty if performed on a sokoban level */
6634 /* TODO: issue some feedback so that player can learn that whatever
6635 he/she just did is a naughty thing to do in sokoban and should
6636 probably be avoided in future....
6637 Caveat: doing this might introduce message sequencing issues,
6638 depending upon feedback during the various actions which trigger
6639 Sokoban luck penalties. */
6643 /* called when a trap has been deleted or had its ttyp replaced */
6645 maybe_finish_sokoban()
6649 if (Sokoban && !in_mklev) {
6650 /* scan all remaining traps, ignoring any created by the hero;
6651 if this level has no more pits or holes, the current sokoban
6652 puzzle has been solved */
6653 for (t = ftrap; t; t = t->ntrap) {
6656 if (t->ttyp == PIT || t->ttyp == HOLE)
6660 /* we've passed the last trap without finding a pit or hole;
6661 clear the sokoban_rules flag so that luck penalties for
6662 things like breaking boulders or jumping will no longer
6663 be given, and restrictions on diagonal moves are lifted */
6664 Sokoban = 0; /* clear level.flags.sokoban_rules */
6665 /* TODO: give some feedback about solving the sokoban puzzle
6666 (perhaps say "congratulations" in Japanese?) */