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);
284 pline("Somehow, the %s %s not affected.", ostr,
285 vtense(ostr, "are"));
287 /* We assume here that if the object is protected because it
288 * is blessed, it still shows some minor signs of wear, and
289 * the hero can distinguish this from an object that is
290 * actually proof against damage. */
291 if (otmp->oerodeproof) {
293 if (victim == &youmonst)
298 } else if (erosion < MAX_ERODE) {
300 const char *adverb = (erosion + 1 == MAX_ERODE)
302 : erosion ? " further" : "";
304 const char *adverb = (erosion + 1 == MAX_ERODE)
306 : erosion ? "
\82³
\82ç
\82É" : "";
309 if (victim == &youmonst)
311 Your("%s %s%s!", ostr, vtense(ostr, action[type]), adverb);
313 pline("%s
\82Í%s%s
\81I", ostr, adverb, action[type]);
316 pline("%s %s %s%s!", s_suffix(Monnam(victim)), ostr,
317 vtense(ostr, action[type]), adverb);
319 pline("%s
\82Ì%s
\82Í%s%s
\81I", Monnam(victim), ostr,
320 adverb, action[type]);
324 pline("The %s %s%s!", ostr, vtense(ostr, action[type]), adverb);
326 pline("%s
\82Í%s%s
\81I", ostr, adverb, action[type]);
328 if (ef_flags & EF_PAY)
329 costly_alteration(otmp, cost_type);
336 if (victim == &youmonst)
340 } else if (ef_flags & EF_DESTROY) {
341 if (victim == &youmonst)
342 Your("%s %s away!", ostr, vtense(ostr, action[type]));
344 pline("%s %s %s away!", s_suffix(Monnam(victim)), ostr,
345 vtense(ostr, action[type]));
347 pline("The %s %s away!", ostr, vtense(ostr, action[type]));
349 if (ef_flags & EF_PAY)
350 costly_alteration(otmp, cost_type);
356 if (flags.verbose && print) {
357 if (victim == &youmonst)
359 Your("%s %s completely %s.", ostr,
360 vtense(ostr, Blind ? "feel" : "look"), msg[type]);
362 Your("%s
\82Í
\8a®
\91S
\82É%s%s
\81D", ostr,
363 msg[type], Blind ? "
\82æ
\82¤
\82¾" : "");
367 pline("%s %s %s completely %s.", s_suffix(Monnam(victim)),
368 ostr, vtense(ostr, "look"), msg[type]);
370 pline("%s
\82Ì%s
\82Í
\8a®
\91S
\82É%s
\81D", Monnam(victim),
375 pline("The %s %s completely %s.", ostr, vtense(ostr, "look"),
378 pline("%s
\82Í
\8a®
\91S
\82É%s
\81D", ostr, msg[type]);
385 /* Protect an item from erosion with grease. Returns TRUE if the grease
389 grease_protect(otmp, ostr, victim)
390 register struct obj *otmp;
392 struct monst *victim;
395 static const char txt[] = "protected by the layer of grease!";
397 static const char txt[] = "
\96û
\82Ì
\93h
\82è
\82±
\82Ý
\82É
\82æ
\82Á
\82Ä
\8eç
\82ç
\82ê
\82Ä
\82¢
\82é
\81I";
398 boolean vismon = victim && (victim != &youmonst) && canseemon(victim);
401 if (victim == &youmonst)
403 Your("%s %s %s", ostr, vtense(ostr, "are"), txt);
405 Your("%s
\82Í%s", ostr, txt);
408 pline("%s's %s %s %s", Monnam(victim),
409 ostr, vtense(ostr, "are"), txt);
411 pline("%s
\82Ì%s
\82Í%s", Monnam(victim), ostr, txt);
413 } else if (victim == &youmonst || vismon) {
415 pline("%s %s", Yobjnam2(otmp, "are"), txt);
417 Your("%s
\82Í%s",xname(otmp), txt);
423 pline_The("grease dissolves.");
425 pline("
\96û
\82Í
\82Í
\82°
\82Ä
\82µ
\82Ü
\82Á
\82½
\81D");
435 register int x, y, typ;
437 static union vlaunchinfo zero_vl;
438 register struct trap *ttmp;
439 register struct rm *lev;
442 if ((ttmp = t_at(x, y)) != 0) {
443 if (ttmp->ttyp == MAGIC_PORTAL || ttmp->ttyp == VIBRATING_SQUARE)
444 return (struct trap *) 0;
446 if (u.utrap && x == u.ux && y == u.uy
447 && ((u.utraptype == TT_BEARTRAP && typ != BEAR_TRAP)
448 || (u.utraptype == TT_WEB && typ != WEB)
449 || (u.utraptype == TT_PIT && typ != PIT
450 && typ != SPIKED_PIT)))
452 /* old <tx,ty> remain valid */
453 } else if (IS_FURNITURE(levl[x][y].typ)) {
454 /* no trap on top of furniture (caller usually screens the
455 location to inhibit this, but wizard mode wishing doesn't) */
456 return (struct trap *) 0;
464 /* [re-]initialize all fields except ntrap (handled below) and <tx,ty> */
466 ttmp->launch.x = ttmp->launch.y = -1; /* force error if used before set */
467 ttmp->dst.dnum = ttmp->dst.dlevel = -1;
470 ttmp->tseen = (typ == HOLE); /* hide non-holes */
475 int tavail[12], tpick[12], tcnt = 0, k;
478 for (k = 0; k < 12; ++k)
479 tavail[k] = tpick[k] = 0;
480 for (t = ftrap; t; t = t->ntrap)
481 if (t->ttyp == SQKY_BOARD && t != ttmp)
482 tavail[t->tnote] = 1;
483 /* now populate tpick[] with the available indices */
484 for (k = 0; k < 12; ++k)
487 /* choose an unused note; if all are in use, pick a random one */
488 ttmp->tnote = (short) ((tcnt > 0) ? tpick[rn2(tcnt)] : rn2(12));
491 case STATUE_TRAP: { /* create a "living" statue */
493 struct obj *otmp, *statue;
494 struct permonst *mptr;
497 do { /* avoid ultimately hostile co-aligned unicorn */
498 mptr = &mons[rndmonnum()];
499 } while (--trycount > 0 && is_unicorn(mptr)
500 && sgn(u.ualign.type) == sgn(mptr->maligntyp));
501 statue = mkcorpstat(STATUE, (struct monst *) 0, mptr, x, y,
503 mtmp = makemon(&mons[statue->corpsenm], 0, 0, MM_NOCOUNTBIRTH);
505 break; /* should never happen */
506 while (mtmp->minvent) {
507 otmp = mtmp->minvent;
509 obj_extract_self(otmp);
510 (void) add_to_container(statue, otmp);
512 statue->owt = weight(statue);
516 case ROLLING_BOULDER_TRAP: /* boulder will roll towards trigger */
517 (void) mkroll_launch(ttmp, x, y, BOULDER, 1L);
526 if (*in_rooms(x, y, SHOPBASE)
527 && (typ == HOLE || typ == TRAPDOOR
528 || IS_DOOR(lev->typ) || IS_WALL(lev->typ)))
529 add_damage(x, y, /* schedule repair */
530 ((IS_DOOR(lev->typ) || IS_WALL(lev->typ))
531 && !context.mon_moving)
534 lev->doormask = 0; /* subsumes altarmask, icedpool... */
535 if (IS_ROOM(lev->typ)) /* && !IS_AIR(lev->typ) */
538 * some cases which can happen when digging
539 * down while phazing thru solid areas
541 else if (lev->typ == STONE || lev->typ == SCORR)
543 else if (IS_WALL(lev->typ) || lev->typ == SDOOR)
544 lev->typ = level.flags.is_maze_lev
546 : level.flags.is_cavernous_lev ? CORR : DOOR;
557 it shouldn't be possible to override a sokoban pit or hole
558 with some other trap, but we'll check just to be safe */
560 maybe_finish_sokoban();
567 boolean td; /* td == TRUE : trap door or hole */
571 const char *dont_fall = 0;
572 int newlevel, bottom;
574 /* we'll fall even while levitating in Sokoban; otherwise, if we
575 won't fall and won't be told that we aren't falling, give up now */
576 if (Blind && Levitation && !Sokoban)
579 bottom = dunlevs_in_dungeon(&u.uz);
580 /* when in the upper half of the quest, don't fall past the
581 middle "quest locate" level if hero hasn't been there yet */
582 if (In_quest(&u.uz)) {
583 int qlocate_depth = qlocate_level.dlevel;
585 /* deepest reached < qlocate implies current < qlocate */
586 if (dunlev_reached(&u.uz) < qlocate_depth)
587 bottom = qlocate_depth; /* early cut-off */
589 newlevel = dunlev(&u.uz); /* current level */
592 } while (!rn2(4) && newlevel < bottom);
595 struct trap *t = t_at(u.ux, u.uy);
599 if (t->ttyp == TRAPDOOR)
601 pline("A trap door opens up under you!");
603 pline("
\97\8e\82µ
\94à
\82ª
\82 \82È
\82½
\82Ì
\91«
\8c³
\82É
\8aJ
\82¢
\82½
\81I");
606 pline("There's a gaping hole under you!");
608 pline("
\82 \82È
\82½
\82Ì
\91«
\89º
\82É
\82Û
\82Á
\82©
\82è
\82Æ
\8c\8a\82ª
\8aJ
\82¢
\82Ä
\82¢
\82é
\81I");
612 pline_The("%s opens up under you!", surface(u.ux, u.uy));
614 pline("
\91«
\8c³
\82Ì%s
\82É
\8c\8a\82ª
\8aJ
\82¢
\82½
\81I", surface(u.ux,u.uy));
616 if (Sokoban && Can_fall_thru(&u.uz))
617 ; /* KMH -- You can't escape the Sokoban level traps */
618 else if (Levitation || u.ustuck
619 || (!Can_fall_thru(&u.uz) && !levl[u.ux][u.uy].candig) || Flying
620 || is_clinger(youmonst.data)
621 || (Inhell && !u.uevent.invoked && newlevel == bottom)) {
623 dont_fall = "don't fall in.";
625 dont_fall = "
\82µ
\82©
\82µ
\82 \82È
\82½
\82Í
\97\8e\82¿
\82È
\82©
\82Á
\82½
\81D";
626 } else if (youmonst.data->msize >= MZ_HUGE) {
628 dont_fall = "don't fit through.";
630 dont_fall = "
\92Ê
\82è
\94²
\82¯
\82é
\82É
\82Í
\83T
\83C
\83Y
\82ª
\8d\87\82í
\82È
\82¢
\81D";
631 } else if (!next_to_u()) {
633 dont_fall = "are jerked back by your pet!";
635 dont_fall = "
\82 \82È
\82½
\82Í
\83y
\83b
\83g
\82É
\82æ
\82Á
\82Ä
\88ø
\82Á
\82Ï
\82è
\82à
\82Ç
\82³
\82ê
\82½
\81I";
638 #if 0 /*JP*//*
\81u
\82 \82È
\82½
\82Í
\81v
\82Å
\8en
\82Ü
\82ç
\82È
\82¢
\82à
\82Ì
\82à
\82 \82é*/
643 /* hero didn't fall through, but any objects here might */
644 impact_drop((struct obj *) 0, u.ux, u.uy, 0);
646 display_nhwindow(WIN_MESSAGE, FALSE);
648 pline_The("opening under you closes up.");
650 pline_The("
\91«
\89º
\82É
\8aJ
\82¢
\82Ä
\82¢
\82½
\82à
\82Ì
\82Í
\95Â
\82¶
\82½
\81D");
657 if (Is_stronghold(&u.uz)) {
660 int dist = newlevel - dunlev(&u.uz);
661 dtmp.dnum = u.uz.dnum;
662 dtmp.dlevel = newlevel;
665 You("fall down a %s%sshaft!", dist > 3 ? "very " : "",
666 dist > 2 ? "deep " : "");
668 You("%s%s
\8c\8a\82Ì
\92\86\82ð
\97\8e\82¿
\82Ä
\82¢
\82Á
\82½
\81I", dist > 3 ? "
\82Æ
\82Ä
\82à" : "",
669 dist > 2 ? "
\90[
\82¢" : "");
674 Sprintf(msgbuf, "The hole in the %s above you closes up.",
676 Sprintf(msgbuf, "%s
\82É
\8aJ
\82¢
\82½
\8c\8a\82Í
\95Â
\82¶
\82½
\81D",
677 ceiling(u.ux, u.uy));
679 schedule_goto(&dtmp, FALSE, TRUE, 0, (char *) 0,
680 !td ? msgbuf : (char *) 0);
684 * Animate the given statue. May have been via shatter attempt, trap,
685 * or stone to flesh spell. Return a monster if successfully animated.
686 * If the monster is animated, the object is deleted. If fail_reason
687 * is non-null, then fill in the reason for failure (or success).
689 * The cause of animation is:
691 * ANIMATE_NORMAL - hero "finds" the monster
692 * ANIMATE_SHATTER - hero tries to destroy the statue
693 * ANIMATE_SPELL - stone to flesh spell hits the statue
695 * Perhaps x, y is not needed if we can use get_obj_location() to find
696 * the statue's location... ???
698 * Sequencing matters:
699 * create monster; if it fails, give up with statue intact;
700 * give "statue comes to life" message;
701 * if statue belongs to shop, have shk give "you owe" message;
702 * transfer statue contents to monster (after stolen_value());
704 * [This ordering means that if the statue ends up wearing a cloak of
705 * invisibility or a mummy wrapping, the visibility checks might be
706 * wrong, but to avoid that we'd have to clone the statue contents
707 * first in order to give them to the monster before checking their
708 * shop status--it's not worth the hassle.]
711 animate_statue(statue, x, y, cause, fail_reason)
717 int mnum = statue->corpsenm;
718 struct permonst *mptr = &mons[mnum];
719 struct monst *mon = 0, *shkp;
722 boolean historic = (Role_if(PM_ARCHEOLOGIST)
723 && (statue->spe & STATUE_HISTORIC) != 0),
724 golem_xform = FALSE, use_saved_traits;
725 const char *comes_to_life;
726 char statuename[BUFSZ], tmpbuf[BUFSZ];
727 static const char historic_statue_is_gone[] =
729 "that the historic statue is now gone";
731 "
\97ð
\8ej
\93I
\82È
\92¤
\91\9c\82ª
\82È
\82
\82È
\82Á
\82Ä
\82µ
\82Ü
\82Á
\82½
\82±
\82Æ";
732 if (cant_revive(&mnum, TRUE, statue)) {
733 /* mnum has changed; we won't be animating this statue as itself */
734 if (mnum != PM_DOPPELGANGER)
736 use_saved_traits = FALSE;
737 } else if (is_golem(mptr) && cause == ANIMATE_SPELL) {
738 /* statue of any golem hit by stone-to-flesh becomes flesh golem */
739 golem_xform = (mptr != &mons[PM_FLESH_GOLEM]);
740 mnum = PM_FLESH_GOLEM;
741 mptr = &mons[PM_FLESH_GOLEM];
742 use_saved_traits = (has_omonst(statue) && !golem_xform);
744 use_saved_traits = has_omonst(statue);
747 if (use_saved_traits) {
748 /* restore a petrified monster */
750 mon = montraits(statue, &cc);
751 if (mon && mon->mtame && !mon->isminion)
754 /* statues of unique monsters from bones or wishing end
755 up here (cant_revive() sets mnum to be doppelganger;
756 mptr reflects the original form for use by newcham()) */
757 if ((mnum == PM_DOPPELGANGER && mptr != &mons[PM_DOPPELGANGER])
758 /* block quest guards from other roles */
759 || (mptr->msound == MS_GUARDIAN
760 && quest_info(MS_GUARDIAN) != mnum)) {
761 mon = makemon(&mons[PM_DOPPELGANGER], x, y,
762 NO_MINVENT | MM_NOCOUNTBIRTH | MM_ADJACENTOK);
763 /* if hero has protection from shape changers, cham field will
764 be NON_PM; otherwise, set form to match the statue */
765 if (mon && mon->cham >= LOW_PM)
766 (void) newcham(mon, mptr, FALSE, FALSE);
768 mon = makemon(mptr, x, y, (cause == ANIMATE_SPELL)
769 ? (NO_MINVENT | MM_ADJACENTOK)
775 *fail_reason = unique_corpstat(&mons[statue->corpsenm])
778 return (struct monst *) 0;
781 /* a non-montraits() statue might specify gender */
782 if (statue->spe & STATUE_MALE)
784 else if (statue->spe & STATUE_FEMALE)
786 /* if statue has been named, give same name to the monster */
787 if (has_oname(statue))
788 mon = christen_monst(mon, ONAME(statue));
789 /* mimic statue becomes seen mimic; other hiders won't be hidden */
793 mon->mundetected = FALSE;
795 if (cause == ANIMATE_NORMAL || cause == ANIMATE_SHATTER) {
796 /* trap always releases hostile monster */
797 mon->mtame = 0; /* (might be petrified pet tossed onto trap) */
803 comes_to_life = !canspotmon(mon)
807 : (nonliving(mon->data) || is_vampshifter(mon))
811 comes_to_life = !canspotmon(mon)
814 ? "
\93÷
\91Ì
\82É
\96ß
\82Á"
815 : (nonliving(mon->data) || is_vampshifter(mon))
817 : "
\90¶
\96½
\82ð
\91Ñ
\82Ñ";
819 if ((x == u.ux && y == u.uy) || cause == ANIMATE_SPELL) {
820 /* "the|your|Manlobbi's statue [of a wombat]" */
821 shkp = shop_keeper(*in_rooms(mon->mx, mon->my, SHOPBASE));
823 Sprintf(statuename, "%s%s", shk_your(tmpbuf, statue),
824 (cause == ANIMATE_SPELL
825 /* avoid "of a shopkeeper" if it's Manlobbi himself
826 (if carried, it can't be unpaid--hence won't be
827 described as "Manlobbi's statue"--because there
828 wasn't any living shk when statue was picked up) */
829 && (mon != shkp || carried(statue)))
833 Sprintf(statuename, "%s%s", shk_your(tmpbuf, statue),
834 (cause == ANIMATE_SPELL
835 && (mon != shkp || carried(statue)))
840 pline("%s %s!", upstart(statuename), comes_to_life);
842 pline("%s
\82Í%s
\82½
\81I", upstart(statuename), comes_to_life);
843 } else if (Hallucination) { /* They don't know it's a statue */
845 pline_The("%s suddenly seems more animated.", rndmonnam((char *) 0));
847 pline_The("%s
\82Í
\93Ë
\91R
\82æ
\82è
\8a\88\93®
\93I
\82É
\82È
\82Á
\82½
\81D", rndmonnam((char *) 0));
848 } else if (cause == ANIMATE_SHATTER) {
850 Sprintf(statuename, "%s%s", shk_your(tmpbuf, statue),
854 Strcpy(statuename, "a statue");
856 Strcpy(statuename, "
\92¤
\91\9c");
858 pline("Instead of shattering, %s suddenly %s!", statuename,
861 pline("%s
\82Í
\8dÓ
\82¯
\82¸
\82É%s
\82½
\81I", statuename,
864 } else { /* cause == ANIMATE_NORMAL */
866 You("find %s posing as a statue.",
868 You("%s
\82ª
\92¤
\91\9c\82Ì
\82Ó
\82è
\82ð
\82µ
\82Ä
\82¢
\82é
\82Ì
\82ð
\8c©
\82Â
\82¯
\82½
\81D",
869 canspotmon(mon) ? a_monnam(mon) : something);
870 if (!canspotmon(mon) && Blind)
875 /* if this isn't caused by a monster using a wand of striking,
876 there might be consequences for the hero */
877 if (!context.mon_moving) {
878 /* if statue is owned by a shop, hero will have to pay for it;
879 stolen_value gives a message (about debt or use of credit)
880 which refers to "it" so needs to follow a message describing
881 the object ("the statue comes to life" one above) */
882 if (cause != ANIMATE_NORMAL && costly_spot(x, y)
883 && (shkp = shop_keeper(*in_rooms(x, y, SHOPBASE))) != 0
884 /* avoid charging for Manlobbi's statue of Manlobbi
885 if stone-to-flesh is used on petrified shopkeep */
887 (void) stolen_value(statue, x, y, (boolean) shkp->mpeaceful,
892 You_feel("guilty %s.", historic_statue_is_gone);
894 You_feel("%s
\82É
\8dß
\82ð
\8a´
\82¶
\82½
\81D", historic_statue_is_gone);
898 if (historic && cansee(x, y))
900 You_feel("regret %s.", historic_statue_is_gone);
902 You_feel("%s
\82ð
\8cã
\89÷
\82µ
\82½
\81D", historic_statue_is_gone);
903 /* no alignment penalty */
906 /* transfer any statue contents to monster's inventory */
907 while ((item = statue->cobj) != 0) {
908 obj_extract_self(item);
909 (void) mpickobj(mon, item);
912 /* in case statue is wielded and hero zaps stone-to-flesh at self */
913 if (statue->owornmask)
914 remove_worn_item(statue, TRUE);
915 /* statue no longer exists */
918 /* avoid hiding under nothing */
919 if (x == u.ux && y == u.uy && Upolyd && hides_under(youmonst.data)
924 *fail_reason = AS_OK;
929 * You've either stepped onto a statue trap's location or you've triggered a
930 * statue trap by searching next to it or by trying to break it with a wand
934 activate_statue_trap(trap, x, y, shatter)
939 struct monst *mtmp = (struct monst *) 0;
940 struct obj *otmp = sobj_at(STATUE, x, y);
944 * Try to animate the first valid statue. Stop the loop when we
945 * actually create something or the failure cause is not because
946 * the mon was unique.
950 mtmp = animate_statue(otmp, x, y,
951 shatter ? ANIMATE_SHATTER : ANIMATE_NORMAL,
953 if (mtmp || fail_reason != AS_MON_IS_UNIQUE)
956 otmp = nxtobj(otmp, STATUE, TRUE);
964 keep_saddle_with_steedcorpse(steed_mid, objchn, saddle)
966 struct obj *objchn, *saddle;
971 if (objchn->otyp == CORPSE && has_omonst(objchn)) {
972 struct monst *mtmp = OMONST(objchn);
974 if (mtmp->m_id == steed_mid) {
977 if (get_obj_location(objchn, &x, &y, 0)) {
978 obj_extract_self(saddle);
979 place_object(saddle, x, y);
985 if (Has_contents(objchn)
986 && keep_saddle_with_steedcorpse(steed_mid, objchn->cobj, saddle))
988 objchn = objchn->nobj;
994 dotrap(trap, trflags)
995 register struct trap *trap;
998 register int ttype = trap->ttyp;
999 register struct obj *otmp;
1000 boolean already_seen = trap->tseen,
1001 forcetrap = (trflags & FORCETRAP) != 0,
1002 webmsgok = (trflags & NOWEBMSG) == 0,
1003 forcebungle = (trflags & FORCEBUNGLE) != 0,
1004 plunged = (trflags & TOOKPLUNGE) != 0,
1005 adj_pit = conjoined_pits(trap, t_at(u.ux0, u.uy0), TRUE);
1007 int steed_article = ARTICLE_THE;
1011 /* KMH -- You can't escape the Sokoban level traps */
1012 if (Sokoban && (ttype == PIT || ttype == SPIKED_PIT
1013 || ttype == HOLE || ttype == TRAPDOOR)) {
1014 /* The "air currents" message is still appropriate -- even when
1015 * the hero isn't flying or levitating -- because it conveys the
1016 * reason why the player cannot escape the trap with a dexterity
1017 * check, clinging to the ceiling, etc.
1020 pline("Air currents pull you down into %s %s!",
1021 a_your[trap->madeby_u],
1022 defsyms[trap_to_defsym(ttype)].explanation);
1024 pline("
\8bó
\8bC
\82Ì
\97¬
\82ê
\82ª
\82 \82È
\82½
\82ð%s
\82É
\88ø
\82«
\96ß
\82µ
\82½
\81I",
1025 defsyms[trap_to_defsym(ttype)].explanation);
1027 /* then proceed to normal trap effect */
1028 } else if (already_seen && !forcetrap) {
1029 if ((Levitation || (Flying && !plunged))
1030 && (ttype == PIT || ttype == SPIKED_PIT || ttype == HOLE
1031 || ttype == BEAR_TRAP)) {
1033 You("%s over %s %s.", Levitation ? "float" : "fly",
1034 a_your[trap->madeby_u],
1035 defsyms[trap_to_defsym(ttype)].explanation);
1037 You("%s%s
\82Ì
\8fã%s
\81D",
1038 set_you[trap->madeby_u],
1039 defsyms[trap_to_defsym(ttype)].explanation,
1040 Levitation ? "
\82ð
\8c©
\89º
\82ë
\82µ
\82½" : "
\82ð
\94ò
\82ñ
\82Å
\82¢
\82é");
1044 if (!Fumbling && ttype != MAGIC_PORTAL && ttype != VIBRATING_SQUARE
1045 && ttype != ANTI_MAGIC && !forcebungle && !plunged && !adj_pit
1046 && (!rn2(5) || ((ttype == PIT || ttype == SPIKED_PIT)
1047 && is_clinger(youmonst.data)))) {
1049 You("escape %s %s.", (ttype == ARROW_TRAP && !trap->madeby_u)
1051 : a_your[trap->madeby_u],
1052 defsyms[trap_to_defsym(ttype)].explanation);
1054 You("%s%s
\82ð
\82·
\82é
\82è
\82Æ
\94ð
\82¯
\82½
\81D",
1055 set_you[trap->madeby_u],
1056 defsyms[trap_to_defsym(ttype)].explanation);
1063 u.usteed->mtrapseen |= (1 << (ttype - 1));
1064 /* suppress article in various steed messages when using its
1065 name (which won't occur when hallucinating) */
1066 if (has_mname(u.usteed) && !Hallucination)
1067 steed_article = ARTICLE_NONE;
1072 if (trap->once && trap->tseen && !rn2(15)) {
1074 You_hear("a loud click!");
1076 You_hear("
\83K
\83`
\83\83\83b
\82Æ
\82¢
\82¤
\91å
\82«
\82È
\89¹
\82ð
\95·
\82¢
\82½
\81I");
1084 pline("An arrow shoots out at you!");
1086 pline("
\96î
\82ª
\94ò
\82ñ
\82Å
\82«
\82½
\81I");
1087 otmp = mksobj(ARROW, TRUE, FALSE);
1089 otmp->owt = weight(otmp);
1090 otmp->opoisoned = 0;
1091 if (u.usteed && !rn2(2) && steedintrap(trap, otmp)) { /* nothing */
1094 } else if (thitu(8, dmgval(otmp, &youmonst), otmp, "arrow")) {
1096 } else if (thitu(8, dmgval(otmp, &youmonst), otmp, "
\96î")) {
1097 obfree(otmp, (struct obj *) 0);
1099 place_object(otmp, u.ux, u.uy);
1108 if (trap->once && trap->tseen && !rn2(15)) {
1110 You_hear("a soft click.");
1112 You_hear("
\83J
\83`
\83b
\82Æ
\82¢
\82¤
\89¹
\82ð
\95·
\82¢
\82½
\81D");
1120 pline("A little dart shoots out at you!");
1122 pline("
\8f¬
\82³
\82È
\93\8a\82°
\96î
\82ª
\94ò
\82ñ
\82Å
\82«
\82½
\81I");
1123 otmp = mksobj(DART, TRUE, FALSE);
1125 otmp->owt = weight(otmp);
1127 otmp->opoisoned = 1;
1128 oldumort = u.umortality;
1129 if (u.usteed && !rn2(2) && steedintrap(trap, otmp)) { /* nothing */
1132 } else if (thitu(7, dmgval(otmp, &youmonst), otmp, "little dart")) {
1134 } else if (thitu(7, dmgval(otmp, &youmonst), otmp, "
\93\8a\82°
\96î")) {
1135 if (otmp->opoisoned)
1137 poisoned("dart", A_CON, "little dart",
1138 /* if damage triggered life-saving,
1139 poison is limited to attrib loss */
1140 (u.umortality > oldumort) ? 0 : 10, TRUE);
1142 poisoned("
\93\8a\82°
\96î", A_CON, "
\8f¬
\82³
\82È
\93\8a\82°
\96î",
1143 /* if damage triggered life-saving,
1144 poison is limited to attrib loss */
1145 (u.umortality > oldumort) ? 0 : 10, TRUE);
1147 obfree(otmp, (struct obj *) 0);
1149 place_object(otmp, u.ux, u.uy);
1158 if (trap->once && trap->tseen && !rn2(15)) {
1160 pline("A trap door in %s opens, but nothing falls out!",
1162 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",
1163 the(ceiling(u.ux, u.uy)));
1167 int dmg = d(2, 6); /* should be std ROCK dmg? */
1171 otmp = mksobj_at(ROCK, u.ux, u.uy, TRUE, FALSE);
1173 otmp->owt = weight(otmp);
1176 pline("A trap door in %s opens and %s falls on your %s!",
1177 the(ceiling(u.ux, u.uy)), an(xname(otmp)), body_part(HEAD));
1179 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",
1180 ceiling(u.ux,u.uy), xname(otmp), body_part(HEAD));
1184 if (is_metallic(uarmh)) {
1186 pline("Fortunately, you are wearing a hard helmet.");
1188 pline("
\8dK
\89^
\82É
\82à
\81C
\82 \82È
\82½
\82Í
\8cÅ
\82¢
\8a\95\82ð
\90g
\82É
\82Â
\82¯
\82Ä
\82¢
\82½
\81D");
1190 } else if (flags.verbose) {
1192 pline("%s does not protect you.", Yname2(uarmh));
1194 pline("%s
\82Å
\82Í
\96h
\82°
\82È
\82¢
\81D", xname(uarmh));
1201 newsym(u.ux, u.uy); /* map the rock */
1204 losehp(Maybe_Half_Phys(dmg), "falling rock", KILLED_BY_AN);
1206 losehp(Maybe_Half_Phys(dmg), "
\97\8e\8aâ
\82Å", KILLED_BY_AN);
1207 exercise(A_STR, FALSE);
1211 case SQKY_BOARD: /* stepped on a squeaky board */
1212 if ((Levitation || Flying) && !forcetrap) {
1217 You("notice a crease in the linoleum.");
1219 You("
\8f°
\82Ì
\8ed
\8fã
\8dÞ
\82Ì
\82µ
\82í
\82É
\8bC
\82ª
\82Â
\82¢
\82½
\81D");
1222 You("notice a loose board below you.");
1224 You("
\91«
\8c³
\82Ì
\8aÉ
\82ñ
\82¾
\94Â
\82É
\8bC
\82ª
\82Â
\82¢
\82½
\81D");
1229 pline("A board beneath you %s%s%s.",
1230 Deaf ? "vibrates" : "squeaks ",
1231 Deaf ? "" : trapnote(trap, 0), Deaf ? "" : " loudly");
1234 pline("
\91«
\8c³
\82Ì
\94Â
\82ª
\82ä
\82ê
\82½
\81D");
1236 pline("
\91«
\8c³
\82Ì
\94Â
\82ª
\91å
\82«
\82%s
\82Ì
\89¹
\82É
\82«
\82µ
\82ñ
\82¾
\81D", trapnote(trap, 0));
1246 if ((Levitation || Flying) && !forcetrap)
1249 if (amorphous(youmonst.data) || is_whirly(youmonst.data)
1250 || unsolid(youmonst.data)) {
1252 pline("%s bear trap closes harmlessly through you.",
1253 A_Your[trap->madeby_u]);
1255 pline("%s
\8cF
\82Ìã©
\82Í
\8a\9a\82Ý
\82Â
\82¢
\82½
\82ª
\81C
\82·
\82é
\82Á
\82Æ
\92Ê
\82è
\94²
\82¯
\82½
\81D",
1256 set_you[trap->madeby_u]);
1260 if (!u.usteed && youmonst.data->msize <= MZ_SMALL) {
1262 pline("%s bear trap closes harmlessly over you.",
1263 A_Your[trap->madeby_u]);
1265 pline("%s
\8cF
\82Ìã©
\82Í
\8a\9a\82Ý
\82Â
\82¢
\82½
\82ª
\81C
\97y
\82©
\8fã
\95û
\82¾
\82Á
\82½
\81D",
1266 set_you[trap->madeby_u]);
1270 u.utrap = rn1(4, 4);
1271 u.utraptype = TT_BEARTRAP;
1274 pline("%s bear trap closes on %s %s!", A_Your[trap->madeby_u],
1275 s_suffix(mon_nam(u.usteed)), mbodypart(u.usteed, FOOT));
1277 pline("%s
\8cF
\82Ìã©
\82Í%s
\82Ì%s
\82É
\8a\9a\82Ý
\82Â
\82¢
\82½
\81I", set_you[trap->madeby_u],
1278 mon_nam(u.usteed), mbodypart(u.usteed, FOOT));
1280 if (thitm(0, u.usteed, (struct obj *) 0, dmg, FALSE))
1281 u.utrap = 0; /* steed died, hero not trapped */
1284 pline("%s bear trap closes on your %s!", A_Your[trap->madeby_u],
1287 pline("%s
\8cF
\82Ìã©
\82ª
\82 \82È
\82½
\82Ì%s
\82É
\8a\9a\82Ý
\82Â
\82¢
\82½
\81I", set_you[trap->madeby_u],
1290 set_wounded_legs(rn2(2) ? RIGHT_SIDE : LEFT_SIDE, rn1(10, 10));
1291 if (u.umonnum == PM_OWLBEAR || u.umonnum == PM_BUGBEAR)
1293 You("howl in anger!");
1295 You("
\93{
\82è
\82Ì
\99ô
\9aK
\82ð
\82 \82°
\82½
\81I");
1297 losehp(Maybe_Half_Phys(dmg), "bear trap", KILLED_BY_AN);
1299 losehp(Maybe_Half_Phys(dmg), "
\8cF
\82Ìã©
\82Å", KILLED_BY_AN);
1301 exercise(A_DEX, FALSE);
1307 if (Sleep_resistance || breathless(youmonst.data)) {
1309 You("are enveloped in a cloud of gas!");
1311 You("
\83K
\83X
\89_
\82É
\82Â
\82Â
\82Ü
\82ê
\82½
\81I");
1314 pline("A cloud of gas puts you to sleep!");
1316 pline("
\82 \82È
\82½
\82Í
\83K
\83X
\89_
\82Å
\96°
\82Á
\82Ä
\82µ
\82Ü
\82Á
\82½
\81I");
1317 fall_asleep(-rnd(25), TRUE);
1319 (void) steedintrap(trap, (struct obj *) 0);
1325 /* Unlike monsters, traps cannot aim their rust attacks at
1326 * you, so instead of looping through and taking either the
1327 * first rustable one or the body, we take whatever we get,
1328 * even if it is not rustable.
1333 pline("%s you on the %s!", A_gush_of_water_hits, body_part(HEAD));
1335 pline("
\90\85\82ª
\95¬
\8fo
\82µ
\82Ä
\82 \82È
\82½
\82Ì%s
\82É
\96½
\92\86\82µ
\82½
\81I", body_part(HEAD));
1336 (void) water_damage(uarmh, helm_simple_name(uarmh), TRUE);
1340 pline("%s your left %s!", A_gush_of_water_hits, body_part(ARM));
1342 pline("
\90\85\82ª
\95¬
\8fo
\82µ
\82Ä
\82 \82È
\82½
\82Ì
\8d¶%s
\82É
\96½
\92\86\82µ
\82½
\81I", body_part(ARM));
1344 if (water_damage(uarms, "shield", TRUE) != ER_NOTHING)
1346 if (water_damage(uarms, "
\8f\82", TRUE) != ER_NOTHING)
1348 if (u.twoweap || (uwep && bimanual(uwep)))
1349 (void) water_damage(u.twoweap ? uswapwep : uwep, 0, TRUE);
1352 (void) water_damage(uarmg, "gauntlets", TRUE);
1354 (void) water_damage(uarmg, "
\8f¬
\8eè", TRUE);
1355 /* Not "metal gauntlets" since it gets called
1356 * even if it's leather for the message
1361 pline("%s your right %s!", A_gush_of_water_hits, body_part(ARM));
1363 pline("
\90\85\82ª
\95¬
\8fo
\82µ
\82Ä
\82 \82È
\82½
\82Ì
\89E%s
\82É
\96½
\92\86\82µ
\82½
\81I", body_part(ARM));
1364 (void) water_damage(uwep, 0, TRUE);
1368 pline("%s you!", A_gush_of_water_hits);
1370 pline("
\90\85\82ª
\95¬
\8fo
\82µ
\82Ä
\82 \82È
\82½
\82É
\96½
\92\86\82µ
\82½
\81I");
1371 for (otmp = invent; otmp; otmp = otmp->nobj)
1372 if (otmp->lamplit && otmp != uwep
1373 && (otmp != uswapwep || !u.twoweap))
1374 (void) snuff_lit(otmp);
1376 (void) water_damage(uarmc, cloak_simple_name(uarmc), TRUE);
1379 (void) water_damage(uarm, "armor", TRUE);
1381 (void) water_damage(uarm, "
\8aZ", TRUE);
1384 (void) water_damage(uarmu, "shirt", TRUE);
1386 (void) water_damage(uarmu, "
\83V
\83\83\83c", TRUE);
1390 if (u.umonnum == PM_IRON_GOLEM) {
1394 pline("%s you!", A_gush_of_water_hits);
1396 pline("
\90\85\82ª
\95¬
\8fo
\82µ
\82Ä
\82 \82È
\82½
\82É
\96½
\92\86\82µ
\82½
\81I");
1398 You("are covered with rust!");
1400 You("
\8eK
\82É
\95¢
\82í
\82ê
\82½
\81I");
1402 losehp(Maybe_Half_Phys(dam), "rusting away", KILLED_BY);
1404 losehp(Maybe_Half_Phys(dam), "
\8a®
\91S
\82É
\8eK
\82Ñ
\82Ä", KILLED_BY);
1405 } else if (u.umonnum == PM_GREMLIN && rn2(3)) {
1407 pline("%s you!", A_gush_of_water_hits);
1409 pline("
\90\85\82ª
\95¬
\8fo
\82µ
\82Ä
\82 \82È
\82½
\82É
\96½
\92\86\82µ
\82½
\81I");
1410 (void) split_mon(&youmonst, (struct monst *) 0);
1417 dofiretrap((struct obj *) 0);
1422 /* KMH -- You can't escape the Sokoban level traps */
1423 if (!Sokoban && (Levitation || (Flying && !plunged)))
1426 if (!Sokoban && is_clinger(youmonst.data) && !plunged) {
1429 You_see("%s %spit below you.", a_your[trap->madeby_u],
1430 ttype == SPIKED_PIT ? "spiked " : "");
1432 pline("
\91«
\8c³
\82É%s%s
\97\8e\82µ
\8c\8a\82ð
\94
\8c©
\82µ
\82½
\81D", dig_you[trap->madeby_u],
1433 ttype == SPIKED_PIT ? "
\83g
\83Q
\82¾
\82ç
\82¯
\82Ì" : "");
1437 pline("%s pit %sopens up under you!", A_Your[trap->madeby_u],
1438 ttype == SPIKED_PIT ? "full of spikes " : "");
1440 pline("%s%s
\97\8e\82µ
\8c\8a\82ª
\91«
\8c³
\82É
\8aJ
\82¢
\82½
\81I", dig_you[trap->madeby_u],
1441 ttype == SPIKED_PIT ? "
\83g
\83Q
\82¾
\82ç
\82¯
\82Ì" : "");
1444 You("don't fall in!");
1446 pline("
\82µ
\82©
\82µ
\81C
\82 \82È
\82½
\82Í
\97\8e\82¿
\82È
\82©
\82Á
\82½
\81I");
1451 char verbbuf[BUFSZ];
1454 if ((trflags & RECURSIVETRAP) != 0)
1456 Sprintf(verbbuf, "and %s fall",
1458 Sprintf(verbbuf, "
\82Æ%s",
1459 x_monnam(u.usteed, steed_article, (char *) 0,
1460 SUPPRESS_SADDLE, FALSE));
1463 Sprintf(verbbuf, "lead %s",
1464 x_monnam(u.usteed, steed_article, "poor",
1465 SUPPRESS_SADDLE, FALSE));
1467 Sprintf(verbbuf,"
\82Æ%s",
1468 x_monnam(u.usteed, steed_article, "
\82©
\82í
\82¢
\82»
\82¤
\82È",
1469 SUPPRESS_SADDLE, FALSE));
1471 } else if (adj_pit) {
1472 You("move into an adjacent pit.");
1476 !plunged ? "fall" : (Flying ? "dive" : "plunge"));
1479 !plunged ? "
\97\8e\82¿
\82½" : (Flying ? "
\94ò
\82Ñ
\8d\9e\82ñ
\82¾" : "
\93Ë
\93ü
\82µ
\82½"));
1482 You("%s into %s pit!", verbbuf, a_your[trap->madeby_u]);
1484 You("%s
\97\8e\82µ
\8c\8a\82É%s!", set_you[trap->madeby_u], verbbuf);
1487 /* wumpus reference */
1488 if (Role_if(PM_RANGER) && !trap->madeby_u && !trap->once
1489 && In_quest(&u.uz) && Is_qlocate(&u.uz)) {
1491 pline("Fortunately it has a bottom after all...");
1493 pline("
\8dK
\82¢
\81C
\8c\8b\8bÇ
\82Í
\92ê
\82ª
\82 \82Á
\82½
\81D
\81D
\81D");
1495 } else if (u.umonnum == PM_PIT_VIPER || u.umonnum == PM_PIT_FIEND) {
1497 pline("How pitiful. Isn't that the pits?");
1499 pline("
\82±
\82Ì
\97\8e\82µ
\8c\8a\82Í
\82¢
\82¢
\8ed
\8e\96\82ð
\82µ
\82Ä
\82¢
\82é
\81D");
1501 if (ttype == SPIKED_PIT) {
1503 const char *predicament = "on a set of sharp iron spikes";
1505 const char *predicament = "
\89s
\82¢
\93S
\82Ì
\83g
\83Q
\83g
\83Q
\82Ì
\8fã
\82É
\97\8e\82¿
\82½";
1510 upstart(x_monnam(u.usteed, steed_article, "poor",
1511 SUPPRESS_SADDLE, FALSE)),
1512 adj_pit ? "steps" : "lands", predicament);
1514 pline("%s
\82Í%s
\81I",
1515 upstart(x_monnam(u.usteed, steed_article, "
\82©
\82í
\82¢
\82»
\82¤
\82È",
1516 SUPPRESS_SADDLE, FALSE)),
1521 You("%s %s!", adj_pit ? "step" : "land", predicament);
1523 You("%s
\81I", predicament);
1526 u.utrap = rn1(6, 2);
1527 u.utraptype = TT_PIT;
1528 if (!steedintrap(trap, (struct obj *) 0)) {
1529 if (ttype == SPIKED_PIT) {
1530 oldumort = u.umortality;
1532 losehp(Maybe_Half_Phys(rnd(adj_pit ? 6 : 10)),
1534 ? "deliberately plunged into a pit of iron spikes"
1535 : adj_pit ? "stepped into a pit of iron spikes"
1536 : "fell into a pit of iron spikes",
1539 losehp(Maybe_Half_Phys(rnd(adj_pit ? 6 : 10)),
1541 ? "
\82í
\82´
\82í
\82´
\83g
\83Q
\82¾
\82ç
\82¯
\82Ì
\97\8e\82µ
\8c\8a\82É
\93Ë
\93ü
\82µ
\82Ä"
1542 : adj_pit ? "
\83g
\83Q
\82¾
\82ç
\82¯
\82Ì
\97\8e\82µ
\8c\8a\82É
\93¥
\82Ý
\8d\9e\82ñ
\82Å"
1543 : "
\83g
\83Q
\82¾
\82ç
\82¯
\82Ì
\97\8e\82µ
\8c\8a\82É
\97\8e\82¿
\82Ä",
1548 poisoned("spikes", A_STR,
1549 adj_pit ? "stepping on poison spikes"
1550 : "fall onto poison spikes",
1551 /* if damage triggered life-saving,
1552 poison is limited to attrib loss */
1553 (u.umortality > oldumort) ? 0 : 8, FALSE);
1555 poisoned("
\83g
\83Q", A_STR,
1556 adj_pit ? "
\93Å
\82Ì
\93h
\82ç
\82ê
\82½
\83g
\83Q
\82ð
\93¥
\82ñ
\82Å"
1557 : "
\93Å
\82Ì
\93h
\82ç
\82ê
\82½
\83g
\83Q
\82Ì
\8fã
\82É
\97\8e\82¿
\82Ä",
1558 /* if damage triggered life-saving,
1559 poison is limited to attrib loss */
1560 (u.umortality > oldumort) ? 0 : 8, FALSE);
1563 /* plunging flyers take spike damage but not pit damage */
1565 && !(plunged && (Flying || is_clinger(youmonst.data))))
1567 losehp(Maybe_Half_Phys(rnd(6)),
1568 plunged ? "deliberately plunged into a pit"
1569 : "fell into a pit",
1572 losehp(Maybe_Half_Phys(rnd(6)),
1573 plunged ? "
\82í
\82´
\82í
\82´
\97\8e\82µ
\8c\8a\82É
\93Ë
\93ü
\82µ
\82Ä"
1574 : "
\97\8e\82µ
\8c\8a\82É
\97\8e\82¿
\82Ä",
1578 if (Punished && !carried(uball)) {
1585 selftouch("Falling, you");
1587 selftouch("
\97\8e\89º
\92\86\81C
\82 \82È
\82½
\82Í");
1588 vision_full_recalc = 1; /* vision limits change */
1589 exercise(A_STR, FALSE);
1590 exercise(A_DEX, FALSE);
1596 if (!Can_fall_thru(&u.uz)) {
1597 seetrap(trap); /* normally done in fall_through */
1598 impossible("dotrap: %ss cannot exist on this level.",
1599 defsyms[trap_to_defsym(ttype)].explanation);
1600 break; /* don't activate it after all */
1612 level_tele_trap(trap);
1615 case WEB: /* Our luckless player has stumbled into a web. */
1617 if (amorphous(youmonst.data) || is_whirly(youmonst.data)
1618 || unsolid(youmonst.data)) {
1619 if (acidic(youmonst.data) || u.umonnum == PM_GELATINOUS_CUBE
1620 || u.umonnum == PM_FIRE_ELEMENTAL) {
1623 You("%s %s spider web!",
1624 (u.umonnum == PM_FIRE_ELEMENTAL) ? "burn"
1626 a_your[trap->madeby_u]);
1628 You("%s
\82
\82à
\82Ì
\91\83\82ð%s
\81I",
1629 web_you[trap->madeby_u],
1630 (u.umonnum == PM_FIRE_ELEMENTAL) ? "
\8fÄ
\82¢
\82½"
1631 : "
\82±
\82È
\82²
\82È
\82É
\82µ
\82½");
1639 You("flow through %s spider web.", a_your[trap->madeby_u]);
1641 You("%s
\82
\82à
\82Ì
\91\83\82ð
\82·
\82é
\82è
\82Æ
\92Ê
\82è
\94²
\82¯
\82½
\81D", web_you[trap->madeby_u]);
1644 if (webmaker(youmonst.data)) {
1647 pline(trap->madeby_u ? "You take a walk on your web."
1648 : "There is a spider web here.");
1650 pline(trap->madeby_u ? "
\8e©
\95ª
\82Å
\92£
\82Á
\82½
\82
\82à
\82Ì
\91\83\82Ì
\8fã
\82ð
\95à
\82¢
\82½
\81D"
1651 : "
\82±
\82±
\82É
\82Í
\82
\82à
\82Ì
\91\83\82ª
\82 \82é
\81D");
1656 char verbbuf[BUFSZ];
1660 Strcpy(verbbuf, "are caught by");
1661 } else if (u.usteed) {
1662 Sprintf(verbbuf, "lead %s into",
1663 x_monnam(u.usteed, steed_article, "poor",
1664 SUPPRESS_SADDLE, FALSE));
1666 Sprintf(verbbuf, "%s into",
1667 Levitation ? (const char *) "float"
1668 : locomotion(youmonst.data, "stumble"));
1670 You("%s %s spider web!", verbbuf, a_your[trap->madeby_u]);
1673 Strcpy(verbbuf, "
\82 \82È
\82½
\82Í");
1674 } else if (u.usteed) {
1675 Sprintf(verbbuf, "
\82 \82È
\82½
\82Æ%s",
1676 x_monnam(u.usteed, steed_article, "
\82©
\82í
\82¢
\82»
\82¤
\82È",
1677 SUPPRESS_SADDLE, FALSE));
1679 Sprintf(verbbuf, "
\82 \82È
\82½
\82Í%s",
1680 Levitation ? (const char *) "
\95\82\82«
\82È
\82ª
\82ç"
1681 : jconj(locomotion(youmonst.data, "
\82Â
\82Ü
\82¸
\82"), "
\82Ä"));
1683 pline("%s%s
\82
\82à
\82Ì
\91\83\82É
\82Ð
\82Á
\82©
\82©
\82Á
\82½
\81I", verbbuf, web_you[trap->madeby_u]);
1686 u.utraptype = TT_WEB;
1688 /* Time stuck in the web depends on your/steed strength. */
1690 register int str = ACURR(A_STR);
1692 /* If mounted, the steed gets trapped. Use mintrap
1693 * to do all the work. If mtrapped is set as a result,
1694 * unset it and set utrap instead. In the case of a
1695 * strongmonst and mintrap said it's trapped, use a
1696 * short but non-zero trap time. Otherwise, monsters
1697 * have no specific strength, so use player strength.
1698 * This gets skipped for webmsgok, which implies that
1699 * the steed isn't a factor.
1701 if (u.usteed && webmsgok) {
1702 /* mtmp location might not be up to date */
1703 u.usteed->mx = u.ux;
1704 u.usteed->my = u.uy;
1706 /* mintrap currently does not return 2(died) for webs */
1707 if (mintrap(u.usteed)) {
1708 u.usteed->mtrapped = 0;
1709 if (strongmonst(u.usteed->data))
1715 webmsgok = FALSE; /* mintrap printed the messages */
1718 u.utrap = rn1(6, 6);
1720 u.utrap = rn1(6, 4);
1722 u.utrap = rn1(4, 4);
1724 u.utrap = rn1(4, 2);
1726 u.utrap = rn1(2, 2);
1735 You("tear through %s web!", a_your[trap->madeby_u]);
1737 You("%s
\82
\82à
\82Ì
\91\83\82ð
\90Ø
\82è
\97ô
\82¢
\82½
\81I", web_you[trap->madeby_u]);
1739 newsym(u.ux, u.uy); /* get rid of trap symbol */
1745 (void) activate_statue_trap(trap, u.ux, u.uy, FALSE);
1748 case MAGIC_TRAP: /* A magic trap. */
1752 newsym(u.ux, u.uy); /* update position */
1754 You("are caught in a magical explosion!");
1756 You("
\96\82\96@
\82Ì
\94\9a\94
\82ð
\97\81\82Ñ
\82½
\81I");
1758 losehp(rnd(10), "magical explosion", KILLED_BY_AN);
1760 losehp(rnd(10), "
\96\82\96@
\82Ì
\94\9a\94
\82ð
\97\81\82Ñ
\82Ä", KILLED_BY_AN);
1762 Your("body absorbs some of the magical energy!");
1764 Your("
\91Ì
\82Í
\96\82\96@
\82Ì
\83G
\83l
\83\8b\83M
\81[
\82ð
\8f
\82µ
\8bz
\82¢
\82Æ
\82Á
\82½
\81I");
1765 u.uen = (u.uenmax += 2);
1770 (void) steedintrap(trap, (struct obj *) 0);
1775 /* hero without magic resistance loses spell energy,
1776 hero with magic resistance takes damage instead;
1777 possibly non-intuitive but useful for play balance */
1779 drain_en(rnd(u.ulevel) + 1);
1781 int dmgval2 = rnd(4), hp = Upolyd ? u.mh : u.uhp;
1783 /* Half_XXX_damage has opposite its usual effect (approx)
1784 but isn't cumulative if hero has more than one */
1785 if (Half_physical_damage || Half_spell_damage)
1787 /* give Magicbane wielder dose of own medicine */
1788 if (uwep && uwep->oartifact == ART_MAGICBANE)
1790 /* having an artifact--other than own quest one--which
1791 confers magic resistance simply by being carried
1792 also increases the effect */
1793 for (otmp = invent; otmp; otmp = otmp->nobj)
1794 if (otmp->oartifact && !is_quest_artifact(otmp)
1795 && defends_when_carried(AD_MAGM, otmp))
1800 dmgval2 = (dmgval2 + 3) / 4;
1803 You_feel((dmgval2 >= hp) ? "unbearably torpid!"
1804 : (dmgval2 >= hp / 4) ? "very lethargic."
1807 You_feel((dmgval2 >= hp) ? "
\91Ï
\82¦
\82ç
\82ê
\82È
\82¢
\82Ù
\82Ç
\96³
\8bC
\97Í
\82É
\82È
\82Á
\82½
\81I"
1808 : (dmgval2 >= hp / 4) ? "
\82Æ
\82Ä
\82à
\8bC
\82¾
\82é
\82
\82È
\82Á
\82½
\81D"
1809 : "
\82à
\82Ì
\82®
\82³
\82È
\8bC
\95ª
\82É
\82È
\82Á
\82½
\81D");
1811 /* opposite of magical explosion */
1813 losehp(dmgval2, "anti-magic implosion", KILLED_BY_AN);
1815 losehp(dmgval2, "
\94½
\96\82\96@
\82Ì
\93à
\95\94\94j
\97ô
\82Å", KILLED_BY_AN);
1820 char verbbuf[BUFSZ];
1825 Sprintf(verbbuf, "lead %s",
1827 Sprintf(verbbuf, "%s
\82Æ
\82Æ
\82à
\82É
\94ò
\82Ñ
\8d\9e\82ñ
\82¾",
1828 x_monnam(u.usteed, steed_article, (char *) 0,
1829 SUPPRESS_SADDLE, FALSE));
1832 Sprintf(verbbuf, "%s", Levitation
1833 ? (const char *) "float"
1834 : locomotion(youmonst.data, "step"));
1836 Sprintf(verbbuf,"%s",
1837 jpast(Levitation ? (const char *)"
\95\82\82«
\82È
\82ª
\82ç
\94ò
\82Ñ
\82±
\82Þ"
1838 : locomotion(youmonst.data, "
\93¥
\82Ý
\8d\9e\82Þ")));
1841 You("%s onto a polymorph trap!", verbbuf);
1843 You("
\95Ï
\89»
\82Ìã©
\82É%s
\81I", verbbuf);
1844 if (Antimagic || Unchanging) {
1845 shieldeff(u.ux, u.uy);
1847 You_feel("momentarily different.");
1849 You("
\88ê
\8fu
\88á
\82Á
\82½
\8a´
\82¶
\82ª
\82µ
\82½
\81D");
1850 /* Trap did nothing; don't remove it --KAA */
1852 (void) steedintrap(trap, (struct obj *) 0);
1853 deltrap(trap); /* delete trap before polymorph */
1854 newsym(u.ux, u.uy); /* get rid of trap symbol */
1856 You_feel("a change coming over you.");
1858 You("
\95Ï
\89»
\82ª
\96K
\82ê
\82½
\82æ
\82¤
\82È
\8bC
\82ª
\82µ
\82½
\81D");
1864 unsigned steed_mid = 0;
1865 struct obj *saddle = 0;
1867 if ((Levitation || Flying) && !forcetrap) {
1868 if (!already_seen && rn2(3))
1872 pline("%s %s in a pile of soil below you.",
1873 already_seen ? "There is" : "You discover",
1874 trap->madeby_u ? "the trigger of your mine" : "a trigger");
1877 pline("
\82±
\82±
\82É
\82Í%s
\92n
\97\8b\82Ì
\8bN
\94\9a\83X
\83C
\83b
\83`
\82ª
\82 \82é
\81D",
1878 set_you[trap->madeby_u]);
1880 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",
1881 set_you[trap->madeby_u]);
1883 if (already_seen && rn2(3))
1886 pline("KAABLAMM!!! %s %s%s off!",
1887 forcebungle ? "Your inept attempt sets"
1888 : "The air currents set",
1889 already_seen ? a_your[trap->madeby_u] : "",
1890 already_seen ? " land mine" : "it");
1892 pline("
\82¿
\82ã
\82Ç
\81[
\82ñ
\81I
\81I%s%s%s
\8bN
\94\9a\83X
\83C
\83b
\83`
\82ª
\94
\93®
\82µ
\82½
\81I",
1893 forcebungle ? "
\95s
\8aí
\97p
\82È
\82¹
\82¢
\82Å"
1894 : "
\8bó
\8bC
\82Ì
\97¬
\82ê
\82Å",
1895 already_seen ? set_you[trap->madeby_u] : "",
1896 already_seen ? "
\92n
\97\8b\82Ì" : "");
1899 /* prevent landmine from killing steed, throwing you to
1900 * the ground, and you being affected again by the same
1901 * mine because it hasn't been deleted yet
1903 static boolean recursive_mine = FALSE;
1909 pline("KAABLAMM!!! You triggered %s land mine!",
1910 a_your[trap->madeby_u]);
1912 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",
1913 set_you[trap->madeby_u]);
1916 steed_mid = u.usteed->m_id;
1917 recursive_mine = TRUE;
1918 (void) steedintrap(trap, (struct obj *) 0);
1919 recursive_mine = FALSE;
1920 saddle = sobj_at(SADDLE, u.ux, u.uy);
1921 set_wounded_legs(LEFT_SIDE, rn1(35, 41));
1922 set_wounded_legs(RIGHT_SIDE, rn1(35, 41));
1923 exercise(A_DEX, FALSE);
1925 blow_up_landmine(trap);
1926 if (steed_mid && saddle && !u.usteed)
1927 (void) keep_saddle_with_steedcorpse(steed_mid, fobj, saddle);
1928 newsym(u.ux, u.uy); /* update trap symbol */
1930 losehp(Maybe_Half_Phys(rnd(16)), "land mine", KILLED_BY_AN);
1932 losehp(Maybe_Half_Phys(rnd(16)), "
\92n
\97\8b\82ð
\93¥
\82ñ
\82Å", KILLED_BY_AN);
1933 /* fall recursively into the pit... */
1934 if ((trap = t_at(u.ux, u.uy)) != 0)
1935 dotrap(trap, RECURSIVETRAP);
1936 fill_pit(u.ux, u.uy);
1940 case ROLLING_BOULDER_TRAP: {
1941 int style = ROLL | (trap->tseen ? LAUNCH_KNOWN : 0);
1945 pline("Click! You trigger a rolling boulder trap!");
1947 pline("
\83J
\83`
\83b
\81I
\82 \82È
\82½
\82Í
\8b\90\8aâ
\82Ìã©
\82Ì
\83X
\83C
\83b
\83`
\82ð
\93¥
\82ñ
\82¾
\81I");
1948 if (!launch_obj(BOULDER, trap->launch.x, trap->launch.y,
1949 trap->launch2.x, trap->launch2.y, style)) {
1951 newsym(u.ux, u.uy); /* get rid of trap symbol */
1953 pline("Fortunately for you, no boulder was released.");
1955 pline("
\89^
\82Ì
\82æ
\82¢
\82±
\82Æ
\82É
\8aâ
\82Í
\93]
\82ª
\82Á
\82Ä
\82±
\82È
\82©
\82Á
\82½
\81D");
1962 domagicportal(trap);
1965 case VIBRATING_SQUARE:
1967 /* messages handled elsewhere; the trap symbol is merely to mark the
1968 * square for future reference */
1973 impossible("You hit a trap of type %u", trap->ttyp);
1978 trapnote(trap, noprefix)
1982 static char tnbuf[12];
1985 *tnnames[12] = { "C note", "D flat", "D note", "E flat",
1986 "E note", "F note", "F sharp", "G note",
1987 "G sharp", "A note", "B flat", "B note" };
1989 *tnnames[12] = { "
\83h", "
\83\8c\81ó", "
\83\8c", "
\83~
\81ó",
1990 "
\83~", "
\83t
\83@", "
\83t
\83@
\81ò", "
\83\",
1991 "
\83\
\81ò", "
\83\89", "
\83V
\81ó", "
\83V" };
1995 tn = tnnames[trap->tnote];
1998 Sprintf(tnbuf, "%s ",
1999 (*tn == 'A' || *tn == 'E' || *tn == 'F') ? "an" : "a");
2000 Sprintf(eos(tnbuf), "%s", tn);
2002 Sprintf(tnbuf, "%s
\82Ì
\89¹", tn);
2008 steedintrap(trap, otmp)
2012 struct monst *steed = u.usteed;
2014 boolean trapkilled, steedhit;
2016 if (!steed || !trap)
2021 trapkilled = steedhit = FALSE;
2026 impossible("steed hit by non-existant arrow?");
2029 trapkilled = thitm(8, steed, otmp, 0, FALSE);
2034 impossible("steed hit by non-existant dart?");
2037 trapkilled = thitm(7, steed, otmp, 0, FALSE);
2041 if (!resists_sleep(steed) && !breathless(steed->data)
2042 && !steed->msleeping && steed->mcanmove) {
2043 if (sleep_monst(steed, rnd(25), -1))
2044 /* no in_sight check here; you can feel it even if blind */
2046 pline("%s suddenly falls asleep!", Monnam(steed));
2048 pline("%s
\82Í
\82Æ
\82Â
\82º
\82ñ
\96°
\82Á
\82Ä
\82µ
\82Ü
\82Á
\82½
\81I", Monnam(steed));
2053 trapkilled = thitm(0, steed, (struct obj *) 0, rnd(16), FALSE);
2058 trapkilled = (steed->mhp <= 0
2059 || thitm(0, steed, (struct obj *) 0,
2060 rnd((tt == PIT) ? 6 : 10), FALSE));
2064 if (!resists_magm(steed) && !resist(steed, WAND_CLASS, 0, NOTELL)) {
2065 (void) newcham(steed, (struct permonst *) 0, FALSE, FALSE);
2066 if (!can_saddle(steed) || !can_ride(steed))
2067 dismount_steed(DISMOUNT_POLY);
2070 You("have to adjust yourself in the saddle on %s.",
2072 You("%s
\82Ì
\88Æ
\82Ì
\8fã
\82Å
\8dÀ
\82è
\82È
\82¨
\82µ
\82½
\81D",
2073 x_monnam(steed, ARTICLE_A, (char *) 0, SUPPRESS_SADDLE,
2083 dismount_steed(DISMOUNT_POLY);
2086 return steedhit ? 1 : 0;
2089 /* some actions common to both player and monsters for triggered landmine */
2091 blow_up_landmine(trap)
2094 int x = trap->tx, y = trap->ty, dbx, dby;
2095 struct rm *lev = &levl[x][y];
2097 (void) scatter(x, y, 4,
2098 MAY_DESTROY | MAY_HIT | MAY_FRACTURE | VIS_EFFECTS,
2101 wake_nearto(x, y, 400);
2102 if (IS_DOOR(lev->typ))
2103 lev->doormask = D_BROKEN;
2104 /* destroy drawbridge if present */
2105 if (lev->typ == DRAWBRIDGE_DOWN || is_drawbridge_wall(x, y) >= 0) {
2107 /* if under the portcullis, the bridge is adjacent */
2108 if (find_drawbridge(&dbx, &dby))
2109 destroy_drawbridge(dbx, dby);
2110 trap = t_at(x, y); /* expected to be null after destruction */
2112 /* convert landmine into pit */
2114 if (Is_waterlevel(&u.uz) || Is_airlevel(&u.uz)) {
2118 trap->ttyp = PIT; /* explosion creates a pit */
2119 trap->madeby_u = FALSE; /* resulting pit isn't yours */
2120 seetrap(trap); /* and it isn't concealed */
2126 * The following are used to track launched objects to
2127 * prevent them from vanishing if you are killed. They
2128 * will reappear at the launchplace in bones files.
2136 launch_drop_spot(obj, x, y)
2141 launchplace.obj = (struct obj *) 0;
2145 launchplace.obj = obj;
2152 launch_in_progress()
2154 if (launchplace.obj)
2160 force_launch_placement()
2162 if (launchplace.obj) {
2163 launchplace.obj->otrapped = 0;
2164 place_object(launchplace.obj, launchplace.x, launchplace.y);
2169 * Move obj from (x1,y1) to (x2,y2)
2171 * Return 0 if no object was launched.
2172 * 1 if an object was launched and placed somewhere.
2173 * 2 if an object was launched, but used up.
2176 launch_obj(otyp, x1, y1, x2, y2, style)
2178 register int x1, y1, x2, y2;
2181 register struct monst *mtmp;
2182 register struct obj *otmp, *otmp2;
2183 register int dx, dy;
2184 struct obj *singleobj;
2185 boolean used_up = FALSE;
2186 boolean otherside = FALSE;
2191 otmp = sobj_at(otyp, x1, y1);
2192 /* Try the other side too, for rolling boulder traps */
2193 if (!otmp && otyp == BOULDER) {
2195 otmp = sobj_at(otyp, x2, y2);
2199 if (otherside) { /* swap 'em */
2210 if (otmp->quan == 1L) {
2211 obj_extract_self(otmp);
2213 otmp = (struct obj *) 0;
2215 singleobj = splitobj(otmp, 1L);
2216 obj_extract_self(singleobj);
2219 /* in case you're using a pick-axe to chop the boulder that's being
2220 launched (perhaps a monster triggered it), destroy context so that
2221 next dig attempt never thinks you're resuming previous effort */
2222 if ((otyp == BOULDER || otyp == STATUE)
2223 && singleobj->ox == context.digging.pos.x
2224 && singleobj->oy == context.digging.pos.y)
2225 (void) memset((genericptr_t) &context.digging, 0,
2226 sizeof(struct dig_info));
2228 dist = distmin(x1, y1, x2, y2);
2234 case ROLL | LAUNCH_UNSEEN:
2235 if (otyp == BOULDER) {
2237 You_hear(Hallucination ? "someone bowling."
2238 : "rumbling in the distance.");
2240 You_hear(Hallucination ? "
\92N
\82©
\82ª
\83{
\81[
\83\8a\83\93\83O
\82ð
\82µ
\82Ä
\82¢
\82é
\89¹
\82ð
\95·
\82¢
\82½
\81D"
2241 : "
\89\93\82
\82Ì
\83S
\83\8d\83S
\83\8d\82Æ
\82¢
\82¤
\89¹
\82ð
\95·
\82¢
\82½
\81D");
2244 style &= ~LAUNCH_UNSEEN;
2246 case ROLL | LAUNCH_KNOWN:
2247 /* use otrapped as a flag to ohitmon */
2248 singleobj->otrapped = 1;
2249 style &= ~LAUNCH_KNOWN;
2258 if (!cansee(bhitpos.x, bhitpos.y))
2260 tmp_at(DISP_FLASH, obj_to_glyph(singleobj));
2261 tmp_at(bhitpos.x, bhitpos.y);
2263 /* Mark a spot to place object in bones files to prevent
2264 * loss of object. Use the starting spot to ensure that
2265 * a rolling boulder will still launch, which it wouldn't
2266 * do if left midstream. Unfortunately we can't use the
2267 * target resting spot, because there are some things/situations
2268 * that would prevent it from ever getting there (bars), and we
2269 * can't tell that yet.
2271 launch_drop_spot(singleobj, bhitpos.x, bhitpos.y);
2273 /* Set the object in motion */
2274 while (dist-- > 0 && !used_up) {
2276 tmp_at(bhitpos.x, bhitpos.y);
2279 /* dstage@u.washington.edu -- Delay only if hero sees it */
2280 if (cansee(bhitpos.x, bhitpos.y))
2286 t = t_at(bhitpos.x, bhitpos.y);
2288 if ((mtmp = m_at(bhitpos.x, bhitpos.y)) != 0) {
2289 if (otyp == BOULDER && throws_rocks(mtmp->data)) {
2292 pline("%s snatches the boulder.", Monnam(mtmp));
2294 pline("%s
\82Í
\8aâ
\82ð
\82Â
\82©
\82Ý
\8eæ
\82Á
\82½
\81D", Monnam(mtmp));
2295 singleobj->otrapped = 0;
2296 (void) mpickobj(mtmp, singleobj);
2298 launch_drop_spot((struct obj *) 0, 0, 0);
2302 if (ohitmon(mtmp, singleobj, (style == ROLL) ? -1 : dist,
2305 launch_drop_spot((struct obj *) 0, 0, 0);
2308 } else if (bhitpos.x == u.ux && bhitpos.y == u.uy) {
2311 if (thitu(9 + singleobj->spe, dmgval(singleobj, &youmonst),
2312 singleobj, (char *) 0))
2315 if (style == ROLL) {
2316 if (down_gate(bhitpos.x, bhitpos.y) != -1) {
2317 if (ship_object(singleobj, bhitpos.x, bhitpos.y, FALSE)) {
2319 launch_drop_spot((struct obj *) 0, 0, 0);
2323 if (t && otyp == BOULDER) {
2330 cansee(bhitpos.x, bhitpos.y)
2331 ? " The rolling boulder triggers a land mine."
2335 "
\82¿
\82ã
\82Ç
\81[
\82ñ
\81I
\81I%s",
2336 cansee(bhitpos.x, bhitpos.y)
2337 ? "
\93]
\82ª
\82Á
\82Ä
\82«
\82½
\8aâ
\82ª
\92n
\97\8b\82Ì
\8bN
\94\9a\83X
\83C
\83b
\83`
\82ð
\93¥
\82ñ
\82¾
\81D"
2341 del_engr_at(bhitpos.x, bhitpos.y);
2342 place_object(singleobj, bhitpos.x, bhitpos.y);
2343 singleobj->otrapped = 0;
2344 fracture_rock(singleobj);
2345 (void) scatter(bhitpos.x, bhitpos.y, 4,
2346 MAY_DESTROY | MAY_HIT | MAY_FRACTURE
2349 if (cansee(bhitpos.x, bhitpos.y))
2350 newsym(bhitpos.x, bhitpos.y);
2352 launch_drop_spot((struct obj *) 0, 0, 0);
2357 if (cansee(bhitpos.x, bhitpos.y))
2359 pline("Suddenly the rolling boulder disappears!");
2361 pline("
\93]
\82ª
\82Á
\82Ä
\82«
\82½
\8aâ
\82ª
\82Æ
\82Â
\82º
\82ñ
\8fÁ
\82¦
\82½
\81I");
2364 You_hear("a rumbling stop abruptly.");
2366 pline("
\83S
\83\8d\83S
\83\8d\82Æ
\82¢
\82¤
\89¹
\82ª
\93Ë
\91R
\8e~
\82Ü
\82Á
\82½
\81D");
2367 singleobj->otrapped = 0;
2368 if (t->ttyp == TELEP_TRAP)
2369 (void) rloco(singleobj);
2371 int newlev = random_teleport_level();
2374 if (newlev == depth(&u.uz) || In_endgame(&u.uz))
2376 add_to_migration(singleobj);
2377 get_level(&dest, newlev);
2378 singleobj->ox = dest.dnum;
2379 singleobj->oy = dest.dlevel;
2380 singleobj->owornmask = (long) MIGR_RANDOM;
2384 launch_drop_spot((struct obj *) 0, 0, 0);
2390 /* the boulder won't be used up if there is a
2391 monster in the trap; stop rolling anyway */
2392 x2 = bhitpos.x, y2 = bhitpos.y; /* stops here */
2394 if (flooreffects(singleobj, x2, y2, "fall")) {
2396 if (flooreffects(singleobj, x2, y2, "
\97\8e\82¿
\82é")) {
2398 launch_drop_spot((struct obj *) 0, 0, 0);
2400 dist = -1; /* stop rolling immediately */
2403 if (used_up || dist == -1)
2407 if (flooreffects(singleobj, bhitpos.x, bhitpos.y, "fall")) {
2409 if (flooreffects(singleobj, bhitpos.x, bhitpos.y, "
\97\8e\82¿
\82é")) {
2411 launch_drop_spot((struct obj *) 0, 0, 0);
2415 && (otmp2 = sobj_at(BOULDER, bhitpos.x, bhitpos.y)) != 0) {
2417 const char *bmsg = " as one boulder sets another in motion";
2419 const char *bmsg = "
\82Ð
\82Æ
\82Â
\82Ì
\8aâ
\82ª
\91¼
\82Ì
\8aâ
\82ð
\93®
\82©
\82µ
\82½
\82©
\82Ì
\82æ
\82¤
\82È
\81C";
2421 if (!isok(bhitpos.x + dx, bhitpos.y + dy) || !dist
2422 || IS_ROCK(levl[bhitpos.x + dx][bhitpos.y + dy].typ))
2424 bmsg = " as one boulder hits another";
2426 bmsg = "
\82Ð
\82Æ
\82Â
\82Ì
\8aâ
\82ª
\91¼
\82Ì
\8aâ
\82É
\93\96\82½
\82Á
\82½
\82æ
\82¤
\82È";
2429 You_hear("a loud crash%s!",
2431 You_hear("%s
\91å
\82«
\82È
\83S
\83\93\82Æ
\82¢
\82¤
\89¹
\82ð
\95·
\82¢
\82½
\81I",
2432 cansee(bhitpos.x, bhitpos.y) ? bmsg : "");
2433 obj_extract_self(otmp2);
2434 /* pass off the otrapped flag to the next boulder */
2435 otmp2->otrapped = singleobj->otrapped;
2436 singleobj->otrapped = 0;
2437 place_object(singleobj, bhitpos.x, bhitpos.y);
2439 otmp2 = (struct obj *) 0;
2440 wake_nearto(bhitpos.x, bhitpos.y, 10 * 10);
2443 if (otyp == BOULDER && closed_door(bhitpos.x, bhitpos.y)) {
2444 if (cansee(bhitpos.x, bhitpos.y))
2446 pline_The("boulder crashes through a door.");
2448 pline("
\8aâ
\82Í
\94à
\82ð
\94j
\89ó
\82µ
\82½
\81D");
2449 levl[bhitpos.x][bhitpos.y].doormask = D_BROKEN;
2451 unblock_point(bhitpos.x, bhitpos.y);
2454 /* if about to hit iron bars, do so now */
2455 if (dist > 0 && isok(bhitpos.x + dx, bhitpos.y + dy)
2456 && levl[bhitpos.x + dx][bhitpos.y + dy].typ == IRONBARS) {
2457 x2 = bhitpos.x, y2 = bhitpos.y; /* object stops here */
2458 if (hits_bars(&singleobj, x2, y2, !rn2(20), 0)) {
2461 launch_drop_spot((struct obj *) 0, 0, 0);
2467 tmp_at(DISP_END, 0);
2468 launch_drop_spot((struct obj *) 0, 0, 0);
2470 singleobj->otrapped = 0;
2471 place_object(singleobj, x2, y2);
2484 newsym(trap->tx, trap->ty);
2488 /* like seetrap() but overrides vision */
2495 /* in case it's beneath something, redisplay the something */
2496 newsym(trap->tx, trap->ty);
2500 mkroll_launch(ttmp, x, y, otyp, ocount)
2513 boolean success = FALSE;
2516 if (ttmp->ttyp == ROLLING_BOULDER_TRAP)
2518 distance = rn1(5, 4); /* 4..8 away */
2519 tmp = rn2(8); /* randomly pick a direction to try first */
2520 while (distance >= mindist) {
2525 /* Prevent boulder from being placed on water */
2526 if (ttmp->ttyp == ROLLING_BOULDER_TRAP
2527 && is_pool_or_lava(x + distance * dx, y + distance * dy))
2530 success = isclearpath(&cc, distance, dx, dy);
2531 if (ttmp->ttyp == ROLLING_BOULDER_TRAP) {
2532 boolean success_otherway;
2536 success_otherway = isclearpath(&bcc, distance, -(dx), -(dy));
2537 if (!success_otherway)
2544 if ((++trycount % 8) == 0)
2548 /* create the trap without any ammo, launch pt at trap location */
2552 otmp = mksobj(otyp, TRUE, FALSE);
2553 otmp->quan = ocount;
2554 otmp->owt = weight(otmp);
2555 place_object(otmp, cc.x, cc.y);
2558 ttmp->launch.x = cc.x;
2559 ttmp->launch.y = cc.y;
2560 if (ttmp->ttyp == ROLLING_BOULDER_TRAP) {
2561 ttmp->launch2.x = bcc.x;
2562 ttmp->launch2.y = bcc.y;
2564 ttmp->launch_otyp = otyp;
2565 newsym(ttmp->launch.x, ttmp->launch.y);
2570 isclearpath(cc, distance, dx, dy)
2580 while (distance-- > 0) {
2583 typ = levl[x][y].typ;
2584 if (!isok(x, y) || !ZAP_POS(typ) || closed_door(x, y))
2594 register struct monst *mtmp;
2596 register struct trap *trap = t_at(mtmp->mx, mtmp->my);
2597 boolean trapkilled = FALSE;
2598 struct permonst *mptr = mtmp->data;
2602 mtmp->mtrapped = 0; /* perhaps teleported? */
2603 } else if (mtmp->mtrapped) { /* is currently in the trap */
2604 if (!trap->tseen && cansee(mtmp->mx, mtmp->my) && canseemon(mtmp)
2605 && (trap->ttyp == SPIKED_PIT || trap->ttyp == BEAR_TRAP
2606 || trap->ttyp == HOLE || trap->ttyp == PIT
2607 || trap->ttyp == WEB)) {
2608 /* If you come upon an obviously trapped monster, then
2609 * you must be able to see the trap it's in too.
2615 if (sobj_at(BOULDER, mtmp->mx, mtmp->my)
2616 && (trap->ttyp == PIT || trap->ttyp == SPIKED_PIT)) {
2619 if (canseemon(mtmp))
2621 pline("%s pulls free...", Monnam(mtmp));
2623 pline("%s
\82Í
\8f\95\82¯
\8fã
\82°
\82ç
\82ê
\82½
\81D", Monnam(mtmp));
2624 fill_pit(mtmp->mx, mtmp->my);
2629 } else if (metallivorous(mptr)) {
2630 if (trap->ttyp == BEAR_TRAP) {
2631 if (canseemon(mtmp))
2633 pline("%s eats a bear trap!", Monnam(mtmp));
2635 pline("%s
\82Í
\8cF
\82Ìã©
\82ð
\90H
\82×
\82½
\81I", Monnam(mtmp));
2639 } else if (trap->ttyp == SPIKED_PIT) {
2640 if (canseemon(mtmp))
2642 pline("%s munches on some spikes!", Monnam(mtmp));
2644 pline("%s
\82Í
\83g
\83Q
\83g
\83Q
\82ð
\90H
\82×
\82½
\81I", Monnam(mtmp));
2650 register int tt = trap->ttyp;
2651 boolean in_sight, tear_web, see_it,
2652 inescapable = force_mintrap || ((tt == HOLE || tt == PIT)
2653 && Sokoban && !trap->madeby_u);
2654 const char *fallverb;
2656 /* true when called from dotrap, inescapable is not an option */
2657 if (mtmp == u.usteed)
2659 if (!inescapable && ((mtmp->mtrapseen & (1 << (tt - 1))) != 0
2660 || (tt == HOLE && !mindless(mptr)))) {
2661 /* it has been in such a trap - perhaps it escapes */
2665 mtmp->mtrapseen |= (1 << (tt - 1));
2667 /* Monster is aggravated by being trapped by you.
2668 Recognizing who made the trap isn't completely
2669 unreasonable; everybody has their own style. */
2670 if (trap->madeby_u && rnl(5))
2673 in_sight = canseemon(mtmp);
2674 see_it = cansee(mtmp->mx, mtmp->my);
2675 /* assume hero can tell what's going on for the steed */
2676 if (mtmp == u.usteed)
2680 if (trap->once && trap->tseen && !rn2(15)) {
2681 if (in_sight && see_it)
2683 pline("%s triggers a trap but nothing happens.",
2686 pline("%s
\82ª
\82í
\82È
\82ð
\8bN
\93®
\82³
\82¹
\82½
\82ª
\89½
\82à
\8bN
\82±
\82ç
\82È
\82©
\82Á
\82½
\81D",
2690 newsym(mtmp->mx, mtmp->my);
2694 otmp = mksobj(ARROW, TRUE, FALSE);
2696 otmp->owt = weight(otmp);
2697 otmp->opoisoned = 0;
2700 if (thitm(8, mtmp, otmp, 0, FALSE))
2704 if (trap->once && trap->tseen && !rn2(15)) {
2705 if (in_sight && see_it)
2707 pline("%s triggers a trap but nothing happens.",
2710 pline("%s
\82ª
\82í
\82È
\82ð
\8bN
\93®
\82³
\82¹
\82½
\82ª
\89½
\82à
\8bN
\82±
\82ç
\82È
\82©
\82Á
\82½
\81D",
2714 newsym(mtmp->mx, mtmp->my);
2718 otmp = mksobj(DART, TRUE, FALSE);
2720 otmp->owt = weight(otmp);
2722 otmp->opoisoned = 1;
2725 if (thitm(7, mtmp, otmp, 0, FALSE))
2729 if (trap->once && trap->tseen && !rn2(15)) {
2730 if (in_sight && see_it)
2733 "A trap door above %s opens, but nothing falls out!",
2735 "%s
\82Ì
\8fã
\82Ì
\94à
\82ª
\8aJ
\82¢
\82½
\82ª
\81C
\89½
\82à
\97\8e\82¿
\82Ä
\82±
\82È
\82©
\82Á
\82½
\81I",
2738 newsym(mtmp->mx, mtmp->my);
2742 otmp = mksobj(ROCK, TRUE, FALSE);
2744 otmp->owt = weight(otmp);
2747 if (thitm(0, mtmp, otmp, d(2, 6), FALSE))
2753 /* stepped on a squeaky board */
2757 pline("A board beneath %s squeaks %s loudly.",
2758 mon_nam(mtmp), trapnote(trap, 0));
2760 pline("%s
\82Ì
\91«
\8c³
\82Ì
\94Â
\82ª
\91å
\82«
\82%s
\82É
\82«
\82µ
\82ñ
\82¾
\81D",
2761 mon_nam(mtmp), trapnote(trap, 0));
2766 pline("%s stops momentarily and appears to cringe.",
2768 pline("%s
\82Í
\88ê
\8fu
\8e~
\82Ü
\82Á
\82Ä
\90g
\82ð
\82·
\82
\82ß
\82½
\82æ
\82¤
\82¾
\81D",
2773 You_hear("a distant %s squeak.", trapnote(trap, 1));
2775 You_hear("
\89\93\82
\82Å%s
\82Å
\82«
\82µ
\82Þ
\89¹
\82ð
\95·
\82¢
\82½
\81D", trapnote(trap, 1));
2776 /* wake up nearby monsters */
2777 wake_nearto(mtmp->mx, mtmp->my, 40);
2780 if (mptr->msize > MZ_SMALL && !amorphous(mptr) && !is_flyer(mptr)
2781 && !is_whirly(mptr) && !unsolid(mptr)) {
2785 pline("%s is caught in %s bear trap!", Monnam(mtmp),
2786 a_your[trap->madeby_u]);
2788 pline("%s
\82Í%s
\8cF
\82Ìã©
\82É
\82Â
\82©
\82Ü
\82Á
\82½
\81I", Monnam(mtmp),
2789 set_you[trap->madeby_u]);
2793 if (mptr == &mons[PM_OWLBEAR]
2794 || mptr == &mons[PM_BUGBEAR])
2796 You_hear("the roaring of an angry bear!");
2798 You_hear("
\93{
\82è
\82Ì
\99ô
\9aK
\82ð
\95·
\82¢
\82½
\81I");
2800 } else if (force_mintrap) {
2803 pline("%s evades %s bear trap!", Monnam(mtmp),
2804 a_your[trap->madeby_u]);
2806 pline("%s
\82Í%s
\8cF
\82Ìã©
\82ð
\82½
\82
\82Ý
\82É
\94ð
\82¯
\82½
\81I", Monnam(mtmp),
2807 set_you[trap->madeby_u]);
2813 trapkilled = thitm(0, mtmp, (struct obj *) 0, d(2, 4), FALSE);
2816 if (!resists_sleep(mtmp) && !breathless(mptr) && !mtmp->msleeping
2817 && mtmp->mcanmove) {
2818 if (sleep_monst(mtmp, rnd(25), -1) && in_sight) {
2820 pline("%s suddenly falls asleep!", Monnam(mtmp));
2822 pline("%s
\82Í
\93Ë
\91R
\96°
\82è
\82É
\97\8e\82¿
\82½
\81I", Monnam(mtmp));
2836 pline("%s %s on the %s!", A_gush_of_water_hits,
2837 mon_nam(mtmp), mbodypart(mtmp, HEAD));
2839 pline("
\90\85\82ª
\95¬
\8fo
\82µ
\82Ä
\81C%s
\82Ì%s
\82É
\96½
\92\86\82µ
\82½
\81I",
2840 mon_nam(mtmp), mbodypart(mtmp, HEAD));
2842 target = which_armor(mtmp, W_ARMH);
2843 (void) water_damage(target, helm_simple_name(target), TRUE);
2848 pline("%s %s's left %s!", A_gush_of_water_hits,
2849 mon_nam(mtmp), mbodypart(mtmp, ARM));
2851 pline("
\90\85\82ª
\95¬
\8fo
\82µ
\82Ä
\81C%s
\82Ì
\8d¶%s
\82É
\96½
\92\86\82µ
\82½
\81I",
2852 mon_nam(mtmp), mbodypart(mtmp, ARM));
2854 target = which_armor(mtmp, W_ARMS);
2856 if (water_damage(target, "shield", TRUE) != ER_NOTHING)
2858 if (water_damage(target, "
\8f\82", TRUE) != ER_NOTHING)
2860 target = MON_WEP(mtmp);
2861 if (target && bimanual(target))
2862 (void) water_damage(target, 0, TRUE);
2864 target = which_armor(mtmp, W_ARMG);
2866 (void) water_damage(target, "gauntlets", TRUE);
2868 (void) water_damage(target, "
\8f¬
\8eè", TRUE);
2873 pline("%s %s's right %s!", A_gush_of_water_hits,
2874 mon_nam(mtmp), mbodypart(mtmp, ARM));
2876 pline("
\90\85\82ª
\95¬
\8fo
\82µ
\82Ä
\81C%s
\82Ì
\89E%s
\82É
\96½
\92\86\82µ
\82½
\81I",
2877 mon_nam(mtmp), mbodypart(mtmp, ARM));
2879 (void) water_damage(MON_WEP(mtmp), 0, TRUE);
2884 pline("%s %s!", A_gush_of_water_hits, mon_nam(mtmp));
2886 pline("
\90\85\82ª
\95¬
\8fo
\82µ
\82Ä
\81C%s
\82É
\96½
\92\86\82µ
\82½
\81I", mon_nam(mtmp));
2887 for (otmp = mtmp->minvent; otmp; otmp = otmp->nobj)
2889 && (otmp->owornmask & (W_WEP | W_SWAPWEP)) == 0)
2890 (void) snuff_lit(otmp);
2891 if ((target = which_armor(mtmp, W_ARMC)) != 0)
2892 (void) water_damage(target, cloak_simple_name(target),
2894 else if ((target = which_armor(mtmp, W_ARM)) != 0)
2896 (void) water_damage(target, "armor", TRUE);
2898 (void) water_damage(target, "
\8aZ", TRUE);
2899 else if ((target = which_armor(mtmp, W_ARMU)) != 0)
2901 (void) water_damage(target, "shirt", TRUE);
2903 (void) water_damage(target, "
\83V
\83\83\83c", TRUE);
2906 if (mptr == &mons[PM_IRON_GOLEM]) {
2909 pline("%s falls to pieces!", Monnam(mtmp));
2911 pline("%s
\82Í
\82
\82¾
\82¯
\82¿
\82Á
\82½
\81I", Monnam(mtmp));
2912 else if (mtmp->mtame)
2914 pline("May %s rust in peace.", mon_nam(mtmp));
2916 pline("%s
\82æ
\81C
\88À
\82ç
\82©
\82É
\8eK
\82Ñ
\82ñ
\8e\96\82ð
\81D", mon_nam(mtmp));
2920 } else if (mptr == &mons[PM_GREMLIN] && rn2(3)) {
2921 (void) split_mon(mtmp, (struct monst *) 0);
2929 pline("A %s erupts from the %s under %s!", tower_of_flame,
2930 surface(mtmp->mx, mtmp->my), mon_nam(mtmp));
2932 pline("
\89Î
\92\8c\82ª%s
\82Ì
\91«
\8c³
\82Ì%s
\82©
\82ç
\97§
\82¿
\82Ì
\82Ú
\82Á
\82½
\81I",
2933 mon_nam(mtmp), surface(mtmp->mx,mtmp->my));
2935 else if (see_it) /* evidently `mtmp' is invisible */
2937 You_see("a %s erupt from the %s!", tower_of_flame,
2938 surface(mtmp->mx, mtmp->my));
2940 You("
\89Î
\92\8c\82ª%s
\82©
\82ç
\90¶
\82¶
\82é
\82Ì
\82ð
\8c©
\82½
\81I",
2941 surface(mtmp->mx,mtmp->my));
2944 if (resists_fire(mtmp)) {
2946 shieldeff(mtmp->mx, mtmp->my);
2948 pline("%s is uninjured.", Monnam(mtmp));
2950 pline("
\82ª
\81C%s
\82Í
\8f\9d\82Â
\82©
\82È
\82¢
\81D", Monnam(mtmp));
2953 int num = d(2, 4), alt;
2954 boolean immolate = FALSE;
2956 /* paper burns very fast, assume straw is tightly
2957 * packed and burns a bit slower */
2958 switch (monsndx(mptr)) {
2959 case PM_PAPER_GOLEM:
2963 case PM_STRAW_GOLEM:
2964 alt = mtmp->mhpmax / 2;
2967 alt = mtmp->mhpmax / 4;
2969 case PM_LEATHER_GOLEM:
2970 alt = mtmp->mhpmax / 8;
2979 if (thitm(0, mtmp, (struct obj *) 0, num, immolate))
2982 /* we know mhp is at least `num' below mhpmax,
2983 so no (mhp > mhpmax) check is needed here */
2984 mtmp->mhpmax -= rn2(num + 1);
2986 if (burnarmor(mtmp) || rn2(3)) {
2987 (void) destroy_mitem(mtmp, SCROLL_CLASS, AD_FIRE);
2988 (void) destroy_mitem(mtmp, SPBOOK_CLASS, AD_FIRE);
2989 (void) destroy_mitem(mtmp, POTION_CLASS, AD_FIRE);
2991 if (burn_floor_objects(mtmp->mx, mtmp->my, see_it, FALSE)
2992 && !see_it && distu(mtmp->mx, mtmp->my) <= 3 * 3)
2994 You("smell smoke.");
2996 pline("
\89\8c\82Ì
\93õ
\82¢
\82ª
\82µ
\82½
\81D");
2997 if (is_ice(mtmp->mx, mtmp->my))
2998 melt_ice(mtmp->mx, mtmp->my, (char *) 0);
3007 fallverb = "
\97\8e\82¿
\82é";
3008 if (is_flyer(mptr) || is_floater(mptr)
3009 || (mtmp->wormno && count_wsegs(mtmp) > 5)
3010 || is_clinger(mptr)) {
3011 if (force_mintrap && !Sokoban) {
3012 /* openfallingtrap; not inescapable here */
3016 pline("%s doesn't fall into the pit.", Monnam(mtmp));
3018 pline("%s
\82Í
\97\8e\82µ
\8c\8a\82É
\97\8e\82¿
\82È
\82©
\82Á
\82½
\81D", Monnam(mtmp));
3020 break; /* inescapable = FALSE; */
3023 break; /* avoids trap */
3025 fallverb = "is dragged"; /* sokoban pit */
3027 fallverb = "
\82¸
\82è
\97\8e\82¿
\82é"; /* sokoban pit */
3030 if (!passes_walls(mptr))
3034 pline("%s %s into %s pit!", Monnam(mtmp), fallverb,
3035 a_your[trap->madeby_u]);
3037 pline("%s
\82Í%s
\97\8e\82µ
\8c\8a\82É%s
\81I", Monnam(mtmp),
3038 set_you[trap->madeby_u], jpast(fallverb));
3040 if (mptr == &mons[PM_PIT_VIPER]
3041 || mptr == &mons[PM_PIT_FIEND])
3043 pline("How pitiful. Isn't that the pits?");
3045 pline("
\82±
\82Ì
\97\8e\82µ
\8c\8a\82Í
\82¢
\82¢
\8ed
\8e\96\82ð
\82µ
\82Ä
\82¢
\82é
\81D");
3049 mselftouch(mtmp, "Falling, ", FALSE);
3051 mselftouch(mtmp, "
\97\8e\89º
\92\86\81C", FALSE);
3052 if (mtmp->mhp <= 0 || thitm(0, mtmp, (struct obj *) 0,
3053 rnd((tt == PIT) ? 6 : 10), FALSE))
3058 if (!Can_fall_thru(&u.uz)) {
3059 impossible("mintrap: %ss cannot exist on this level.",
3060 defsyms[trap_to_defsym(tt)].explanation);
3061 break; /* don't activate it after all */
3063 if (is_flyer(mptr) || is_floater(mptr) || mptr == &mons[PM_WUMPUS]
3064 || (mtmp->wormno && count_wsegs(mtmp) > 5)
3065 || mptr->msize >= MZ_HUGE) {
3066 if (force_mintrap && !Sokoban) {
3067 /* openfallingtrap; not inescapable here */
3073 "A trap door opens, but %s doesn't fall through.",
3075 "
\97\8e\82µ
\94à
\82ª
\8aJ
\82¢
\82½
\82ª
\81C%s
\82Í
\97\8e\82¿
\82È
\82©
\82Á
\82½
\81D",
3077 else /* (tt == HOLE) */
3079 pline("%s doesn't fall through the hole.",
3081 pline("%s
\82Í
\8c\8a\82É
\97\8e\82¿
\82È
\82©
\82Á
\82½
\81D",
3084 break; /* inescapable = FALSE; */
3086 if (inescapable) { /* sokoban hole */
3089 pline("%s seems to be yanked down!", Monnam(mtmp));
3091 pline("%s
\82Í
\88ø
\82«
\97\8e\82³
\82ê
\82½
\82æ
\82¤
\82¾
\81I", Monnam(mtmp));
3092 /* suppress message in mlevel_tele_trap() */
3101 case MAGIC_PORTAL: {
3104 mlev_res = mlevel_tele_trap(mtmp, trap, inescapable, in_sight);
3110 mtele_trap(mtmp, trap, in_sight);
3113 /* Monster in a web. */
3116 if (amorphous(mptr) || is_whirly(mptr) || unsolid(mptr)) {
3117 if (acidic(mptr) || mptr == &mons[PM_GELATINOUS_CUBE]
3118 || mptr == &mons[PM_FIRE_ELEMENTAL]) {
3121 pline("%s %s %s spider web!", Monnam(mtmp),
3122 (mptr == &mons[PM_FIRE_ELEMENTAL])
3125 a_your[trap->madeby_u]);
3127 pline("%s%s
\82
\82à
\82Ì
\91\83\82ð%s
\81I",
3129 web_you[trap->madeby_u],
3130 (mptr == &mons[PM_FIRE_ELEMENTAL]) ?
3131 "
\8fÄ
\82¢
\82½" : "
\82±
\82È
\82²
\82È
\82É
\82µ
\82½");
3134 newsym(mtmp->mx, mtmp->my);
3139 pline("%s flows through %s spider web.", Monnam(mtmp),
3140 a_your[trap->madeby_u]);
3142 pline("%s
\82Í%s
\82
\82à
\82Ì
\91\83\82ð
\82·
\82é
\82è
\82Æ
\92Ê
\82è
\94²
\82¯
\82½
\81D", Monnam(mtmp),
3143 web_you[trap->madeby_u]);
3150 switch (monsndx(mptr)) {
3151 case PM_OWLBEAR: /* Eric Backus */
3155 You_hear("the roaring of a confused bear!");
3157 You_hear("
\8d¬
\97\90\82Ì
\99ô
\9aK
\82ð
\95·
\82¢
\82½
\81I");
3163 if (mptr->mlet == S_GIANT
3164 /* exclude baby dragons and relatively short worms */
3165 || (mptr->mlet == S_DRAGON && extra_nasty(mptr))
3166 || (mtmp->wormno && count_wsegs(mtmp) > 5)) {
3168 } else if (in_sight) {
3170 pline("%s is caught in %s spider web.", Monnam(mtmp),
3171 a_your[trap->madeby_u]);
3173 pline("%s
\82Í%s
\82
\82à
\82Ì
\91\83\82É
\82Â
\82©
\82Ü
\82Á
\82½
\81D", Monnam(mtmp),
3174 web_you[trap->madeby_u]);
3178 mtmp->mtrapped = tear_web ? 0 : 1;
3180 /* this list is fairly arbitrary; it deliberately
3181 excludes wumpus & giant/ettin zombies/mummies */
3182 case PM_TITANOTHERE:
3183 case PM_BALUCHITHERIUM:
3184 case PM_PURPLE_WORM:
3193 case PM_LORD_SURTUR:
3200 pline("%s tears through %s spider web!", Monnam(mtmp),
3201 a_your[trap->madeby_u]);
3203 pline("%s
\82Í%s
\82
\82à
\82Ì
\91\83\82ð
\88ø
\82«
\97ô
\82¢
\82½
\81I", Monnam(mtmp),
3204 web_you[trap->madeby_u]);
3207 newsym(mtmp->mx, mtmp->my);
3208 } else if (force_mintrap && !mtmp->mtrapped) {
3211 pline("%s avoids %s spider web!", Monnam(mtmp),
3212 a_your[trap->madeby_u]);
3214 pline("%s
\82Í%s
\82
\82à
\82Ì
\91\83\82ð
\94ð
\82¯
\82½
\81I", Monnam(mtmp),
3215 web_you[trap->madeby_u]);
3224 /* A magic trap. Monsters usually immune. */
3229 /* similar to hero's case, more or less */
3230 if (!resists_magm(mtmp)) { /* lose spell energy */
3231 if (!mtmp->mcan && (attacktype(mptr, AT_MAGC)
3232 || attacktype(mptr, AT_BREA))) {
3233 mtmp->mspec_used += d(2, 2);
3237 pline("%s seems lethargic.", Monnam(mtmp));
3239 pline("%s
\88ê
\8fu
\96³
\8bC
\97Í
\8a´
\82ð
\8a´
\82¶
\82½
\81D", Monnam(mtmp));
3242 } else { /* take some damage */
3243 int dmgval2 = rnd(4);
3245 if ((otmp = MON_WEP(mtmp)) != 0
3246 && otmp->oartifact == ART_MAGICBANE)
3248 for (otmp = mtmp->minvent; otmp; otmp = otmp->nobj)
3250 && defends_when_carried(AD_MAGM, otmp))
3254 if (passes_walls(mptr))
3255 dmgval2 = (dmgval2 + 3) / 4;
3259 if ((mtmp->mhp -= dmgval2) <= 0)
3263 ? "compression from an anti-magic field"
3265 ? "
\94½
\96\82\96@
\8bó
\8aÔ
\82Ì
\88³
\8fk"
3271 newsym(trap->tx, trap->ty);
3276 break; /* monsters usually don't set it off */
3277 if (is_flyer(mptr)) {
3278 boolean already_seen = trap->tseen;
3280 if (in_sight && !already_seen) {
3282 pline("A trigger appears in a pile of soil below %s.",
3284 pline("%s
\82Ì
\91«
\8c³
\82Ì
\93y
\82Ì
\8eR
\82É
\8bN
\94\9a\83X
\83C
\83b
\83`
\82ª
\8c»
\82í
\82ê
\82½
\81D",
3291 newsym(mtmp->mx, mtmp->my);
3293 pline_The("air currents set %s off!",
3294 already_seen ? "a land mine" : "it");
3296 pline("
\8bó
\8bC
\82Ì
\97¬
\82ê
\82Å
\83X
\83C
\83b
\83`
\82ª
\93ü
\82Á
\82½
\81I");
3299 } else if (in_sight) {
3300 newsym(mtmp->mx, mtmp->my);
3302 pline("KAABLAMM!!! %s triggers %s land mine!", Monnam(mtmp),
3303 a_your[trap->madeby_u]);
3305 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),
3306 set_you[trap->madeby_u]);
3311 pline("Kaablamm! You hear an explosion in the distance!");
3313 pline("
\82¿
\82ã
\82Ç
\81[
\82ñ
\81I
\82 \82È
\82½
\82Í
\89\93\95û
\82Ì
\94\9a\94
\89¹
\82ð
\95·
\82¢
\82½
\81I");
3314 blow_up_landmine(trap);
3315 /* explosion might have destroyed a drawbridge; don't
3316 dish out more damage if monster is already dead */
3318 || thitm(0, mtmp, (struct obj *) 0, rnd(16), FALSE))
3321 /* monsters recursively fall into new pit */
3322 if (mintrap(mtmp) == 2)
3325 /* a boulder may fill the new pit, crushing monster */
3326 fill_pit(trap->tx, trap->ty);
3329 if (unconscious()) {
3332 nomovemsg = "The explosion awakens you!";
3334 nomovemsg = "
\94\9a\94
\82Å
\82 \82È
\82½
\82Í
\8bN
\82«
\82½
\81I";
3338 if (resists_magm(mtmp)) {
3339 shieldeff(mtmp->mx, mtmp->my);
3340 } else if (!resist(mtmp, WAND_CLASS, 0, NOTELL)) {
3341 if (newcham(mtmp, (struct permonst *) 0, FALSE, FALSE))
3342 /* we're done with mptr but keep it up to date */
3348 case ROLLING_BOULDER_TRAP:
3349 if (!is_flyer(mptr)) {
3350 int style = ROLL | (in_sight ? 0 : LAUNCH_UNSEEN);
3352 newsym(mtmp->mx, mtmp->my);
3355 pline("Click! %s triggers %s.", Monnam(mtmp),
3356 trap->tseen ? "a rolling boulder trap" : something);
3358 pline("
\83J
\83`
\83b
\81I%s
\82Í%s
\82Ì
\83X
\83C
\83b
\83`
\82ð
\93¥
\82ñ
\82¾
\81I", Monnam(mtmp),
3359 trap->tseen ? "
\97\8e\8aâ
\82Ìã©" : "
\89½
\82©");
3361 if (launch_obj(BOULDER, trap->launch.x, trap->launch.y,
3362 trap->launch2.x, trap->launch2.y, style)) {
3369 newsym(mtmp->mx, mtmp->my);
3373 case VIBRATING_SQUARE:
3374 if (see_it && !Blind) {
3377 pline("You see a strange vibration beneath %s %s.",
3378 s_suffix(mon_nam(mtmp)),
3379 makeplural(mbodypart(mtmp, FOOT)));
3381 pline("%s
\82Ì%s
\82ª
\95s
\8ev
\8bc
\82É
\90U
\93®
\82µ
\82Ä
\82¢
\82é
\82Ì
\82ð
\8c©
\82½
\81D",
3382 mon_nam(mtmp), mbodypart(mtmp, FOOT));
3386 pline("You see the ground vibrate in the distance.");
3388 pline("
\89\93\82
\82Å
\92n
\96Ê
\82ª
\90U
\93®
\82µ
\82Ä
\82¢
\82é
\82Ì
\82ð
\8c©
\82½
\81D");
3393 impossible("Some monster encountered a strange trap of type %d.",
3399 return mtmp->mtrapped;
3402 /* Combine cockatrice checks into single functions to avoid repeating code. */
3407 if (Stone_resistance)
3409 if (poly_when_stoned(youmonst.data) && polymon(PM_STONE_GOLEM))
3412 You("turn to stone...");
3414 You("
\90Î
\82É
\82È
\82Á
\82½
\81D
\81D
\81D");
3415 killer.format = KILLED_BY;
3416 if (str != killer.name)
3417 Strcpy(killer.name, str ? str : "");
3422 minstapetrify(mon, byplayer)
3426 if (resists_ston(mon))
3428 if (poly_when_stoned(mon->data)) {
3433 /* give a "<mon> is slowing down" message and also remove
3434 intrinsic speed (comparable to similar effect on the hero) */
3435 mon_adjust_speed(mon, -3, (struct obj *) 0);
3437 if (cansee(mon->mx, mon->my))
3439 pline("%s turns to stone.", Monnam(mon));
3441 pline("%s
\82Í
\90Î
\82É
\82È
\82Á
\82½
\81D", Monnam(mon));
3455 if (uwep && uwep->otyp == CORPSE && touch_petrifies(&mons[uwep->corpsenm])
3456 && !Stone_resistance) {
3458 pline("%s touch the %s corpse.", arg, mons[uwep->corpsenm].mname);
3460 pline("%s%s
\82Ì
\8e\80\91Ì
\82É
\90G
\82Á
\82½
\81D", arg, mons[uwep->corpsenm].mname);
3462 Sprintf(kbuf, "%s corpse", an(mons[uwep->corpsenm].mname));
3464 Sprintf(kbuf, "%s
\82Ì
\8e\80\91Ì
\82Å", mons[uwep->corpsenm].mname);
3466 /* life-saved; unwield the corpse if we can't handle it */
3467 if (!uarmg && !Stone_resistance)
3470 /* Or your secondary weapon, if wielded [hypothetical; we don't
3471 allow two-weapon combat when either weapon is a corpse] */
3472 if (u.twoweap && uswapwep && uswapwep->otyp == CORPSE
3473 && touch_petrifies(&mons[uswapwep->corpsenm]) && !Stone_resistance) {
3475 pline("%s touch the %s corpse.", arg, mons[uswapwep->corpsenm].mname);
3477 pline("%s%s
\82Ì
\8e\80\91Ì
\82É
\90G
\82Á
\82½
\81D", arg, mons[uswapwep->corpsenm].mname);
3479 Sprintf(kbuf, "%s corpse", an(mons[uswapwep->corpsenm].mname));
3481 Sprintf(kbuf, "%s
\82Ì
\8e\80\91Ì
\82Å", mons[uswapwep->corpsenm].mname);
3483 /* life-saved; unwield the corpse */
3484 if (!uarmg && !Stone_resistance)
3490 mselftouch(mon, arg, byplayer)
3495 struct obj *mwep = MON_WEP(mon);
3497 if (mwep && mwep->otyp == CORPSE && touch_petrifies(&mons[mwep->corpsenm])
3498 && !resists_ston(mon)) {
3499 if (cansee(mon->mx, mon->my)) {
3501 pline("%s%s touches %s.", arg ? arg : "",
3502 arg ? mon_nam(mon) : Monnam(mon),
3503 corpse_xname(mwep, (const char *) 0, CXN_PFX_THE));
3505 pline("%s%s
\82Í%s
\82Ì
\8e\80\91Ì
\82É
\90G
\82Á
\82½
\81D", arg ? arg : "",
3506 arg ? mon_nam(mon) : Monnam(mon),
3507 corpse_xname(mwep, (const char *) 0, CXN_PFX_THE));
3510 minstapetrify(mon, byplayer);
3511 /* if life-saved, might not be able to continue wielding */
3512 if (mon->mhp > 0 && !which_armor(mon, W_ARMG) && !resists_ston(mon))
3517 /* start levitating */
3522 if (u.utraptype == TT_PIT) {
3525 You("float up, out of the pit!");
3527 You("
\95\82\82«
\8fã
\82ª
\82Á
\82Ä
\81C
\97\8e\82µ
\8c\8a\82©
\82ç
\8fo
\82½
\81I");
3528 vision_full_recalc = 1; /* vision limits change */
3529 fill_pit(u.ux, u.uy);
3530 } else if (u.utraptype == TT_INFLOOR) {
3532 Your("body pulls upward, but your %s are still stuck.",
3534 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",
3535 makeplural(body_part(LEG)));
3538 You("float up, only your %s is still stuck.", body_part(LEG));
3540 You("
\95\82\82«
\8fo
\82½
\81D%s
\82¾
\82¯
\82ª
\82Í
\82Ü
\82Á
\82Ä
\82¢
\82é
\81D", body_part(LEG));
3543 } else if (Is_waterlevel(&u.uz)) {
3545 pline("It feels as though you've lost some weight.");
3547 You("
\82Ü
\82é
\82Å
\91Ì
\8fd
\82ª
\8c¸
\82Á
\82½
\82æ
\82¤
\82É
\8a´
\82¶
\82½
\81D");
3549 } else if (u.uinwater) {
3551 } else if (u.uswallow) {
3553 You(is_animal(u.ustuck->data) ? "float away from the %s."
3554 : "spiral up into %s.",
3555 is_animal(u.ustuck->data) ? surface(u.ux, u.uy)
3556 : mon_nam(u.ustuck));
3558 You(is_animal(u.ustuck->data) ? "%s
\82Ì
\92\86\82Å
\95\82\82¢
\82½
\81D"
3559 : "%s
\82Ì
\92\86\82Å
\82®
\82é
\82®
\82é
\89ñ
\93]
\82µ
\82½
\81D",
3560 is_animal(u.ustuck->data) ? surface(u.ux, u.uy)
3561 : mon_nam(u.ustuck));
3563 } else if (Hallucination) {
3565 pline("Up, up, and awaaaay! You're walking on air!");
3567 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");
3568 } else if (Is_airlevel(&u.uz)) {
3570 You("gain control over your movements.");
3572 You("
\82¤
\82Ü
\82
\95à
\82¯
\82é
\82æ
\82¤
\82É
\82È
\82Á
\82½
\81D");
3575 You("start to float in the air!");
3577 You("
\8bó
\92\86\82É
\95\82\82«
\82Í
\82¶
\82ß
\82½
\81I");
3579 if (u.usteed && !is_floater(u.usteed->data)
3580 && !is_flyer(u.usteed->data)) {
3583 pline("%s magically floats up!", Monnam(u.usteed));
3585 pline("%s
\82Í
\96\82\96@
\82Ì
\97Í
\82Å
\95\82\82¢
\82½
\81I", Monnam(u.usteed));
3588 You("cannot stay on %s.", mon_nam(u.usteed));
3590 You("%s
\82Ì
\8fã
\82É
\8fæ
\82Á
\82Ä
\82¢
\82ç
\82ê
\82È
\82¢
\81D", mon_nam(u.usteed));
3591 dismount_steed(DISMOUNT_GENERIC);
3595 You("are no longer able to control your flight.");
3596 BFlying |= I_SPECIAL;
3607 if ((t = t_at(x, y)) && ((t->ttyp == PIT) || (t->ttyp == SPIKED_PIT))
3608 && (otmp = sobj_at(BOULDER, x, y))) {
3609 obj_extract_self(otmp);
3611 (void) flooreffects(otmp, x, y, "settle");
3613 (void) flooreffects(otmp, x, y, "
\82Í
\82Ü
\82é");
3617 /* stop levitating */
3619 float_down(hmask, emask)
3620 long hmask, emask; /* might cancel timeout */
3622 register struct trap *trap = (struct trap *) 0;
3623 d_level current_dungeon_level;
3624 boolean no_msg = FALSE;
3626 HLevitation &= ~hmask;
3627 ELevitation &= ~emask;
3629 return 0; /* maybe another ring/potion/boots */
3631 /* Levitation is blocked, so hero is not actually floating
3632 hence shouldn't have float_down effects and feedback */
3633 float_vs_flight(); /* before nomul() rather than after */
3636 nomul(0); /* stop running or resting */
3638 /* controlled flight no longer overridden by levitation */
3639 BFlying &= ~I_SPECIAL;
3641 You("have stopped levitating and are now flying.");
3647 You("float down, but you are still %s.",
3648 is_animal(u.ustuck->data) ? "swallowed" : "engulfed");
3650 You("
\92\85\92n
\82µ
\82½
\82ª
\81C
\82Ü
\82¾
\88ù
\82Ý
\8d\9e\82Ü
\82ê
\82½
\82Ü
\82Ü
\82¾
\81D");
3655 if (Punished && !carried(uball)
3656 && (is_pool(uball->ox, uball->oy)
3657 || ((trap = t_at(uball->ox, uball->oy))
3658 && ((trap->ttyp == PIT) || (trap->ttyp == SPIKED_PIT)
3659 || (trap->ttyp == TRAPDOOR) || (trap->ttyp == HOLE))))) {
3664 movobj(uchain, uball->ox, uball->oy);
3665 newsym(u.ux0, u.uy0);
3666 vision_full_recalc = 1; /* in case the hero moved. */
3668 /* check for falling into pool - added by GAN 10/20/86 */
3670 if (!u.uswallow && u.ustuck) {
3671 if (sticks(youmonst.data))
3673 You("aren't able to maintain your hold on %s.",
3676 You("%s
\82ð
\82Â
\82©
\82Ü
\82¦
\91±
\82¯
\82Ä
\82¢
\82ç
\82ê
\82È
\82
\82È
\82Á
\82½
\81D",
3681 pline("Startled, %s can no longer hold you!",
3684 pline("%s
\82Í
\8bÁ
\82¢
\82Ä
\82 \82È
\82½
\82ð
\95ú
\82µ
\82Ä
\82µ
\82Ü
\82Á
\82½
\81I",
3690 * drown() and lava_effects() print various messages almost
3691 * every time they're called which conflict with the "fall
3692 * into" message below. Thus, we want to avoid printing
3693 * confusing, duplicate or out-of-order messages.
3694 * Use knowledge of the two routines as a hack -- this
3695 * should really be handled differently -dlc
3697 if (is_pool(u.ux, u.uy) && !Wwalking && !Swimming && !u.uinwater)
3700 if (is_lava(u.ux, u.uy)) {
3701 (void) lava_effects();
3706 trap = t_at(u.ux, u.uy);
3707 if (Is_airlevel(&u.uz)) {
3709 You("begin to tumble in place.");
3711 You("
\82»
\82Ì
\8fê
\82Å
\82Ð
\82Á
\82
\82è
\95Ô
\82è
\82Í
\82¶
\82ß
\82½
\81D");
3712 } else if (Is_waterlevel(&u.uz) && !no_msg) {
3714 You_feel("heavier.");
3716 You("
\8fd
\82
\82È
\82Á
\82½
\82æ
\82¤
\82È
\8bC
\82ª
\82µ
\82½
\81D");
3717 /* u.uinwater msgs already in spoteffects()/drown() */
3718 } else if (!u.uinwater && !no_msg) {
3719 if (!(emask & W_SADDLE)) {
3720 if (Sokoban && trap) {
3721 /* Justification elsewhere for Sokoban traps is based
3722 * on air currents. This is consistent with that.
3723 * The unexpected additional force of the air currents
3724 * once levitation ceases knocks you off your feet.
3728 pline("Bummer! You've crashed.");
3730 pline("
\82â
\82ß
\82Ä
\82¥
\81I
\82 \82È
\82½
\82Í
\92@
\82«
\82Â
\82¯
\82ç
\82ê
\82½
\81D");
3735 You("
\82Â
\82Ü
\82Ã
\82¢
\82½
\81D");
3737 losehp(rnd(2), "dangerous winds", KILLED_BY);
3739 losehp(rnd(2), "
\8aë
\8c¯
\82È
\95\97\82Å", KILLED_BY);
3741 dismount_steed(DISMOUNT_FELL);
3743 selftouch("As you fall, you");
3745 selftouch("
\97\8e\82¿
\82È
\82ª
\82ç
\81C
\82 \82È
\82½
\82Í");
3746 } else if (u.usteed && (is_floater(u.usteed->data)
3747 || is_flyer(u.usteed->data))) {
3748 You("settle more firmly in the saddle.");
3749 } else if (Hallucination) {
3750 pline("Bummer! You've %s.",
3753 : "hit the ground");
3756 You("float gently to the %s.", surface(u.ux, u.uy));
3758 You("
\90Ã
\82©
\82É%s
\82Ü
\82Å
\92H
\82è
\82Â
\82¢
\82½
\81D", surface(u.ux, u.uy));
3764 /* can't rely on u.uz0 for detecting trap door-induced level change;
3765 it gets changed to reflect the new level before we can check it */
3766 assign_level(¤t_dungeon_level, &u.uz);
3768 switch (trap->ttyp) {
3773 if (!Can_fall_thru(&u.uz) || u.ustuck)
3777 if (!u.utrap) /* not already in the trap */
3781 if (!Is_airlevel(&u.uz) && !Is_waterlevel(&u.uz) && !u.uswallow
3782 /* falling through trap door calls goto_level,
3783 and goto_level does its own pickup() call */
3784 && on_level(&u.uz, ¤t_dungeon_level))
3789 /* shared code for climbing out of a pit */
3793 if (!u.utrap || u.utraptype != TT_PIT)
3797 /* marked as trapped so they can pick things up */
3798 You("ascend from the pit.");
3800 fill_pit(u.ux, u.uy);
3801 vision_full_recalc = 1; /* vision limits change */
3802 } else if (!rn2(2) && sobj_at(BOULDER, u.ux, u.uy)) {
3803 Your("%s gets stuck in a crevice.", body_part(LEG));
3804 display_nhwindow(WIN_MESSAGE, FALSE);
3805 clear_nhwindow(WIN_MESSAGE);
3806 You("free your %s.", body_part(LEG));
3807 } else if ((Flying || is_clinger(youmonst.data)) && !Sokoban) {
3808 /* eg fell in pit, then poly'd to a flying monster;
3809 or used '>' to deliberately enter it */
3810 You("%s from the pit.", Flying ? "fly" : "climb");
3812 fill_pit(u.ux, u.uy);
3813 vision_full_recalc = 1; /* vision limits change */
3814 } else if (!(--u.utrap)) {
3815 You("%s to the edge of the pit.",
3816 (Sokoban && Levitation)
3817 ? "struggle against the air currents and float"
3818 : u.usteed ? "ride" : "crawl");
3819 fill_pit(u.ux, u.uy);
3820 vision_full_recalc = 1; /* vision limits change */
3821 } else if (u.dz || flags.verbose) {
3823 Norep("%s is still in a pit.", upstart(y_monnam(u.usteed)));
3825 Norep((Hallucination && !rn2(5))
3826 ? "You've fallen, and you can't get up."
3827 : "You are still in a pit.");
3833 struct obj *box; /* null for floor trap */
3835 boolean see_it = !Blind;
3838 /* Bug: for box case, the equivalent of burn_floor_objects() ought
3839 * to be done upon its contents.
3842 if ((box && !carried(box)) ? is_pool(box->ox, box->oy) : Underwater) {
3844 pline("A cascade of steamy bubbles erupts from %s!",
3846 pline("
\8fö
\8bC
\82Ì
\96A
\82ª%s
\82©
\82ç
\82µ
\82ã
\81[
\82Á
\82Æ
\94
\90¶
\82µ
\82½
\81I",
3847 the(box ? xname(box) : surface(u.ux, u.uy)));
3848 if (Fire_resistance)
3850 You("are uninjured.");
3852 You("
\8f\9d\82Â
\82©
\82È
\82¢
\81D");
3855 losehp(rnd(3), "boiling water", KILLED_BY);
3857 losehp(rnd(3), "
\95¦
\93«
\82µ
\82½
\90\85\82Å", KILLED_BY);
3861 pline("A %s %s from %s!", tower_of_flame, box ? "bursts" : "erupts",
3862 the(box ? xname(box) : surface(u.ux, u.uy)));
3864 pline("
\89Î
\92\8c\82ª%s
\82©
\82ç%s
\81I", box ? xname(box) : surface(u.ux,u.uy),
3865 box ? "
\90\81\82«
\8fo
\82µ
\82½" : "
\97§
\82¿
\82Ì
\82Ú
\82Á
\82½");
3867 if (Fire_resistance) {
3868 shieldeff(u.ux, u.uy);
3870 } else if (Upolyd) {
3872 switch (u.umonnum) {
3873 case PM_PAPER_GOLEM:
3876 case PM_STRAW_GOLEM:
3882 case PM_LEATHER_GOLEM:
3891 if (u.mhmax > mons[u.umonnum].mlevel)
3892 u.mhmax -= rn2(min(u.mhmax, num + 1)), context.botl = 1;
3895 if (u.uhpmax > u.ulevel)
3896 u.uhpmax -= rn2(min(u.uhpmax, num + 1)), context.botl = 1;
3900 You("are uninjured.");
3902 You("
\8f\9d\82Â
\82©
\82È
\82¢
\81D");
3905 losehp(num, tower_of_flame, KILLED_BY_AN); /* fire damage */
3907 losehp(num, "
\89Î
\92\8c\82Å", KILLED_BY_AN); /* fire damage */
3911 if (burnarmor(&youmonst) || rn2(3)) {
3912 destroy_item(SCROLL_CLASS, AD_FIRE);
3913 destroy_item(SPBOOK_CLASS, AD_FIRE);
3914 destroy_item(POTION_CLASS, AD_FIRE);
3916 if (!box && burn_floor_objects(u.ux, u.uy, see_it, TRUE) && !see_it)
3918 You("smell paper burning.");
3920 You("
\8e\86\82Ì
\82±
\82°
\82é
\93õ
\82¢
\82ª
\82µ
\82½
\81D");
3921 if (is_ice(u.ux, u.uy))
3922 melt_ice(u.ux, u.uy, (char *) 0);
3928 register int fate = rnd(20);
3930 /* What happened to the poor sucker? */
3933 /* Most of the time, it creates some monsters. */
3934 register int cnt = rnd(4);
3936 if (!resists_blnd(&youmonst)) {
3938 You("are momentarily blinded by a flash of light!");
3940 You("
\82Ü
\82Î
\82ä
\82¢
\8cõ
\82Å
\88ê
\8fu
\96Ú
\82ª
\82
\82ç
\82ñ
\82¾
\81I");
3941 make_blinded((long) rn1(5, 10), FALSE);
3943 Your1(vision_clears);
3944 } else if (!Blind) {
3946 You_see("a flash of light!");
3948 You("
\82Ü
\82Î
\82ä
\82¢
\8cõ
\82ð
\97\81\82Ñ
\82½
\81I");
3951 You_hear("a deafening roar!");
3953 You_hear("
\8e¨
\82ð
\82Â
\82ñ
\82´
\82
\82æ
\82¤
\82È
\99ô
\9aK
\82ð
\95·
\82¢
\82½
\81I");
3954 incr_itimeout(&HDeaf, rn1(20, 30));
3956 (void) makemon((struct permonst *) 0, u.ux, u.uy, NO_MM_FLAGS);
3961 /* sometimes nothing happens */
3963 case 12: /* a flash of fire */
3964 dofiretrap((struct obj *) 0);
3970 pline("A shiver runs up and down your %s!", body_part(SPINE));
3972 pline("
\90k
\82¦
\82ª
\82 \82È
\82½
\82Ì%s
\82ð
\91\96\82Á
\82½
\81I", body_part(SPINE));
3976 You_hear(Hallucination ? "the moon howling at you."
3977 : "distant howling.");
3979 You_hear(Hallucination ? "
\8c\8e\82ª
\96i
\82¦
\82Ä
\82¢
\82é
\82Ì
\82ð
\95·
\82¢
\82½
\81D"
3980 : "
\89\93\95û
\82Ì
\89\93\96i
\82ð
\95·
\82¢
\82½
\81D");
3984 if (on_level(&u.uz, &qstart_level))
3987 "%slike the prodigal son.",
3988 (flags.female || (Upolyd && is_neuter(youmonst.data)))
3991 #else /*JP
\90¹
\8f\91\82Ì
\83\8b\83J
\93`
\82æ
\82è */
3992 You("%s
\95ú
\93 \91§
\8eq
\82Ì
\82æ
\82¤
\82É
\82È
\82Á
\82½
\82æ
\82¤
\82È
\8bC
\82ª
\82µ
\82½
\81D",
3993 (flags.female || (Upolyd && is_neuter(youmonst.data)))
3999 You("suddenly yearn for %s.",
4002 : (In_quest(&u.uz) || at_dgn_entrance("The Quest"))
4003 ? "your nearby homeland"
4004 : "your distant homeland");
4006 You("
\93Ë
\91R%s
\82ª
\97ö
\82µ
\82
\82È
\82Á
\82½
\81D",
4007 Hallucination ? "
\90Â
\90X"
4008 : (In_quest(&u.uz) || at_dgn_entrance("
\83N
\83G
\83X
\83g"))
4009 ? "
\82·
\82®
\82»
\82±
\82É
\82 \82é
\8cÌ
\8b½"
4010 : "
\82Í
\82é
\82©
\82©
\82È
\82½
\82Ì
\8cÌ
\8b½");
4015 Your("pack shakes violently!");
4017 Your("
\91Ü
\82Í
\8c\83\82µ
\82
\97h
\82ê
\82½
\81I");
4021 You(Hallucination ? "smell hamburgers." : "smell charred flesh.");
4023 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");
4029 You("
\94æ
\82ê
\82ð
\8a´
\82¶
\82½
\81D");
4032 /* very occasionally something nice happens. */
4033 case 19: { /* tame nearby monsters */
4037 (void) adjattrib(A_CHA, 1, FALSE);
4038 for (i = -1; i <= 1; i++)
4039 for (j = -1; j <= 1; j++) {
4040 if (!isok(u.ux + i, u.uy + j))
4042 mtmp = m_at(u.ux + i, u.uy + j);
4044 (void) tamedog(mtmp, (struct obj *) 0);
4048 case 20: { /* uncurse stuff */
4050 long save_conf = HConfusion;
4052 pseudo = zeroobj; /* neither cursed nor blessed,
4053 and zero out oextra */
4054 pseudo.otyp = SCR_REMOVE_CURSE;
4056 (void) seffects(&pseudo);
4057 HConfusion = save_conf;
4065 /* Set an item on fire.
4066 * "force" means not to roll a luck-based protection check for the
4068 * "x" and "y" are the coordinates to dump the contents of a
4069 * container, if it burns up.
4071 * Return whether the object was destroyed.
4074 fire_damage(obj, force, x, y)
4080 struct obj *otmp, *ncobj;
4081 int in_sight = !Blind && couldsee(x, y); /* Don't care if it's lit */
4084 /* object might light in a controlled manner */
4088 if (Is_container(obj)) {
4089 switch (obj->otyp) {
4091 return FALSE; /* Immune */
4102 if ((!force && (Luck + 5) > rn2(chance))
4103 || (is_flammable(obj) && obj->oerodeproof))
4105 /* Container is burnt up - dump contents out */
4108 pline("%s catches fire and burns.", Yname2(obj));
4110 pline("%s
\82Í
\89Î
\82ª
\82Â
\82¢
\82Ä
\94R
\82¦
\82½
\81D", Yname2(obj));
4111 if (Has_contents(obj)) {
4114 pline("Its contents fall out.");
4116 pline("
\92\86\90g
\82ª
\8fo
\82Ä
\82«
\82½
\81D");
4117 for (otmp = obj->cobj; otmp; otmp = ncobj) {
4119 obj_extract_self(otmp);
4120 if (!flooreffects(otmp, x, y, ""))
4121 place_object(otmp, x, y);
4127 } else if (!force && (Luck + 5) > rn2(20)) {
4128 /* chance per item of sustaining damage:
4129 * max luck (Luck==13): 10%
4130 * avg luck (Luck==0): 75%
4131 * awful luck (Luck<-4): 100%
4134 } else if (obj->oclass == SCROLL_CLASS || obj->oclass == SPBOOK_CLASS) {
4135 if (obj->otyp == SCR_FIRE || obj->otyp == SPE_FIREBALL)
4137 if (obj->otyp == SPE_BOOK_OF_THE_DEAD) {
4140 pline("Smoke rises from %s.", the(xname(obj)));
4142 pline("%s
\82©
\82ç
\89\8c\82ª
\82 \82ª
\82Á
\82½
\81D", the(xname(obj)));
4145 dindx = (obj->oclass == SCROLL_CLASS) ? 3 : 4;
4148 pline("%s %s.", Yname2(obj),
4149 destroy_strings[dindx][(obj->quan > 1L)]);
4151 pline("%s
\82Í%s
\81D", Yname2(obj),
4152 destroy_strings[dindx][(obj->quan > 1L)]);
4157 } else if (obj->oclass == POTION_CLASS) {
4158 dindx = (obj->otyp != POT_OIL) ? 1 : 2;
4161 pline("%s %s.", Yname2(obj),
4162 destroy_strings[dindx][(obj->quan > 1L)]);
4164 pline("%s
\82Í%s
\81D", Yname2(obj),
4165 destroy_strings[dindx][(obj->quan > 1L)]);
4170 } else if (erode_obj(obj, (char *) 0, ERODE_BURN, EF_DESTROY)
4178 * Apply fire_damage() to an entire chain.
4180 * Return number of objects destroyed. --ALI
4183 fire_damage_chain(chain, force, here, x, y)
4185 boolean force, here;
4188 struct obj *obj, *nobj;
4190 for (obj = chain; obj; obj = nobj) {
4191 nobj = here ? obj->nexthere : obj->nobj;
4192 if (fire_damage(obj, force, x, y))
4196 if (num && (Blind && !couldsee(x, y)))
4198 You("smell smoke.");
4200 You("
\89\8c\82Ì
\82É
\82¨
\82¢
\82ª
\82µ
\82½
\81D");
4208 /* Scrolls but not spellbooks can be erased by acid. */
4209 struct monst *victim;
4215 victim = carried(obj) ? &youmonst : mcarried(obj) ? obj->ocarry : NULL;
4216 vismon = victim && (victim != &youmonst) && canseemon(victim);
4219 grease_protect(obj, (char *) 0, victim);
4220 } else if (obj->oclass == SCROLL_CLASS && obj->otyp != SCR_BLANK_PAPER) {
4221 if (obj->otyp != SCR_BLANK_PAPER
4223 && obj->otyp != SCR_MAIL
4227 if (victim == &youmonst)
4229 pline("Your %s.", aobjnam(obj, "fade"));
4231 pline("%s
\82Ì
\95¶
\8e\9a\82Í
\94\96\82ê
\82½
\81D", xname(obj));
4234 pline("%s %s.", s_suffix(Monnam(victim)),
4235 aobjnam(obj, "fade"));
4237 pline("%s
\82Ì%s
\82Ì
\95¶
\8e\9a\82Í
\94\96\82ê
\82½
\81D", Monnam(victim),
4242 obj->otyp = SCR_BLANK_PAPER;
4246 erode_obj(obj, (char *) 0, ERODE_CORRODE, EF_GREASE | EF_VERBOSE);
4249 /* context for water_damage(), managed by water_damage_chain();
4250 when more than one stack of potions of acid explode while processing
4251 a chain of objects, use alternate phrasing after the first message */
4252 static struct h2o_ctx {
4253 int dkn_boom, unk_boom; /* track dknown, !dknown separately */
4255 } acid_ctx = { 0, 0, FALSE };
4257 /* Get an object wet and damage it appropriately.
4258 * "ostr", if present, is used instead of the object name in some
4260 * "force" means not to roll luck to protect some objects.
4261 * Returns an erosion return value (ER_*)
4264 water_damage(obj, ostr, force)
4278 if (obj->otyp == CAN_OF_GREASE && obj->spe > 0) {
4280 } else if (obj->otyp == TOWEL && obj->spe < 7) {
4281 wet_a_towel(obj, rnd(7), TRUE);
4283 } else if (obj->greased) {
4289 } else if (Is_container(obj) && !Is_box(obj)
4290 && (obj->otyp != OILSKIN_SACK || (obj->cursed && !rn2(3)))) {
4293 pline("Water gets into your %s!", ostr);
4295 pline("
\90\85\82ª%s
\82Ì
\92\86\82É
\93ü
\82Á
\82½
\81I", ostr);
4297 water_damage_chain(obj->cobj, FALSE);
4299 } else if (!force && (Luck + 5) > rn2(20)) {
4300 /* chance per item of sustaining damage:
4302 * avg luck (Luck==0): 75%
4303 * awful luck (Luck<-4): 100%
4306 } else if (obj->oclass == SCROLL_CLASS) {
4308 if (obj->otyp == SCR_MAIL)
4313 pline("Your %s %s.", ostr, vtense(ostr, "fade"));
4315 pline("%s
\82Ì
\95¶
\8e\9a\82Í
\94\96\82ê
\82½
\81D", ostr);
4317 obj->otyp = SCR_BLANK_PAPER;
4323 } else if (obj->oclass == SPBOOK_CLASS) {
4324 if (obj->otyp == SPE_BOOK_OF_THE_DEAD) {
4326 pline("Steam rises from %s.", the(xname(obj)));
4328 pline("
\8fö
\8bC
\82ª%s
\82©
\82ç
\97§
\82¿
\82Ì
\82Ú
\82Á
\82½
\81D", xname(obj));
4334 pline("Your %s %s.", ostr, vtense(ostr, "fade"));
4336 pline("%s
\82Ì
\95¶
\8e\9a\82Í
\94\96\82ê
\82½
\81D", ostr);
4338 if (obj->otyp == SPE_NOVEL) {
4343 obj->otyp = SPE_BLANK_PAPER;
4348 } else if (obj->oclass == POTION_CLASS) {
4349 if (obj->otyp == POT_ACID) {
4351 boolean one = (obj->quan == 1L), update = carried(obj),
4354 if (Blind && !carried(obj))
4356 if (acid_ctx.ctx_valid)
4357 exploded = ((obj->dknown ? acid_ctx.dkn_boom
4358 : acid_ctx.unk_boom) > 0);
4360 * "a [potion|<color> potion|potion of acid] explodes"
4361 * depending on obj->dknown (potion has been seen) and
4362 * objects[POT_ACID].oc_name_known (fully discovered),
4363 * or "some {plural version} explode" when relevant.
4364 * Second and subsequent messages for same chain and
4365 * matching dknown status are
4366 * "another [potion|<color> &c] explodes" or plural
4369 bufp = simpleonames(obj);
4371 pline("%s %s %s!", /* "A potion explodes!" */
4372 !exploded ? (one ? "A" : "Some")
4373 : (one ? "Another" : "More"),
4374 bufp, vtense(bufp, "explode"));
4376 pline("
\96ò
\95r
\82ª
\94\9a\94
\82µ
\82½
\81I");
4378 if (acid_ctx.ctx_valid) {
4380 acid_ctx.dkn_boom++;
4382 acid_ctx.unk_boom++;
4388 return ER_DESTROYED;
4389 } else if (obj->odiluted) {
4392 pline("Your %s %s further.", ostr, vtense(ostr, "dilute"));
4394 pline("%s
\82Í
\82³
\82ç
\82É
\94\96\82Ü
\82Á
\82½
\81D", ostr);
4396 obj->otyp = POT_WATER;
4398 obj->blessed = obj->cursed = 0;
4403 } else if (obj->otyp != POT_WATER) {
4406 pline("Your %s %s.", ostr, vtense(ostr, "dilute"));
4408 pline("%s
\82Í
\94\96\82Ü
\82Á
\82½
\81D", ostr);
4416 return erode_obj(obj, ostr, ERODE_RUST, EF_NONE);
4422 water_damage_chain(obj, here)
4428 /* initialize acid context: so far, neither seen (dknown) potions of
4429 acid nor unseen have exploded during this water damage sequence */
4430 acid_ctx.dkn_boom = acid_ctx.unk_boom = 0;
4431 acid_ctx.ctx_valid = TRUE;
4433 for (; obj; obj = otmp) {
4434 otmp = here ? obj->nexthere : obj->nobj;
4435 water_damage(obj, (char *) 0, FALSE);
4438 /* reset acid context */
4439 acid_ctx.dkn_boom = acid_ctx.unk_boom = 0;
4440 acid_ctx.ctx_valid = FALSE;
4444 * This function is potentially expensive - rolling
4445 * inventory list multiple times. Luckily it's seldom needed.
4446 * Returns TRUE if disrobing made player unencumbered enough to
4447 * crawl out of the current predicament.
4450 emergency_disrobe(lostsome)
4453 int invc = inv_cnt(TRUE);
4455 while (near_capacity() > (Punished ? UNENCUMBERED : SLT_ENCUMBER)) {
4456 register struct obj *obj, *otmp = (struct obj *) 0;
4459 /* Pick a random object */
4462 for (obj = invent; obj; obj = obj->nobj) {
4464 * Undroppables are: body armor, boots, gloves,
4465 * amulets, and rings because of the time and effort
4466 * in removing them + loadstone and other cursed stuff
4467 * for obvious reasons.
4469 if (!((obj->otyp == LOADSTONE && obj->cursed) || obj == uamul
4470 || obj == uleft || obj == uright || obj == ublindf
4471 || obj == uarm || obj == uarmc || obj == uarmg
4472 || obj == uarmf || obj == uarmu
4473 || (obj->cursed && (obj == uarmh || obj == uarms))
4476 /* reached the mark and found some stuff to drop? */
4477 if (--i < 0 && otmp)
4484 return FALSE; /* nothing to drop! */
4485 if (otmp->owornmask)
4486 remove_worn_item(otmp, FALSE);
4495 /* return TRUE iff player relocated */
4499 const char *pool_of_water;
4500 boolean inpool_ok = FALSE, crawl_ok;
4503 /* happily wading in the same contiguous pool */
4504 if (u.uinwater && is_pool(u.ux - u.dx, u.uy - u.dy)
4505 && (Swimming || Amphibious)) {
4506 /* water effects on objects every now and then */
4515 You("%s into the water%c", Is_waterlevel(&u.uz) ? "plunge" : "fall",
4516 Amphibious || Swimming ? '.' : '!');
4518 You("
\90\85\82Ì
\92\86\82É%s%s", Is_waterlevel(&u.uz) ? "
\94ò
\82Ñ
\82±
\82ñ
\82¾" : "
\97\8e\82¿
\82½",
4519 Amphibious || Swimming ? "
\81D" : "
\81I");
4521 if (!Swimming && !Is_waterlevel(&u.uz))
4523 You("sink like %s.", Hallucination ? "the Titanic" : "a rock");
4525 You("%s
\82Ì
\82æ
\82¤
\82É
\92¾
\82ñ
\82¾
\81D", Hallucination ? "
\83^
\83C
\83^
\83j
\83b
\83N
\8d\86" : "
\8aâ");
4528 water_damage_chain(invent, FALSE);
4530 if (u.umonnum == PM_GREMLIN && rn2(3))
4531 (void) split_mon(&youmonst, (struct monst *) 0);
4532 else if (u.umonnum == PM_IRON_GOLEM) {
4536 You("
\8eK
\82Ñ
\82½
\81I");
4537 i = Maybe_Half_Phys(d(2, 6));
4541 losehp(i, "rusting away", KILLED_BY);
4543 losehp(i, "
\8a®
\91S
\82É
\8eK
\82Ñ
\82Ä", KILLED_BY);
4548 if ((i = number_leashed()) > 0) {
4550 pline_The("leash%s slip%s loose.", (i > 1) ? "es" : "",
4551 (i > 1) ? "" : "s");
4553 pline("
\95R
\82ª
\82ä
\82é
\82ñ
\82¾
\81D");
4558 if (Amphibious || Swimming) {
4562 pline("But you aren't drowning.");
4564 pline("
\82µ
\82©
\82µ
\81C
\82 \82È
\82½
\82Í
\93M
\82ê
\82È
\82©
\82Á
\82½
\81D");
4565 if (!Is_waterlevel(&u.uz)) {
4568 Your("keel hits the bottom.");
4570 You("
\92ê
\82É
\83j
\81[
\83h
\83\8d\83b
\83v
\82ð
\8c\88\82ß
\82½
\81D");
4573 You("touch bottom.");
4575 You("
\92ê
\82É
\82Â
\82¢
\82½
\81D");
4582 vision_recalc(2); /* unsee old position */
4585 vision_full_recalc = 1;
4588 if ((Teleportation || can_teleport(youmonst.data)) && !Unaware
4589 && (Teleport_control || rn2(3) < Luck + 2)) {
4591 You("attempt a teleport spell."); /* utcsri!carroll */
4593 You("
\8fu
\8aÔ
\88Ú
\93®
\82Ì
\8eô
\95¶
\82ð
\8f¥
\82¦
\82Ä
\82Ý
\82½
\81D");
4595 if (!level.flags.noteleport) {
4597 if (!is_pool(u.ux, u.uy))
4601 pline_The("attempted teleport spell fails.");
4603 pline("
\8fu
\8aÔ
\88Ú
\93®
\82Ì
\8eô
\95¶
\82Í
\8e¸
\94s
\82µ
\82½
\81D");
4606 dismount_steed(DISMOUNT_GENERIC);
4607 if (!is_pool(u.ux, u.uy))
4611 x = y = 0; /* lint suppression */
4612 /* if sleeping, wake up now so that we don't crawl out of water
4613 while still asleep; we can't do that the same way that waking
4614 due to combat is handled; note unmul() clears u.usleep */
4617 unmul("Suddenly you wake up!");
4619 unmul("
\93Ë
\91R
\82 \82È
\82½
\82Í
\96Ú
\82ª
\8ao
\82ß
\82½
\81I");
4620 /* being doused will revive from fainting */
4623 /* can't crawl if unable to move (crawl_ok flag stays false) */
4624 if (multi < 0 || (Upolyd && !youmonst.data->mmove))
4626 /* look around for a place to crawl to */
4627 for (i = 0; i < 100; i++) {
4628 x = rn1(3, u.ux - 1);
4629 y = rn1(3, u.uy - 1);
4630 if (crawl_destination(x, y)) {
4636 for (x = u.ux - 1; x <= u.ux + 1; x++)
4637 for (y = u.uy - 1; y <= u.uy + 1; y++)
4638 if (crawl_destination(x, y)) {
4644 boolean lost = FALSE;
4645 /* time to do some strip-tease... */
4646 boolean succ = Is_waterlevel(&u.uz) ? TRUE : emergency_disrobe(&lost);
4649 You("try to crawl out of the water.");
4651 You("
\90\85\82©
\82ç
\82Í
\82¢
\82 \82ª
\82ë
\82¤
\82Æ
\82µ
\82½
\81D");
4654 You("dump some of your gear to lose weight...");
4656 You("
\91Ì
\82ð
\8cy
\82
\82·
\82é
\82½
\82ß
\82¢
\82
\82Â
\82©
\95¨
\82ð
\93\8a\82°
\82·
\82Ä
\82½
\81D
\81D
\81D");
4659 pline("Pheew! That was close.");
4661 pline("
\83n
\83@
\83n
\83@
\81I
\82 \82Ô
\82È
\82©
\82Á
\82½
\81D");
4665 /* still too much weight */
4667 pline("But in vain.");
4669 pline("
\82ª
\81C
\96³
\91Ê
\82¾
\82Á
\82½
\81D");
4675 You("
\93M
\82ê
\82½
\81D");
4676 for (i = 0; i < 5; i++) { /* arbitrary number of loops */
4677 /* killer format and name are reconstructed every iteration
4678 because lifesaving resets them */
4679 pool_of_water = waterbody_name(u.ux, u.uy);
4680 killer.format = KILLED_BY_AN;
4681 /* avoid "drowned in [a] water" */
4682 if (!strcmp(pool_of_water, "water"))
4683 pool_of_water = "deep water", killer.format = KILLED_BY;
4684 Strcpy(killer.name, pool_of_water);
4686 /* oops, we're still alive. better get out of the water. */
4687 if (safe_teleds(TRUE))
4688 break; /* successful life-save */
4689 /* nowhere safe to land; repeat drowning loop... */
4691 pline("You're still drowning.");
4693 You("
\82Ü
\82¾
\93M
\82ê
\82Ä
\82¢
\82é
\81D");
4698 You("find yourself back %s.",
4699 Is_waterlevel(&u.uz) ? "in an air bubble" : "on land");
4701 You("
\82¢
\82Â
\82Ì
\82Ü
\82É
\82©%s
\82É
\82¢
\82é
\82Ì
\82É
\8bC
\82ª
\82Â
\82¢
\82½
\81D",
4702 Is_waterlevel(&u.uz) ? "
\8bó
\8bC
\82Ì
\96A
\82Ì
\92\86" : "
\92n
\96Ê");
4713 /* energy is completely gone */
4715 You_feel("momentarily lethargic.");
4717 You("
\88ê
\8fu
\96³
\8bC
\97Í
\8a´
\82ð
\8a´
\82¶
\82½
\81D");
4719 /* throttle further loss a bit when there's not much left to lose */
4720 if (n > u.uenmax || n > u.ulevel)
4724 You_feel("your magical energy drain away%c", (n > u.uen) ? '!' : '.');
4726 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");
4729 u.uenmax -= rnd(-u.uen);
4742 if (near_capacity() >= HVY_ENCUMBER) {
4744 pline("You're too strained to do that.");
4746 pline("ã©
\82ð
\89ð
\8f\9c\82µ
\82æ
\82¤
\82É
\82à
\95¨
\82ð
\8e\9d\82¿
\82·
\82¬
\82Ä
\82¢
\82é
\81D");
4749 if ((nohands(youmonst.data) && !webmaker(youmonst.data))
4750 || !youmonst.data->mmove) {
4752 pline("And just how do you expect to do that?");
4754 pline("
\82¢
\82Á
\82½
\82¢
\89½
\82ð
\8aú
\91Ò
\82µ
\82Ä
\82¢
\82é
\82ñ
\82¾
\82¢
\81H");
4756 } else if (u.ustuck && sticks(youmonst.data)) {
4758 pline("You'll have to let go of %s first.", mon_nam(u.ustuck));
4760 pline("%s
\82ð
\8eè
\97£
\82³
\82È
\82¢
\82±
\82Æ
\82É
\82Í
\82Å
\82«
\82È
\82¢
\81D", mon_nam(u.ustuck));
4763 if (u.ustuck || (welded(uwep) && bimanual(uwep))) {
4765 Your("%s seem to be too busy for that.", makeplural(body_part(HAND)));
4767 Your("
\82»
\82ñ
\82È
\82±
\82Æ
\82ð
\82·
\82é
\97]
\97T
\82È
\82ñ
\82Ä
\82È
\82¢
\81D");
4770 return untrap(FALSE);
4773 /* Probability of disabling a trap. Helge Hafting */
4780 /* Only spiders know how to deal with webs reliably */
4781 if (ttmp->ttyp == WEB && !webmaker(youmonst.data))
4783 if (Confusion || Hallucination)
4791 /* Your own traps are better known than others. */
4792 if (ttmp && ttmp->madeby_u)
4794 if (Role_if(PM_ROGUE)) {
4795 if (rn2(2 * MAXULEV) < u.ulevel)
4797 if (u.uhave.questart && chance > 1)
4799 } else if (Role_if(PM_RANGER) && chance > 1)
4804 /* Replace trap with object(s). Helge Hafting */
4806 cnv_trap_obj(otyp, cnt, ttmp, bury_it)
4812 struct obj *otmp = mksobj(otyp, TRUE, FALSE);
4815 otmp->owt = weight(otmp);
4816 /* Only dart traps are capable of being poisonous */
4818 otmp->opoisoned = 0;
4819 place_object(otmp, ttmp->tx, ttmp->ty);
4821 /* magical digging first disarms this trap, then will unearth it */
4822 (void) bury_an_obj(otmp, (boolean *) 0);
4824 /* Sell your own traps only... */
4826 sellobj(otmp, ttmp->tx, ttmp->ty);
4829 newsym(ttmp->tx, ttmp->ty);
4830 if (u.utrap && ttmp->tx == u.ux && ttmp->ty == u.uy)
4835 /* while attempting to disarm an adjacent trap, we've fallen into it */
4837 move_into_trap(ttmp)
4841 xchar x = ttmp->tx, y = ttmp->ty, bx, by, cx, cy;
4844 bx = by = cx = cy = 0; /* lint suppression */
4845 /* we know there's no monster in the way, and we're not trapped */
4847 || drag_ball(x, y, &bc, &bx, &by, &cx, &cy, &unused, TRUE)) {
4848 u.ux0 = u.ux, u.uy0 = u.uy;
4851 newsym(u.ux0, u.uy0);
4853 check_leash(u.ux0, u.uy0);
4855 move_bc(0, bc, bx, by, cx, cy);
4856 /* marking the trap unseen forces dotrap() to treat it like a new
4857 discovery and prevents pickup() -> look_here() -> check_here()
4858 from giving a redundant "there is a <trap> here" message when
4859 there are objects covering this trap */
4860 ttmp->tseen = 0; /* hack for check_here() */
4861 /* trigger the trap */
4862 spoteffects(TRUE); /* pickup() + dotrap() */
4863 exercise(A_WIS, FALSE);
4867 /* 0: doesn't even try
4868 * 1: tries and fails
4872 try_disarm(ttmp, force_failure)
4874 boolean force_failure;
4876 struct monst *mtmp = m_at(ttmp->tx, ttmp->ty);
4877 int ttype = ttmp->ttyp;
4878 boolean under_u = (!u.dx && !u.dy);
4879 boolean holdingtrap = (ttype == BEAR_TRAP || ttype == WEB);
4881 /* Test for monster first, monsters are displayed instead of trap. */
4882 if (mtmp && (!mtmp->mtrapped || !holdingtrap)) {
4884 pline("%s is in the way.", Monnam(mtmp));
4886 pline("
\82»
\82±
\82É
\82Í%s
\82ª
\82¢
\82é
\81D", Monnam(mtmp));
4889 /* We might be forced to move onto the trap's location. */
4890 if (sobj_at(BOULDER, ttmp->tx, ttmp->ty) && !Passes_walls && !under_u) {
4892 There("is a boulder in your way.");
4894 pline("
\82»
\82±
\82É
\82Í
\8aâ
\82ª
\82 \82é
\81D");
4897 /* duplicate tight-space checks from test_move */
4898 if (u.dx && u.dy && bad_rock(youmonst.data, u.ux, ttmp->ty)
4899 && bad_rock(youmonst.data, ttmp->tx, u.uy)) {
4900 if ((invent && (inv_weight() + weight_cap() > 600))
4901 || bigmonst(youmonst.data)) {
4902 /* don't allow untrap if they can't get thru to it */
4904 You("are unable to reach the %s!",
4905 defsyms[trap_to_defsym(ttype)].explanation);
4907 You("%s
\82É
\93Í
\82©
\82È
\82¢
\81I",
4908 defsyms[trap_to_defsym(ttype)].explanation);
4913 /* untrappable traps are located on the ground. */
4914 if (!can_reach_floor(TRUE)) {
4915 if (u.usteed && P_SKILL(P_RIDING) < P_BASIC)
4919 You("are unable to reach the %s!",
4920 defsyms[trap_to_defsym(ttype)].explanation);
4922 You("%s
\82É
\93Í
\82©
\82È
\82¢
\81I",
4923 defsyms[trap_to_defsym(ttype)].explanation);
4928 /* Will our hero succeed? */
4929 if (force_failure || untrap_prob(ttmp)) {
4934 pline("
\82¤
\82í
\82Á
\81D
\81D
\81D");
4935 if (mtmp) { /* must be a trap that holds monsters */
4936 if (ttype == BEAR_TRAP) {
4939 if ((mtmp->mhp -= rnd(4)) <= 0)
4941 } else if (ttype == WEB) {
4942 if (!webmaker(youmonst.data)) {
4943 struct trap *ttmp2 = maketrap(u.ux, u.uy, WEB);
4948 "webbing sticks to you. You're caught too!");
4950 "
\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");
4951 dotrap(ttmp2, NOWEBMSG);
4952 if (u.usteed && u.utrap) {
4953 /* you, not steed, are trapped */
4954 dismount_steed(DISMOUNT_FELL);
4959 pline("%s remains entangled.", Monnam(mtmp));
4961 pline("%s
\82Í
\82©
\82ç
\82Ü
\82Á
\82½
\82Ü
\82Ü
\82¾
\81D", Monnam(mtmp));
4963 } else if (under_u) {
4966 move_into_trap(ttmp);
4970 pline("%s %s is difficult to %s.",
4971 ttmp->madeby_u ? "Your" : under_u ? "This" : "That",
4972 defsyms[trap_to_defsym(ttype)].explanation,
4973 (ttype == WEB) ? "remove" : "disarm");
4975 pline("%s%s
\82ð
\89ð
\8f\9c\82·
\82é
\82Ì
\82Í
\8d¢
\93ï
\82¾
\81D",
4976 ttmp->madeby_u ? "
\82 \82È
\82½
\82Ì
\8ed
\8a|
\82¯
\82½" : under_u ? "
\82±
\82Ì" : "
\82»
\82Ì",
4977 defsyms[trap_to_defsym(ttype)].explanation);
4986 reward_untrap(ttmp, mtmp)
4990 if (!ttmp->madeby_u) {
4991 if (rnl(10) < 8 && !mtmp->mpeaceful && !mtmp->msleeping
4992 && !mtmp->mfrozen && !mindless(mtmp->data)
4993 && mtmp->data->mlet != S_HUMAN) {
4994 mtmp->mpeaceful = 1;
4995 set_malign(mtmp); /* reset alignment */
4997 pline("%s is grateful.", Monnam(mtmp));
4999 pline("%s
\82Í
\8aì
\82ñ
\82Å
\82¢
\82é
\81D", Monnam(mtmp));
5001 /* Helping someone out of a trap is a nice thing to do,
5002 * A lawful may be rewarded, but not too often. */
5003 if (!rn2(3) && !rnl(8) && u.ualign.type == A_LAWFUL) {
5006 You_feel("that you did the right thing.");
5008 You("
\90³
\82µ
\82¢
\82±
\82Æ
\82ð
\82µ
\82½
\82æ
\82¤
\82È
\8bC
\82ª
\82µ
\82½
\81D");
5014 disarm_holdingtrap(ttmp) /* Helge Hafting */
5018 int fails = try_disarm(ttmp, FALSE);
5023 /* ok, disarm it. */
5025 /* untrap the monster, if any.
5026 There's no need for a cockatrice test, only the trap is touched */
5027 if ((mtmp = m_at(ttmp->tx, ttmp->ty)) != 0) {
5030 You("remove %s %s from %s.", the_your[ttmp->madeby_u],
5031 (ttmp->ttyp == BEAR_TRAP) ? "bear trap" : "webbing",
5034 You("%s%s
\82ð%s
\82©
\82ç
\82Í
\82¸
\82µ
\82½
\81D", set_you[ttmp->madeby_u],
5035 (ttmp->ttyp == BEAR_TRAP) ? "
\8cF
\82Ìã©" : "
\82
\82à
\82Ì
\91\83",
5038 reward_untrap(ttmp, mtmp);
5040 if (ttmp->ttyp == BEAR_TRAP) {
5042 You("disarm %s bear trap.", the_your[ttmp->madeby_u]);
5044 You("%s
\8cF
\82Ìã©
\82ð
\89ð
\8f\9c\82µ
\82½
\81D", set_you[ttmp->madeby_u]);
5045 cnv_trap_obj(BEARTRAP, 1, ttmp, FALSE);
5046 } else /* if (ttmp->ttyp == WEB) */ {
5048 You("succeed in removing %s web.", the_your[ttmp->madeby_u]);
5050 You("%s
\82
\82à
\82Ì
\91\83\82ð
\8eæ
\82è
\8f\9c\82¢
\82½
\81D", set_you[ttmp->madeby_u]);
5054 newsym(u.ux + u.dx, u.uy + u.dy);
5059 disarm_landmine(ttmp) /* Helge Hafting */
5062 int fails = try_disarm(ttmp, FALSE);
5067 You("disarm %s land mine.", the_your[ttmp->madeby_u]);
5069 You("%s
\92n
\97\8b\82ð
\89ð
\8f\9c\82µ
\82½
\81D", set_you[ttmp->madeby_u]);
5070 cnv_trap_obj(LAND_MINE, 1, ttmp, FALSE);
5074 /* getobj will filter down to cans of grease and known potions of oil */
5075 static NEARDATA const char oil[] = { ALL_CLASSES, TOOL_CLASS, POTION_CLASS,
5078 /* it may not make much sense to use grease on floor boards, but so what? */
5080 disarm_squeaky_board(ttmp)
5087 obj = getobj(oil, "untrap with");
5091 bad_tool = (obj->cursed
5092 || ((obj->otyp != POT_OIL || obj->lamplit)
5093 && (obj->otyp != CAN_OF_GREASE || !obj->spe)));
5094 fails = try_disarm(ttmp, bad_tool);
5098 /* successfully used oil or grease to fix squeaky board */
5099 if (obj->otyp == CAN_OF_GREASE) {
5100 consume_obj_charge(obj, TRUE);
5102 useup(obj); /* oil */
5106 You("repair the squeaky board."); /* no madeby_u */
5108 You("
\82«
\82µ
\82Þ
\94Â
\82ð
\8fC
\97\9d\82µ
\82½
\81D"); /* no madeby_u */
5111 newsym(u.ux + u.dx, u.uy + u.dy);
5112 more_experienced(1, 5);
5117 /* removes traps that shoot arrows, darts, etc. */
5119 disarm_shooting_trap(ttmp, otyp)
5123 int fails = try_disarm(ttmp, FALSE);
5128 You("disarm %s trap.", the_your[ttmp->madeby_u]);
5130 pline("%sã©
\82ð
\89ð
\8f\9c\82µ
\82½
\81D", set_you[ttmp->madeby_u]);
5131 cnv_trap_obj(otyp, 50 - rnl(50), ttmp, FALSE);
5135 /* Is the weight too heavy?
5136 * Formula as in near_capacity() & check_capacity() */
5138 try_lift(mtmp, ttmp, wt, stuff)
5144 int wc = weight_cap();
5146 if (((wt * 2) / wc) >= HVY_ENCUMBER) {
5148 pline("%s is %s for you to lift.", Monnam(mtmp),
5149 stuff ? "carrying too much" : "too heavy");
5151 pline("%s
\82Í%s
\8e\9d\82¿
\82 \82°
\82é
\82±
\82Æ
\82ª
\82Å
\82«
\82È
\82¢
\81D", Monnam(mtmp),
5152 stuff ? "
\95¨
\82ð
\8e\9d\82¿
\82·
\82¬
\82Ä
\82¨
\82è" : "
\8fd
\82·
\82¬
\82Ä");
5154 if (!ttmp->madeby_u && !mtmp->mpeaceful && mtmp->mcanmove
5155 && !mindless(mtmp->data) && mtmp->data->mlet != S_HUMAN
5157 mtmp->mpeaceful = 1;
5158 set_malign(mtmp); /* reset alignment */
5160 pline("%s thinks it was nice of you to try.", Monnam(mtmp));
5162 pline("%s
\82Í
\82 \82È
\82½
\82Ì
\93w
\97Í
\82É
\8a´
\8eÓ
\82µ
\82Ä
\82¢
\82é
\82æ
\82¤
\82¾
\81D", Monnam(mtmp));
5169 /* Help trapped monster (out of a (spiked) pit) */
5171 help_monster_out(mtmp, ttmp)
5180 * This works when levitating too -- consistent with the ability
5181 * to hit monsters while levitating.
5183 * Should perhaps check that our hero has arms/hands at the
5184 * moment. Helping can also be done by engulfing...
5186 * Test the monster first - monsters are displayed before traps.
5188 if (!mtmp->mtrapped) {
5190 pline("%s isn't trapped.", Monnam(mtmp));
5192 pline("%s
\82Íã©
\82É
\82©
\82©
\82Á
\82Ä
\82¢
\82È
\82¢
\81D", Monnam(mtmp));
5195 /* Do you have the necessary capacity to lift anything? */
5196 if (check_capacity((char *) 0))
5199 /* Will our hero succeed? */
5200 if ((uprob = untrap_prob(ttmp)) && !mtmp->msleeping && mtmp->mcanmove) {
5202 You("try to reach out your %s, but %s backs away skeptically.",
5203 makeplural(body_part(ARM)), mon_nam(mtmp));
5205 You("%s
\82ð
\8d·
\82µ
\89\84\82×
\82æ
\82¤
\82Æ
\82µ
\82½
\82ª%s
\82Í
\8cx
\89ú
\82µ
\82Ä
\82¢
\82é
\81D",
5206 body_part(ARM), mon_nam(mtmp));
5211 /* is it a cockatrice?... */
5212 if (touch_petrifies(mtmp->data) && !uarmg && !Stone_resistance) {
5214 You("grab the trapped %s using your bare %s.", mtmp->data->mname,
5215 makeplural(body_part(HAND)));
5217 You("ã©
\82É
\82©
\82©
\82Á
\82Ä
\82¢
\82é%s
\82ð
\91f%s
\82Å
\92Í
\82ñ
\82¾
\81D", mtmp->data->mname,
5221 if (poly_when_stoned(youmonst.data) && polymon(PM_STONE_GOLEM)) {
5222 display_nhwindow(WIN_MESSAGE, FALSE);
5227 Sprintf(kbuf, "trying to help %s out of a pit",
5228 an(mtmp->data->mname));
5230 Sprintf(kbuf, "ã©
\82É
\82©
\82©
\82Á
\82Ä
\82¢
\82é%s
\82ð
\8f\95\82¯
\82æ
\82¤
\82Æ
\82µ
\82Ä",
5237 /* need to do cockatrice check first if sleeping or paralyzed */
5240 You("try to grab %s, but cannot get a firm grasp.", mon_nam(mtmp));
5242 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));
5243 if (mtmp->msleeping) {
5244 mtmp->msleeping = 0;
5246 pline("%s awakens.", Monnam(mtmp));
5248 pline("%s
\82Í
\96Ú
\82ð
\8ao
\82Ü
\82µ
\82½
\81D", Monnam(mtmp));
5254 You("reach out your %s and grab %s.", makeplural(body_part(ARM)),
5257 You("%s
\82ð
\90L
\82Î
\82µ
\82Ä%s
\82ð
\82Â
\82©
\82ñ
\82¾
\81D", body_part(ARM),
5261 if (mtmp->msleeping) {
5262 mtmp->msleeping = 0;
5264 pline("%s awakens.", Monnam(mtmp));
5266 pline("%s
\82Í
\96Ú
\82ð
\8ao
\82Ü
\82µ
\82½
\81D", Monnam(mtmp));
5267 } else if (mtmp->mfrozen && !rn2(mtmp->mfrozen)) {
5268 /* After such manhandling, perhaps the effect wears off */
5272 pline("%s stirs.", Monnam(mtmp));
5274 pline("%s
\82Í
\93®
\82«
\8en
\82ß
\82½
\81D", Monnam(mtmp));
5277 /* is the monster too heavy? */
5278 wt = inv_weight() + mtmp->data->cwt;
5279 if (!try_lift(mtmp, ttmp, wt, FALSE))
5282 /* is the monster with inventory too heavy? */
5283 for (otmp = mtmp->minvent; otmp; otmp = otmp->nobj)
5285 if (!try_lift(mtmp, ttmp, wt, TRUE))
5289 You("pull %s out of the pit.", mon_nam(mtmp));
5291 You("%s
\82ð
\97\8e\82µ
\8c\8a\82©
\82ç
\82Ð
\82Á
\82Ï
\82Á
\82½
\81D", mon_nam(mtmp));
5293 fill_pit(mtmp->mx, mtmp->my);
5294 reward_untrap(ttmp, mtmp);
5302 register struct obj *otmp;
5307 const char *trapdescr;
5308 boolean here, useplural, confused = (Confusion || Hallucination),
5309 trap_skipped = FALSE, deal_with_floor_trap;
5311 char the_trap[BUFSZ], qbuf[QBUFSZ];
5313 if (!getdir((char *) 0))
5319 pline_The("perils lurking there are beyond your grasp.");
5321 pline_The("
\82»
\82±
\82É
\82 \82é
\8aë
\8c¯
\82Í
\82 \82È
\82½
\82Ì
\8eè
\82É
\95\89\82¦
\82È
\82¢
\81D");
5325 if (ttmp && !ttmp->tseen)
5327 trapdescr = ttmp ? defsyms[trap_to_defsym(ttmp->ttyp)].explanation : 0;
5328 here = (x == u.ux && y == u.uy); /* !u.dx && !u.dy */
5330 if (here) /* are there are one or more containers here? */
5331 for (otmp = level.objects[x][y]; otmp; otmp = otmp->nexthere)
5337 deal_with_floor_trap = can_reach_floor(FALSE);
5338 if (!deal_with_floor_trap) {
5341 Strcat(the_trap, an(trapdescr));
5344 Strcat(the_trap, " and ");
5346 Strcat(the_trap, "
\82Æ");
5349 Strcat(the_trap, (boxcnt == 1) ? "a container" : "containers");
5351 Strcat(the_trap, "
\97e
\8aí");
5352 useplural = ((ttmp && boxcnt > 0) || boxcnt > 1);
5353 /* note: boxcnt and useplural will always be 0 for !here case */
5356 There("%s %s %s but you can't reach %s%s.",
5357 useplural ? "are" : "is", the_trap, here ? "here" : "there",
5358 useplural ? "them" : "it",
5359 u.usteed ? " while mounted" : "");
5361 pline("%s
\82ª
\82 \82é
\82ª
\81C%s
\93Í
\82©
\82È
\82¢
\81D",
5363 u.usteed ? "
\8fæ
\82Á
\82Ä
\82¢
\82é
\82Æ" : "");
5365 trap_skipped = (ttmp != 0);
5366 } else { /* deal_with_floor_trap */
5369 Strcpy(the_trap, the(trapdescr));
5371 if (ttmp->ttyp == PIT || ttmp->ttyp == SPIKED_PIT) {
5373 You_cant("do much about %s%s.", the_trap,
5374 u.utrap ? " that you're stuck in"
5375 : " while standing on the edge of it");
5377 pline("%s%s
\82É
\91Î
\82µ
\82Ä
\82Í
\82½
\82¢
\82µ
\82½
\82±
\82Æ
\82Í
\82Å
\82«
\82È
\82¢
\81D",
5378 u.utrap ? "
\8e©
\95ª
\82ª
\82Í
\82Ü
\82Á
\82Ä
\82¢
\82é"
5379 : "
\82·
\82®
\82»
\82Î
\82Ì",
5382 trap_skipped = TRUE;
5383 deal_with_floor_trap = FALSE;
5387 qbuf, "There %s and %s here. %s %s?",
5388 (boxcnt == 1) ? "is a container" : "are containers",
5390 (ttmp->ttyp == WEB) ? "Remove" : "Disarm", the_trap);
5393 qbuf, "
\94 \82Æ%s
\82ª
\82 \82é
\81D%s
\81H",
5395 (ttmp->ttyp == WEB) ? "
\8eæ
\82è
\8f\9c\82" : "
\89ð
\8f\9c\82·
\82é");
5397 switch (ynq(qbuf)) {
5401 trap_skipped = TRUE;
5402 deal_with_floor_trap = FALSE;
5407 if (deal_with_floor_trap) {
5410 You("cannot deal with %s while trapped%s!", the_trap,
5411 (x == u.ux && y == u.uy) ? " in it" : "");
5413 pline("ã©
\82É
\82©
\82©
\82Á
\82Ä
\82¢
\82é
\8aÔ
\82Íã©
\82ð
\89ð
\8f\9c\82Å
\82«
\82È
\82¢
\81I");
5417 if ((mtmp = m_at(x, y)) != 0
5418 && (mtmp->m_ap_type == M_AP_FURNITURE
5419 || mtmp->m_ap_type == M_AP_OBJECT)) {
5420 stumble_onto_mimic(mtmp);
5423 switch (ttmp->ttyp) {
5426 return disarm_holdingtrap(ttmp);
5428 return disarm_landmine(ttmp);
5430 return disarm_squeaky_board(ttmp);
5432 return disarm_shooting_trap(ttmp, DART);
5434 return disarm_shooting_trap(ttmp, ARROW);
5439 You("are already on the edge of the pit.");
5441 You("
\82à
\82¤
\97\8e\82µ
\8c\8a\82Ì
\92[
\82É
\82¢
\82é
\81D");
5446 pline("Try filling the pit instead.");
5448 pline("
\82È
\82ñ
\82Æ
\82©
\96\84\82ß
\82é
\82±
\82Æ
\82ð
\8dl
\82¦
\82Ä
\82Ý
\82½
\82ç
\81H");
5451 return help_monster_out(mtmp, ttmp);
5454 You("cannot disable %s trap.", !here ? "that" : "this");
5456 pline("%sã©
\82Í
\89ð
\8f\9c\82Å
\82«
\82È
\82¢
\81D", !here ? "
\82»
\82Ì" : "
\82±
\82Ì");
5463 for (otmp = level.objects[x][y]; otmp; otmp = otmp->nexthere)
5466 (void) safe_qbuf(qbuf, "There is ",
5467 " here. Check it for traps?", otmp,
5468 doname, ansimpleoname, "a box");
5470 (void) safe_qbuf(qbuf, "",
5471 "
\82ª
\82 \82é
\81Dã©
\82ð
\92²
\82×
\82Ü
\82·
\82©
\81H", otmp,
5472 doname, ansimpleoname, "
\94 ");
5474 switch (ynq(qbuf)) {
5482 && (force || (!confused
5483 && rn2(MAXULEV + 1 - u.ulevel) < 10)))
5484 || (!force && confused && !rn2(3))) {
5486 You("find a trap on %s!", the(xname(otmp)));
5488 pline("%s
\82Éã©
\82ð
\94
\8c©
\82µ
\82½
\81I", the(xname(otmp)));
5490 exercise(A_WIS, TRUE);
5493 switch (ynq("Disarm it?")) {
5495 switch (ynq("
\89ð
\8f\9c\82µ
\82Ü
\82·
\82©
\81H")) {
5499 trap_skipped = TRUE;
5503 if (otmp->otrapped) {
5504 exercise(A_DEX, TRUE);
5505 ch = ACURR(A_DEX) + u.ulevel;
5506 if (Role_if(PM_ROGUE))
5508 if (!force && (confused || Fumbling
5509 || rnd(75 + level_difficulty() / 2)
5511 (void) chest_trap(otmp, FINGER, TRUE);
5516 You("
\89ð
\8f\9c\82µ
\82½
\81I");
5521 pline("That %s was not trapped.", xname(otmp));
5523 pline("
\82»
\82Ì%s
\82Éã©
\82Í
\82È
\82¢
\81D", xname(otmp));
5527 You("find no traps on %s.", the(xname(otmp)));
5529 pline("ã©
\82ð
\94
\8c©
\82Å
\82«
\82È
\82©
\82Á
\82½
\81D");
5535 You(trap_skipped ? "find no other traps here."
5536 : "know of no traps here.");
5538 You(trap_skipped ? "
\91¼
\82Ìã©
\82ð
\8c©
\82Â
\82¯
\82ç
\82ê
\82È
\82©
\82Á
\82½
\81D"
5539 : "
\82±
\82±
\82Éã©
\82ª
\82È
\82¢
\82±
\82Æ
\82ð
\92m
\82Á
\82Ä
\82¢
\82é
\81D");
5544 if (stumble_on_door_mimic(x, y))
5547 } /* deal_with_floor_trap */
5548 /* doors can be manipulated even while levitating/unskilled riding */
5550 if (!IS_DOOR(levl[x][y].typ)) {
5553 You("know of no traps there.");
5555 You("
\82»
\82±
\82Éã©
\82ª
\82È
\82¢
\82±
\82Æ
\82ð
\92m
\82Á
\82Ä
\82¢
\82é
\81D");
5559 switch (levl[x][y].doormask) {
5562 You("%s no door there.", Blind ? "feel" : "see");
5564 pline("
\82»
\82±
\82É
\82Í
\94à
\82ª
\82È
\82¢%s
\81D", Blind ? "
\82æ
\82¤
\82¾" : "
\82æ
\82¤
\82É
\8c©
\82¦
\82é");
5568 pline("This door is safely open.");
5570 pline("
\82»
\82Ì
\94à
\82Í
\88À
\91S
\82É
\8aJ
\82¢
\82Ä
\82¢
\82é
\81D");
5574 pline("This door is broken.");
5576 pline("
\82»
\82Ì
\94à
\82Í
\89ó
\82ê
\82Ä
\82¢
\82é
\81D");
5580 if ((levl[x][y].doormask & D_TRAPPED
5581 && (force || (!confused && rn2(MAXULEV - u.ulevel + 11) < 10)))
5582 || (!force && confused && !rn2(3))) {
5584 You("find a trap on the door!");
5586 pline("
\94à
\82Éã©
\82ð
\94
\8c©
\82µ
\82½
\81I");
5587 exercise(A_WIS, TRUE);
5589 if (ynq("Disarm it?") != 'y')
5591 if (ynq("
\89ð
\8f\9c\82µ
\82Ü
\82·
\82©
\81H") != 'y')
5593 if (levl[x][y].doormask & D_TRAPPED) {
5594 ch = 15 + (Role_if(PM_ROGUE) ? u.ulevel * 3 : u.ulevel);
5595 exercise(A_DEX, TRUE);
5596 if (!force && (confused || Fumbling
5597 || rnd(75 + level_difficulty() / 2) > ch)) {
5601 You("
\83X
\83C
\83b
\83`
\82ð
\93ü
\82ê
\82Ä
\82µ
\82Ü
\82Á
\82½
\81I");
5603 b_trapped("door", FINGER);
5605 b_trapped("
\94à", FINGER);
5606 levl[x][y].doormask = D_NODOOR;
5607 unblock_point(x, y);
5609 /* (probably ought to charge for this damage...) */
5610 if (*in_rooms(x, y, SHOPBASE))
5611 add_damage(x, y, 0L);
5616 You("
\89ð
\8f\9c\82µ
\82½
\81I");
5617 levl[x][y].doormask &= ~D_TRAPPED;
5621 pline("This door was not trapped.");
5623 pline("
\94à
\82Éã©
\82Í
\82È
\82©
\82Á
\82½
\81D");
5627 You("find no traps on the door.");
5629 pline("
\94à
\82Éã©
\82ð
\94
\8c©
\82Å
\82«
\82È
\82©
\82Á
\82½
\81D");
5634 /* for magic unlocking; returns true if targetted monster (which might
5635 be hero) gets untrapped; the trap remains intact */
5637 openholdingtrap(mon, noticed)
5639 boolean *noticed; /* set to true iff hero notices the effect; */
5640 { /* otherwise left with its previous value intact */
5643 const char *trapdescr, *which;
5644 boolean ishero = (mon == &youmonst);
5646 if (mon == u.usteed)
5648 t = t_at(ishero ? u.ux : mon->mx, ishero ? u.uy : mon->my);
5649 /* if no trap here or it's not a holding trap, we're done */
5650 if (!t || (t->ttyp != BEAR_TRAP && t->ttyp != WEB))
5653 trapdescr = defsyms[trap_to_defsym(t->ttyp)].explanation;
5655 which = t->tseen ? the_your[t->madeby_u]
5656 : index(vowels, *trapdescr) ? "an" : "a";
5658 which = t->tseen ? set_you[t->madeby_u] : "";
5664 u.utrap = 0; /* released regardless of type */
5666 /* give message only if trap was the expected type */
5667 if (u.utraptype == TT_BEARTRAP || u.utraptype == TT_WEB) {
5670 Sprintf(buf, "%s is", noit_Monnam(u.usteed));
5672 Strcpy(buf, noit_Monnam(u.usteed));
5675 Strcpy(buf, "You are");
5677 Strcpy(buf, "
\82 \82È
\82½");
5679 pline("%s released from %s %s.", buf, which, trapdescr);
5681 pline("%s
\82Í%s%s
\82©
\82ç
\89ð
\95ú
\82³
\82ê
\82½
\81D", buf, which, trapdescr);
5687 if (canspotmon(mon)) {
5690 pline("%s is released from %s %s.", Monnam(mon), which,
5693 pline("%s
\82Í%s%s
\82©
\82ç
\89ð
\95ú
\82³
\82ê
\82½
\81D", Monnam(mon), which,
5696 } else if (cansee(t->tx, t->ty) && t->tseen) {
5700 pline("%s is released from %s %s.", Something, which,
5703 pline("
\89½
\8eÒ
\82©
\82Í%s%s
\82©
\82ç
\89ð
\95ú
\82³
\82ê
\82½
\81D", which,
5706 else /* BEAR_TRAP */
5708 pline("%s %s opens.", upstart(strcpy(buf, which)), trapdescr);
5710 pline("%s%s
\82Í
\8aJ
\82¢
\82½
\81D", which, trapdescr);
5712 /* might pacify monster if adjacent */
5713 if (rn2(2) && distu(mon->mx, mon->my) <= 2)
5714 reward_untrap(t, mon);
5719 /* for magic locking; returns true if targetted monster (which might
5720 be hero) gets hit by a trap (might avoid actually becoming trapped) */
5722 closeholdingtrap(mon, noticed)
5724 boolean *noticed; /* set to true iff hero notices the effect; */
5725 { /* otherwise left with its previous value intact */
5727 unsigned dotrapflags;
5728 boolean ishero = (mon == &youmonst), result;
5730 if (mon == u.usteed)
5732 t = t_at(ishero ? u.ux : mon->mx, ishero ? u.uy : mon->my);
5733 /* if no trap here or it's not a holding trap, we're done */
5734 if (!t || (t->ttyp != BEAR_TRAP && t->ttyp != WEB))
5739 return FALSE; /* already trapped */
5741 dotrapflags = FORCETRAP;
5742 /* dotrap calls mintrap when mounted hero encounters a web */
5744 dotrapflags |= NOWEBMSG;
5746 dotrap(t, dotrapflags);
5748 result = (u.utrap != 0);
5751 return FALSE; /* already trapped */
5752 /* you notice it if you see the trap close/tremble/whatever
5753 or if you sense the monster who becomes trapped */
5754 *noticed = cansee(t->tx, t->ty) || canspotmon(mon);
5756 result = (mintrap(mon) != 0);
5762 /* for magic unlocking; returns true if targetted monster (which might
5763 be hero) gets hit by a trap (target might avoid its effect) */
5765 openfallingtrap(mon, trapdoor_only, noticed)
5767 boolean trapdoor_only;
5768 boolean *noticed; /* set to true iff hero notices the effect; */
5769 { /* otherwise left with its previous value intact */
5771 boolean ishero = (mon == &youmonst), result;
5773 if (mon == u.usteed)
5775 t = t_at(ishero ? u.ux : mon->mx, ishero ? u.uy : mon->my);
5776 /* if no trap here or it's not a falling trap, we're done
5777 (note: falling rock traps have a trapdoor in the ceiling) */
5778 if (!t || ((t->ttyp != TRAPDOOR && t->ttyp != ROCKTRAP)
5779 && (trapdoor_only || (t->ttyp != HOLE && t->ttyp != PIT
5780 && t->ttyp != SPIKED_PIT))))
5785 return FALSE; /* already trapped */
5787 dotrap(t, FORCETRAP);
5788 result = (u.utrap != 0);
5791 return FALSE; /* already trapped */
5792 /* you notice it if you see the trap close/tremble/whatever
5793 or if you sense the monster who becomes trapped */
5794 *noticed = cansee(t->tx, t->ty) || canspotmon(mon);
5795 /* monster will be angered; mintrap doesn't handle that */
5798 result = (mintrap(mon) != 0);
5800 /* mon might now be on the migrating monsters list */
5805 /* only called when the player is doing something to the chest directly */
5807 chest_trap(obj, bodypart, disarm)
5808 register struct obj *obj;
5809 register int bodypart;
5812 register struct obj *otmp = obj, *otmp2;
5817 if (get_obj_location(obj, &cc.x, &cc.y, 0)) /* might be carried */
5818 obj->ox = cc.x, obj->oy = cc.y;
5820 otmp->otrapped = 0; /* trap is one-shot; clear flag first in case
5821 chest kills you and ends up in bones file */
5823 You(disarm ? "set it off!" : "trigger a trap!");
5825 You(disarm ? "
\83X
\83C
\83b
\83`
\82ð
\93ü
\82ê
\82Ä
\82µ
\82Ü
\82Á
\82½
\81I" : "ã©
\82É
\82Ð
\82Á
\82©
\82©
\82Á
\82½
\81I");
5826 display_nhwindow(WIN_MESSAGE, FALSE);
5827 if (Luck > -13 && rn2(13 + Luck) > 7) { /* saved by luck */
5828 /* trap went off, but good luck prevents damage */
5833 msg = "explosive charge is a dud";
5835 msg = "
\94\9a\94
\82Í
\95s
\94
\82¾
\82Á
\82½";
5840 msg = "electric charge is grounded";
5842 msg = "
\93d
\8c\82\82ª
\95ú
\8fo
\82³
\82ê
\82½
\82ª
\83A
\81[
\83X
\82³
\82ê
\82Ä
\82¢
\82½";
5847 msg = "flame fizzles out";
5849 msg = "
\89\8a\82Í
\83V
\83\85\81[
\82Á
\82Æ
\8fÁ
\82¦
\82½";
5855 msg = "poisoned needle misses";
5857 msg = "
\93Å
\90j
\82Í
\8eh
\82³
\82ç
\82È
\82©
\82Á
\82½";
5864 msg = "gas cloud blows away";
5866 msg = "
\83K
\83X
\89_
\82Í
\90\81\82«
\94ò
\82ñ
\82¾";
5869 impossible("chest disarm bug");
5875 pline("But luckily the %s!", msg);
5877 pline("
\82µ
\82©
\82µ
\89^
\82Ì
\82æ
\82¢
\82±
\82Æ
\82É%s
\81I", msg);
5879 switch (rn2(20) ? ((Luck >= 13) ? 0 : rn2(13 - Luck)) : rn2(26)) {
5885 struct monst *shkp = 0;
5887 boolean costly, insider;
5888 register xchar ox = obj->ox, oy = obj->oy;
5890 /* the obj location need not be that of player */
5891 costly = (costly_spot(ox, oy)
5892 && (shkp = shop_keeper(*in_rooms(ox, oy, SHOPBASE)))
5893 != (struct monst *) 0);
5894 insider = (*u.ushops && inside_shop(u.ux, u.uy)
5895 && *in_rooms(ox, oy, SHOPBASE) == *u.ushops);
5898 pline("%s!", Tobjnam(obj, "explode"));
5900 pline("%s
\82Í
\94\9a\94
\82µ
\82½
\81I", xname(obj));
5902 Sprintf(buf, "exploding %s", xname(obj));
5904 Sprintf(buf, "%s
\82Ì
\94\9a\94
\82Å", xname(obj));
5907 loss += stolen_value(obj, ox, oy, (boolean) shkp->mpeaceful,
5909 delete_contents(obj);
5910 /* we're about to delete all things at this location,
5911 * which could include the ball & chain.
5912 * If we attempt to call unpunish() in the
5913 * for-loop below we can end up with otmp2
5914 * being invalid once the chain is gone.
5915 * Deal with ball & chain right now instead.
5917 if (Punished && !carried(uball)
5918 && ((uchain->ox == u.ux && uchain->oy == u.uy)
5919 || (uball->ox == u.ux && uball->oy == u.uy)))
5922 for (otmp = level.objects[u.ux][u.uy]; otmp; otmp = otmp2) {
5923 otmp2 = otmp->nexthere;
5925 loss += stolen_value(otmp, otmp->ox, otmp->oy,
5926 (boolean) shkp->mpeaceful, TRUE);
5930 losehp(Maybe_Half_Phys(d(6, 6)), buf, KILLED_BY_AN);
5931 exercise(A_STR, FALSE);
5932 if (costly && loss) {
5935 You("owe %ld %s for objects destroyed.", loss,
5938 You("
\8aí
\95¨
\94j
\91¹
\82Å%ld%s
\82Ì
\8eØ
\82è
\82ð
\82Â
\82
\82Á
\82½
\81D", loss,
5943 You("caused %ld %s worth of damage!", loss,
5946 You("%ld%s
\95ª
\82Ì
\91¹
\8aQ
\82ð
\88ø
\82«
\82¨
\82±
\82µ
\82½
\81I", loss,
5949 make_angry_shk(shkp, ox, oy);
5959 pline("A cloud of noxious gas billows from %s.", the(xname(obj)));
5961 pline("
\97L
\93Å
\83K
\83X
\82ª%s
\82©
\82ç
\89Q
\82Ü
\82¢
\82½
\81D", the(xname(obj)));
5963 poisoned("gas cloud", A_STR, "cloud of poison gas", 15, FALSE);
5965 poisoned("
\83K
\83X
\89_", A_STR, "
\83K
\83X
\89_", 15, FALSE);
5966 exercise(A_CON, FALSE);
5973 You_feel("a needle prick your %s.", body_part(bodypart));
5975 You("%s
\83`
\83N
\83b
\82Æ
\82¢
\82¤
\92É
\82Ý
\82ð
\8a´
\82¶
\82½
\81D", body_part(bodypart));
5977 poisoned("needle", A_CON, "poisoned needle", 10, FALSE);
5979 poisoned("
\90j", A_CON, "
\93Å
\90j", 10, FALSE);
5980 exercise(A_CON, FALSE);
5994 You("are jolted by a surge of electricity!");
5996 You("
\93d
\8bC
\83V
\83\87\83b
\83N
\82ð
\82
\82ç
\82Á
\82½
\81I");
5997 if (Shock_resistance) {
5998 shieldeff(u.ux, u.uy);
6000 You("don't seem to be affected.");
6002 pline("
\82µ
\82©
\82µ
\82 \82È
\82½
\82Í
\89e
\8b¿
\82ð
\8eó
\82¯
\82È
\82¢
\81D");
6006 destroy_item(RING_CLASS, AD_ELEC);
6007 destroy_item(WAND_CLASS, AD_ELEC);
6010 losehp(dmg, "electric shock", KILLED_BY_AN);
6012 losehp(dmg, "
\93d
\8bC
\83V
\83\87\83b
\83N
\82Å", KILLED_BY_AN);
6020 pline("Suddenly you are frozen in place!");
6022 pline("
\93Ë
\91R
\82»
\82Ì
\8fê
\82Å
\93®
\82¯
\82È
\82
\82È
\82Á
\82½
\81I");
6024 multi_reason = "frozen by a trap";
6025 exercise(A_DEX, FALSE);
6026 nomovemsg = You_can_move_again;
6029 You("momentarily stiffen.");
6031 You("
\88ê
\8fu
\8dd
\92¼
\82µ
\82½
\81D");
6037 pline("A cloud of %s gas billows from %s.",
6038 Blind ? blindgas[rn2(SIZE(blindgas))] : rndcolor(),
6041 pline("%s
\83K
\83X
\89_
\82ª%s
\82Ì
\92ê
\82Å
\89Q
\82Ü
\82¢
\82½
\81D",
6042 Blind ? blindgas[rn2(SIZE(blindgas))] :
6043 jconj_adj(rndcolor()), xname(obj));
6048 pline("What a groovy feeling!");
6050 pline("
\82È
\82ñ
\82Ä
\91f
\93G
\82È
\82ñ
\82¾
\81I");
6053 You("%s%s...", stagger(youmonst.data, "stagger"),
6054 Halluc_resistance ? ""
6055 : Blind ? " and get dizzy"
6056 : " and your vision blurs");
6058 You("
\82
\82ç
\82
\82ç
\82µ%s
\82½...",
6059 Halluc_resistance ? ""
6060 : Blind ? "
\81C
\82ß
\82Ü
\82¢
\82ª
\82µ"
6061 : "
\81C
\8ci
\90F
\82ª
\82Ú
\82â
\82¯
\82Ä
\82«");
6064 make_stunned((HStun & TIMEOUT) + (long) rn1(7, 16), FALSE);
6065 (void) make_hallucinated(
6066 (HHallucination & TIMEOUT) + (long) rn1(5, 16), FALSE, 0L);
6069 impossible("bad chest trap");
6072 bot(); /* to get immediate botl re-display */
6082 register struct trap *trap = ftrap;
6085 if (trap->tx == x && trap->ty == y)
6089 return (struct trap *) 0;
6094 register struct trap *trap;
6096 register struct trap *ttmp;
6098 clear_conjoined_pits(trap);
6099 if (trap == ftrap) {
6100 ftrap = ftrap->ntrap;
6102 for (ttmp = ftrap; ttmp; ttmp = ttmp->ntrap)
6103 if (ttmp->ntrap == trap)
6106 panic("deltrap: no preceding trap!");
6107 ttmp->ntrap = trap->ntrap;
6109 if (Sokoban && (trap->ttyp == PIT || trap->ttyp == HOLE))
6110 maybe_finish_sokoban();
6115 conjoined_pits(trap2, trap1, u_entering_trap2)
6116 struct trap *trap2, *trap1;
6117 boolean u_entering_trap2;
6119 int dx, dy, diridx, adjidx;
6121 if (!trap1 || !trap2)
6123 if (!isok(trap2->tx, trap2->ty) || !isok(trap1->tx, trap1->ty)
6124 || !(trap2->ttyp == PIT || trap2->ttyp == SPIKED_PIT)
6125 || !(trap1->ttyp == PIT || trap1->ttyp == SPIKED_PIT)
6126 || (u_entering_trap2 && !(u.utrap && u.utraptype == TT_PIT)))
6128 dx = sgn(trap2->tx - trap1->tx);
6129 dy = sgn(trap2->ty - trap1->ty);
6130 for (diridx = 0; diridx < 8; diridx++)
6131 if (xdir[diridx] == dx && ydir[diridx] == dy)
6133 /* diridx is valid if < 8 */
6135 adjidx = (diridx + 4) % 8;
6136 if ((trap1->conjoined & (1 << diridx))
6137 && (trap2->conjoined & (1 << adjidx)))
6144 clear_conjoined_pits(trap)
6147 int diridx, adjidx, x, y;
6150 if (trap && (trap->ttyp == PIT || trap->ttyp == SPIKED_PIT)) {
6151 for (diridx = 0; diridx < 8; ++diridx) {
6152 if (trap->conjoined & (1 << diridx)) {
6153 x = trap->tx + xdir[diridx];
6154 y = trap->ty + ydir[diridx];
6156 && (t = t_at(x, y)) != 0
6157 && (t->ttyp == PIT || t->ttyp == SPIKED_PIT)) {
6158 adjidx = (diridx + 4) % 8;
6159 t->conjoined &= ~(1 << adjidx);
6161 trap->conjoined &= ~(1 << diridx);
6169 * Mark all neighboring pits as conjoined pits.
6170 * (currently not called from anywhere)
6173 join_adjacent_pits(trap)
6181 for (diridx = 0; diridx < 8; ++diridx) {
6182 x = trap->tx + xdir[diridx];
6183 y = trap->ty + ydir[diridx];
6185 if ((t = t_at(x, y)) != 0
6186 && (t->ttyp == PIT || t->ttyp == SPIKED_PIT)) {
6187 trap->conjoined |= (1 << diridx);
6188 join_adjacent_pits(t);
6190 trap->conjoined &= ~(1 << diridx);
6197 * Returns TRUE if you escaped a pit and are standing on the precipice.
6200 uteetering_at_seen_pit(trap)
6203 if (trap && trap->tseen && (!u.utrap || u.utraptype != TT_PIT)
6204 && (trap->ttyp == PIT || trap->ttyp == SPIKED_PIT))
6210 /* Destroy a trap that emanates from the floor. */
6213 register struct trap *ttmp;
6215 /* some of these are arbitrary -dlc */
6216 if (ttmp && ((ttmp->ttyp == SQKY_BOARD) || (ttmp->ttyp == BEAR_TRAP)
6217 || (ttmp->ttyp == LANDMINE) || (ttmp->ttyp == FIRE_TRAP)
6218 || (ttmp->ttyp == PIT) || (ttmp->ttyp == SPIKED_PIT)
6219 || (ttmp->ttyp == HOLE) || (ttmp->ttyp == TRAPDOOR)
6220 || (ttmp->ttyp == TELEP_TRAP) || (ttmp->ttyp == LEVEL_TELEP)
6221 || (ttmp->ttyp == WEB) || (ttmp->ttyp == MAGIC_TRAP)
6222 || (ttmp->ttyp == ANTI_MAGIC))) {
6223 register struct monst *mtmp;
6225 if (ttmp->tx == u.ux && ttmp->ty == u.uy) {
6228 } else if ((mtmp = m_at(ttmp->tx, ttmp->ty)) != 0) {
6237 /* used for doors (also tins). can be used for anything else that opens. */
6239 b_trapped(item, bodypart)
6243 int lvl = level_difficulty(),
6244 dmg = rnd(5 + (lvl < 5 ? lvl : 2 + lvl / 2));
6247 pline("KABOOM!! %s was booby-trapped!", The(item));
6249 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);
6252 losehp(Maybe_Half_Phys(dmg), "explosion", KILLED_BY_AN);
6254 losehp(Maybe_Half_Phys(dmg), "
\83u
\81[
\83r
\81[
\83g
\83\89\83b
\83v
\82Ì
\94\9a\94
\82Å", KILLED_BY_AN);
6255 exercise(A_STR, FALSE);
6257 exercise(A_CON, FALSE);
6258 make_stunned((HStun & TIMEOUT) + (long) dmg, TRUE);
6261 /* Monster is hit by trap. */
6262 /* Note: doesn't work if both obj and d_override are null */
6264 thitm(tlev, mon, obj, d_override, nocorpse)
6272 boolean trapkilled = FALSE;
6277 strike = (find_mac(mon) + tlev + obj->spe <= rnd(20));
6279 strike = (find_mac(mon) + tlev <= rnd(20));
6281 /* Actually more accurate than thitu, which doesn't take
6282 * obj->spe into account.
6285 if (obj && cansee(mon->mx, mon->my))
6287 pline("%s is almost hit by %s!", Monnam(mon), doname(obj));
6289 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));
6293 if (obj && cansee(mon->mx, mon->my))
6295 pline("%s is hit by %s!", Monnam(mon), doname(obj));
6297 pline("%s
\82ª%s
\82É
\96½
\92\86\82µ
\82½
\81I", doname(obj), Monnam(mon));
6301 dam = dmgval(obj, mon);
6305 if ((mon->mhp -= dam) <= 0) {
6309 monkilled(mon, "", nocorpse ? -AD_RBRE : AD_PHYS);
6310 if (mon->mhp <= 0) {
6316 if (obj && (!strike || d_override)) {
6317 place_object(obj, mon->mx, mon->my);
6332 return (boolean) (u.usleep
6334 && (!strncmp(nomovemsg, "You awake", 9)
6335 || !strncmp(nomovemsg, "You regain con", 14)
6336 || !strncmp(nomovemsg, "You are consci", 14))));
6338 /*JP 3.6.0
\82Å
\82Ì
\8fo
\8c»
\88Ê
\92u/
\89ñ
\90\94
6339 "You awake" : potion.c(1)
6340 "You regain con": eat.c(1)
6341 "You are consci": eat.c(1)
6343 return (boolean) (u.usleep
6345 && (!strncmp(nomovemsg, "
\96Ú
\82ª
\82³
\82ß
\82½
\82ª
\93ª
\92É", 18)
6346 || !strncmp(nomovemsg, "
\82 \82È
\82½
\82Í
\90³
\8bC
\82Ã
\82¢
\82½", 18)
6347 || !strncmp(nomovemsg, "
\82 \82È
\82½
\82Í
\82Ü
\82½
\90³
\8bC
\82Ã", 18))));
6352 static const char lava_killer[] = "molten lava";
6354 static const char lava_killer[] = "
\82Ç
\82ë
\82Ç
\82ë
\82Ì
\97n
\8aâ
\82Å";
6359 register struct obj *obj, *obj2;
6360 int dmg = d(6, 6); /* only applicable for water walking */
6361 boolean usurvive, boil_away;
6364 if (likes_lava(youmonst.data))
6367 usurvive = Fire_resistance || (Wwalking && dmg < u.uhp);
6369 * A timely interrupt might manage to salvage your life
6370 * but not your gear. For scrolls and potions this
6371 * will destroy whole stacks, where fire resistant hero
6372 * survivor only loses partial stacks via destroy_item().
6374 * Flag items to be destroyed before any messages so
6375 * that player causing hangup at --More-- won't get an
6376 * emergency save file created before item destruction.
6379 for (obj = invent; obj; obj = obj->nobj)
6380 if ((is_organic(obj) || obj->oclass == POTION_CLASS)
6381 && !obj->oerodeproof
6382 && objects[obj->otyp].oc_oprop != FIRE_RES
6383 && obj->otyp != SCR_FIRE && obj->otyp != SPE_FIREBALL
6384 && !obj_resists(obj, 0, 0)) /* for invocation items */
6387 /* Check whether we should burn away boots *first* so we know whether to
6388 * make the player sink into the lava. Assumption: water walking only
6391 if (Wwalking && uarmf && is_organic(uarmf) && !uarmf->oerodeproof) {
6394 pline("%s into flame!", Yobjnam2(obj, "burst"));
6396 Your("%s
\82Í
\94R
\82¦
\82½
\81I", xname(obj));
6397 iflags.in_lava_effects++; /* (see above) */
6400 iflags.in_lava_effects--;
6403 if (!Fire_resistance) {
6406 pline_The("lava here burns you!");
6408 pline("
\97n
\8aâ
\82ª
\82 \82È
\82½
\82ð
\8fÄ
\82«
\82Â
\82
\82µ
\82½
\81I");
6410 losehp(dmg, lava_killer, KILLED_BY); /* lava damage */
6415 You("fall into the lava!");
6417 You("
\97n
\8aâ
\82É
\97\8e\82¿
\82½
\81I");
6419 usurvive = Lifesaved || discover;
6423 /* prevent remove_worn_item() -> Boots_off(WATER_WALKING_BOOTS) ->
6424 spoteffects() -> lava_effects() recursion which would
6425 successfully delete (via useupall) the no-longer-worn boots;
6426 once recursive call returned, we would try to delete them again
6427 here in the outer call (and access stale memory, probably panic) */
6428 iflags.in_lava_effects++;
6430 for (obj = invent; obj; obj = obj2) {
6432 /* above, we set in_use for objects which are to be destroyed */
6433 if (obj->otyp == SPE_BOOK_OF_THE_DEAD && !Blind) {
6436 pline("%s glows a strange %s, but remains intact.",
6437 The(xname(obj)), hcolor("dark red"));
6439 pline("%s
\82Í
\95s
\8ev
\8bc
\82É%s
\8bP
\82¢
\82½
\82ª
\81C
\96³
\8f\9d\82Ì
\82æ
\82¤
\82¾
\81D",
6440 xname(obj), jconj_adj(hcolor("
\88Ã
\90Ô
\90F
\82Ì")));
6442 } else if (obj->in_use) {
6443 if (obj->owornmask) {
6446 pline("%s into flame!", Yobjnam2(obj, "burst"));
6448 Your("%s
\82Í
\94R
\82¦
\82½
\81I", xname(obj));
6449 remove_worn_item(obj, TRUE);
6455 iflags.in_lava_effects--;
6458 boil_away = (u.umonnum == PM_WATER_ELEMENTAL
6459 || u.umonnum == PM_STEAM_VORTEX
6460 || u.umonnum == PM_FOG_CLOUD);
6463 /* killer format and name are reconstructed every iteration
6464 because lifesaving resets them */
6465 killer.format = KILLED_BY;
6466 Strcpy(killer.name, lava_killer);
6468 You("%s...", boil_away ? "boil away" : "burn to a crisp");
6470 You("%s
\81D
\81D
\81D", boil_away ? "
\95¦
\93«
\82µ
\82½" : "
\94R
\82¦
\82Ä
\83p
\83\8a\83p
\83\8a\82É
\82È
\82Á
\82½");
6472 if (safe_teleds(TRUE))
6473 break; /* successful life-save */
6474 /* nowhere safe to land; repeat burning loop */
6476 pline("You're still burning.");
6478 You("
\82Ü
\82¾
\94R
\82¦
\82Ä
\82¢
\82é
\81D");
6481 You("find yourself back on solid %s.", surface(u.ux, u.uy));
6483 You("
\82¢
\82Â
\82Ì
\82Ü
\82É
\82©
\8cÅ
\82¢%s
\82É
\96ß
\82Á
\82Ä
\82¢
\82½
\81D", surface(u.ux, u.uy));
6485 } else if (!Wwalking && (!u.utrap || u.utraptype != TT_LAVA)) {
6486 boil_away = !Fire_resistance;
6487 /* if not fire resistant, sink_into_lava() will quickly be fatal;
6488 hero needs to escape immediately */
6489 u.utrap = rn1(4, 4) + ((boil_away ? 2 : rn1(4, 12)) << 8);
6490 u.utraptype = TT_LAVA;
6492 You("sink into the lava%s!", !boil_away
6493 ? ", but it only burns slightly"
6494 : " and are about to be immolated");
6496 You("
\97n
\8aâ
\82É
\92¾
\82ñ%s
\82¾
\81I", !boil_away
6497 ? "
\82¾
\82ª
\81C
\82¿
\82å
\82Á
\82Æ
\8fÅ
\82°
\82½
\82¾
\82¯"
6498 : "
\82Å
\8fÄ
\82«
\8eE
\82³
\82ê
\82»
\82¤");
6501 losehp(!boil_away ? 1 : (u.uhp / 2), lava_killer,
6502 KILLED_BY); /* lava damage */
6506 destroy_item(SCROLL_CLASS, AD_FIRE);
6507 destroy_item(SPBOOK_CLASS, AD_FIRE);
6508 destroy_item(POTION_CLASS, AD_FIRE);
6512 /* called each turn when trapped in lava */
6517 static const char sink_deeper[] = "You sink deeper into the lava.";
6519 static const char sink_deeper[] = "
\82 \82È
\82½
\82Í
\82æ
\82è
\90[
\82
\97n
\8aâ
\82É
\92¾
\82ñ
\82¾
\81D";
6521 if (!u.utrap || u.utraptype != TT_LAVA) {
6522 ; /* do nothing; this shouldn't happen */
6523 } else if (!is_lava(u.ux, u.uy)) {
6524 u.utrap = 0; /* this shouldn't happen either */
6525 } else if (!u.uinvulnerable) {
6526 /* ordinarily we'd have to be fire resistant to survive long
6527 enough to become stuck in lava, but it can happen without
6528 resistance if water walking boots allow survival and then
6529 get burned up; u.utrap time will be quite short in that case */
6530 if (!Fire_resistance)
6531 u.uhp = (u.uhp + 2) / 3;
6533 u.utrap -= (1 << 8);
6534 if (u.utrap < (1 << 8)) {
6535 killer.format = KILLED_BY;
6537 Strcpy(killer.name, "molten lava");
6539 Strcpy(killer.name, "
\82Ç
\82ë
\82Ç
\82ë
\82Ì
\97n
\8aâ
\82Å");
6541 You("sink below the surface and die.");
6543 You("
\8a®
\91S
\82É
\97n
\8aâ
\82Ì
\92\86\82É
\92¾
\82ñ
\82Å
\81A
\8e\80\82É
\82Ü
\82µ
\82½
\81D
\81D
\81D");
6544 burn_away_slime(); /* add insult to injury? */
6546 } else if (!u.umoved) {
6547 /* can't fully turn into slime while in lava, but might not
6548 have it be burned away until you've come awfully close */
6549 if (Slimed && rnd(10 - 1) >= (int) (Slimed & TIMEOUT)) {
6560 /* called when something has been done (breaking a boulder, for instance)
6561 which entails a luck penalty if performed on a sokoban level */
6567 /* TODO: issue some feedback so that player can learn that whatever
6568 he/she just did is a naughty thing to do in sokoban and should
6569 probably be avoided in future....
6570 Caveat: doing this might introduce message sequencing issues,
6571 depending upon feedback during the various actions which trigger
6572 Sokoban luck penalties. */
6576 /* called when a trap has been deleted or had its ttyp replaced */
6578 maybe_finish_sokoban()
6582 if (Sokoban && !in_mklev) {
6583 /* scan all remaining traps, ignoring any created by the hero;
6584 if this level has no more pits or holes, the current sokoban
6585 puzzle has been solved */
6586 for (t = ftrap; t; t = t->ntrap) {
6589 if (t->ttyp == PIT || t->ttyp == HOLE)
6593 /* we've passed the last trap without finding a pit or hole;
6594 clear the sokoban_rules flag so that luck penalties for
6595 things like breaking boulders or jumping will no longer
6596 be given, and restrictions on diagonal moves are lifted */
6597 Sokoban = 0; /* clear level.flags.sokoban_rules */
6598 /* TODO: give some feedback about solving the sokoban puzzle
6599 (perhaps say "congratulations" in Japanese?) */