OSDN Git Service

96102e15b326ea642f17c2a4c9d362bc65e6d068
[jnethack/source.git] / src / trap.c
1 /* NetHack 3.6  trap.c  $NHDT-Date: 1545259936 2018/12/19 22:52:16 $  $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.313 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /*-Copyright (c) Robert Patrick Rankin, 2013. */
4 /* NetHack may be freely redistributed.  See license for details. */
5
6 /* JNetHack Copyright */
7 /* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000  */
8 /* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2019            */
9 /* JNetHack may be freely redistributed.  See license for details. */
10
11 #include "hack.h"
12
13 extern const char *const destroy_strings[][3]; /* from zap.c */
14
15 STATIC_DCL boolean FDECL(keep_saddle_with_steedcorpse, (unsigned, struct obj *,
16                                                         struct obj *));
17 STATIC_DCL struct obj *FDECL(t_missile, (int, struct trap *));
18 STATIC_DCL char *FDECL(trapnote, (struct trap *, BOOLEAN_P));
19 STATIC_DCL int FDECL(steedintrap, (struct trap *, struct obj *));
20 STATIC_DCL void FDECL(launch_drop_spot, (struct obj *, XCHAR_P, XCHAR_P));
21 STATIC_DCL int FDECL(mkroll_launch, (struct trap *, XCHAR_P, XCHAR_P,
22                                      SHORT_P, long));
23 STATIC_DCL boolean FDECL(isclearpath, (coord *, int, SCHAR_P, SCHAR_P));
24 STATIC_DCL void FDECL(dofiretrap, (struct obj *));
25 STATIC_DCL void NDECL(domagictrap);
26 STATIC_DCL boolean FDECL(emergency_disrobe, (boolean *));
27 STATIC_DCL int FDECL(untrap_prob, (struct trap *));
28 STATIC_DCL void FDECL(move_into_trap, (struct trap *));
29 STATIC_DCL int FDECL(try_disarm, (struct trap *, BOOLEAN_P));
30 STATIC_DCL void FDECL(reward_untrap, (struct trap *, struct monst *));
31 STATIC_DCL int FDECL(disarm_holdingtrap, (struct trap *));
32 STATIC_DCL int FDECL(disarm_landmine, (struct trap *));
33 STATIC_DCL int FDECL(disarm_squeaky_board, (struct trap *));
34 STATIC_DCL int FDECL(disarm_shooting_trap, (struct trap *, int));
35 STATIC_DCL void FDECL(clear_conjoined_pits, (struct trap *));
36 STATIC_DCL boolean FDECL(adj_nonconjoined_pit, (struct trap *));
37 STATIC_DCL int FDECL(try_lift, (struct monst *, struct trap *, int,
38                                 BOOLEAN_P));
39 STATIC_DCL int FDECL(help_monster_out, (struct monst *, struct trap *));
40 #if 0
41 STATIC_DCL void FDECL(join_adjacent_pits, (struct trap *));
42 #endif
43 STATIC_DCL boolean FDECL(thitm, (int, struct monst *, struct obj *, int,
44                                  BOOLEAN_P));
45 STATIC_DCL void NDECL(maybe_finish_sokoban);
46
47 /* mintrap() should take a flags argument, but for time being we use this */
48 STATIC_VAR int force_mintrap = 0;
49
50 #if 0 /*JP*/
51 STATIC_VAR const char *const a_your[2] = { "a", "your" };
52 STATIC_VAR const char *const A_Your[2] = { "A", "Your" };
53 STATIC_VAR const char tower_of_flame[] = "tower of flame";
54 STATIC_VAR const char *const A_gush_of_water_hits = "A gush of water hits";
55 #endif
56 #if 0 /*JP*/
57 STATIC_VAR const char *const blindgas[6] = { "humid",   "odorless",
58                                              "pungent", "chilling",
59                                              "acrid",   "biting" };
60 #else
61 STATIC_VAR const char * const blindgas[6] = {
62     "\82Þ\82µ\82Þ\82µ\82·\82é", "\96³\8fL\82Ì",
63     "\8eh\8c\83\8fL\82Ì\82·\82é", "\97â\82½\82¢",
64     "\83c\83\93\82Æ\82µ\82½\82É\82¨\82¢\82Ì", "\82Ð\82è\82Ð\82è\82·\82é"
65     };
66 #endif
67 #if 1 /*JP*/
68 const char *set_you[2] = { "", "\82 \82È\82½\82Ì\8ed\8a|\82¯\82½" };
69 STATIC_VAR const char *dig_you[2] = { "", "\82 \82È\82½\82ª\8c@\82Á\82½" };
70 STATIC_VAR const char *web_you[2] = { "", "\82 \82È\82½\82ª\92£\82Á\82½" };
71 #endif
72
73 /* called when you're hit by fire (dofiretrap,buzz,zapyourself,explode);
74    returns TRUE if hit on torso */
75 boolean
76 burnarmor(victim)
77 struct monst *victim;
78 {
79     struct obj *item;
80     char buf[BUFSZ];
81     int mat_idx, oldspe;
82     boolean hitting_u;
83
84     if (!victim)
85         return 0;
86     hitting_u = (victim == &youmonst);
87
88     /* burning damage may dry wet towel */
89     item = hitting_u ? carrying(TOWEL) : m_carrying(victim, TOWEL);
90     while (item) {
91         if (is_wet_towel(item)) {
92             oldspe = item->spe;
93             dry_a_towel(item, rn2(oldspe + 1), TRUE);
94             if (item->spe != oldspe)
95                 break; /* stop once one towel has been affected */
96         }
97         item = item->nobj;
98     }
99
100 #define burn_dmg(obj, descr) erode_obj(obj, descr, ERODE_BURN, EF_GREASE)
101     while (1) {
102         switch (rn2(5)) {
103         case 0:
104             item = hitting_u ? uarmh : which_armor(victim, W_ARMH);
105             if (item) {
106                 mat_idx = objects[item->otyp].oc_material;
107 #if 0 /*JP*/
108                 Sprintf(buf, "%s %s", materialnm[mat_idx],
109                         helm_simple_name(item));
110 #else
111                 Sprintf(buf, "%s\82Ì%s", materialnm[mat_idx],
112                         helm_simple_name(item));
113 #endif
114             }
115 /*JP
116             if (!burn_dmg(item, item ? buf : "helmet"))
117 */
118             if (!burn_dmg(item, item ? buf : "\8a\95"))
119                 continue;
120             break;
121         case 1:
122             item = hitting_u ? uarmc : which_armor(victim, W_ARMC);
123             if (item) {
124                 (void) burn_dmg(item, cloak_simple_name(item));
125                 return TRUE;
126             }
127             item = hitting_u ? uarm : which_armor(victim, W_ARM);
128             if (item) {
129                 (void) burn_dmg(item, xname(item));
130                 return TRUE;
131             }
132             item = hitting_u ? uarmu : which_armor(victim, W_ARMU);
133             if (item)
134 /*JP
135                 (void) burn_dmg(item, "shirt");
136 */
137                 (void) burn_dmg(item, "\83V\83\83\83c");
138             return TRUE;
139         case 2:
140             item = hitting_u ? uarms : which_armor(victim, W_ARMS);
141 /*JP
142             if (!burn_dmg(item, "wooden shield"))
143 */
144             if (!burn_dmg(item, "\96Ø\82Ì\8f\82"))
145                 continue;
146             break;
147         case 3:
148             item = hitting_u ? uarmg : which_armor(victim, W_ARMG);
149 /*JP
150             if (!burn_dmg(item, "gloves"))
151 */
152             if (!burn_dmg(item, "\8f¬\8eè"))
153                 continue;
154             break;
155         case 4:
156             item = hitting_u ? uarmf : which_armor(victim, W_ARMF);
157 /*JP
158             if (!burn_dmg(item, "boots"))
159 */
160             if (!burn_dmg(item, "\8cC"))
161                 continue;
162             break;
163         }
164         break; /* Out of while loop */
165     }
166 #undef burn_dmg
167
168     return FALSE;
169 }
170
171 /* Generic erode-item function.
172  * "ostr", if non-null, is an alternate string to print instead of the
173  *   object's name.
174  * "type" is an ERODE_* value for the erosion type
175  * "flags" is an or-ed list of EF_* flags
176  *
177  * Returns an erosion return value (ER_*)
178  */
179 int
180 erode_obj(otmp, ostr, type, ef_flags)
181 register struct obj *otmp;
182 const char *ostr;
183 int type;
184 int ef_flags;
185 {
186     static NEARDATA const char
187 /*JP
188         *const action[] = { "smoulder", "rust", "rot", "corrode" },
189 */
190         *const action[] = { "\82­\82·\82Ô\82Á\82½", "\8eK\82Ñ\82½", "\95\85\82Á\82½", "\95\85\90H\82µ\82½" },
191 /*JP
192         *const msg[] = { "burnt", "rusted", "rotten", "corroded" },
193 */
194         *const msg[] =  { "\8fÅ\82°\82½", "\8eK\82Ñ\82½", "\95\85\82Á\82½", "\95\85\90H\82µ\82½" },
195         *const bythe[] = { "heat", "oxidation", "decay", "corrosion" };
196     boolean vulnerable = FALSE, is_primary = TRUE,
197             check_grease = (ef_flags & EF_GREASE) ? TRUE : FALSE,
198             print = (ef_flags & EF_VERBOSE) ? TRUE : FALSE,
199             uvictim, vismon, visobj;
200     int erosion, cost_type;
201     struct monst *victim;
202
203     if (!otmp)
204         return ER_NOTHING;
205
206     victim = carried(otmp) ? &youmonst : mcarried(otmp) ? otmp->ocarry : NULL;
207     uvictim = (victim == &youmonst);
208     vismon = victim && (victim != &youmonst) && canseemon(victim);
209     /* Is bhitpos correct here? Ugh. */
210     visobj = !victim && cansee(bhitpos.x, bhitpos.y);
211
212     switch (type) {
213     case ERODE_BURN:
214         vulnerable = is_flammable(otmp);
215         check_grease = FALSE;
216         cost_type = COST_BURN;
217         break;
218     case ERODE_RUST:
219         vulnerable = is_rustprone(otmp);
220         cost_type = COST_RUST;
221         break;
222     case ERODE_ROT:
223         vulnerable = is_rottable(otmp);
224         check_grease = FALSE;
225         is_primary = FALSE;
226         cost_type = COST_ROT;
227         break;
228     case ERODE_CORRODE:
229         vulnerable = is_corrodeable(otmp);
230         is_primary = FALSE;
231         cost_type = COST_CORRODE;
232         break;
233     default:
234         impossible("Invalid erosion type in erode_obj");
235         return ER_NOTHING;
236     }
237     erosion = is_primary ? otmp->oeroded : otmp->oeroded2;
238
239     if (!ostr)
240         ostr = cxname(otmp);
241     /* 'visobj' messages insert "the"; probably ought to switch to the() */
242     if (visobj && !(uvictim || vismon) && !strncmpi(ostr, "the ", 4))
243         ostr += 4;
244
245     if (check_grease && otmp->greased) {
246         grease_protect(otmp, ostr, victim);
247         return ER_GREASED;
248     } else if (!erosion_matters(otmp)) {
249         return ER_NOTHING;
250     } else if (!vulnerable || (otmp->oerodeproof && otmp->rknown)) {
251         if (flags.verbose && print && (uvictim || vismon))
252 #if 0 /*JP*/
253             pline("%s %s %s not affected by %s.",
254                   uvictim ? "Your" : s_suffix(Monnam(victim)),
255                   ostr, vtense(ostr, "are"), bythe[type]);
256 #else
257             pline("%s%s\82Í%s\82Ì\89e\8b¿\82ð\8eó\82¯\82È\82©\82Á\82½\81D",
258                   uvictim ? "\82 \82È\82½\82Ì" : s_suffix(Monnam(victim)),
259                   ostr, bythe[type]);
260 #endif
261         return ER_NOTHING;
262     } else if (otmp->oerodeproof || (otmp->blessed && !rnl(4))) {
263         if (flags.verbose && (print || otmp->oerodeproof)
264             && (uvictim || vismon || visobj))
265 #if 0 /*JP*/
266             pline("Somehow, %s %s %s not affected by the %s.",
267                   uvictim ? "your"
268                           : !vismon ? "the" /* visobj */
269                                     : s_suffix(mon_nam(victim)),
270                   ostr, vtense(ostr, "are"), bythe[type]);
271 #else
272             pline("\82È\82º\82©\81C%s%s\82Í%s\82Ì\89e\8b¿\82ð\8eó\82¯\82È\82©\82Á\82½\81D",
273                   uvictim ? "\82 \82È\82½\82Ì"
274                           : !vismon ? "" /* visobj */
275                                     : s_suffix(mon_nam(victim)),
276                   ostr, bythe[type]);
277 #endif
278         /* We assume here that if the object is protected because it
279          * is blessed, it still shows some minor signs of wear, and
280          * the hero can distinguish this from an object that is
281          * actually proof against damage.
282          */
283         if (otmp->oerodeproof) {
284             otmp->rknown = TRUE;
285             if (victim == &youmonst)
286                 update_inventory();
287         }
288
289         return ER_NOTHING;
290     } else if (erosion < MAX_ERODE) {
291 #if 0 /*JP:T*/
292         const char *adverb = (erosion + 1 == MAX_ERODE)
293                                  ? " completely"
294                                  : erosion ? " further" : "";
295 #else
296         const char *adverb = (erosion + 1 == MAX_ERODE)
297                                  ? "\8a®\91S\82É"
298                                  : erosion ? "\82³\82ç\82É" : "";
299 #endif
300
301         if (uvictim || vismon || visobj)
302 #if 0 /*JP*/
303             pline("%s %s %s%s!",
304                   uvictim ? "Your"
305                           : !vismon ? "The" /* visobj */
306                                     : s_suffix(Monnam(victim)),
307                   ostr, vtense(ostr, action[type]), adverb);
308 #else
309             pline("%s%s\82Í%s%s!",
310                   uvictim ? "\82 \82È\82½\82Ì"
311                           : !vismon ? "" /* visobj */
312                                     : s_suffix(Monnam(victim)),
313                   ostr, adverb, action[type]);
314 #endif
315
316         if (ef_flags & EF_PAY)
317             costly_alteration(otmp, cost_type);
318
319         if (is_primary)
320             otmp->oeroded++;
321         else
322             otmp->oeroded2++;
323
324         if (victim == &youmonst)
325             update_inventory();
326
327         return ER_DAMAGED;
328     } else if (ef_flags & EF_DESTROY) {
329         if (uvictim || vismon || visobj)
330 #if 0 /*JP*/
331             pline("%s %s %s away!",
332                   uvictim ? "Your"
333                           : !vismon ? "The" /* visobj */
334                                     : s_suffix(Monnam(victim)),
335                   ostr, vtense(ostr, action[type]));
336 #else
337             pline("%s%s\82Í\8a®\91S\82É%s\81I",
338                   uvictim ? "\82 \82È\82½\82Ì"
339                           : !vismon ? "" /* visobj */
340                                     : s_suffix(Monnam(victim)),
341                   ostr, action[type]);
342 #endif
343
344         if (ef_flags & EF_PAY)
345             costly_alteration(otmp, cost_type);
346
347         setnotworn(otmp);
348         delobj(otmp);
349         return ER_DESTROYED;
350     } else {
351         if (flags.verbose && print) {
352             if (uvictim)
353 #if 0 /*JP*/
354                 Your("%s %s completely %s.",
355                      ostr, vtense(ostr, Blind ? "feel" : "look"), msg[type]);
356 #else
357                 Your("%s\82Í\8a®\91S\82É%s%s\81D",
358                      ostr, msg[type], Blind ? "\82æ\82¤\82¾" : "");
359 #endif
360             else if (vismon || visobj)
361 #if 0 /*JP*/
362                 pline("%s %s %s completely %s.",
363                       !vismon ? "The" : s_suffix(Monnam(victim)),
364                       ostr, vtense(ostr, "look"), msg[type]);
365 #else
366                 pline("%s%s\82Í\8a®\91S\82É%s\82æ\82¤\82¾\81D",
367                       !vismon ? "" : s_suffix(Monnam(victim)),
368                       ostr, msg[type]);
369 #endif
370         }
371         return ER_NOTHING;
372     }
373 }
374
375 /* Protect an item from erosion with grease. Returns TRUE if the grease
376  * wears off.
377  */
378 boolean
379 grease_protect(otmp, ostr, victim)
380 register struct obj *otmp;
381 const char *ostr;
382 struct monst *victim;
383 {
384 /*JP
385     static const char txt[] = "protected by the layer of grease!";
386 */
387     static const char txt[] = "\96û\82Ì\93h\82è\82±\82Ý\82É\82æ\82Á\82Ä\8eç\82ç\82ê\82Ä\82¢\82é\81I";
388     boolean vismon = victim && (victim != &youmonst) && canseemon(victim);
389
390     if (ostr) {
391         if (victim == &youmonst)
392 /*JP
393             Your("%s %s %s", ostr, vtense(ostr, "are"), txt);
394 */
395             Your("%s\82Í%s", ostr, txt);
396         else if (vismon)
397 #if 0 /*JP*/
398             pline("%s's %s %s %s", Monnam(victim),
399                   ostr, vtense(ostr, "are"), txt);
400 #else
401             pline("%s\82Ì%s\82Í%s", Monnam(victim), ostr, txt);
402 #endif
403     } else if (victim == &youmonst || vismon) {
404 /*JP
405         pline("%s %s", Yobjnam2(otmp, "are"), txt);
406 */
407         Your("%s\82Í%s",xname(otmp), txt);
408     }
409     if (!rn2(2)) {
410         otmp->greased = 0;
411         if (carried(otmp)) {
412 /*JP
413             pline_The("grease dissolves.");
414 */
415             pline("\96û\82Í\82Í\82°\82Ä\82µ\82Ü\82Á\82½\81D");
416             update_inventory();
417         }
418         return TRUE;
419     }
420     return FALSE;
421 }
422
423 struct trap *
424 maketrap(x, y, typ)
425 int x, y, typ;
426 {
427     static union vlaunchinfo zero_vl;
428     boolean oldplace;
429     struct trap *ttmp;
430     struct rm *lev = &levl[x][y];
431
432     if ((ttmp = t_at(x, y)) != 0) {
433         if (ttmp->ttyp == MAGIC_PORTAL || ttmp->ttyp == VIBRATING_SQUARE)
434             return (struct trap *) 0;
435         oldplace = TRUE;
436         if (u.utrap && x == u.ux && y == u.uy
437             && ((u.utraptype == TT_BEARTRAP && typ != BEAR_TRAP)
438                 || (u.utraptype == TT_WEB && typ != WEB)
439                 || (u.utraptype == TT_PIT && !is_pit(typ))))
440             u.utrap = 0;
441         /* old <tx,ty> remain valid */
442     } else if (IS_FURNITURE(lev->typ)
443                && (!IS_GRAVE(lev->typ) || (typ != PIT && typ != HOLE))) {
444         /* no trap on top of furniture (caller usually screens the
445            location to inhibit this, but wizard mode wishing doesn't) */
446         return (struct trap *) 0;
447     } else {
448         oldplace = FALSE;
449         ttmp = newtrap();
450         (void) memset((genericptr_t)ttmp, 0, sizeof(struct trap));
451         ttmp->ntrap = 0;
452         ttmp->tx = x;
453         ttmp->ty = y;
454     }
455     /* [re-]initialize all fields except ntrap (handled below) and <tx,ty> */
456     ttmp->vl = zero_vl;
457     ttmp->launch.x = ttmp->launch.y = -1; /* force error if used before set */
458     ttmp->dst.dnum = ttmp->dst.dlevel = -1;
459     ttmp->madeby_u = 0;
460     ttmp->once = 0;
461     ttmp->tseen = (typ == HOLE); /* hide non-holes */
462     ttmp->ttyp = typ;
463
464     switch (typ) {
465     case SQKY_BOARD: {
466         int tavail[12], tpick[12], tcnt = 0, k;
467         struct trap *t;
468
469         for (k = 0; k < 12; ++k)
470             tavail[k] = tpick[k] = 0;
471         for (t = ftrap; t; t = t->ntrap)
472             if (t->ttyp == SQKY_BOARD && t != ttmp)
473                 tavail[t->tnote] = 1;
474         /* now populate tpick[] with the available indices */
475         for (k = 0; k < 12; ++k)
476             if (tavail[k] == 0)
477                 tpick[tcnt++] = k;
478         /* choose an unused note; if all are in use, pick a random one */
479         ttmp->tnote = (short) ((tcnt > 0) ? tpick[rn2(tcnt)] : rn2(12));
480         break;
481     }
482     case STATUE_TRAP: { /* create a "living" statue */
483         struct monst *mtmp;
484         struct obj *otmp, *statue;
485         struct permonst *mptr;
486         int trycount = 10;
487
488         do { /* avoid ultimately hostile co-aligned unicorn */
489             mptr = &mons[rndmonnum()];
490         } while (--trycount > 0 && is_unicorn(mptr)
491                  && sgn(u.ualign.type) == sgn(mptr->maligntyp));
492         statue = mkcorpstat(STATUE, (struct monst *) 0, mptr, x, y,
493                             CORPSTAT_NONE);
494         mtmp = makemon(&mons[statue->corpsenm], 0, 0, MM_NOCOUNTBIRTH);
495         if (!mtmp)
496             break; /* should never happen */
497         while (mtmp->minvent) {
498             otmp = mtmp->minvent;
499             otmp->owornmask = 0;
500             obj_extract_self(otmp);
501             (void) add_to_container(statue, otmp);
502         }
503         statue->owt = weight(statue);
504         mongone(mtmp);
505         break;
506     }
507     case ROLLING_BOULDER_TRAP: /* boulder will roll towards trigger */
508         (void) mkroll_launch(ttmp, x, y, BOULDER, 1L);
509         break;
510     case PIT:
511     case SPIKED_PIT:
512         ttmp->conjoined = 0;
513         /*FALLTHRU*/
514     case HOLE:
515     case TRAPDOOR:
516         if (*in_rooms(x, y, SHOPBASE)
517             && (is_hole(typ) || IS_DOOR(lev->typ) || IS_WALL(lev->typ)))
518             add_damage(x, y, /* schedule repair */
519                        ((IS_DOOR(lev->typ) || IS_WALL(lev->typ))
520                         && !context.mon_moving)
521                            ? SHOP_HOLE_COST
522                            : 0L);
523         lev->doormask = 0;     /* subsumes altarmask, icedpool... */
524         if (IS_ROOM(lev->typ)) /* && !IS_AIR(lev->typ) */
525             lev->typ = ROOM;
526         /*
527          * some cases which can happen when digging
528          * down while phazing thru solid areas
529          */
530         else if (lev->typ == STONE || lev->typ == SCORR)
531             lev->typ = CORR;
532         else if (IS_WALL(lev->typ) || lev->typ == SDOOR)
533             lev->typ = level.flags.is_maze_lev
534                            ? ROOM
535                            : level.flags.is_cavernous_lev ? CORR : DOOR;
536
537         unearth_objs(x, y);
538         break;
539     }
540
541     if (!oldplace) {
542         ttmp->ntrap = ftrap;
543         ftrap = ttmp;
544     } else {
545         /* oldplace;
546            it shouldn't be possible to override a sokoban pit or hole
547            with some other trap, but we'll check just to be safe */
548         if (Sokoban)
549             maybe_finish_sokoban();
550     }
551     return ttmp;
552 }
553
554 void
555 fall_through(td)
556 boolean td; /* td == TRUE : trap door or hole */
557 {
558     d_level dtmp;
559     char msgbuf[BUFSZ];
560     const char *dont_fall = 0;
561     int newlevel, bottom;
562
563     /* we'll fall even while levitating in Sokoban; otherwise, if we
564        won't fall and won't be told that we aren't falling, give up now */
565     if (Blind && Levitation && !Sokoban)
566         return;
567
568     bottom = dunlevs_in_dungeon(&u.uz);
569     /* when in the upper half of the quest, don't fall past the
570        middle "quest locate" level if hero hasn't been there yet */
571     if (In_quest(&u.uz)) {
572         int qlocate_depth = qlocate_level.dlevel;
573
574         /* deepest reached < qlocate implies current < qlocate */
575         if (dunlev_reached(&u.uz) < qlocate_depth)
576             bottom = qlocate_depth; /* early cut-off */
577     }
578     newlevel = dunlev(&u.uz); /* current level */
579     do {
580         newlevel++;
581     } while (!rn2(4) && newlevel < bottom);
582
583     if (td) {
584         struct trap *t = t_at(u.ux, u.uy);
585
586         feeltrap(t);
587         if (!Sokoban) {
588             if (t->ttyp == TRAPDOOR)
589 /*JP
590                 pline("A trap door opens up under you!");
591 */
592                 pline("\97\8e\82µ\94à\82ª\82 \82È\82½\82Ì\91«\8c³\82É\8aJ\82¢\82½\81I");
593             else
594 /*JP
595                 pline("There's a gaping hole under you!");
596 */
597                 pline("\82 \82È\82½\82Ì\91«\89º\82É\82Û\82Á\82©\82è\82Æ\8c\8a\82ª\8aJ\82¢\82Ä\82¢\82é\81I");
598         }
599     } else
600 /*JP
601         pline_The("%s opens up under you!", surface(u.ux, u.uy));
602 */
603         pline("\91«\8c³\82Ì%s\82É\8c\8a\82ª\8aJ\82¢\82½\81I", surface(u.ux,u.uy));
604
605     if (Sokoban && Can_fall_thru(&u.uz))
606         ; /* KMH -- You can't escape the Sokoban level traps */
607     else if (Levitation || u.ustuck
608              || (!Can_fall_thru(&u.uz) && !levl[u.ux][u.uy].candig) || Flying
609              || is_clinger(youmonst.data)
610              || (Inhell && !u.uevent.invoked && newlevel == bottom)) {
611 /*JP
612         dont_fall = "don't fall in.";
613 */
614         dont_fall = "\82µ\82©\82µ\82 \82È\82½\82Í\97\8e\82¿\82È\82©\82Á\82½\81D";
615     } else if (youmonst.data->msize >= MZ_HUGE) {
616 /*JP
617         dont_fall = "don't fit through.";
618 */
619         dont_fall = "\92Ê\82è\94²\82¯\82é\82É\82Í\83T\83C\83Y\82ª\8d\87\82í\82È\82¢\81D";
620     } else if (!next_to_u()) {
621 /*JP
622         dont_fall = "are jerked back by your pet!";
623 */
624         dont_fall = "\82 \82È\82½\82Í\83y\83b\83g\82É\82æ\82Á\82Ä\88ø\82Á\82Ï\82è\82à\82Ç\82³\82ê\82½\81I";
625     }
626     if (dont_fall) {
627 #if 0 /*JP*//*\81u\82 \82È\82½\82Í\81v\82Å\8en\82Ü\82ç\82È\82¢\82à\82Ì\82à\82 \82é*/
628         You1(dont_fall);
629 #else
630         pline1(dont_fall);
631 #endif
632         /* hero didn't fall through, but any objects here might */
633         impact_drop((struct obj *) 0, u.ux, u.uy, 0);
634         if (!td) {
635             display_nhwindow(WIN_MESSAGE, FALSE);
636 /*JP
637             pline_The("opening under you closes up.");
638 */
639             pline_The("\91«\89º\82É\8aJ\82¢\82Ä\82¢\82½\82à\82Ì\82Í\95Â\82\82½\81D");
640         }
641         return;
642     }
643
644     if (*u.ushops)
645         shopdig(1);
646     if (Is_stronghold(&u.uz)) {
647         find_hell(&dtmp);
648     } else {
649         int dist = newlevel - dunlev(&u.uz);
650         dtmp.dnum = u.uz.dnum;
651         dtmp.dlevel = newlevel;
652         if (dist > 1)
653 #if 0 /*JP*/
654             You("fall down a %s%sshaft!", dist > 3 ? "very " : "",
655                 dist > 2 ? "deep " : "");
656 #else
657             You("%s%s\8c\8a\82Ì\92\86\82ð\97\8e\82¿\82Ä\82¢\82Á\82½\81I", dist > 3 ? "\82Æ\82Ä\82à" : "",
658                 dist > 2 ? "\90[\82¢" : "");
659 #endif
660     }
661     if (!td)
662 /*JP
663         Sprintf(msgbuf, "The hole in the %s above you closes up.",
664 */
665         Sprintf(msgbuf, "%s\82É\8aJ\82¢\82½\8c\8a\82Í\95Â\82\82½\81D",
666                 ceiling(u.ux, u.uy));
667
668     schedule_goto(&dtmp, FALSE, TRUE, 0, (char *) 0,
669                   !td ? msgbuf : (char *) 0);
670 }
671
672 /*
673  * Animate the given statue.  May have been via shatter attempt, trap,
674  * or stone to flesh spell.  Return a monster if successfully animated.
675  * If the monster is animated, the object is deleted.  If fail_reason
676  * is non-null, then fill in the reason for failure (or success).
677  *
678  * The cause of animation is:
679  *
680  *      ANIMATE_NORMAL  - hero "finds" the monster
681  *      ANIMATE_SHATTER - hero tries to destroy the statue
682  *      ANIMATE_SPELL   - stone to flesh spell hits the statue
683  *
684  * Perhaps x, y is not needed if we can use get_obj_location() to find
685  * the statue's location... ???
686  *
687  * Sequencing matters:
688  *      create monster; if it fails, give up with statue intact;
689  *      give "statue comes to life" message;
690  *      if statue belongs to shop, have shk give "you owe" message;
691  *      transfer statue contents to monster (after stolen_value());
692  *      delete statue.
693  *      [This ordering means that if the statue ends up wearing a cloak of
694  *       invisibility or a mummy wrapping, the visibility checks might be
695  *       wrong, but to avoid that we'd have to clone the statue contents
696  *       first in order to give them to the monster before checking their
697  *       shop status--it's not worth the hassle.]
698  */
699 struct monst *
700 animate_statue(statue, x, y, cause, fail_reason)
701 struct obj *statue;
702 xchar x, y;
703 int cause;
704 int *fail_reason;
705 {
706     int mnum = statue->corpsenm;
707     struct permonst *mptr = &mons[mnum];
708     struct monst *mon = 0, *shkp;
709     struct obj *item;
710     coord cc;
711     boolean historic = (Role_if(PM_ARCHEOLOGIST)
712                         && (statue->spe & STATUE_HISTORIC) != 0),
713             golem_xform = FALSE, use_saved_traits;
714     const char *comes_to_life;
715     char statuename[BUFSZ], tmpbuf[BUFSZ];
716     static const char historic_statue_is_gone[] =
717 /*JP
718         "that the historic statue is now gone";
719 */
720         "\97ð\8ej\93I\82È\92¤\91\9c\82ª\82È\82­\82È\82Á\82Ä\82µ\82Ü\82Á\82½\82±\82Æ";
721
722     if (cant_revive(&mnum, TRUE, statue)) {
723         /* mnum has changed; we won't be animating this statue as itself */
724         if (mnum != PM_DOPPELGANGER)
725             mptr = &mons[mnum];
726         use_saved_traits = FALSE;
727     } else if (is_golem(mptr) && cause == ANIMATE_SPELL) {
728         /* statue of any golem hit by stone-to-flesh becomes flesh golem */
729         golem_xform = (mptr != &mons[PM_FLESH_GOLEM]);
730         mnum = PM_FLESH_GOLEM;
731         mptr = &mons[PM_FLESH_GOLEM];
732         use_saved_traits = (has_omonst(statue) && !golem_xform);
733     } else {
734         use_saved_traits = has_omonst(statue);
735     }
736
737     if (use_saved_traits) {
738         /* restore a petrified monster */
739         cc.x = x, cc.y = y;
740         mon = montraits(statue, &cc, (cause == ANIMATE_SPELL));
741         if (mon && mon->mtame && !mon->isminion)
742             wary_dog(mon, TRUE);
743     } else {
744         /* statues of unique monsters from bones or wishing end
745            up here (cant_revive() sets mnum to be doppelganger;
746            mptr reflects the original form for use by newcham()) */
747         if ((mnum == PM_DOPPELGANGER && mptr != &mons[PM_DOPPELGANGER])
748             /* block quest guards from other roles */
749             || (mptr->msound == MS_GUARDIAN
750                 && quest_info(MS_GUARDIAN) != mnum)) {
751             mon = makemon(&mons[PM_DOPPELGANGER], x, y,
752                           NO_MINVENT | MM_NOCOUNTBIRTH | MM_ADJACENTOK);
753             /* if hero has protection from shape changers, cham field will
754                be NON_PM; otherwise, set form to match the statue */
755             if (mon && mon->cham >= LOW_PM)
756                 (void) newcham(mon, mptr, FALSE, FALSE);
757         } else
758             mon = makemon(mptr, x, y, (cause == ANIMATE_SPELL)
759                                           ? (NO_MINVENT | MM_ADJACENTOK)
760                                           : NO_MINVENT);
761     }
762
763     if (!mon) {
764         if (fail_reason)
765             *fail_reason = unique_corpstat(&mons[statue->corpsenm])
766                                ? AS_MON_IS_UNIQUE
767                                : AS_NO_MON;
768         return (struct monst *) 0;
769     }
770
771     /* a non-montraits() statue might specify gender */
772     if (statue->spe & STATUE_MALE)
773         mon->female = FALSE;
774     else if (statue->spe & STATUE_FEMALE)
775         mon->female = TRUE;
776     /* if statue has been named, give same name to the monster */
777     if (has_oname(statue) && !unique_corpstat(mon->data))
778         mon = christen_monst(mon, ONAME(statue));
779     /* mimic statue becomes seen mimic; other hiders won't be hidden */
780     if (M_AP_TYPE(mon))
781         seemimic(mon);
782     else
783         mon->mundetected = FALSE;
784     mon->msleeping = 0;
785     if (cause == ANIMATE_NORMAL || cause == ANIMATE_SHATTER) {
786         /* trap always releases hostile monster */
787         mon->mtame = 0; /* (might be petrified pet tossed onto trap) */
788         mon->mpeaceful = 0;
789         set_malign(mon);
790     }
791
792 #if 0 /*JP*/
793     comes_to_life = !canspotmon(mon)
794                         ? "disappears"
795                         : golem_xform
796                               ? "turns into flesh"
797                               : (nonliving(mon->data) || is_vampshifter(mon))
798                                     ? "moves"
799                                     : "comes to life";
800 #else
801     comes_to_life = !canspotmon(mon)
802                         ? "\8fÁ\82¦"
803                         : golem_xform
804                               ? "\93÷\91Ì\82É\96ß\82Á"
805                               : (nonliving(mon->data) || is_vampshifter(mon))
806                                     ? "\93®\82¢"
807                                     : "\90\96½\82ð\91Ñ\82Ñ";
808 #endif
809     if ((x == u.ux && y == u.uy) || cause == ANIMATE_SPELL) {
810         /* "the|your|Manlobbi's statue [of a wombat]" */
811         shkp = shop_keeper(*in_rooms(mon->mx, mon->my, SHOPBASE));
812 #if 0 /*JP*/
813         Sprintf(statuename, "%s%s", shk_your(tmpbuf, statue),
814                 (cause == ANIMATE_SPELL
815                  /* avoid "of a shopkeeper" if it's Manlobbi himself
816                     (if carried, it can't be unpaid--hence won't be
817                     described as "Manlobbi's statue"--because there
818                     wasn't any living shk when statue was picked up) */
819                  && (mon != shkp || carried(statue)))
820                    ? xname(statue)
821                    : "statue");
822 #else
823         Sprintf(statuename, "%s%s", shk_your(tmpbuf, statue),
824                 (cause == ANIMATE_SPELL
825                  && (mon != shkp || carried(statue)))
826                    ? xname(statue)
827                    : "\92¤\91\9c");
828 #endif
829 /*JP
830         pline("%s %s!", upstart(statuename), comes_to_life);
831 */
832         pline("%s\82Í%s\82½\81I", upstart(statuename), comes_to_life);
833     } else if (Hallucination) { /* They don't know it's a statue */
834 /*JP
835         pline_The("%s suddenly seems more animated.", rndmonnam((char *) 0));
836 */
837         pline_The("%s\82Í\93Ë\91R\82æ\82è\8a\88\93®\93I\82É\82È\82Á\82½\81D", rndmonnam((char *) 0));
838     } else if (cause == ANIMATE_SHATTER) {
839         if (cansee(x, y))
840             Sprintf(statuename, "%s%s", shk_your(tmpbuf, statue),
841                     xname(statue));
842         else
843 /*JP
844             Strcpy(statuename, "a statue");
845 */
846             Strcpy(statuename, "\92¤\91\9c");
847 #if 0 /*JP*/
848         pline("Instead of shattering, %s suddenly %s!", statuename,
849               comes_to_life);
850 #else
851         pline("%s\82Í\8dÓ\82¯\82¸\82É%s\82½\81I", statuename,
852               comes_to_life);
853 #endif
854     } else { /* cause == ANIMATE_NORMAL */
855 /*JP
856         You("find %s posing as a statue.",
857 */
858         You("%s\82ª\92¤\91\9c\82Ì\82Ó\82è\82ð\82µ\82Ä\82¢\82é\82Ì\82ð\8c©\82Â\82¯\82½\81D",
859             canspotmon(mon) ? a_monnam(mon) : something);
860         if (!canspotmon(mon) && Blind)
861             map_invisible(x, y);
862         stop_occupation();
863     }
864
865     /* if this isn't caused by a monster using a wand of striking,
866        there might be consequences for the hero */
867     if (!context.mon_moving) {
868         /* if statue is owned by a shop, hero will have to pay for it;
869            stolen_value gives a message (about debt or use of credit)
870            which refers to "it" so needs to follow a message describing
871            the object ("the statue comes to life" one above) */
872         if (cause != ANIMATE_NORMAL && costly_spot(x, y)
873             && (carried(statue) ? statue->unpaid : !statue->no_charge)
874             && (shkp = shop_keeper(*in_rooms(x, y, SHOPBASE))) != 0
875             /* avoid charging for Manlobbi's statue of Manlobbi
876                if stone-to-flesh is used on petrified shopkeep */
877             && mon != shkp)
878             (void) stolen_value(statue, x, y, (boolean) shkp->mpeaceful,
879                                 FALSE);
880
881         if (historic) {
882 /*JP
883             You_feel("guilty %s.", historic_statue_is_gone);
884 */
885             You_feel("%s\82É\8dß\82ð\8a´\82\82½\81D", historic_statue_is_gone);
886             adjalign(-1);
887         }
888     } else {
889         if (historic && cansee(x, y))
890 /*JP
891             You_feel("regret %s.", historic_statue_is_gone);
892 */
893             You_feel("%s\82ð\8cã\89÷\82µ\82½\81D", historic_statue_is_gone);
894         /* no alignment penalty */
895     }
896
897     /* transfer any statue contents to monster's inventory */
898     while ((item = statue->cobj) != 0) {
899         obj_extract_self(item);
900         (void) mpickobj(mon, item);
901     }
902     m_dowear(mon, TRUE);
903     /* in case statue is wielded and hero zaps stone-to-flesh at self */
904     if (statue->owornmask)
905         remove_worn_item(statue, TRUE);
906     /* statue no longer exists */
907     delobj(statue);
908
909     /* avoid hiding under nothing */
910     if (x == u.ux && y == u.uy && Upolyd && hides_under(youmonst.data)
911         && !OBJ_AT(x, y))
912         u.uundetected = 0;
913
914     if (fail_reason)
915         *fail_reason = AS_OK;
916     return mon;
917 }
918
919 /*
920  * You've either stepped onto a statue trap's location or you've triggered a
921  * statue trap by searching next to it or by trying to break it with a wand
922  * or pick-axe.
923  */
924 struct monst *
925 activate_statue_trap(trap, x, y, shatter)
926 struct trap *trap;
927 xchar x, y;
928 boolean shatter;
929 {
930     struct monst *mtmp = (struct monst *) 0;
931     struct obj *otmp = sobj_at(STATUE, x, y);
932     int fail_reason;
933
934     /*
935      * Try to animate the first valid statue.  Stop the loop when we
936      * actually create something or the failure cause is not because
937      * the mon was unique.
938      */
939     deltrap(trap);
940     while (otmp) {
941         mtmp = animate_statue(otmp, x, y,
942                               shatter ? ANIMATE_SHATTER : ANIMATE_NORMAL,
943                               &fail_reason);
944         if (mtmp || fail_reason != AS_MON_IS_UNIQUE)
945             break;
946
947         otmp = nxtobj(otmp, STATUE, TRUE);
948     }
949
950     feel_newsym(x, y);
951     return mtmp;
952 }
953
954 STATIC_OVL boolean
955 keep_saddle_with_steedcorpse(steed_mid, objchn, saddle)
956 unsigned steed_mid;
957 struct obj *objchn, *saddle;
958 {
959     if (!saddle)
960         return FALSE;
961     while (objchn) {
962         if (objchn->otyp == CORPSE && has_omonst(objchn)) {
963             struct monst *mtmp = OMONST(objchn);
964
965             if (mtmp->m_id == steed_mid) {
966                 /* move saddle */
967                 xchar x, y;
968                 if (get_obj_location(objchn, &x, &y, 0)) {
969                     obj_extract_self(saddle);
970                     place_object(saddle, x, y);
971                     stackobj(saddle);
972                 }
973                 return TRUE;
974             }
975         }
976         if (Has_contents(objchn)
977             && keep_saddle_with_steedcorpse(steed_mid, objchn->cobj, saddle))
978             return TRUE;
979         objchn = objchn->nobj;
980     }
981     return FALSE;
982 }
983
984 /* monster or you go through and possibly destroy a web.
985    return TRUE if could go through. */
986 boolean
987 mu_maybe_destroy_web(mtmp, domsg, trap)
988 struct monst *mtmp;
989 boolean domsg;
990 struct trap *trap;
991 {
992     boolean isyou = (mtmp == &youmonst);
993     struct permonst *mptr = mtmp->data;
994
995     if (amorphous(mptr) || is_whirly(mptr) || flaming(mptr)
996         || unsolid(mptr) || mptr == &mons[PM_GELATINOUS_CUBE]) {
997         xchar x = trap->tx;
998         xchar y = trap->ty;
999
1000         if (flaming(mptr) || acidic(mptr)) {
1001             if (domsg) {
1002                 if (isyou)
1003 #if 0 /*JP*/
1004                     You("%s %s spider web!",
1005                         (flaming(mptr)) ? "burn" : "dissolve",
1006                         a_your[trap->madeby_u]);
1007 #else
1008                     You("%s\82­\82à\82Ì\91\83\82ð%s\81I",
1009                         web_you[trap->madeby_u],
1010                         (flaming(mptr)) ? "\8fÄ\82¢\82½" : "\82±\82È\82²\82È\82É\82µ\82½");
1011 #endif
1012                 else
1013 #if 0 /*JP*/
1014                     pline("%s %s %s spider web!", Monnam(mtmp),
1015                           (flaming(mptr)) ? "burns" : "dissolves",
1016                           a_your[trap->madeby_u]);
1017 #else
1018                     pline("%s%s\82­\82à\82Ì\91\83\82ð%s\81I", Monnam(mtmp),
1019                         web_you[trap->madeby_u],
1020                         (flaming(mptr)) ? "\8fÄ\82¢\82½" : "\82±\82È\82²\82È\82É\82µ\82½");
1021 #endif
1022             }
1023             deltrap(trap);
1024             newsym(x, y);
1025             return TRUE;
1026         }
1027         if (domsg) {
1028             if (isyou) {
1029 /*JP
1030                 You("flow through %s spider web.", a_your[trap->madeby_u]);
1031 */
1032                 You("%s\82­\82à\82Ì\91\83\82ð\82·\82é\82è\82Æ\92Ê\82è\94²\82¯\82½\81D", web_you[trap->madeby_u]);
1033             } else {
1034 #if 0 /*JP*/
1035                 pline("%s flows through %s spider web.", Monnam(mtmp),
1036                       a_your[trap->madeby_u]);
1037 #else
1038                 pline("%s\82Í%s\82­\82à\82Ì\91\83\82ð\82·\82é\82è\82Æ\92Ê\82è\94²\82¯\82½\81D", Monnam(mtmp),
1039                       web_you[trap->madeby_u]);
1040 #endif
1041                 seetrap(trap);
1042             }
1043         }
1044         return TRUE;
1045     }
1046     return FALSE;
1047 }
1048
1049 /* make a single arrow/dart/rock for a trap to shoot or drop */
1050 STATIC_OVL struct obj *
1051 t_missile(otyp, trap)
1052 int otyp;
1053 struct trap *trap;
1054 {
1055     struct obj *otmp = mksobj(otyp, TRUE, FALSE);
1056
1057     otmp->quan = 1L;
1058     otmp->owt = weight(otmp);
1059     otmp->opoisoned = 0;
1060     otmp->ox = trap->tx, otmp->oy = trap->ty;
1061     return otmp;
1062 }
1063
1064 void
1065 set_utrap(tim, typ)
1066 unsigned tim, typ;
1067 {
1068     u.utrap = tim;
1069     /* FIXME:
1070      * utraptype==0 is bear trap rather than 'none'; we probably ought
1071      * to change that but can't do so until save file compatability is
1072      * able to be broken.
1073      */
1074     u.utraptype = tim ? typ : 0;
1075
1076     float_vs_flight(); /* maybe block Lev and/or Fly */
1077 }
1078
1079 void
1080 reset_utrap(msg)
1081 boolean msg;
1082 {
1083     boolean was_Lev = (Levitation != 0), was_Fly = (Flying != 0);
1084
1085     set_utrap(0, 0);
1086
1087     if (msg) {
1088         if (!was_Lev && Levitation)
1089             float_up();
1090         if (!was_Fly && Flying)
1091             You("can fly.");
1092     }
1093 }
1094
1095 void
1096 dotrap(trap, trflags)
1097 register struct trap *trap;
1098 unsigned trflags;
1099 {
1100     register int ttype = trap->ttyp;
1101     struct obj *otmp;
1102     boolean already_seen = trap->tseen,
1103             forcetrap = ((trflags & FORCETRAP) != 0
1104                          || (trflags & FAILEDUNTRAP) != 0),
1105             webmsgok = (trflags & NOWEBMSG) == 0,
1106             forcebungle = (trflags & FORCEBUNGLE) != 0,
1107             plunged = (trflags & TOOKPLUNGE) != 0,
1108             viasitting = (trflags & VIASITTING) != 0,
1109             conj_pit = conjoined_pits(trap, t_at(u.ux0, u.uy0), TRUE),
1110             adj_pit = adj_nonconjoined_pit(trap);
1111     int oldumort;
1112     int steed_article = ARTICLE_THE;
1113
1114     nomul(0);
1115
1116     /* KMH -- You can't escape the Sokoban level traps */
1117     if (Sokoban && (is_pit(ttype) || is_hole(ttype))) {
1118         /* The "air currents" message is still appropriate -- even when
1119          * the hero isn't flying or levitating -- because it conveys the
1120          * reason why the player cannot escape the trap with a dexterity
1121          * check, clinging to the ceiling, etc.
1122          */
1123 #if 0 /*JP*/
1124         pline("Air currents pull you down into %s %s!",
1125               a_your[trap->madeby_u],
1126               defsyms[trap_to_defsym(ttype)].explanation);
1127 #else
1128         pline("\8bó\8bC\82Ì\97¬\82ê\82ª\82 \82È\82½\82ð%s\82É\88ø\82«\96ß\82µ\82½\81I",
1129               defsyms[trap_to_defsym(ttype)].explanation);
1130 #endif
1131         /* then proceed to normal trap effect */
1132     } else if (already_seen && !forcetrap) {
1133         if ((Levitation || (Flying && !plunged))
1134             && (is_pit(ttype) || ttype == HOLE || ttype == BEAR_TRAP)) {
1135 #if 0 /*JP*/
1136             You("%s over %s %s.", Levitation ? "float" : "fly",
1137                 a_your[trap->madeby_u],
1138                 defsyms[trap_to_defsym(ttype)].explanation);
1139 #else
1140             You("%s%s\82Ì\8fã%s\81D",
1141                 set_you[trap->madeby_u],
1142                 defsyms[trap_to_defsym(ttype)].explanation,
1143                 Levitation ? "\82ð\8c©\89º\82ë\82µ\82½" : "\82ð\94ò\82ñ\82Å\82¢\82é");
1144 #endif
1145             return;
1146         }
1147         if (!Fumbling && ttype != MAGIC_PORTAL && ttype != VIBRATING_SQUARE
1148             && ttype != ANTI_MAGIC && !forcebungle && !plunged
1149             && !conj_pit && !adj_pit
1150             && (!rn2(5) || (is_pit(ttype)
1151                             && is_clinger(youmonst.data)))) {
1152 #if 0 /*JP*/
1153                 You("escape %s %s.", (ttype == ARROW_TRAP && !trap->madeby_u)
1154                                      ? "an"
1155                                      : a_your[trap->madeby_u],
1156                 defsyms[trap_to_defsym(ttype)].explanation);
1157 #else
1158                 You("%s%s\82ð\82·\82é\82è\82Æ\94ð\82¯\82½\81D",
1159                     set_you[trap->madeby_u],
1160                     defsyms[trap_to_defsym(ttype)].explanation);
1161 #endif
1162             return;
1163         }
1164     }
1165
1166     if (u.usteed) {
1167         u.usteed->mtrapseen |= (1 << (ttype - 1));
1168         /* suppress article in various steed messages when using its
1169            name (which won't occur when hallucinating) */
1170         if (has_mname(u.usteed) && !Hallucination)
1171             steed_article = ARTICLE_NONE;
1172     }
1173
1174     switch (ttype) {
1175     case ARROW_TRAP:
1176         if (trap->once && trap->tseen && !rn2(15)) {
1177 /*JP
1178             You_hear("a loud click!");
1179 */
1180             You_hear("\83K\83`\83\83\83b\82Æ\82¢\82¤\91å\82«\82È\89¹\82ð\95·\82¢\82½\81I");
1181             deltrap(trap);
1182             newsym(u.ux, u.uy);
1183             break;
1184         }
1185         trap->once = 1;
1186         seetrap(trap);
1187 /*JP
1188         pline("An arrow shoots out at you!");
1189 */
1190         pline("\96î\82ª\94ò\82ñ\82Å\82«\82½\81I");
1191         otmp = t_missile(ARROW, trap);
1192         if (u.usteed && !rn2(2) && steedintrap(trap, otmp)) {
1193             ; /* nothing */
1194 #if 0 /*JP:T*/
1195         } else if (thitu(8, dmgval(otmp, &youmonst), &otmp, "arrow")) {
1196 #else
1197         } else if (thitu(8, dmgval(otmp, &youmonst), &otmp, "\96î")) {
1198 #endif
1199             if (otmp)
1200                 obfree(otmp, (struct obj *) 0);
1201         } else {
1202             place_object(otmp, u.ux, u.uy);
1203             if (!Blind)
1204                 otmp->dknown = 1;
1205             stackobj(otmp);
1206             newsym(u.ux, u.uy);
1207         }
1208         break;
1209
1210     case DART_TRAP:
1211         if (trap->once && trap->tseen && !rn2(15)) {
1212 /*JP
1213             You_hear("a soft click.");
1214 */
1215             You_hear("\83J\83`\83b\82Æ\82¢\82¤\89¹\82ð\95·\82¢\82½\81D");
1216             deltrap(trap);
1217             newsym(u.ux, u.uy);
1218             break;
1219         }
1220         trap->once = 1;
1221         seetrap(trap);
1222 /*JP
1223         pline("A little dart shoots out at you!");
1224 */
1225         pline("\8f¬\82³\82È\93\8a\82°\96î\82ª\94ò\82ñ\82Å\82«\82½\81I");
1226         otmp = t_missile(DART, trap);
1227         if (!rn2(6))
1228             otmp->opoisoned = 1;
1229         oldumort = u.umortality;
1230         if (u.usteed && !rn2(2) && steedintrap(trap, otmp)) {
1231             ; /* nothing */
1232 #if 0 /*JP*/
1233         } else if (thitu(7, dmgval(otmp, &youmonst), &otmp, "little dart")) {
1234 #else
1235         } else if (thitu(7, dmgval(otmp, &youmonst), &otmp, "\93\8a\82°\96î")) {
1236 #endif
1237             if (otmp) {
1238                 if (otmp->opoisoned)
1239 #if 0 /*JP:T*/
1240                     poisoned("dart", A_CON, "little dart",
1241                              /* if damage triggered life-saving,
1242                                 poison is limited to attrib loss */
1243                              (u.umortality > oldumort) ? 0 : 10, TRUE);
1244 #else
1245                     poisoned("\93\8a\82°\96î", A_CON, "\8f¬\82³\82È\93\8a\82°\96î",
1246                              /* if damage triggered life-saving,
1247                                 poison is limited to attrib loss */
1248                              (u.umortality > oldumort) ? 0 : 10, TRUE);
1249 #endif
1250                 obfree(otmp, (struct obj *) 0);
1251             }
1252         } else {
1253             place_object(otmp, u.ux, u.uy);
1254             if (!Blind)
1255                 otmp->dknown = 1;
1256             stackobj(otmp);
1257             newsym(u.ux, u.uy);
1258         }
1259         break;
1260
1261     case ROCKTRAP:
1262         if (trap->once && trap->tseen && !rn2(15)) {
1263 /*JP
1264             pline("A trap door in %s opens, but nothing falls out!",
1265 */
1266             pline("\97\8e\82µ\94à\82ª%s\82É\8aJ\82¢\82½\82ª\81C\89½\82à\97\8e\82¿\82Ä\82±\82È\82©\82Á\82½\81I",
1267                   the(ceiling(u.ux, u.uy)));
1268             deltrap(trap);
1269             newsym(u.ux, u.uy);
1270         } else {
1271             int dmg = d(2, 6); /* should be std ROCK dmg? */
1272
1273             trap->once = 1;
1274             feeltrap(trap);
1275             otmp = t_missile(ROCK, trap);
1276             place_object(otmp, u.ux, u.uy);
1277
1278 #if 0 /*JP*/
1279             pline("A trap door in %s opens and %s falls on your %s!",
1280                   the(ceiling(u.ux, u.uy)), an(xname(otmp)), body_part(HEAD));
1281 #else
1282             pline("\97\8e\82µ\94à\82ª%s\82É\8aJ\82«\81C%s\82ª\82 \82È\82½\82Ì%s\82É\97\8e\82¿\82Ä\82«\82½\81I",
1283                   ceiling(u.ux,u.uy), xname(otmp), body_part(HEAD));
1284 #endif
1285             if (uarmh) {
1286                 if (is_metallic(uarmh)) {
1287 /*JP
1288                     pline("Fortunately, you are wearing a hard helmet.");
1289 */
1290                     pline("\8dK\89^\82É\82à\81C\82 \82È\82½\82Í\8cÅ\82¢\8a\95\82ð\90g\82É\82Â\82¯\82Ä\82¢\82½\81D");
1291                     dmg = 2;
1292                 } else if (flags.verbose) {
1293 /*JP
1294                     pline("%s does not protect you.", Yname2(uarmh));
1295 */
1296                     pline("%s\82Å\82Í\96h\82°\82È\82¢\81D", xname(uarmh));
1297                 }
1298             }
1299             if (!Blind)
1300                 otmp->dknown = 1;
1301             stackobj(otmp);
1302             newsym(u.ux, u.uy); /* map the rock */
1303
1304 /*JP
1305             losehp(Maybe_Half_Phys(dmg), "falling rock", KILLED_BY_AN);
1306 */
1307             losehp(Maybe_Half_Phys(dmg), "\97\8e\8aâ\82Å", KILLED_BY_AN);
1308             exercise(A_STR, FALSE);
1309         }
1310         break;
1311
1312     case SQKY_BOARD: /* stepped on a squeaky board */
1313         if ((Levitation || Flying) && !forcetrap) {
1314             if (!Blind) {
1315                 seetrap(trap);
1316                 if (Hallucination)
1317 /*JP
1318                     You("notice a crease in the linoleum.");
1319 */
1320                     You("\8f°\82Ì\8ed\8fã\8dÞ\82Ì\82µ\82í\82É\8bC\82ª\82Â\82¢\82½\81D");
1321                 else
1322 /*JP
1323                     You("notice a loose board below you.");
1324 */
1325                     You("\91«\8c³\82Ì\8aÉ\82ñ\82¾\94Â\82É\8bC\82ª\82Â\82¢\82½\81D");
1326             }
1327         } else {
1328             seetrap(trap);
1329 #if 0 /*JP*/
1330             pline("A board beneath you %s%s%s.",
1331                   Deaf ? "vibrates" : "squeaks ",
1332                   Deaf ? "" : trapnote(trap, 0), Deaf ? "" : " loudly");
1333 #else
1334             if (Deaf) {
1335                 pline("\91«\8c³\82Ì\94Â\82ª\82ä\82ê\82½\81D");
1336             } else {
1337                 pline("\91«\8c³\82Ì\94Â\82ª\91å\82«\82­%s\82Ì\89¹\82É\82«\82µ\82ñ\82¾\81D", trapnote(trap, 0));
1338             }
1339 #endif
1340             wake_nearby();
1341         }
1342         break;
1343
1344     case BEAR_TRAP: {
1345         int dmg = d(2, 4);
1346
1347         if ((Levitation || Flying) && !forcetrap)
1348             break;
1349         feeltrap(trap);
1350         if (amorphous(youmonst.data) || is_whirly(youmonst.data)
1351             || unsolid(youmonst.data)) {
1352 #if 0 /*JP*/
1353             pline("%s bear trap closes harmlessly through you.",
1354                   A_Your[trap->madeby_u]);
1355 #else
1356             pline("%s\8cF\82Ìã©\82Í\8a\9a\82Ý\82Â\82¢\82½\82ª\81C\82·\82é\82Á\82Æ\92Ê\82è\94²\82¯\82½\81D",
1357                   set_you[trap->madeby_u]);
1358 #endif
1359             break;
1360         }
1361         if (!u.usteed && youmonst.data->msize <= MZ_SMALL) {
1362 #if 0 /*JP*/
1363             pline("%s bear trap closes harmlessly over you.",
1364                   A_Your[trap->madeby_u]);
1365 #else
1366             pline("%s\8cF\82Ìã©\82Í\8a\9a\82Ý\82Â\82¢\82½\82ª\81C\97y\82©\8fã\95û\82¾\82Á\82½\81D",
1367                   set_you[trap->madeby_u]);
1368 #endif
1369             break;
1370         }
1371         set_utrap((unsigned) rn1(4, 4), TT_BEARTRAP);
1372         if (u.usteed) {
1373 #if 0 /*JP*/
1374             pline("%s bear trap closes on %s %s!", A_Your[trap->madeby_u],
1375                   s_suffix(mon_nam(u.usteed)), mbodypart(u.usteed, FOOT));
1376 #else
1377             pline("%s\8cF\82Ìã©\82Í%s\82Ì%s\82É\8a\9a\82Ý\82Â\82¢\82½\81I", set_you[trap->madeby_u],
1378                   mon_nam(u.usteed), mbodypart(u.usteed, FOOT));
1379 #endif
1380             if (thitm(0, u.usteed, (struct obj *) 0, dmg, FALSE))
1381                 reset_utrap(TRUE); /* steed died, hero not trapped */
1382         } else {
1383 #if 0 /*JP*/
1384             pline("%s bear trap closes on your %s!", A_Your[trap->madeby_u],
1385                   body_part(FOOT));
1386 #else
1387             pline("%s\8cF\82Ìã©\82ª\82 \82È\82½\82Ì%s\82É\8a\9a\82Ý\82Â\82¢\82½\81I", set_you[trap->madeby_u],
1388                   body_part(FOOT));
1389 #endif
1390             set_wounded_legs(rn2(2) ? RIGHT_SIDE : LEFT_SIDE, rn1(10, 10));
1391             if (u.umonnum == PM_OWLBEAR || u.umonnum == PM_BUGBEAR)
1392 /*JP
1393                 You("howl in anger!");
1394 */
1395                 You("\93{\82è\82Ì\99ô\9aK\82ð\82 \82°\82½\81I");
1396 /*JP
1397             losehp(Maybe_Half_Phys(dmg), "bear trap", KILLED_BY_AN);
1398 */
1399             losehp(Maybe_Half_Phys(dmg), "\8cF\82Ìã©\82Å", KILLED_BY_AN);
1400         }
1401         exercise(A_DEX, FALSE);
1402         break;
1403     }
1404
1405     case SLP_GAS_TRAP:
1406         seetrap(trap);
1407         if (Sleep_resistance || breathless(youmonst.data)) {
1408 /*JP
1409             You("are enveloped in a cloud of gas!");
1410 */
1411             You("\83K\83X\89_\82É\82Â\82Â\82Ü\82ê\82½\81I");
1412         } else {
1413 /*JP
1414             pline("A cloud of gas puts you to sleep!");
1415 */
1416             pline("\82 \82È\82½\82Í\83K\83X\89_\82Å\96°\82Á\82Ä\82µ\82Ü\82Á\82½\81I");
1417             fall_asleep(-rnd(25), TRUE);
1418         }
1419         (void) steedintrap(trap, (struct obj *) 0);
1420         break;
1421
1422     case RUST_TRAP:
1423         seetrap(trap);
1424
1425         /* Unlike monsters, traps cannot aim their rust attacks at
1426          * you, so instead of looping through and taking either the
1427          * first rustable one or the body, we take whatever we get,
1428          * even if it is not rustable.
1429          */
1430         switch (rn2(5)) {
1431         case 0:
1432 /*JP
1433             pline("%s you on the %s!", A_gush_of_water_hits, body_part(HEAD));
1434 */
1435             pline("\90\85\82ª\95¬\8fo\82µ\82Ä\82 \82È\82½\82Ì%s\82É\96½\92\86\82µ\82½\81I", body_part(HEAD));
1436             (void) water_damage(uarmh, helm_simple_name(uarmh), TRUE);
1437             break;
1438         case 1:
1439 /*JP
1440             pline("%s your left %s!", A_gush_of_water_hits, body_part(ARM));
1441 */
1442             pline("\90\85\82ª\95¬\8fo\82µ\82Ä\82 \82È\82½\82Ì\8d¶%s\82É\96½\92\86\82µ\82½\81I", body_part(ARM));
1443 /*JP
1444             if (water_damage(uarms, "shield", TRUE) != ER_NOTHING)
1445 */
1446             if (water_damage(uarms, "\8f\82", TRUE) != ER_NOTHING)
1447                 break;
1448             if (u.twoweap || (uwep && bimanual(uwep)))
1449                 (void) water_damage(u.twoweap ? uswapwep : uwep, 0, TRUE);
1450         glovecheck:
1451 /*JP
1452             (void) water_damage(uarmg, "gauntlets", TRUE);
1453 */
1454             (void) water_damage(uarmg, "\8f¬\8eè", TRUE);
1455             /* Not "metal gauntlets" since it gets called
1456              * even if it's leather for the message
1457              */
1458             break;
1459         case 2:
1460 /*JP
1461             pline("%s your right %s!", A_gush_of_water_hits, body_part(ARM));
1462 */
1463             pline("\90\85\82ª\95¬\8fo\82µ\82Ä\82 \82È\82½\82Ì\89E%s\82É\96½\92\86\82µ\82½\81I", body_part(ARM));
1464             (void) water_damage(uwep, 0, TRUE);
1465             goto glovecheck;
1466         default:
1467 /*JP
1468             pline("%s you!", A_gush_of_water_hits);
1469 */
1470             pline("\90\85\82ª\95¬\8fo\82µ\82Ä\82 \82È\82½\82É\96½\92\86\82µ\82½\81I");
1471             for (otmp = invent; otmp; otmp = otmp->nobj)
1472                 if (otmp->lamplit && otmp != uwep
1473                     && (otmp != uswapwep || !u.twoweap))
1474                     (void) snuff_lit(otmp);
1475             if (uarmc)
1476                 (void) water_damage(uarmc, cloak_simple_name(uarmc), TRUE);
1477             else if (uarm)
1478                 (void) water_damage(uarm, suit_simple_name(uarm), TRUE);
1479             else if (uarmu)
1480 /*JP
1481                 (void) water_damage(uarmu, "shirt", TRUE);
1482 */
1483                 (void) water_damage(uarmu, "\83V\83\83\83c", TRUE);
1484         }
1485         update_inventory();
1486
1487         if (u.umonnum == PM_IRON_GOLEM) {
1488             int dam = u.mhmax;
1489
1490 /*JP
1491             You("are covered with rust!");
1492 */
1493             You("\8eK\82É\95¢\82í\82ê\82½\81I");
1494 /*JP
1495             losehp(Maybe_Half_Phys(dam), "rusting away", KILLED_BY);
1496 */
1497             losehp(Maybe_Half_Phys(dam), "\8a®\91S\82É\8eK\82Ñ\82Ä", KILLED_BY);
1498         } else if (u.umonnum == PM_GREMLIN && rn2(3)) {
1499             (void) split_mon(&youmonst, (struct monst *) 0);
1500         }
1501
1502         break;
1503
1504     case FIRE_TRAP:
1505         seetrap(trap);
1506         dofiretrap((struct obj *) 0);
1507         break;
1508
1509     case PIT:
1510     case SPIKED_PIT:
1511         /* KMH -- You can't escape the Sokoban level traps */
1512         if (!Sokoban && (Levitation || (Flying && !plunged)))
1513             break;
1514         feeltrap(trap);
1515         if (!Sokoban && is_clinger(youmonst.data) && !plunged) {
1516             if (trap->tseen) {
1517 #if 0 /*JP*/
1518                 You_see("%s %spit below you.", a_your[trap->madeby_u],
1519                         ttype == SPIKED_PIT ? "spiked " : "");
1520 #else
1521                 pline("\91«\8c³\82É%s%s\97\8e\82µ\8c\8a\82ð\94­\8c©\82µ\82½\81D", dig_you[trap->madeby_u],
1522                       ttype == SPIKED_PIT ? "\83g\83Q\82¾\82ç\82¯\82Ì" : "");
1523 #endif
1524             } else {
1525 #if 0 /*JP*/
1526                 pline("%s pit %sopens up under you!", A_Your[trap->madeby_u],
1527                       ttype == SPIKED_PIT ? "full of spikes " : "");
1528 #else
1529                 pline("%s%s\97\8e\82µ\8c\8a\82ª\91«\8c³\82É\8aJ\82¢\82½\81I", dig_you[trap->madeby_u],
1530                       ttype == SPIKED_PIT ? "\83g\83Q\82¾\82ç\82¯\82Ì" : "");
1531 #endif
1532 /*JP
1533                 You("don't fall in!");
1534 */
1535                 pline("\82µ\82©\82µ\81C\82 \82È\82½\82Í\97\8e\82¿\82È\82©\82Á\82½\81I");
1536             }
1537             break;
1538         }
1539         if (!Sokoban) {
1540             char verbbuf[BUFSZ];
1541
1542             *verbbuf = '\0';
1543             if (u.usteed) {
1544                 if ((trflags & RECURSIVETRAP) != 0)
1545 /*JP
1546                     Sprintf(verbbuf, "and %s fall",
1547 */
1548                     Sprintf(verbbuf, "\82Æ%s",
1549                             x_monnam(u.usteed, steed_article, (char *) 0,
1550                                      SUPPRESS_SADDLE, FALSE));
1551                 else
1552 #if 0 /*JP*/
1553                     Sprintf(verbbuf, "lead %s",
1554                             x_monnam(u.usteed, steed_article, "poor",
1555                                      SUPPRESS_SADDLE, FALSE));
1556 #else
1557                     Sprintf(verbbuf, "\82Æ%s",
1558                             x_monnam(u.usteed, steed_article, "\82©\82í\82¢\82»\82¤\82È",
1559                                      SUPPRESS_SADDLE, FALSE));
1560 #endif
1561             } else if (conj_pit) {
1562 /*JP
1563                 You("move into an adjacent pit.");
1564 */
1565                 You("\97×\82Ì\97\8e\82µ\8c\8a\82É\88Ú\93®\82µ\82½\81D");
1566             } else if (adj_pit) {
1567                 You("stumble over debris%s.",
1568                     !rn2(5) ? " between the pits" : "");
1569             } else {
1570 #if 0 /*JP*/
1571                 Strcpy(verbbuf,
1572                        !plunged ? "fall" : (Flying ? "dive" : "plunge"));
1573 #else
1574                 Strcpy(verbbuf,
1575                        !plunged ? "\97\8e\82¿\82½" : (Flying ? "\94ò\82Ñ\8d\9e\82ñ\82¾" : "\93Ë\93ü\82µ\82½"));
1576 #endif
1577             }
1578             if (*verbbuf)
1579 /*JP
1580                 You("%s into %s pit!", verbbuf, a_your[trap->madeby_u]);
1581 */
1582                 You("%s\97\8e\82µ\8c\8a\82É%s!", set_you[trap->madeby_u], verbbuf);
1583         }
1584         /* wumpus reference */
1585         if (Role_if(PM_RANGER) && !trap->madeby_u && !trap->once
1586             && In_quest(&u.uz) && Is_qlocate(&u.uz)) {
1587 /*JP
1588             pline("Fortunately it has a bottom after all...");
1589 */
1590             pline("\8dK\82¢\81C\8c\8b\8bÇ\82Í\92ê\82ª\82 \82Á\82½\81D\81D\81D");
1591             trap->once = 1;
1592         } else if (u.umonnum == PM_PIT_VIPER || u.umonnum == PM_PIT_FIEND) {
1593 /*JP
1594             pline("How pitiful.  Isn't that the pits?");
1595 */
1596             pline("\82±\82Ì\97\8e\82µ\8c\8a\82Í\82¢\82¢\8ed\8e\96\82ð\82µ\82Ä\82¢\82é\81D");
1597         }
1598         if (ttype == SPIKED_PIT) {
1599 /*JP
1600             const char *predicament = "on a set of sharp iron spikes";
1601 */
1602             const char *predicament = "\89s\82¢\93S\82Ì\83g\83Q\83g\83Q\82Ì\8fã\82É";
1603
1604             if (u.usteed) {
1605 #if 0 /*JP:T*/
1606                 pline("%s %s %s!",
1607                       upstart(x_monnam(u.usteed, steed_article, "poor",
1608                                        SUPPRESS_SADDLE, FALSE)),
1609                       conj_pit ? "steps" : "lands", predicament);
1610 #else
1611                 pline("%s\82Í%s%s\81I",
1612                       upstart(x_monnam(u.usteed, steed_article, "\82©\82í\82¢\82»\82¤\82È",
1613                                        SUPPRESS_SADDLE, FALSE)),
1614                       predicament, conj_pit ? "\97\8e\82¿\82½" : "\8d~\82è\82½");
1615 #endif
1616             } else
1617 /*JP
1618                 You("%s %s!", conj_pit ? "step" : "land", predicament);
1619 */
1620                 You("%s%s\81I", predicament, conj_pit ? "\97\8e\82¿\82½" : "\8d~\82è\82½");
1621         }
1622         /* FIXME:
1623          * if hero gets killed here, setting u.utrap in advance will
1624          * show "you were trapped in a pit" during disclosure's display
1625          * of enlightenment, but hero is dying *before* becoming trapped.
1626          */
1627         set_utrap((unsigned) rn1(6, 2), TT_PIT);
1628         if (!steedintrap(trap, (struct obj *) 0)) {
1629             if (ttype == SPIKED_PIT) {
1630                 oldumort = u.umortality;
1631 #if 0 /*JP:T*/
1632                 losehp(Maybe_Half_Phys(rnd(conj_pit ? 4 : adj_pit ? 6 : 10)),
1633                        /* note: these don't need locomotion() handling;
1634                           if fatal while poly'd and Unchanging, the
1635                           death reason will be overridden with
1636                           "killed while stuck in creature form" */
1637                        plunged
1638                           ? "deliberately plunged into a pit of iron spikes"
1639                           : conj_pit
1640                              ? "stepped into a pit of iron spikes"
1641                              : adj_pit
1642                                 ? "stumbled into a pit of iron spikes"
1643                                 : "fell into a pit of iron spikes",
1644                        NO_KILLER_PREFIX);
1645 #else
1646                 losehp(Maybe_Half_Phys(rnd(conj_pit ? 4 : adj_pit ? 6 : 10)),
1647                        plunged
1648                           ? "\82í\82´\82í\82´\83g\83Q\82¾\82ç\82¯\82Ì\97\8e\82µ\8c\8a\82É\93Ë\93ü\82µ\82Ä"
1649                           : conj_pit
1650                              ? "\83g\83Q\82¾\82ç\82¯\82Ì\97\8e\82µ\8c\8a\82É\93¥\82Ý\8d\9e\82ñ\82Å"
1651                              : adj_pit
1652                                 ? "\83g\83Q\82¾\82ç\82¯\82Ì\97\8e\82µ\8c\8a\82É\82æ\82ë\82ß\82«\97\8e\82¿\82Ä"
1653                                 : "\83g\83Q\82¾\82ç\82¯\82Ì\97\8e\82µ\8c\8a\82É\97\8e\82¿\82Ä",
1654                        KILLED_BY);
1655 #endif
1656                 if (!rn2(6))
1657 #if 0 /*JP:T*/
1658                     poisoned("spikes", A_STR,
1659                              (conj_pit || adj_pit)
1660                                 ? "stepping on poison spikes"
1661                                 : "fall onto poison spikes",
1662                              /* if damage triggered life-saving,
1663                                 poison is limited to attrib loss */
1664                              (u.umortality > oldumort) ? 0 : 8, FALSE);
1665 #else
1666                     poisoned("\83g\83Q", A_STR,
1667                              (conj_pit || adj_pit)
1668                                 ? "\93Å\82Ì\93h\82ç\82ê\82½\83g\83Q\82ð\93¥\82ñ\82Å"
1669                                 : "\93Å\82Ì\93h\82ç\82ê\82½\83g\83Q\82Ì\8fã\82É\97\8e\82¿\82Ä",
1670                              /* if damage triggered life-saving,
1671                                 poison is limited to attrib loss */
1672                              (u.umortality > oldumort) ? 0 : 8, FALSE);
1673 #endif
1674             } else {
1675                 /* plunging flyers take spike damage but not pit damage */
1676                 if (!conj_pit
1677                     && !(plunged && (Flying || is_clinger(youmonst.data))))
1678 #if 0 /*JP:T*/
1679                     losehp(Maybe_Half_Phys(rnd(adj_pit ? 3 : 6)),
1680                            plunged ? "deliberately plunged into a pit"
1681                                    : "fell into a pit",
1682                            NO_KILLER_PREFIX);
1683 #else
1684                     losehp(Maybe_Half_Phys(rnd(adj_pit ? 3 : 6)),
1685                            plunged ? "\82í\82´\82í\82´\97\8e\82µ\8c\8a\82É\93Ë\93ü\82µ\82Ä"
1686                                    : "\97\8e\82µ\8c\8a\82É\97\8e\82¿\82Ä",
1687                            KILLED_BY);
1688 #endif
1689             }
1690             if (Punished && !carried(uball)) {
1691                 unplacebc();
1692                 ballfall();
1693                 placebc();
1694             }
1695             if (!conj_pit)
1696 /*JP
1697                 selftouch("Falling, you");
1698 */
1699                 selftouch("\97\8e\89º\92\86\81C\82 \82È\82½\82Í");
1700             vision_full_recalc = 1; /* vision limits change */
1701             exercise(A_STR, FALSE);
1702             exercise(A_DEX, FALSE);
1703         }
1704         break;
1705
1706     case HOLE:
1707     case TRAPDOOR:
1708         if (!Can_fall_thru(&u.uz)) {
1709             seetrap(trap); /* normally done in fall_through */
1710             impossible("dotrap: %ss cannot exist on this level.",
1711                        defsyms[trap_to_defsym(ttype)].explanation);
1712             break; /* don't activate it after all */
1713         }
1714         fall_through(TRUE);
1715         break;
1716
1717     case TELEP_TRAP:
1718         seetrap(trap);
1719         tele_trap(trap);
1720         break;
1721
1722     case LEVEL_TELEP:
1723         seetrap(trap);
1724         level_tele_trap(trap, trflags);
1725         break;
1726
1727     case WEB: /* Our luckless player has stumbled into a web. */
1728         feeltrap(trap);
1729         if (mu_maybe_destroy_web(&youmonst, webmsgok, trap))
1730             break;
1731         if (webmaker(youmonst.data)) {
1732             if (webmsgok)
1733 #if 0 /*JP*/
1734                 pline(trap->madeby_u ? "You take a walk on your web."
1735                                      : "There is a spider web here.");
1736 #else
1737                 pline(trap->madeby_u ? "\8e©\95ª\82Å\92£\82Á\82½\82­\82à\82Ì\91\83\82Ì\8fã\82ð\95à\82¢\82½\81D"
1738                                      : "\82±\82±\82É\82Í\82­\82à\82Ì\91\83\82ª\82 \82é\81D");
1739 #endif
1740             break;
1741         }
1742         if (webmsgok) {
1743             char verbbuf[BUFSZ];
1744
1745 #if 0 /*JP*/
1746             if (forcetrap || viasitting) {
1747                 Strcpy(verbbuf, "are caught by");
1748             } else if (u.usteed) {
1749                 Sprintf(verbbuf, "lead %s into",
1750                         x_monnam(u.usteed, steed_article, "poor",
1751                                  SUPPRESS_SADDLE, FALSE));
1752             } else {
1753                 Sprintf(verbbuf, "%s into",
1754                         Levitation ? (const char *) "float"
1755                                    : locomotion(youmonst.data, "stumble"));
1756             }
1757             You("%s %s spider web!", verbbuf, a_your[trap->madeby_u]);
1758 #else
1759             if (forcetrap) {
1760                 Strcpy(verbbuf, "\82 \82È\82½\82Í");
1761             } else if (u.usteed) {
1762                 Sprintf(verbbuf, "\82 \82È\82½\82Æ%s",
1763                         x_monnam(u.usteed, steed_article, "\82©\82í\82¢\82»\82¤\82È",
1764                                  SUPPRESS_SADDLE, FALSE));
1765             } else {
1766                 Sprintf(verbbuf, "\82 \82È\82½\82Í%s",
1767                         Levitation ? (const char *) "\95\82\82«\82È\82ª\82ç"
1768                         : jconj(locomotion(youmonst.data, "\82Â\82Ü\82¸\82­"), "\82Ä"));
1769             }
1770             pline("%s%s\82­\82à\82Ì\91\83\82É\82Ð\82Á\82©\82©\82Á\82½\81I", verbbuf, web_you[trap->madeby_u]);
1771 #endif
1772         }
1773
1774         /* time will be adjusted below */
1775         set_utrap(1, TT_WEB);
1776
1777         /* Time stuck in the web depends on your/steed strength. */
1778         {
1779             int tim, str = ACURR(A_STR);
1780
1781             /* If mounted, the steed gets trapped.  Use mintrap
1782              * to do all the work.  If mtrapped is set as a result,
1783              * unset it and set utrap instead.  In the case of a
1784              * strongmonst and mintrap said it's trapped, use a
1785              * short but non-zero trap time.  Otherwise, monsters
1786              * have no specific strength, so use player strength.
1787              * This gets skipped for webmsgok, which implies that
1788              * the steed isn't a factor.
1789              */
1790             if (u.usteed && webmsgok) {
1791                 /* mtmp location might not be up to date */
1792                 u.usteed->mx = u.ux;
1793                 u.usteed->my = u.uy;
1794
1795                 /* mintrap currently does not return 2(died) for webs */
1796                 if (mintrap(u.usteed)) {
1797                     u.usteed->mtrapped = 0;
1798                     if (strongmonst(u.usteed->data))
1799                         str = 17;
1800                 } else {
1801                     reset_utrap(FALSE);
1802                     break;
1803                 }
1804
1805                 webmsgok = FALSE; /* mintrap printed the messages */
1806             }
1807             if (str <= 3)
1808                 tim = rn1(6, 6);
1809             else if (str < 6)
1810                 tim = rn1(6, 4);
1811             else if (str < 9)
1812                 tim = rn1(4, 4);
1813             else if (str < 12)
1814                 tim = rn1(4, 2);
1815             else if (str < 15)
1816                 tim = rn1(2, 2);
1817             else if (str < 18)
1818                 tim = rnd(2);
1819             else if (str < 69)
1820                 tim = 1;
1821             else {
1822                 tim = 0;
1823                 if (webmsgok)
1824 /*JP
1825                     You("tear through %s web!", a_your[trap->madeby_u]);
1826 */
1827                     You("%s\82­\82à\82Ì\91\83\82ð\90Ø\82è\97ô\82¢\82½\81I", web_you[trap->madeby_u]);
1828                 deltrap(trap);
1829                 newsym(u.ux, u.uy); /* get rid of trap symbol */
1830             }
1831             set_utrap((unsigned) tim, TT_WEB);
1832         }
1833         break;
1834
1835     case STATUE_TRAP:
1836         (void) activate_statue_trap(trap, u.ux, u.uy, FALSE);
1837         break;
1838
1839     case MAGIC_TRAP: /* A magic trap. */
1840         seetrap(trap);
1841         if (!rn2(30)) {
1842             deltrap(trap);
1843             newsym(u.ux, u.uy); /* update position */
1844 /*JP
1845             You("are caught in a magical explosion!");
1846 */
1847             You("\96\82\96@\82Ì\94\9a\94­\82ð\97\81\82Ñ\82½\81I");
1848 /*JP
1849             losehp(rnd(10), "magical explosion", KILLED_BY_AN);
1850 */
1851             losehp(rnd(10), "\96\82\96@\82Ì\94\9a\94­\82ð\97\81\82Ñ\82Ä", KILLED_BY_AN);
1852 /*JP
1853             Your("body absorbs some of the magical energy!");
1854 */
1855             Your("\91Ì\82Í\96\82\96@\82Ì\83G\83l\83\8b\83M\81[\82ð\8f­\82µ\8bz\82¢\82Æ\82Á\82½\81I");
1856             u.uen = (u.uenmax += 2);
1857             break;
1858         } else {
1859             domagictrap();
1860         }
1861         (void) steedintrap(trap, (struct obj *) 0);
1862         break;
1863
1864     case ANTI_MAGIC:
1865         seetrap(trap);
1866         /* hero without magic resistance loses spell energy,
1867            hero with magic resistance takes damage instead;
1868            possibly non-intuitive but useful for play balance */
1869         if (!Antimagic) {
1870             drain_en(rnd(u.ulevel) + 1);
1871         } else {
1872             int dmgval2 = rnd(4), hp = Upolyd ? u.mh : u.uhp;
1873
1874             /* Half_XXX_damage has opposite its usual effect (approx)
1875                but isn't cumulative if hero has more than one */
1876             if (Half_physical_damage || Half_spell_damage)
1877                 dmgval2 += rnd(4);
1878             /* give Magicbane wielder dose of own medicine */
1879             if (uwep && uwep->oartifact == ART_MAGICBANE)
1880                 dmgval2 += rnd(4);
1881             /* having an artifact--other than own quest one--which
1882                confers magic resistance simply by being carried
1883                also increases the effect */
1884             for (otmp = invent; otmp; otmp = otmp->nobj)
1885                 if (otmp->oartifact && !is_quest_artifact(otmp)
1886                     && defends_when_carried(AD_MAGM, otmp))
1887                     break;
1888             if (otmp)
1889                 dmgval2 += rnd(4);
1890             if (Passes_walls)
1891                 dmgval2 = (dmgval2 + 3) / 4;
1892
1893 #if 0 /*JP*/
1894             You_feel((dmgval2 >= hp) ? "unbearably torpid!"
1895                                      : (dmgval2 >= hp / 4) ? "very lethargic."
1896                                                            : "sluggish.");
1897 #else
1898             You_feel((dmgval2 >= hp) ? "\91Ï\82¦\82ç\82ê\82È\82¢\82Ù\82Ç\96³\8bC\97Í\82É\82È\82Á\82½\81I"
1899                                      : (dmgval2 >= hp / 4) ? "\82Æ\82Ä\82à\8bC\82¾\82é\82­\82È\82Á\82½\81D"
1900                                                            : "\82à\82Ì\82®\82³\82È\8bC\95ª\82É\82È\82Á\82½\81D");
1901 #endif
1902             /* opposite of magical explosion */
1903 /*JP
1904             losehp(dmgval2, "anti-magic implosion", KILLED_BY_AN);
1905 */
1906             losehp(dmgval2, "\94½\96\82\96@\82Ì\93à\95\94\94j\97ô\82Å", KILLED_BY_AN);
1907         }
1908         break;
1909
1910     case POLY_TRAP: {
1911         char verbbuf[BUFSZ];
1912
1913         seetrap(trap);
1914         if (viasitting)
1915             Strcpy(verbbuf, "trigger"); /* follows "You sit down." */
1916         else if (u.usteed)
1917 #if 0 /*JP*/
1918             Sprintf(verbbuf, "lead %s onto",
1919                     x_monnam(u.usteed, steed_article, (char *) 0,
1920                              SUPPRESS_SADDLE, FALSE));
1921 #else
1922             Sprintf(verbbuf, "%s\82Æ\82Æ\82à\82É\94ò\82Ñ\8d\9e\82ñ\82¾",
1923                     x_monnam(u.usteed, steed_article, (char *) 0,
1924                              SUPPRESS_SADDLE, FALSE));
1925 #endif
1926         else
1927 #if 0 /*JP*/
1928             Sprintf(verbbuf, "%s onto",
1929                     Levitation ? (const char *) "float"
1930                                : locomotion(youmonst.data, "step"));
1931 #else
1932             Sprintf(verbbuf,"%s",
1933                     jpast(Levitation ? (const char *)"\95\82\82«\82È\82ª\82ç\94ò\82Ñ\82±\82Þ"
1934                           : locomotion(youmonst.data, "\93¥\82Ý\8d\9e\82Þ")));
1935 #endif
1936 /*JP
1937         You("%s a polymorph trap!", verbbuf);
1938 */
1939         You("\95Ï\89»\82Ìã©\82É%s\81I", verbbuf);
1940         if (Antimagic || Unchanging) {
1941             shieldeff(u.ux, u.uy);
1942 /*JP
1943             You_feel("momentarily different.");
1944 */
1945             You("\88ê\8fu\88á\82Á\82½\8a´\82\82ª\82µ\82½\81D");
1946             /* Trap did nothing; don't remove it --KAA */
1947         } else {
1948             (void) steedintrap(trap, (struct obj *) 0);
1949             deltrap(trap);      /* delete trap before polymorph */
1950             newsym(u.ux, u.uy); /* get rid of trap symbol */
1951 /*JP
1952             You_feel("a change coming over you.");
1953 */
1954             You("\95Ï\89»\82ª\96K\82ê\82½\82æ\82¤\82È\8bC\82ª\82µ\82½\81D");
1955             polyself(0);
1956         }
1957         break;
1958     }
1959     case LANDMINE: {
1960         unsigned steed_mid = 0;
1961         struct obj *saddle = 0;
1962
1963         if ((Levitation || Flying) && !forcetrap) {
1964             if (!already_seen && rn2(3))
1965                 break;
1966             feeltrap(trap);
1967 #if 0 /*JP*/
1968             pline("%s %s in a pile of soil below you.",
1969                   already_seen ? "There is" : "You discover",
1970                   trap->madeby_u ? "the trigger of your mine" : "a trigger");
1971 #else
1972             if(already_seen)
1973                 pline("\82±\82±\82É\82Í%s\92n\97\8b\82Ì\8bN\94\9a\83X\83C\83b\83`\82ª\82 \82é\81D",
1974                       set_you[trap->madeby_u]);
1975             else
1976                 You("\91«\89º\82Ì\93y\82Ì\8eR\82É%s\92n\97\8b\82Ì\8bN\94\9a\83X\83C\83b\83`\82ð\82Ý\82Â\82¯\82½\81D",
1977                     set_you[trap->madeby_u]);
1978 #endif
1979             if (already_seen && rn2(3))
1980                 break;
1981 #if 0 /*JP*/
1982             pline("KAABLAMM!!!  %s %s%s off!",
1983                   forcebungle ? "Your inept attempt sets"
1984                               : "The air currents set",
1985                   already_seen ? a_your[trap->madeby_u] : "",
1986                   already_seen ? " land mine" : "it");
1987 #else
1988             pline("\82¿\82ã\82Ç\81[\82ñ\81I\81I%s%s%s\8bN\94\9a\83X\83C\83b\83`\82ª\94­\93®\82µ\82½\81I",
1989                   forcebungle ? "\95s\8aí\97p\82È\82¹\82¢\82Å"
1990                               : "\8bó\8bC\82Ì\97¬\82ê\82Å",
1991                   already_seen ? set_you[trap->madeby_u] : "",
1992                   already_seen ? "\92n\97\8b\82Ì" : "");
1993 #endif
1994         } else {
1995             /* prevent landmine from killing steed, throwing you to
1996              * the ground, and you being affected again by the same
1997              * mine because it hasn't been deleted yet
1998              */
1999             static boolean recursive_mine = FALSE;
2000
2001             if (recursive_mine)
2002                 break;
2003             feeltrap(trap);
2004 #if 0 /*JP*/
2005             pline("KAABLAMM!!!  You triggered %s land mine!",
2006                   a_your[trap->madeby_u]);
2007 #else
2008             pline("\82¿\82ã\82Ç\81[\82ñ\81I\81I%s\92n\97\8b\82Ì\8bN\94\9a\83X\83C\83b\83`\82ð\93¥\82ñ\82¾\81I",
2009                   set_you[trap->madeby_u]);
2010 #endif
2011             if (u.usteed)
2012                 steed_mid = u.usteed->m_id;
2013             recursive_mine = TRUE;
2014             (void) steedintrap(trap, (struct obj *) 0);
2015             recursive_mine = FALSE;
2016             saddle = sobj_at(SADDLE, u.ux, u.uy);
2017             set_wounded_legs(LEFT_SIDE, rn1(35, 41));
2018             set_wounded_legs(RIGHT_SIDE, rn1(35, 41));
2019             exercise(A_DEX, FALSE);
2020         }
2021         blow_up_landmine(trap);
2022         if (steed_mid && saddle && !u.usteed)
2023             (void) keep_saddle_with_steedcorpse(steed_mid, fobj, saddle);
2024         newsym(u.ux, u.uy); /* update trap symbol */
2025 /*JP
2026         losehp(Maybe_Half_Phys(rnd(16)), "land mine", KILLED_BY_AN);
2027 */
2028         losehp(Maybe_Half_Phys(rnd(16)), "\92n\97\8b\82ð\93¥\82ñ\82Å", KILLED_BY_AN);
2029         /* fall recursively into the pit... */
2030         if ((trap = t_at(u.ux, u.uy)) != 0)
2031             dotrap(trap, RECURSIVETRAP);
2032         fill_pit(u.ux, u.uy);
2033         break;
2034     }
2035
2036     case ROLLING_BOULDER_TRAP: {
2037         int style = ROLL | (trap->tseen ? LAUNCH_KNOWN : 0);
2038
2039         feeltrap(trap);
2040 /*JP
2041         pline("Click!  You trigger a rolling boulder trap!");
2042 */
2043         pline("\83J\83`\83b\81I\82 \82È\82½\82Í\8b\90\8aâ\82Ìã©\82Ì\83X\83C\83b\83`\82ð\93¥\82ñ\82¾\81I");
2044         if (!launch_obj(BOULDER, trap->launch.x, trap->launch.y,
2045                         trap->launch2.x, trap->launch2.y, style)) {
2046             deltrap(trap);
2047             newsym(u.ux, u.uy); /* get rid of trap symbol */
2048 /*JP
2049             pline("Fortunately for you, no boulder was released.");
2050 */
2051             pline("\89^\82Ì\82æ\82¢\82±\82Æ\82É\8aâ\82Í\93]\82ª\82Á\82Ä\82±\82È\82©\82Á\82½\81D");
2052         }
2053         break;
2054     }
2055
2056     case MAGIC_PORTAL:
2057         feeltrap(trap);
2058         domagicportal(trap);
2059         break;
2060
2061     case VIBRATING_SQUARE:
2062         feeltrap(trap);
2063         /* messages handled elsewhere; the trap symbol is merely to mark the
2064          * square for future reference */
2065         break;
2066
2067     default:
2068         feeltrap(trap);
2069         impossible("You hit a trap of type %u", trap->ttyp);
2070     }
2071 }
2072
2073 STATIC_OVL char *
2074 trapnote(trap, noprefix)
2075 struct trap *trap;
2076 boolean noprefix;
2077 {
2078     static char tnbuf[12];
2079     const char *tn,
2080 #if 0 /*JP*/
2081         *tnnames[12] = { "C note",  "D flat", "D note",  "E flat",
2082                          "E note",  "F note", "F sharp", "G note",
2083                          "G sharp", "A note", "B flat",  "B note" };
2084 #else
2085         *tnnames[12] = { "\83h",  "\83\8c\81ó", "\83\8c",  "\83~\81ó",
2086                          "\83~",  "\83t\83@", "\83t\83@\81ò", "\83\",
2087                          "\83\\81ò", "\83\89", "\83V\81ó",  "\83V" };
2088 #endif
2089
2090     tnbuf[0] = '\0';
2091     tn = tnnames[trap->tnote];
2092 #if 0 /*JP*/
2093     if (!noprefix)
2094         Sprintf(tnbuf, "%s ",
2095                 (*tn == 'A' || *tn == 'E' || *tn == 'F') ? "an" : "a");
2096     Sprintf(eos(tnbuf), "%s", tn);
2097 #else
2098     Sprintf(tnbuf, "%s\82Ì\89¹", tn);
2099 #endif
2100     return tnbuf;
2101 }
2102
2103 STATIC_OVL int
2104 steedintrap(trap, otmp)
2105 struct trap *trap;
2106 struct obj *otmp;
2107 {
2108     struct monst *steed = u.usteed;
2109     int tt;
2110     boolean trapkilled, steedhit;
2111
2112     if (!steed || !trap)
2113         return 0;
2114     tt = trap->ttyp;
2115     steed->mx = u.ux;
2116     steed->my = u.uy;
2117     trapkilled = steedhit = FALSE;
2118
2119     switch (tt) {
2120     case ARROW_TRAP:
2121         if (!otmp) {
2122             impossible("steed hit by non-existant arrow?");
2123             return 0;
2124         }
2125         trapkilled = thitm(8, steed, otmp, 0, FALSE);
2126         steedhit = TRUE;
2127         break;
2128     case DART_TRAP:
2129         if (!otmp) {
2130             impossible("steed hit by non-existant dart?");
2131             return 0;
2132         }
2133         trapkilled = thitm(7, steed, otmp, 0, FALSE);
2134         steedhit = TRUE;
2135         break;
2136     case SLP_GAS_TRAP:
2137         if (!resists_sleep(steed) && !breathless(steed->data)
2138             && !steed->msleeping && steed->mcanmove) {
2139             if (sleep_monst(steed, rnd(25), -1))
2140                 /* no in_sight check here; you can feel it even if blind */
2141 /*JP
2142                 pline("%s suddenly falls asleep!", Monnam(steed));
2143 */
2144                 pline("%s\82Í\82Æ\82Â\82º\82ñ\96°\82Á\82Ä\82µ\82Ü\82Á\82½\81I", Monnam(steed));
2145         }
2146         steedhit = TRUE;
2147         break;
2148     case LANDMINE:
2149         trapkilled = thitm(0, steed, (struct obj *) 0, rnd(16), FALSE);
2150         steedhit = TRUE;
2151         break;
2152     case PIT:
2153     case SPIKED_PIT:
2154         trapkilled = (DEADMONSTER(steed)
2155                       || thitm(0, steed, (struct obj *) 0,
2156                                rnd((tt == PIT) ? 6 : 10), FALSE));
2157         steedhit = TRUE;
2158         break;
2159     case POLY_TRAP:
2160         if (!resists_magm(steed) && !resist(steed, WAND_CLASS, 0, NOTELL)) {
2161             (void) newcham(steed, (struct permonst *) 0, FALSE, FALSE);
2162             if (!can_saddle(steed) || !can_ride(steed))
2163                 dismount_steed(DISMOUNT_POLY);
2164             else
2165 /*JP
2166                 You("have to adjust yourself in the saddle on %s.",
2167 */
2168                 You("%s\82Ì\88Æ\82Ì\8fã\82Å\8dÀ\82è\82È\82¨\82µ\82½\81D",
2169                     x_monnam(steed, ARTICLE_A, (char *) 0, SUPPRESS_SADDLE,
2170                              FALSE));
2171         }
2172         steedhit = TRUE;
2173         break;
2174     default:
2175         break;
2176     }
2177
2178     if (trapkilled) {
2179         dismount_steed(DISMOUNT_POLY);
2180         return 2;
2181     }
2182     return steedhit ? 1 : 0;
2183 }
2184
2185 /* some actions common to both player and monsters for triggered landmine */
2186 void
2187 blow_up_landmine(trap)
2188 struct trap *trap;
2189 {
2190     int x = trap->tx, y = trap->ty, dbx, dby;
2191     struct rm *lev = &levl[x][y];
2192
2193     (void) scatter(x, y, 4,
2194                    MAY_DESTROY | MAY_HIT | MAY_FRACTURE | VIS_EFFECTS,
2195                    (struct obj *) 0);
2196     del_engr_at(x, y);
2197     wake_nearto(x, y, 400);
2198     if (IS_DOOR(lev->typ))
2199         lev->doormask = D_BROKEN;
2200     /* destroy drawbridge if present */
2201     if (lev->typ == DRAWBRIDGE_DOWN || is_drawbridge_wall(x, y) >= 0) {
2202         dbx = x, dby = y;
2203         /* if under the portcullis, the bridge is adjacent */
2204         if (find_drawbridge(&dbx, &dby))
2205             destroy_drawbridge(dbx, dby);
2206         trap = t_at(x, y); /* expected to be null after destruction */
2207     }
2208     /* convert landmine into pit */
2209     if (trap) {
2210         if (Is_waterlevel(&u.uz) || Is_airlevel(&u.uz)) {
2211             /* no pits here */
2212             deltrap(trap);
2213         } else {
2214             trap->ttyp = PIT;       /* explosion creates a pit */
2215             trap->madeby_u = FALSE; /* resulting pit isn't yours */
2216             seetrap(trap);          /* and it isn't concealed */
2217         }
2218     }
2219 }
2220
2221 /*
2222  * The following are used to track launched objects to
2223  * prevent them from vanishing if you are killed. They
2224  * will reappear at the launchplace in bones files.
2225  */
2226 static struct {
2227     struct obj *obj;
2228     xchar x, y;
2229 } launchplace;
2230
2231 STATIC_OVL void
2232 launch_drop_spot(obj, x, y)
2233 struct obj *obj;
2234 xchar x, y;
2235 {
2236     if (!obj) {
2237         launchplace.obj = (struct obj *) 0;
2238         launchplace.x = 0;
2239         launchplace.y = 0;
2240     } else {
2241         launchplace.obj = obj;
2242         launchplace.x = x;
2243         launchplace.y = y;
2244     }
2245 }
2246
2247 boolean
2248 launch_in_progress()
2249 {
2250     if (launchplace.obj)
2251         return TRUE;
2252     return FALSE;
2253 }
2254
2255 void
2256 force_launch_placement()
2257 {
2258     if (launchplace.obj) {
2259         launchplace.obj->otrapped = 0;
2260         place_object(launchplace.obj, launchplace.x, launchplace.y);
2261     }
2262 }
2263
2264 /*
2265  * Move obj from (x1,y1) to (x2,y2)
2266  *
2267  * Return 0 if no object was launched.
2268  *        1 if an object was launched and placed somewhere.
2269  *        2 if an object was launched, but used up.
2270  */
2271 int
2272 launch_obj(otyp, x1, y1, x2, y2, style)
2273 short otyp;
2274 register int x1, y1, x2, y2;
2275 int style;
2276 {
2277     register struct monst *mtmp;
2278     register struct obj *otmp, *otmp2;
2279     register int dx, dy;
2280     struct obj *singleobj;
2281     boolean used_up = FALSE;
2282     boolean otherside = FALSE;
2283     int dist;
2284     int tmp;
2285     int delaycnt = 0;
2286
2287     otmp = sobj_at(otyp, x1, y1);
2288     /* Try the other side too, for rolling boulder traps */
2289     if (!otmp && otyp == BOULDER) {
2290         otherside = TRUE;
2291         otmp = sobj_at(otyp, x2, y2);
2292     }
2293     if (!otmp)
2294         return 0;
2295     if (otherside) { /* swap 'em */
2296         int tx, ty;
2297
2298         tx = x1;
2299         ty = y1;
2300         x1 = x2;
2301         y1 = y2;
2302         x2 = tx;
2303         y2 = ty;
2304     }
2305
2306     if (otmp->quan == 1L) {
2307         obj_extract_self(otmp);
2308         singleobj = otmp;
2309         otmp = (struct obj *) 0;
2310     } else {
2311         singleobj = splitobj(otmp, 1L);
2312         obj_extract_self(singleobj);
2313     }
2314     newsym(x1, y1);
2315     /* in case you're using a pick-axe to chop the boulder that's being
2316        launched (perhaps a monster triggered it), destroy context so that
2317        next dig attempt never thinks you're resuming previous effort */
2318     if ((otyp == BOULDER || otyp == STATUE)
2319         && singleobj->ox == context.digging.pos.x
2320         && singleobj->oy == context.digging.pos.y)
2321         (void) memset((genericptr_t) &context.digging, 0,
2322                       sizeof(struct dig_info));
2323
2324     dist = distmin(x1, y1, x2, y2);
2325     bhitpos.x = x1;
2326     bhitpos.y = y1;
2327     dx = sgn(x2 - x1);
2328     dy = sgn(y2 - y1);
2329     switch (style) {
2330     case ROLL | LAUNCH_UNSEEN:
2331         if (otyp == BOULDER) {
2332 #if 0 /*JP*/
2333             You_hear(Hallucination ? "someone bowling."
2334                                    : "rumbling in the distance.");
2335 #else
2336             You_hear(Hallucination ? "\92N\82©\82ª\83{\81[\83\8a\83\93\83O\82ð\82µ\82Ä\82¢\82é\89¹\82ð\95·\82¢\82½\81D"
2337                                    : "\89\93\82­\82Ì\83S\83\8d\83S\83\8d\82Æ\82¢\82¤\89¹\82ð\95·\82¢\82½\81D");
2338 #endif
2339         }
2340         style &= ~LAUNCH_UNSEEN;
2341         goto roll;
2342     case ROLL | LAUNCH_KNOWN:
2343         /* use otrapped as a flag to ohitmon */
2344         singleobj->otrapped = 1;
2345         style &= ~LAUNCH_KNOWN;
2346     /* fall through */
2347     roll:
2348     case ROLL:
2349         delaycnt = 2;
2350     /* fall through */
2351     default:
2352         if (!delaycnt)
2353             delaycnt = 1;
2354         if (!cansee(bhitpos.x, bhitpos.y))
2355             curs_on_u();
2356         tmp_at(DISP_FLASH, obj_to_glyph(singleobj, rn2_on_display_rng));
2357         tmp_at(bhitpos.x, bhitpos.y);
2358     }
2359     /* Mark a spot to place object in bones files to prevent
2360      * loss of object. Use the starting spot to ensure that
2361      * a rolling boulder will still launch, which it wouldn't
2362      * do if left midstream. Unfortunately we can't use the
2363      * target resting spot, because there are some things/situations
2364      * that would prevent it from ever getting there (bars), and we
2365      * can't tell that yet.
2366      */
2367     launch_drop_spot(singleobj, bhitpos.x, bhitpos.y);
2368
2369     /* Set the object in motion */
2370     while (dist-- > 0 && !used_up) {
2371         struct trap *t;
2372         tmp_at(bhitpos.x, bhitpos.y);
2373         tmp = delaycnt;
2374
2375         /* dstage@u.washington.edu -- Delay only if hero sees it */
2376         if (cansee(bhitpos.x, bhitpos.y))
2377             while (tmp-- > 0)
2378                 delay_output();
2379
2380         bhitpos.x += dx;
2381         bhitpos.y += dy;
2382         t = t_at(bhitpos.x, bhitpos.y);
2383
2384         if ((mtmp = m_at(bhitpos.x, bhitpos.y)) != 0) {
2385             if (otyp == BOULDER && throws_rocks(mtmp->data)) {
2386                 if (rn2(3)) {
2387                     if (cansee(bhitpos.x, bhitpos.y))
2388 /*JP
2389                     pline("%s snatches the boulder.", Monnam(mtmp));
2390 */
2391                     pline("%s\82Í\8aâ\82ð\82Â\82©\82Ý\8eæ\82Á\82½\81D", Monnam(mtmp));
2392                     singleobj->otrapped = 0;
2393                     (void) mpickobj(mtmp, singleobj);
2394                     used_up = TRUE;
2395                     launch_drop_spot((struct obj *) 0, 0, 0);
2396                     break;
2397                 }
2398             }
2399             if (ohitmon(mtmp, singleobj, (style == ROLL) ? -1 : dist,
2400                         FALSE)) {
2401                 used_up = TRUE;
2402                 launch_drop_spot((struct obj *) 0, 0, 0);
2403                 break;
2404             }
2405         } else if (bhitpos.x == u.ux && bhitpos.y == u.uy) {
2406             if (multi)
2407                 nomul(0);
2408             if (thitu(9 + singleobj->spe, dmgval(singleobj, &youmonst),
2409                       &singleobj, (char *) 0))
2410                 stop_occupation();
2411         }
2412         if (style == ROLL) {
2413             if (down_gate(bhitpos.x, bhitpos.y) != -1) {
2414                 if (ship_object(singleobj, bhitpos.x, bhitpos.y, FALSE)) {
2415                     used_up = TRUE;
2416                     launch_drop_spot((struct obj *) 0, 0, 0);
2417                     break;
2418                 }
2419             }
2420             if (t && otyp == BOULDER) {
2421                 switch (t->ttyp) {
2422                 case LANDMINE:
2423                     if (rn2(10) > 2) {
2424 #if 0 /*JP*/
2425                         pline(
2426                             "KAABLAMM!!!%s",
2427                             cansee(bhitpos.x, bhitpos.y)
2428                                 ? " The rolling boulder triggers a land mine."
2429                                 : "");
2430 #else
2431                         pline(
2432                             "\82¿\82ã\82Ç\81[\82ñ\81I\81I%s",
2433                             cansee(bhitpos.x, bhitpos.y)
2434                                 ? "\93]\82ª\82Á\82Ä\82«\82½\8aâ\82ª\92n\97\8b\82Ì\8bN\94\9a\83X\83C\83b\83`\82ð\93¥\82ñ\82¾\81D"
2435                                 : "");
2436 #endif
2437                         deltrap(t);
2438                         del_engr_at(bhitpos.x, bhitpos.y);
2439                         place_object(singleobj, bhitpos.x, bhitpos.y);
2440                         singleobj->otrapped = 0;
2441                         fracture_rock(singleobj);
2442                         (void) scatter(bhitpos.x, bhitpos.y, 4,
2443                                        MAY_DESTROY | MAY_HIT | MAY_FRACTURE
2444                                            | VIS_EFFECTS,
2445                                        (struct obj *) 0);
2446                         if (cansee(bhitpos.x, bhitpos.y))
2447                             newsym(bhitpos.x, bhitpos.y);
2448                         used_up = TRUE;
2449                         launch_drop_spot((struct obj *) 0, 0, 0);
2450                     }
2451                     break;
2452                 case LEVEL_TELEP:
2453                 case TELEP_TRAP:
2454                     if (cansee(bhitpos.x, bhitpos.y))
2455 /*JP
2456                         pline("Suddenly the rolling boulder disappears!");
2457 */
2458                         pline("\93]\82ª\82Á\82Ä\82«\82½\8aâ\82ª\82Æ\82Â\82º\82ñ\8fÁ\82¦\82½\81I");
2459                     else
2460 /*JP
2461                         You_hear("a rumbling stop abruptly.");
2462 */
2463                         pline("\83S\83\8d\83S\83\8d\82Æ\82¢\82¤\89¹\82ª\93Ë\91R\8e~\82Ü\82Á\82½\81D");
2464                     singleobj->otrapped = 0;
2465                     if (t->ttyp == TELEP_TRAP)
2466                         (void) rloco(singleobj);
2467                     else {
2468                         int newlev = random_teleport_level();
2469                         d_level dest;
2470
2471                         if (newlev == depth(&u.uz) || In_endgame(&u.uz))
2472                             continue;
2473                         add_to_migration(singleobj);
2474                         get_level(&dest, newlev);
2475                         singleobj->ox = dest.dnum;
2476                         singleobj->oy = dest.dlevel;
2477                         singleobj->owornmask = (long) MIGR_RANDOM;
2478                     }
2479                     seetrap(t);
2480                     used_up = TRUE;
2481                     launch_drop_spot((struct obj *) 0, 0, 0);
2482                     break;
2483                 case PIT:
2484                 case SPIKED_PIT:
2485                 case HOLE:
2486                 case TRAPDOOR:
2487                     /* the boulder won't be used up if there is a
2488                        monster in the trap; stop rolling anyway */
2489                     x2 = bhitpos.x, y2 = bhitpos.y; /* stops here */
2490 /*JP
2491                     if (flooreffects(singleobj, x2, y2, "fall")) {
2492 */
2493                     if (flooreffects(singleobj, x2, y2, "\97\8e\82¿\82é")) {
2494                         used_up = TRUE;
2495                         launch_drop_spot((struct obj *) 0, 0, 0);
2496                     }
2497                     dist = -1; /* stop rolling immediately */
2498                     break;
2499                 }
2500                 if (used_up || dist == -1)
2501                     break;
2502             }
2503 /*JP
2504             if (flooreffects(singleobj, bhitpos.x, bhitpos.y, "fall")) {
2505 */
2506             if (flooreffects(singleobj, bhitpos.x, bhitpos.y, "\97\8e\82¿\82é")) {
2507                 used_up = TRUE;
2508                 launch_drop_spot((struct obj *) 0, 0, 0);
2509                 break;
2510             }
2511             if (otyp == BOULDER
2512                 && (otmp2 = sobj_at(BOULDER, bhitpos.x, bhitpos.y)) != 0) {
2513 /*JP
2514                 const char *bmsg = " as one boulder sets another in motion";
2515 */
2516                 const char *bmsg = "\82Ð\82Æ\82Â\82Ì\8aâ\82ª\91¼\82Ì\8aâ\82ð\93®\82©\82µ\82½\82©\82Ì\82æ\82¤\82È\81C";
2517
2518                 if (!isok(bhitpos.x + dx, bhitpos.y + dy) || !dist
2519                     || IS_ROCK(levl[bhitpos.x + dx][bhitpos.y + dy].typ))
2520 /*JP
2521                     bmsg = " as one boulder hits another";
2522 */
2523                     bmsg = "\82Ð\82Æ\82Â\82Ì\8aâ\82ª\91¼\82Ì\8aâ\82É\93\96\82½\82Á\82½\82æ\82¤\82È";
2524
2525 /*JP
2526                 You_hear("a loud crash%s!",
2527 */
2528                 You_hear("%s\91å\82«\82È\83S\83\93\82Æ\82¢\82¤\89¹\82ð\95·\82¢\82½\81I",
2529                          cansee(bhitpos.x, bhitpos.y) ? bmsg : "");
2530                 obj_extract_self(otmp2);
2531                 /* pass off the otrapped flag to the next boulder */
2532                 otmp2->otrapped = singleobj->otrapped;
2533                 singleobj->otrapped = 0;
2534                 place_object(singleobj, bhitpos.x, bhitpos.y);
2535                 singleobj = otmp2;
2536                 otmp2 = (struct obj *) 0;
2537                 wake_nearto(bhitpos.x, bhitpos.y, 10 * 10);
2538             }
2539         }
2540         if (otyp == BOULDER && closed_door(bhitpos.x, bhitpos.y)) {
2541             if (cansee(bhitpos.x, bhitpos.y))
2542 /*JP
2543                 pline_The("boulder crashes through a door.");
2544 */
2545                 pline("\8aâ\82Í\94à\82ð\94j\89ó\82µ\82½\81D");
2546             levl[bhitpos.x][bhitpos.y].doormask = D_BROKEN;
2547             if (dist)
2548                 unblock_point(bhitpos.x, bhitpos.y);
2549         }
2550
2551         /* if about to hit iron bars, do so now */
2552         if (dist > 0 && isok(bhitpos.x + dx, bhitpos.y + dy)
2553             && levl[bhitpos.x + dx][bhitpos.y + dy].typ == IRONBARS) {
2554             x2 = bhitpos.x, y2 = bhitpos.y; /* object stops here */
2555             if (hits_bars(&singleobj,
2556                           x2, y2, x2+dx, y2+dy,
2557                           !rn2(20), 0)) {
2558                 if (!singleobj) {
2559                     used_up = TRUE;
2560                     launch_drop_spot((struct obj *) 0, 0, 0);
2561                 }
2562                 break;
2563             }
2564         }
2565     }
2566     tmp_at(DISP_END, 0);
2567     launch_drop_spot((struct obj *) 0, 0, 0);
2568     if (!used_up) {
2569         singleobj->otrapped = 0;
2570         place_object(singleobj, x2, y2);
2571         newsym(x2, y2);
2572         return 1;
2573     } else
2574         return 2;
2575 }
2576
2577 void
2578 seetrap(trap)
2579 struct trap *trap;
2580 {
2581     if (!trap->tseen) {
2582         trap->tseen = 1;
2583         newsym(trap->tx, trap->ty);
2584     }
2585 }
2586
2587 /* like seetrap() but overrides vision */
2588 void
2589 feeltrap(trap)
2590 struct trap *trap;
2591 {
2592     trap->tseen = 1;
2593     map_trap(trap, 1);
2594     /* in case it's beneath something, redisplay the something */
2595     newsym(trap->tx, trap->ty);
2596 }
2597
2598 STATIC_OVL int
2599 mkroll_launch(ttmp, x, y, otyp, ocount)
2600 struct trap *ttmp;
2601 xchar x, y;
2602 short otyp;
2603 long ocount;
2604 {
2605     struct obj *otmp;
2606     register int tmp;
2607     schar dx, dy;
2608     int distance;
2609     coord cc;
2610     coord bcc;
2611     int trycount = 0;
2612     boolean success = FALSE;
2613     int mindist = 4;
2614
2615     if (ttmp->ttyp == ROLLING_BOULDER_TRAP)
2616         mindist = 2;
2617     distance = rn1(5, 4); /* 4..8 away */
2618     tmp = rn2(8);         /* randomly pick a direction to try first */
2619     while (distance >= mindist) {
2620         dx = xdir[tmp];
2621         dy = ydir[tmp];
2622         cc.x = x;
2623         cc.y = y;
2624         /* Prevent boulder from being placed on water */
2625         if (ttmp->ttyp == ROLLING_BOULDER_TRAP
2626             && is_pool_or_lava(x + distance * dx, y + distance * dy))
2627             success = FALSE;
2628         else
2629             success = isclearpath(&cc, distance, dx, dy);
2630         if (ttmp->ttyp == ROLLING_BOULDER_TRAP) {
2631             boolean success_otherway;
2632
2633             bcc.x = x;
2634             bcc.y = y;
2635             success_otherway = isclearpath(&bcc, distance, -(dx), -(dy));
2636             if (!success_otherway)
2637                 success = FALSE;
2638         }
2639         if (success)
2640             break;
2641         if (++tmp > 7)
2642             tmp = 0;
2643         if ((++trycount % 8) == 0)
2644             --distance;
2645     }
2646     if (!success) {
2647         /* create the trap without any ammo, launch pt at trap location */
2648         cc.x = bcc.x = x;
2649         cc.y = bcc.y = y;
2650     } else {
2651         otmp = mksobj(otyp, TRUE, FALSE);
2652         otmp->quan = ocount;
2653         otmp->owt = weight(otmp);
2654         place_object(otmp, cc.x, cc.y);
2655         stackobj(otmp);
2656     }
2657     ttmp->launch.x = cc.x;
2658     ttmp->launch.y = cc.y;
2659     if (ttmp->ttyp == ROLLING_BOULDER_TRAP) {
2660         ttmp->launch2.x = bcc.x;
2661         ttmp->launch2.y = bcc.y;
2662     } else
2663         ttmp->launch_otyp = otyp;
2664     newsym(ttmp->launch.x, ttmp->launch.y);
2665     return 1;
2666 }
2667
2668 STATIC_OVL boolean
2669 isclearpath(cc, distance, dx, dy)
2670 coord *cc;
2671 int distance;
2672 schar dx, dy;
2673 {
2674     uchar typ;
2675     xchar x, y;
2676
2677     x = cc->x;
2678     y = cc->y;
2679     while (distance-- > 0) {
2680         x += dx;
2681         y += dy;
2682         typ = levl[x][y].typ;
2683         if (!isok(x, y) || !ZAP_POS(typ) || closed_door(x, y))
2684             return FALSE;
2685     }
2686     cc->x = x;
2687     cc->y = y;
2688     return TRUE;
2689 }
2690
2691 int
2692 mintrap(mtmp)
2693 register struct monst *mtmp;
2694 {
2695     register struct trap *trap = t_at(mtmp->mx, mtmp->my);
2696     boolean trapkilled = FALSE;
2697     struct permonst *mptr = mtmp->data;
2698     struct obj *otmp;
2699
2700     if (!trap) {
2701         mtmp->mtrapped = 0;      /* perhaps teleported? */
2702     } else if (mtmp->mtrapped) { /* is currently in the trap */
2703         if (!trap->tseen && cansee(mtmp->mx, mtmp->my) && canseemon(mtmp)
2704             && (is_pit(trap->ttyp) || trap->ttyp == BEAR_TRAP
2705                 || trap->ttyp == HOLE
2706                 || trap->ttyp == WEB)) {
2707             /* If you come upon an obviously trapped monster, then
2708              * you must be able to see the trap it's in too.
2709              */
2710             seetrap(trap);
2711         }
2712
2713         if (!rn2(40)) {
2714             if (sobj_at(BOULDER, mtmp->mx, mtmp->my)
2715                 && is_pit(trap->ttyp)) {
2716                 if (!rn2(2)) {
2717                     mtmp->mtrapped = 0;
2718                     if (canseemon(mtmp))
2719 /*JP
2720                         pline("%s pulls free...", Monnam(mtmp));
2721 */
2722                         pline("%s\82Í\8f\95\82¯\8fã\82°\82ç\82ê\82½\81D", Monnam(mtmp));
2723                     fill_pit(mtmp->mx, mtmp->my);
2724                 }
2725             } else {
2726                 mtmp->mtrapped = 0;
2727             }
2728         } else if (metallivorous(mptr)) {
2729             if (trap->ttyp == BEAR_TRAP) {
2730                 if (canseemon(mtmp))
2731 /*JP
2732                     pline("%s eats a bear trap!", Monnam(mtmp));
2733 */
2734                     pline("%s\82Í\8cF\82Ìã©\82ð\90H\82×\82½\81I", Monnam(mtmp));
2735                 deltrap(trap);
2736                 mtmp->meating = 5;
2737                 mtmp->mtrapped = 0;
2738             } else if (trap->ttyp == SPIKED_PIT) {
2739                 if (canseemon(mtmp))
2740 /*JP
2741                     pline("%s munches on some spikes!", Monnam(mtmp));
2742 */
2743                     pline("%s\82Í\83g\83Q\83g\83Q\82ð\90H\82×\82½\81I", Monnam(mtmp));
2744                 trap->ttyp = PIT;
2745                 mtmp->meating = 5;
2746             }
2747         }
2748     } else {
2749         register int tt = trap->ttyp;
2750         boolean in_sight, tear_web, see_it,
2751             inescapable = force_mintrap || ((tt == HOLE || tt == PIT)
2752                                             && Sokoban && !trap->madeby_u);
2753         const char *fallverb;
2754
2755         /* true when called from dotrap, inescapable is not an option */
2756         if (mtmp == u.usteed)
2757             inescapable = TRUE;
2758         if (!inescapable && ((mtmp->mtrapseen & (1 << (tt - 1))) != 0
2759                              || (tt == HOLE && !mindless(mptr)))) {
2760             /* it has been in such a trap - perhaps it escapes */
2761             if (rn2(4))
2762                 return 0;
2763         } else {
2764             mtmp->mtrapseen |= (1 << (tt - 1));
2765         }
2766         /* Monster is aggravated by being trapped by you.
2767            Recognizing who made the trap isn't completely
2768            unreasonable; everybody has their own style. */
2769         if (trap->madeby_u && rnl(5))
2770             setmangry(mtmp, TRUE);
2771
2772         in_sight = canseemon(mtmp);
2773         see_it = cansee(mtmp->mx, mtmp->my);
2774         /* assume hero can tell what's going on for the steed */
2775         if (mtmp == u.usteed)
2776             in_sight = TRUE;
2777         switch (tt) {
2778         case ARROW_TRAP:
2779             if (trap->once && trap->tseen && !rn2(15)) {
2780                 if (in_sight && see_it)
2781 #if 0 /*JP:T*/
2782                     pline("%s triggers a trap but nothing happens.",
2783                           Monnam(mtmp));
2784 #else
2785                     pline("%s\82ª\82í\82È\82ð\8bN\93®\82³\82¹\82½\82ª\89½\82à\8bN\82±\82ç\82È\82©\82Á\82½\81D",
2786                           Monnam(mtmp));
2787 #endif
2788                 deltrap(trap);
2789                 newsym(mtmp->mx, mtmp->my);
2790                 break;
2791             }
2792             trap->once = 1;
2793             otmp = t_missile(ARROW, trap);
2794             if (in_sight)
2795                 seetrap(trap);
2796             if (thitm(8, mtmp, otmp, 0, FALSE))
2797                 trapkilled = TRUE;
2798             break;
2799         case DART_TRAP:
2800             if (trap->once && trap->tseen && !rn2(15)) {
2801                 if (in_sight && see_it)
2802 #if 0 /*JP:T*/
2803                     pline("%s triggers a trap but nothing happens.",
2804                           Monnam(mtmp));
2805 #else
2806                     pline("%s\82ª\82í\82È\82ð\8bN\93®\82³\82¹\82½\82ª\89½\82à\8bN\82±\82ç\82È\82©\82Á\82½\81D",
2807                           Monnam(mtmp));
2808 #endif
2809                 deltrap(trap);
2810                 newsym(mtmp->mx, mtmp->my);
2811                 break;
2812             }
2813             trap->once = 1;
2814             otmp = t_missile(DART, trap);
2815             if (!rn2(6))
2816                 otmp->opoisoned = 1;
2817             if (in_sight)
2818                 seetrap(trap);
2819             if (thitm(7, mtmp, otmp, 0, FALSE))
2820                 trapkilled = TRUE;
2821             break;
2822         case ROCKTRAP:
2823             if (trap->once && trap->tseen && !rn2(15)) {
2824                 if (in_sight && see_it)
2825                     pline(
2826 /*JP
2827                         "A trap door above %s opens, but nothing falls out!",
2828 */
2829                         "%s\82Ì\8fã\82Ì\94à\82ª\8aJ\82¢\82½\82ª\81C\89½\82à\97\8e\82¿\82Ä\82±\82È\82©\82Á\82½\81I",
2830                         mon_nam(mtmp));
2831                 deltrap(trap);
2832                 newsym(mtmp->mx, mtmp->my);
2833                 break;
2834             }
2835             trap->once = 1;
2836             otmp = t_missile(ROCK, trap);
2837             if (in_sight)
2838                 seetrap(trap);
2839             if (thitm(0, mtmp, otmp, d(2, 6), FALSE))
2840                 trapkilled = TRUE;
2841             break;
2842         case SQKY_BOARD:
2843             if (is_flyer(mptr))
2844                 break;
2845             /* stepped on a squeaky board */
2846             if (in_sight) {
2847                 if (!Deaf) {
2848 #if 0 /*JP*/
2849                     pline("A board beneath %s squeaks %s loudly.",
2850                           mon_nam(mtmp), trapnote(trap, 0));
2851 #else
2852                     pline("%s\82Ì\91«\8c³\82Ì\94Â\82ª\91å\82«\82­%s\82É\82«\82µ\82ñ\82¾\81D",
2853                           mon_nam(mtmp), trapnote(trap, 0));
2854 #endif
2855                     seetrap(trap);
2856                 } else {
2857 /*JP
2858                     pline("%s stops momentarily and appears to cringe.",
2859 */
2860                     pline("%s\82Í\88ê\8fu\8e~\82Ü\82Á\82Ä\90g\82ð\82·\82­\82ß\82½\82æ\82¤\82¾\81D",
2861                           Monnam(mtmp));
2862                 }
2863             } else {
2864                 /* same near/far threshold as mzapmsg() */
2865                 int range = couldsee(mtmp->mx, mtmp->my) /* 9 or 5 */
2866                                ? (BOLT_LIM + 1) : (BOLT_LIM - 3);
2867
2868 #if 0 /*JP*/
2869                 You_hear("a %s squeak %s.", trapnote(trap, 1),
2870                          (distu(mtmp->mx, mtmp->my) <= range * range)
2871                             ? "nearby" : "in the distance");
2872 #else
2873                 You_hear("%s\82­\82Å%s\82ª\82«\82µ\82Þ\89¹\82ð\95·\82¢\82½\81D",
2874                          (distu(mtmp->mx, mtmp->my) <= range * range)
2875                             ? "\8bß" : "\89\93",
2876                          trapnote(trap, 1));
2877 #endif
2878             }
2879             /* wake up nearby monsters */
2880             wake_nearto(mtmp->mx, mtmp->my, 40);
2881             break;
2882         case BEAR_TRAP:
2883             if (mptr->msize > MZ_SMALL && !amorphous(mptr) && !is_flyer(mptr)
2884                 && !is_whirly(mptr) && !unsolid(mptr)) {
2885                 mtmp->mtrapped = 1;
2886                 if (in_sight) {
2887 #if 0 /*JP*/
2888                     pline("%s is caught in %s bear trap!", Monnam(mtmp),
2889                           a_your[trap->madeby_u]);
2890 #else
2891                     pline("%s\82Í%s\8cF\82Ìã©\82É\82Â\82©\82Ü\82Á\82½\81I", Monnam(mtmp),
2892                           set_you[trap->madeby_u]);
2893 #endif
2894                     seetrap(trap);
2895                 } else {
2896                     if (mptr == &mons[PM_OWLBEAR]
2897                         || mptr == &mons[PM_BUGBEAR])
2898 /*JP
2899                         You_hear("the roaring of an angry bear!");
2900 */
2901                         You_hear("\93{\82è\82Ì\99ô\9aK\82ð\95·\82¢\82½\81I");
2902                 }
2903             } else if (force_mintrap) {
2904                 if (in_sight) {
2905 #if 0 /*JP*/
2906                     pline("%s evades %s bear trap!", Monnam(mtmp),
2907                           a_your[trap->madeby_u]);
2908 #else
2909                     pline("%s\82Í%s\8cF\82Ìã©\82ð\82½\82­\82Ý\82É\94ð\82¯\82½\81I", Monnam(mtmp),
2910                           set_you[trap->madeby_u]);
2911 #endif
2912                     seetrap(trap);
2913                 }
2914             }
2915             if (mtmp->mtrapped)
2916                 trapkilled = thitm(0, mtmp, (struct obj *) 0, d(2, 4), FALSE);
2917             break;
2918         case SLP_GAS_TRAP:
2919             if (!resists_sleep(mtmp) && !breathless(mptr) && !mtmp->msleeping
2920                 && mtmp->mcanmove) {
2921                 if (sleep_monst(mtmp, rnd(25), -1) && in_sight) {
2922 /*JP
2923                     pline("%s suddenly falls asleep!", Monnam(mtmp));
2924 */
2925                     pline("%s\82Í\93Ë\91R\96°\82è\82É\97\8e\82¿\82½\81I", Monnam(mtmp));
2926                     seetrap(trap);
2927                 }
2928             }
2929             break;
2930         case RUST_TRAP: {
2931             struct obj *target;
2932
2933             if (in_sight)
2934                 seetrap(trap);
2935             switch (rn2(5)) {
2936             case 0:
2937                 if (in_sight)
2938 #if 0 /*JP*/
2939                     pline("%s %s on the %s!", A_gush_of_water_hits,
2940                           mon_nam(mtmp), mbodypart(mtmp, HEAD));
2941 #else
2942                     pline("\90\85\82ª\95¬\8fo\82µ\82Ä\81C%s\82Ì%s\82É\96½\92\86\82µ\82½\81I", 
2943                           mon_nam(mtmp), mbodypart(mtmp, HEAD));
2944 #endif
2945                 target = which_armor(mtmp, W_ARMH);
2946                 (void) water_damage(target, helm_simple_name(target), TRUE);
2947                 break;
2948             case 1:
2949                 if (in_sight)
2950 #if 0 /*JP*/
2951                     pline("%s %s's left %s!", A_gush_of_water_hits,
2952                           mon_nam(mtmp), mbodypart(mtmp, ARM));
2953 #else
2954                     pline("\90\85\82ª\95¬\8fo\82µ\82Ä\81C%s\82Ì\8d¶%s\82É\96½\92\86\82µ\82½\81I",
2955                           mon_nam(mtmp), mbodypart(mtmp, ARM));
2956 #endif
2957                 target = which_armor(mtmp, W_ARMS);
2958 /*JP
2959                 if (water_damage(target, "shield", TRUE) != ER_NOTHING)
2960 */
2961                 if (water_damage(target, "\8f\82", TRUE) != ER_NOTHING)
2962                     break;
2963                 target = MON_WEP(mtmp);
2964                 if (target && bimanual(target))
2965                     (void) water_damage(target, 0, TRUE);
2966             glovecheck:
2967                 target = which_armor(mtmp, W_ARMG);
2968 /*JP
2969                 (void) water_damage(target, "gauntlets", TRUE);
2970 */
2971                 (void) water_damage(target, "\8f¬\8eè", TRUE);
2972                 break;
2973             case 2:
2974                 if (in_sight)
2975 #if 0 /*JP*/
2976                     pline("%s %s's right %s!", A_gush_of_water_hits,
2977                           mon_nam(mtmp), mbodypart(mtmp, ARM));
2978 #else
2979                     pline("\90\85\82ª\95¬\8fo\82µ\82Ä\81C%s\82Ì\89E%s\82É\96½\92\86\82µ\82½\81I",
2980                           mon_nam(mtmp), mbodypart(mtmp, ARM));
2981 #endif
2982                 (void) water_damage(MON_WEP(mtmp), 0, TRUE);
2983                 goto glovecheck;
2984             default:
2985                 if (in_sight)
2986 /*JP
2987                     pline("%s %s!", A_gush_of_water_hits, mon_nam(mtmp));
2988 */
2989                     pline("\90\85\82ª\95¬\8fo\82µ\82Ä\81C%s\82É\96½\92\86\82µ\82½\81I", mon_nam(mtmp));
2990                 for (otmp = mtmp->minvent; otmp; otmp = otmp->nobj)
2991                     if (otmp->lamplit
2992                         && (otmp->owornmask & (W_WEP | W_SWAPWEP)) == 0)
2993                         (void) snuff_lit(otmp);
2994                 if ((target = which_armor(mtmp, W_ARMC)) != 0)
2995                     (void) water_damage(target, cloak_simple_name(target),
2996                                         TRUE);
2997                 else if ((target = which_armor(mtmp, W_ARM)) != 0)
2998                     (void) water_damage(target, suit_simple_name(target),
2999                                         TRUE);
3000                 else if ((target = which_armor(mtmp, W_ARMU)) != 0)
3001 /*JP
3002                     (void) water_damage(target, "shirt", TRUE);
3003 */
3004                     (void) water_damage(target, "\83V\83\83\83c", TRUE);
3005             }
3006
3007             if (mptr == &mons[PM_IRON_GOLEM]) {
3008                 if (in_sight)
3009 /*JP
3010                     pline("%s falls to pieces!", Monnam(mtmp));
3011 */
3012                     pline("%s\82Í\82­\82¾\82¯\82¿\82Á\82½\81I", Monnam(mtmp));
3013                 else if (mtmp->mtame)
3014 /*JP
3015                     pline("May %s rust in peace.", mon_nam(mtmp));
3016 */
3017                     pline("%s\82æ\81C\88À\82ç\82©\82É\8eK\82Ñ\82ñ\8e\96\82ð\81D", mon_nam(mtmp));
3018                 mondied(mtmp);
3019                 if (DEADMONSTER(mtmp))
3020                     trapkilled = TRUE;
3021             } else if (mptr == &mons[PM_GREMLIN] && rn2(3)) {
3022                 (void) split_mon(mtmp, (struct monst *) 0);
3023             }
3024             break;
3025         } /* RUST_TRAP */
3026         case FIRE_TRAP:
3027         mfiretrap:
3028             if (in_sight)
3029 #if 0 /*JP*/
3030                 pline("A %s erupts from the %s under %s!", tower_of_flame,
3031                       surface(mtmp->mx, mtmp->my), mon_nam(mtmp));
3032 #else
3033                 pline("\89Î\92\8c\82ª%s\82Ì\91«\8c³\82Ì%s\82©\82ç\97§\82¿\82Ì\82Ú\82Á\82½\81I",
3034                       mon_nam(mtmp), surface(mtmp->mx,mtmp->my));
3035 #endif
3036             else if (see_it) /* evidently `mtmp' is invisible */
3037 #if 0 /*JP*/
3038                 You_see("a %s erupt from the %s!", tower_of_flame,
3039                         surface(mtmp->mx, mtmp->my));
3040 #else
3041                 You("\89Î\92\8c\82ª%s\82©\82ç\90\82\82é\82Ì\82ð\8c©\82½\81I",
3042                     surface(mtmp->mx,mtmp->my));
3043 #endif
3044
3045             if (resists_fire(mtmp)) {
3046                 if (in_sight) {
3047                     shieldeff(mtmp->mx, mtmp->my);
3048 /*JP
3049                     pline("%s is uninjured.", Monnam(mtmp));
3050 */
3051                     pline("\82ª\81C%s\82Í\8f\9d\82Â\82©\82È\82¢\81D", Monnam(mtmp));
3052                 }
3053             } else {
3054                 int num = d(2, 4), alt;
3055                 boolean immolate = FALSE;
3056
3057                 /* paper burns very fast, assume straw is tightly
3058                  * packed and burns a bit slower */
3059                 switch (monsndx(mptr)) {
3060                 case PM_PAPER_GOLEM:
3061                     immolate = TRUE;
3062                     alt = mtmp->mhpmax;
3063                     break;
3064                 case PM_STRAW_GOLEM:
3065                     alt = mtmp->mhpmax / 2;
3066                     break;
3067                 case PM_WOOD_GOLEM:
3068                     alt = mtmp->mhpmax / 4;
3069                     break;
3070                 case PM_LEATHER_GOLEM:
3071                     alt = mtmp->mhpmax / 8;
3072                     break;
3073                 default:
3074                     alt = 0;
3075                     break;
3076                 }
3077                 if (alt > num)
3078                     num = alt;
3079
3080                 if (thitm(0, mtmp, (struct obj *) 0, num, immolate))
3081                     trapkilled = TRUE;
3082                 else
3083                     /* we know mhp is at least `num' below mhpmax,
3084                        so no (mhp > mhpmax) check is needed here */
3085                     mtmp->mhpmax -= rn2(num + 1);
3086             }
3087             if (burnarmor(mtmp) || rn2(3)) {
3088                 (void) destroy_mitem(mtmp, SCROLL_CLASS, AD_FIRE);
3089                 (void) destroy_mitem(mtmp, SPBOOK_CLASS, AD_FIRE);
3090                 (void) destroy_mitem(mtmp, POTION_CLASS, AD_FIRE);
3091             }
3092             if (burn_floor_objects(mtmp->mx, mtmp->my, see_it, FALSE)
3093                 && !see_it && distu(mtmp->mx, mtmp->my) <= 3 * 3)
3094 /*JP
3095                 You("smell smoke.");
3096 */
3097                 pline("\89\8c\82Ì\93õ\82¢\82ª\82µ\82½\81D");
3098             if (is_ice(mtmp->mx, mtmp->my))
3099                 melt_ice(mtmp->mx, mtmp->my, (char *) 0);
3100             if (see_it && t_at(mtmp->mx, mtmp->my))
3101                 seetrap(trap);
3102             break;
3103         case PIT:
3104         case SPIKED_PIT:
3105 /*JP
3106             fallverb = "falls";
3107 */
3108             fallverb = "\97\8e\82¿\82½";
3109             if (is_flyer(mptr) || is_floater(mptr)
3110                 || (mtmp->wormno && count_wsegs(mtmp) > 5)
3111                 || is_clinger(mptr)) {
3112                 if (force_mintrap && !Sokoban) {
3113                     /* openfallingtrap; not inescapable here */
3114                     if (in_sight) {
3115                         seetrap(trap);
3116 /*JP
3117                         pline("%s doesn't fall into the pit.", Monnam(mtmp));
3118 */
3119                         pline("%s\82Í\97\8e\82µ\8c\8a\82É\97\8e\82¿\82È\82©\82Á\82½\81D", Monnam(mtmp));
3120                     }
3121                     break; /* inescapable = FALSE; */
3122                 }
3123                 if (!inescapable)
3124                     break;               /* avoids trap */
3125 #if 0 /*JP*/
3126                 fallverb = "is dragged"; /* sokoban pit */
3127 #else
3128                 fallverb = "\82¸\82è\97\8e\82¿\82½"; /* sokoban pit */
3129 #endif
3130             }
3131             if (!passes_walls(mptr))
3132                 mtmp->mtrapped = 1;
3133             if (in_sight) {
3134 #if 0 /*JP*/
3135                 pline("%s %s into %s pit!", Monnam(mtmp), fallverb,
3136                       a_your[trap->madeby_u]);
3137 #else
3138                 pline("%s\82Í%s\97\8e\82µ\8c\8a\82É%s\81I", Monnam(mtmp),
3139                       set_you[trap->madeby_u], fallverb);
3140 #endif
3141                 if (mptr == &mons[PM_PIT_VIPER]
3142                     || mptr == &mons[PM_PIT_FIEND])
3143 /*JP
3144                     pline("How pitiful.  Isn't that the pits?");
3145 */
3146                     pline("\82±\82Ì\97\8e\82µ\8c\8a\82Í\82¢\82¢\8ed\8e\96\82ð\82µ\82Ä\82¢\82é\81D");
3147                 seetrap(trap);
3148             }
3149 /*JP
3150             mselftouch(mtmp, "Falling, ", FALSE);
3151 */
3152             mselftouch(mtmp, "\97\8e\89º\92\86\81C", FALSE);
3153             if (DEADMONSTER(mtmp) || thitm(0, mtmp, (struct obj *) 0,
3154                                         rnd((tt == PIT) ? 6 : 10), FALSE))
3155                 trapkilled = TRUE;
3156             break;
3157         case HOLE:
3158         case TRAPDOOR:
3159             if (!Can_fall_thru(&u.uz)) {
3160                 impossible("mintrap: %ss cannot exist on this level.",
3161                            defsyms[trap_to_defsym(tt)].explanation);
3162                 break; /* don't activate it after all */
3163             }
3164             if (is_flyer(mptr) || is_floater(mptr) || mptr == &mons[PM_WUMPUS]
3165                 || (mtmp->wormno && count_wsegs(mtmp) > 5)
3166                 || mptr->msize >= MZ_HUGE) {
3167                 if (force_mintrap && !Sokoban) {
3168                     /* openfallingtrap; not inescapable here */
3169                     if (in_sight) {
3170                         seetrap(trap);
3171                         if (tt == TRAPDOOR)
3172                             pline(
3173 /*JP
3174                             "A trap door opens, but %s doesn't fall through.",
3175 */
3176                             "\97\8e\82µ\94à\82ª\8aJ\82¢\82½\82ª\81C%s\82Í\97\8e\82¿\82È\82©\82Á\82½\81D",
3177                                   mon_nam(mtmp));
3178                         else /* (tt == HOLE) */
3179 /*JP
3180                             pline("%s doesn't fall through the hole.",
3181 */
3182                             pline("%s\82Í\8c\8a\82É\97\8e\82¿\82È\82©\82Á\82½\81D",
3183                                   Monnam(mtmp));
3184                     }
3185                     break; /* inescapable = FALSE; */
3186                 }
3187                 if (inescapable) { /* sokoban hole */
3188                     if (in_sight) {
3189 /*JP
3190                         pline("%s seems to be yanked down!", Monnam(mtmp));
3191 */
3192                         pline("%s\82Í\88ø\82«\97\8e\82³\82ê\82½\82æ\82¤\82¾\81I", Monnam(mtmp));
3193                         /* suppress message in mlevel_tele_trap() */
3194                         in_sight = FALSE;
3195                         seetrap(trap);
3196                     }
3197                 } else
3198                     break;
3199             }
3200             /*FALLTHRU*/
3201         case LEVEL_TELEP:
3202         case MAGIC_PORTAL: {
3203             int mlev_res;
3204
3205             mlev_res = mlevel_tele_trap(mtmp, trap, inescapable, in_sight);
3206             if (mlev_res)
3207                 return mlev_res;
3208             break;
3209         }
3210         case TELEP_TRAP:
3211             mtele_trap(mtmp, trap, in_sight);
3212             break;
3213         case WEB:
3214             /* Monster in a web. */
3215             if (webmaker(mptr))
3216                 break;
3217             if (mu_maybe_destroy_web(mtmp, in_sight, trap))
3218                 break;
3219             tear_web = FALSE;
3220             switch (monsndx(mptr)) {
3221             case PM_OWLBEAR: /* Eric Backus */
3222             case PM_BUGBEAR:
3223                 if (!in_sight) {
3224 /*JP
3225                     You_hear("the roaring of a confused bear!");
3226 */
3227                     You_hear("\8d¬\97\90\82Ì\99ô\9aK\82ð\95·\82¢\82½\81I");
3228                     mtmp->mtrapped = 1;
3229                     break;
3230                 }
3231                 /*FALLTHRU*/
3232             default:
3233                 if (mptr->mlet == S_GIANT
3234                     /* exclude baby dragons and relatively short worms */
3235                     || (mptr->mlet == S_DRAGON && extra_nasty(mptr))
3236                     || (mtmp->wormno && count_wsegs(mtmp) > 5)) {
3237                     tear_web = TRUE;
3238                 } else if (in_sight) {
3239 #if 0 /*JP*/
3240                     pline("%s is caught in %s spider web.", Monnam(mtmp),
3241                           a_your[trap->madeby_u]);
3242 #else
3243                     pline("%s\82Í%s\82­\82à\82Ì\91\83\82É\82Â\82©\82Ü\82Á\82½\81D", Monnam(mtmp),
3244                           web_you[trap->madeby_u]);
3245 #endif
3246                     seetrap(trap);
3247                 }
3248                 mtmp->mtrapped = tear_web ? 0 : 1;
3249                 break;
3250             /* this list is fairly arbitrary; it deliberately
3251                excludes wumpus & giant/ettin zombies/mummies */
3252             case PM_TITANOTHERE:
3253             case PM_BALUCHITHERIUM:
3254             case PM_PURPLE_WORM:
3255             case PM_JABBERWOCK:
3256             case PM_IRON_GOLEM:
3257             case PM_BALROG:
3258             case PM_KRAKEN:
3259             case PM_MASTODON:
3260             case PM_ORION:
3261             case PM_NORN:
3262             case PM_CYCLOPS:
3263             case PM_LORD_SURTUR:
3264                 tear_web = TRUE;
3265                 break;
3266             }
3267             if (tear_web) {
3268                 if (in_sight)
3269 #if 0 /*JP*/
3270                     pline("%s tears through %s spider web!", Monnam(mtmp),
3271                           a_your[trap->madeby_u]);
3272 #else
3273                     pline("%s\82Í%s\82­\82à\82Ì\91\83\82ð\88ø\82«\97ô\82¢\82½\81I", Monnam(mtmp),
3274                           web_you[trap->madeby_u]);
3275 #endif
3276                 deltrap(trap);
3277                 newsym(mtmp->mx, mtmp->my);
3278             } else if (force_mintrap && !mtmp->mtrapped) {
3279                 if (in_sight) {
3280 #if 0 /*JP*/
3281                     pline("%s avoids %s spider web!", Monnam(mtmp),
3282                           a_your[trap->madeby_u]);
3283 #else
3284                     pline("%s\82Í%s\82­\82à\82Ì\91\83\82ð\94ð\82¯\82½\81I", Monnam(mtmp),
3285                           web_you[trap->madeby_u]);
3286 #endif
3287                     seetrap(trap);
3288                 }
3289             }
3290             break;
3291         case STATUE_TRAP:
3292             break;
3293         case MAGIC_TRAP:
3294             /* A magic trap.  Monsters usually immune. */
3295             if (!rn2(21))
3296                 goto mfiretrap;
3297             break;
3298         case ANTI_MAGIC:
3299             /* similar to hero's case, more or less */
3300             if (!resists_magm(mtmp)) { /* lose spell energy */
3301                 if (!mtmp->mcan && (attacktype(mptr, AT_MAGC)
3302                                     || attacktype(mptr, AT_BREA))) {
3303                     mtmp->mspec_used += d(2, 2);
3304                     if (in_sight) {
3305                         seetrap(trap);
3306 /*JP
3307                         pline("%s seems lethargic.", Monnam(mtmp));
3308 */
3309                         pline("%s\88ê\8fu\96³\8bC\97Í\8a´\82ð\8a´\82\82½\81D", Monnam(mtmp));
3310                     }
3311                 }
3312             } else { /* take some damage */
3313                 int dmgval2 = rnd(4);
3314
3315                 if ((otmp = MON_WEP(mtmp)) != 0
3316                     && otmp->oartifact == ART_MAGICBANE)
3317                     dmgval2 += rnd(4);
3318                 for (otmp = mtmp->minvent; otmp; otmp = otmp->nobj)
3319                     if (otmp->oartifact
3320                         && defends_when_carried(AD_MAGM, otmp))
3321                         break;
3322                 if (otmp)
3323                     dmgval2 += rnd(4);
3324                 if (passes_walls(mptr))
3325                     dmgval2 = (dmgval2 + 3) / 4;
3326
3327                 if (in_sight)
3328                     seetrap(trap);
3329                 mtmp->mhp -= dmgval2;
3330                 if (DEADMONSTER(mtmp))
3331                     monkilled(mtmp,
3332                               in_sight
3333 /*JP
3334                                   ? "compression from an anti-magic field"
3335 */
3336                                   ? "\94½\96\82\96@\8bó\8aÔ\82Ì\88³\8fk"
3337                                   : (const char *) 0,
3338                               -AD_MAGM);
3339                 if (DEADMONSTER(mtmp))
3340                     trapkilled = TRUE;
3341                 if (see_it)
3342                     newsym(trap->tx, trap->ty);
3343             }
3344             break;
3345         case LANDMINE:
3346             if (rn2(3))
3347                 break; /* monsters usually don't set it off */
3348             if (is_flyer(mptr)) {
3349                 boolean already_seen = trap->tseen;
3350
3351                 if (in_sight && !already_seen) {
3352 /*JP
3353                     pline("A trigger appears in a pile of soil below %s.",
3354 */
3355                     pline("%s\82Ì\91«\8c³\82Ì\93y\82Ì\8eR\82É\8bN\94\9a\83X\83C\83b\83`\82ª\8c»\82í\82ê\82½\81D",
3356                           mon_nam(mtmp));
3357                     seetrap(trap);
3358                 }
3359                 if (rn2(3))
3360                     break;
3361                 if (in_sight) {
3362                     newsym(mtmp->mx, mtmp->my);
3363 #if 0 /*JP*/
3364                     pline_The("air currents set %s off!",
3365                               already_seen ? "a land mine" : "it");
3366 #else
3367                     pline("\8bó\8bC\82Ì\97¬\82ê\82Å\83X\83C\83b\83`\82ª\93ü\82Á\82½\81I");
3368 #endif
3369                 }
3370             } else if (in_sight) {
3371                 newsym(mtmp->mx, mtmp->my);
3372 #if 0 /*JP*/
3373                 pline("%s%s triggers %s land mine!",
3374                       !Deaf ? "KAABLAMM!!!  " : "", Monnam(mtmp),
3375                       a_your[trap->madeby_u]);
3376 #else
3377                 pline("%s%s\82Í%s\92n\97\8b\82Ì\8bN\94\9a\83X\83C\83b\83`\82ð\93¥\82ñ\82¾\81I",
3378                       !Deaf ? "\82¿\82ã\82Ç\81[\82ñ\81I\81I" : "", Monnam(mtmp),
3379                       set_you[trap->madeby_u]);
3380 #endif
3381             }
3382             if (!in_sight && !Deaf)
3383 /*JP
3384                 pline("Kaablamm!  You hear an explosion in the distance!");
3385 */
3386                 pline("\82¿\82ã\82Ç\81[\82ñ\81I\82 \82È\82½\82Í\89\93\95û\82Ì\94\9a\94­\89¹\82ð\95·\82¢\82½\81I");
3387             blow_up_landmine(trap);
3388             /* explosion might have destroyed a drawbridge; don't
3389                dish out more damage if monster is already dead */
3390             if (DEADMONSTER(mtmp)
3391                 || thitm(0, mtmp, (struct obj *) 0, rnd(16), FALSE)) {
3392                 trapkilled = TRUE;
3393             } else {
3394                 /* monsters recursively fall into new pit */
3395                 if (mintrap(mtmp) == 2)
3396                     trapkilled = TRUE;
3397             }
3398             /* a boulder may fill the new pit, crushing monster */
3399             fill_pit(trap->tx, trap->ty);
3400             if (DEADMONSTER(mtmp))
3401                 trapkilled = TRUE;
3402             if (unconscious()) {
3403                 multi = -1;
3404 /*JP
3405                 nomovemsg = "The explosion awakens you!";
3406 */
3407                 nomovemsg = "\94\9a\94­\82Å\82 \82È\82½\82Í\8bN\82«\82½\81I";
3408             }
3409             break;
3410         case POLY_TRAP:
3411             if (resists_magm(mtmp)) {
3412                 shieldeff(mtmp->mx, mtmp->my);
3413             } else if (!resist(mtmp, WAND_CLASS, 0, NOTELL)) {
3414                 if (newcham(mtmp, (struct permonst *) 0, FALSE, FALSE))
3415                     /* we're done with mptr but keep it up to date */
3416                     mptr = mtmp->data;
3417                 if (in_sight)
3418                     seetrap(trap);
3419             }
3420             break;
3421         case ROLLING_BOULDER_TRAP:
3422             if (!is_flyer(mptr)) {
3423                 int style = ROLL | (in_sight ? 0 : LAUNCH_UNSEEN);
3424
3425                 newsym(mtmp->mx, mtmp->my);
3426                 if (in_sight)
3427 #if 0 /*JP*/
3428                     pline("Click!  %s triggers %s.", Monnam(mtmp),
3429                           trap->tseen ? "a rolling boulder trap" : something);
3430 #else
3431                     pline("\83J\83`\83b\81I%s\82Í%s\82Ì\83X\83C\83b\83`\82ð\93¥\82ñ\82¾\81I", Monnam(mtmp),
3432                           trap->tseen ? "\97\8e\8aâ\82Ìã©" : "\89½\82©");
3433 #endif
3434                 if (launch_obj(BOULDER, trap->launch.x, trap->launch.y,
3435                                trap->launch2.x, trap->launch2.y, style)) {
3436                     if (in_sight)
3437                         trap->tseen = TRUE;
3438                     if (DEADMONSTER(mtmp))
3439                         trapkilled = TRUE;
3440                 } else {
3441                     deltrap(trap);
3442                     newsym(mtmp->mx, mtmp->my);
3443                 }
3444             }
3445             break;
3446         case VIBRATING_SQUARE:
3447             if (see_it && !Blind) {
3448                 seetrap(trap); /* before messages */
3449                 if (in_sight) {
3450 #if 0 /*JP*/
3451                     char buf[BUFSZ], *p, *monnm = mon_nam(mtmp);
3452
3453                     if (nolimbs(mtmp->data)
3454                         || is_floater(mtmp->data) || is_flyer(mtmp->data)) {
3455                         /* just "beneath <mon>" */
3456                         Strcpy(buf, monnm);
3457                     } else {
3458                         Strcpy(buf, s_suffix(monnm));
3459                         p = eos(strcat(buf, " "));
3460                         Strcpy(p, makeplural(mbodypart(mtmp, FOOT)));
3461                         /* avoid "beneath 'rear paws'" or 'rear hooves' */
3462                         (void) strsubst(p, "rear ", "");
3463                     }
3464                     You_see("a strange vibration beneath %s.", buf);
3465 #else /* \91«\82ª\82È\82­\82Ä\82à\81u\91«\8c³\81v\82Å\93\9d\88ê */
3466                     You_see("%s\82Ì\91«\8c³\82ª\95s\8ev\8bc\82É\90U\93®\82µ\82Ä\82¢\82é\82Ì\82ð\8c©\82½\81D",
3467                             mon_nam(mtmp));
3468 #endif
3469                 } else {
3470                     /* notice something (hearing uses a larger threshold
3471                        for 'nearby') */
3472 #if 0 /*JP:T*/
3473                     You_see("the ground vibrate %s.",
3474                             (distu(mtmp->mx, mtmp->my) <= 2 * 2)
3475                                ? "nearby" : "in the distance");
3476 #else
3477                     You_see("%s\82­\82Å\92n\96Ê\82ª\90U\93®\82µ\82Ä\82¢\82é\82Ì\82ð\8c©\82½\81D",
3478                             (distu(mtmp->mx, mtmp->my) <= 2 * 2)
3479                                ? "\8bß" : "\89\93");
3480 #endif
3481                 }
3482             }
3483             break;
3484         default:
3485             impossible("Some monster encountered a strange trap of type %d.",
3486                        tt);
3487         }
3488     }
3489     if (trapkilled)
3490         return 2;
3491     return mtmp->mtrapped;
3492 }
3493
3494 /* Combine cockatrice checks into single functions to avoid repeating code. */
3495 void
3496 instapetrify(str)
3497 const char *str;
3498 {
3499     if (Stone_resistance)
3500         return;
3501     if (poly_when_stoned(youmonst.data) && polymon(PM_STONE_GOLEM))
3502         return;
3503 /*JP
3504     You("turn to stone...");
3505 */
3506     You("\90Î\82É\82È\82Á\82½\81D\81D\81D");
3507     killer.format = KILLED_BY;
3508     if (str != killer.name)
3509         Strcpy(killer.name, str ? str : "");
3510     done(STONING);
3511 }
3512
3513 void
3514 minstapetrify(mon, byplayer)
3515 struct monst *mon;
3516 boolean byplayer;
3517 {
3518     if (resists_ston(mon))
3519         return;
3520     if (poly_when_stoned(mon->data)) {
3521         mon_to_stone(mon);
3522         return;
3523     }
3524     if (!vamp_stone(mon))
3525         return;
3526
3527     /* give a "<mon> is slowing down" message and also remove
3528        intrinsic speed (comparable to similar effect on the hero) */
3529     mon_adjust_speed(mon, -3, (struct obj *) 0);
3530
3531     if (cansee(mon->mx, mon->my))
3532 /*JP
3533         pline("%s turns to stone.", Monnam(mon));
3534 */
3535         pline("%s\82Í\90Î\82É\82È\82Á\82½\81D", Monnam(mon));
3536     if (byplayer) {
3537         stoned = TRUE;
3538         xkilled(mon, XKILL_NOMSG);
3539     } else
3540         monstone(mon);
3541 }
3542
3543 void
3544 selftouch(arg)
3545 const char *arg;
3546 {
3547     char kbuf[BUFSZ];
3548
3549     if (uwep && uwep->otyp == CORPSE && touch_petrifies(&mons[uwep->corpsenm])
3550         && !Stone_resistance) {
3551 /*JP
3552         pline("%s touch the %s corpse.", arg, mons[uwep->corpsenm].mname);
3553 */
3554         pline("%s%s\82Ì\8e\80\91Ì\82É\90G\82Á\82½\81D", arg, mons[uwep->corpsenm].mname);
3555 /*JP
3556         Sprintf(kbuf, "%s corpse", an(mons[uwep->corpsenm].mname));
3557 */
3558         Sprintf(kbuf, "%s\82Ì\8e\80\91Ì\82Å", mons[uwep->corpsenm].mname);
3559         instapetrify(kbuf);
3560         /* life-saved; unwield the corpse if we can't handle it */
3561         if (!uarmg && !Stone_resistance)
3562             uwepgone();
3563     }
3564     /* Or your secondary weapon, if wielded [hypothetical; we don't
3565        allow two-weapon combat when either weapon is a corpse] */
3566     if (u.twoweap && uswapwep && uswapwep->otyp == CORPSE
3567         && touch_petrifies(&mons[uswapwep->corpsenm]) && !Stone_resistance) {
3568 /*JP
3569         pline("%s touch the %s corpse.", arg, mons[uswapwep->corpsenm].mname);
3570 */
3571         pline("%s%s\82Ì\8e\80\91Ì\82É\90G\82Á\82½\81D", arg, mons[uswapwep->corpsenm].mname);
3572 /*JP
3573         Sprintf(kbuf, "%s corpse", an(mons[uswapwep->corpsenm].mname));
3574 */
3575         Sprintf(kbuf, "%s\82Ì\8e\80\91Ì\82Å", mons[uswapwep->corpsenm].mname);
3576         instapetrify(kbuf);
3577         /* life-saved; unwield the corpse */
3578         if (!uarmg && !Stone_resistance)
3579             uswapwepgone();
3580     }
3581 }
3582
3583 void
3584 mselftouch(mon, arg, byplayer)
3585 struct monst *mon;
3586 const char *arg;
3587 boolean byplayer;
3588 {
3589     struct obj *mwep = MON_WEP(mon);
3590
3591     if (mwep && mwep->otyp == CORPSE && touch_petrifies(&mons[mwep->corpsenm])
3592         && !resists_ston(mon)) {
3593         if (cansee(mon->mx, mon->my)) {
3594 #if 0 /*JP*/
3595             pline("%s%s touches %s.", arg ? arg : "",
3596                   arg ? mon_nam(mon) : Monnam(mon),
3597                   corpse_xname(mwep, (const char *) 0, CXN_PFX_THE));
3598 #else
3599             pline("%s%s\82Í%s\82Ì\8e\80\91Ì\82É\90G\82Á\82½\81D", arg ? arg : "",
3600                   arg ? mon_nam(mon) : Monnam(mon),
3601                   corpse_xname(mwep, (const char *) 0, CXN_PFX_THE));
3602 #endif
3603         }
3604         minstapetrify(mon, byplayer);
3605         /* if life-saved, might not be able to continue wielding */
3606         if (!DEADMONSTER(mon) && !which_armor(mon, W_ARMG) && !resists_ston(mon))
3607             mwepgone(mon);
3608     }
3609 }
3610
3611 /* start levitating */
3612 void
3613 float_up()
3614 {
3615     context.botl = TRUE;
3616     if (u.utrap) {
3617         if (u.utraptype == TT_PIT) {
3618             reset_utrap(FALSE);
3619 /*JP
3620             You("float up, out of the pit!");
3621 */
3622             You("\95\82\82«\8fã\82ª\82Á\82Ä\81C\97\8e\82µ\8c\8a\82©\82ç\8fo\82½\81I");
3623             vision_full_recalc = 1; /* vision limits change */
3624             fill_pit(u.ux, u.uy);
3625         } else if (u.utraptype == TT_LAVA /* molten lava */
3626                    || u.utraptype == TT_INFLOOR) { /* solidified lava */
3627 /*JP
3628             Your("body pulls upward, but your %s are still stuck.",
3629 */
3630             Your("\91Ì\82Í\88ø\82«\8fã\82°\82ç\82ê\82½\81D\82µ\82©\82µ%s\82Í\82Ü\82¾\82Í\82Ü\82Á\82Ä\82¢\82é\81D",
3631                  makeplural(body_part(LEG)));
3632         } else if (u.utraptype == TT_BURIEDBALL) { /* tethered */
3633             coord cc;
3634
3635             cc.x = u.ux, cc.y = u.uy;
3636             /* caveat: this finds the first buried iron ball within
3637                one step of the specified location, not necessarily the
3638                buried [former] uball at the original anchor point */
3639             (void) buried_ball(&cc);
3640             /* being chained to the floor blocks levitation from floating
3641                above that floor but not from enhancing carrying capacity */
3642             You("feel lighter, but your %s is still chained to the %s.",
3643                 body_part(LEG),
3644                 IS_ROOM(levl[cc.x][cc.y].typ) ? "floor" : "ground");
3645         } else if (u.utraptype == WEB) {
3646             You("float up slightly, but you are still stuck in the web.");
3647         } else { /* bear trap */
3648 /*JP
3649             You("float up slightly, but your %s is still stuck.",
3650 */
3651             You("\8f­\82µ\95\82\82«\8fã\82ª\82Á\82½\82ª%s\82Í\82Ü\82¾\82Í\82Ü\82Á\82Ä\82¢\82é\81D",
3652                 body_part(LEG));
3653         }
3654         /* when still trapped, float_vs_flight() below will block levitation */
3655 #if 0
3656     } else if (Is_waterlevel(&u.uz)) {
3657 /*JP
3658         pline("It feels as though you've lost some weight.");
3659 */
3660         You("\82Ü\82é\82Å\91Ì\8fd\82ª\8c¸\82Á\82½\82æ\82¤\82É\8a´\82\82½\81D");
3661 #endif
3662     } else if (u.uinwater) {
3663         spoteffects(TRUE);
3664     } else if (u.uswallow) {
3665 #if 0 /*JP*/
3666         You(is_animal(u.ustuck->data) ? "float away from the %s."
3667                                       : "spiral up into %s.",
3668             is_animal(u.ustuck->data) ? surface(u.ux, u.uy)
3669                                       : mon_nam(u.ustuck));
3670 #else
3671         You(is_animal(u.ustuck->data) ? "%s\82Ì\92\86\82Å\95\82\82¢\82½\81D"
3672                                       : "%s\82Ì\92\86\82Å\82®\82é\82®\82é\89ñ\93]\82µ\82½\81D",
3673             is_animal(u.ustuck->data) ? surface(u.ux, u.uy)
3674                                       : mon_nam(u.ustuck));
3675 #endif
3676     } else if (Hallucination) {
3677 /*JP
3678         pline("Up, up, and awaaaay!  You're walking on air!");
3679 */
3680         pline("\8fã\82ê\81C\8fã\82ê\81C\8fã\82ê\82¥\82¥\82¥\82¥\81I\82 \82È\82½\82Í\8bó\92\86\82ð\95à\82¢\82Ä\82¢\82é\81I");
3681     } else if (Is_airlevel(&u.uz)) {
3682 /*JP
3683         You("gain control over your movements.");
3684 */
3685         You("\82¤\82Ü\82­\93®\82¯\82é\82æ\82¤\82É\82È\82Á\82½\81D");
3686     } else {
3687 /*JP
3688         You("start to float in the air!");
3689 */
3690         You("\8bó\92\86\82É\95\82\82«\82Í\82\82ß\82½\81I");
3691     }
3692     if (u.usteed && !is_floater(u.usteed->data) && !is_flyer(u.usteed->data)) {
3693         if (Lev_at_will) {
3694 /*JP
3695             pline("%s magically floats up!", Monnam(u.usteed));
3696 */
3697             pline("%s\82Í\96\82\96@\82Ì\97Í\82Å\95\82\82¢\82½\81I", Monnam(u.usteed));
3698         } else {
3699 /*JP
3700             You("cannot stay on %s.", mon_nam(u.usteed));
3701 */
3702             You("%s\82Ì\8fã\82É\8fæ\82Á\82Ä\82¢\82ç\82ê\82È\82¢\81D", mon_nam(u.usteed));
3703             dismount_steed(DISMOUNT_GENERIC);
3704         }
3705     }
3706     if (Flying)
3707 /*JP
3708         You("are no longer able to control your flight.");
3709 */
3710         You("\8bó\92\86\82Å\82¤\82Ü\82­\93®\82¯\82È\82­\82È\82Á\82½\81D");
3711     float_vs_flight(); /* set BFlying, also BLevitation if still trapped */
3712     /* levitation gives maximum carrying capacity, so encumbrance
3713        state might be reduced */
3714     (void) encumber_msg();
3715     return;
3716 }
3717
3718 void
3719 fill_pit(x, y)
3720 int x, y;
3721 {
3722     struct obj *otmp;
3723     struct trap *t;
3724
3725     if ((t = t_at(x, y)) && is_pit(t->ttyp)
3726         && (otmp = sobj_at(BOULDER, x, y))) {
3727         obj_extract_self(otmp);
3728 /*JP
3729         (void) flooreffects(otmp, x, y, "settle");
3730 */
3731         (void) flooreffects(otmp, x, y, "\82Í\82Ü\82é");
3732     }
3733 }
3734
3735 /* stop levitating */
3736 int
3737 float_down(hmask, emask)
3738 long hmask, emask; /* might cancel timeout */
3739 {
3740     register struct trap *trap = (struct trap *) 0;
3741     d_level current_dungeon_level;
3742     boolean no_msg = FALSE;
3743
3744     HLevitation &= ~hmask;
3745     ELevitation &= ~emask;
3746     if (Levitation)
3747         return 0; /* maybe another ring/potion/boots */
3748     if (BLevitation) {
3749         /* if blocked by terrain, we haven't actually been levitating so
3750            we don't give any end-of-levitation feedback or side-effects,
3751            but if blocking is solely due to being trapped in/on floor,
3752            do give some feedback but skip other float_down() effects */
3753         boolean trapped = (BLevitation == I_SPECIAL);
3754
3755         float_vs_flight();
3756         if (trapped && u.utrap) /* u.utrap => paranoia */
3757             You("are no longer trying to float up from the %s.",
3758                 (u.utraptype == TT_BEARTRAP) ? "trap's jaws"
3759                   : (u.utraptype == TT_WEB) ? "web"
3760                       : (u.utraptype == TT_BURIEDBALL) ? "chain"
3761                           : (u.utraptype == TT_LAVA) ? "lava"
3762                               : "ground"); /* TT_INFLOOR */
3763         (void) encumber_msg(); /* carrying capacity might have changed */
3764         return 0;
3765     }
3766     context.botl = TRUE;
3767     nomul(0); /* stop running or resting */
3768     if (BFlying) {
3769         /* controlled flight no longer overridden by levitation */
3770         float_vs_flight(); /* clears BFlying & I_SPECIAL
3771                             * unless hero is stuck in floor */
3772         if (Flying) {
3773 /*JP
3774             You("have stopped levitating and are now flying.");
3775 */
3776             You("\8bó\92\86\95\82\97V\82ð\8e~\82ß\82Ä\8bó\82ð\94ò\82Ñ\82Í\82\82ß\82½\81D");
3777             (void) encumber_msg(); /* carrying capacity might have changed */
3778             return 1;
3779         }
3780     }
3781     if (u.uswallow) {
3782 #if 0 /*JP*/
3783         You("float down, but you are still %s.",
3784             is_animal(u.ustuck->data) ? "swallowed" : "engulfed");
3785 #else
3786         You("\92\85\92n\82µ\82½\82ª\81C\82Ü\82¾\88ù\82Ý\8d\9e\82Ü\82ê\82½\82Ü\82Ü\82¾\81D");
3787 #endif
3788         (void) encumber_msg();
3789         return 1;
3790     }
3791
3792     if (Punished && !carried(uball)
3793         && (is_pool(uball->ox, uball->oy)
3794             || ((trap = t_at(uball->ox, uball->oy))
3795                 && (is_pit(trap->ttyp) || is_hole(trap->ttyp))))) {
3796         u.ux0 = u.ux;
3797         u.uy0 = u.uy;
3798         u.ux = uball->ox;
3799         u.uy = uball->oy;
3800         movobj(uchain, uball->ox, uball->oy);
3801         newsym(u.ux0, u.uy0);
3802         vision_full_recalc = 1; /* in case the hero moved. */
3803     }
3804     /* check for falling into pool - added by GAN 10/20/86 */
3805     if (!Flying) {
3806         if (!u.uswallow && u.ustuck) {
3807             if (sticks(youmonst.data))
3808 #if 0 /*JP:T*/
3809                 You("aren't able to maintain your hold on %s.",
3810                     mon_nam(u.ustuck));
3811 #else
3812                 You("%s\82ð\82Â\82©\82Ü\82¦\91±\82¯\82Ä\82¢\82ç\82ê\82È\82­\82È\82Á\82½\81D",
3813                     mon_nam(u.ustuck));
3814 #endif
3815             else
3816 #if 0 /*JP:T*/
3817                 pline("Startled, %s can no longer hold you!",
3818                       mon_nam(u.ustuck));
3819 #else
3820                 pline("%s\82Í\8bÁ\82¢\82Ä\82 \82È\82½\82ð\95ú\82µ\82Ä\82µ\82Ü\82Á\82½\81I",
3821                       mon_nam(u.ustuck));
3822 #endif
3823             u.ustuck = 0;
3824         }
3825         /* kludge alert:
3826          * drown() and lava_effects() print various messages almost
3827          * every time they're called which conflict with the "fall
3828          * into" message below.  Thus, we want to avoid printing
3829          * confusing, duplicate or out-of-order messages.
3830          * Use knowledge of the two routines as a hack -- this
3831          * should really be handled differently -dlc
3832          */
3833         if (is_pool(u.ux, u.uy) && !Wwalking && !Swimming && !u.uinwater)
3834             no_msg = drown();
3835
3836         if (is_lava(u.ux, u.uy)) {
3837             (void) lava_effects();
3838             no_msg = TRUE;
3839         }
3840     }
3841     if (!trap) {
3842         trap = t_at(u.ux, u.uy);
3843         if (Is_airlevel(&u.uz)) {
3844 /*JP
3845             You("begin to tumble in place.");
3846 */
3847             You("\82»\82Ì\8fê\82Å\82Ð\82Á\82­\82è\95Ô\82è\82Í\82\82ß\82½\81D");
3848         } else if (Is_waterlevel(&u.uz) && !no_msg) {
3849 /*JP
3850             You_feel("heavier.");
3851 */
3852             You("\8fd\82­\82È\82Á\82½\82æ\82¤\82È\8bC\82ª\82µ\82½\81D");
3853         /* u.uinwater msgs already in spoteffects()/drown() */
3854         } else if (!u.uinwater && !no_msg) {
3855             if (!(emask & W_SADDLE)) {
3856                 if (Sokoban && trap) {
3857                     /* Justification elsewhere for Sokoban traps is based
3858                      * on air currents.  This is consistent with that.
3859                      * The unexpected additional force of the air currents
3860                      * once levitation ceases knocks you off your feet.
3861                      */
3862                     if (Hallucination)
3863 /*JP
3864                         pline("Bummer!  You've crashed.");
3865 */
3866                         pline("\82â\82ß\82Ä\82¥\81I\82 \82È\82½\82Í\92@\82«\82Â\82¯\82ç\82ê\82½\81D");
3867                     else
3868 /*JP
3869                         You("fall over.");
3870 */
3871                         You("\82Â\82Ü\82Ã\82¢\82½\81D");
3872 /*JP
3873                     losehp(rnd(2), "dangerous winds", KILLED_BY);
3874 */
3875                     losehp(rnd(2), "\8aë\8c¯\82È\95\97\82Å", KILLED_BY);
3876                     if (u.usteed)
3877                         dismount_steed(DISMOUNT_FELL);
3878 /*JP
3879                     selftouch("As you fall, you");
3880 */
3881                     selftouch("\97\8e\82¿\82È\82ª\82ç\81C\82 \82È\82½\82Í");
3882                 } else if (u.usteed && (is_floater(u.usteed->data)
3883                                         || is_flyer(u.usteed->data))) {
3884 /*JP
3885                     You("settle more firmly in the saddle.");
3886 */
3887                     You("\82æ\82è\82µ\82Á\82©\82è\82Æ\88Æ\82É\94[\82Ü\82Á\82½\81D");
3888                 } else if (Hallucination) {
3889 #if 0 /*JP*/
3890                     pline("Bummer!  You've %s.",
3891                           is_pool(u.ux, u.uy)
3892                              ? "splashed down"
3893                              : "hit the ground");
3894 #else
3895                     pline("\82â\82ß\82Ä\82¥\81I\82 \82È\82½\82Í%s\82É\92@\82«\82Â\82¯\82ç\82ê\82½\81D",
3896                           is_pool(u.ux, u.uy)
3897                              ? "\90\85\96Ê"
3898                              : "\92n\96Ê");
3899 #endif
3900                 } else {
3901 /*JP
3902                     You("float gently to the %s.", surface(u.ux, u.uy));
3903 */
3904                     You("\90Ã\82©\82É%s\82Ü\82Å\92H\82è\82Â\82¢\82½\81D", surface(u.ux, u.uy));
3905                 }
3906             }
3907         }
3908     }
3909
3910     /* levitation gives maximum carrying capacity, so having it end
3911        potentially triggers greater encumbrance; do this after
3912        'come down' messages, before trap activation or autopickup */
3913     (void) encumber_msg();
3914
3915     /* can't rely on u.uz0 for detecting trap door-induced level change;
3916        it gets changed to reflect the new level before we can check it */
3917     assign_level(&current_dungeon_level, &u.uz);
3918     if (trap) {
3919         switch (trap->ttyp) {
3920         case STATUE_TRAP:
3921             break;
3922         case HOLE:
3923         case TRAPDOOR:
3924             if (!Can_fall_thru(&u.uz) || u.ustuck)
3925                 break;
3926             /*FALLTHRU*/
3927         default:
3928             if (!u.utrap) /* not already in the trap */
3929                 dotrap(trap, 0);
3930         }
3931     }
3932     if (!Is_airlevel(&u.uz) && !Is_waterlevel(&u.uz) && !u.uswallow
3933         /* falling through trap door calls goto_level,
3934            and goto_level does its own pickup() call */
3935         && on_level(&u.uz, &current_dungeon_level))
3936         (void) pickup(1);
3937     return 1;
3938 }
3939
3940 /* shared code for climbing out of a pit */
3941 void
3942 climb_pit()
3943 {
3944     if (!u.utrap || u.utraptype != TT_PIT)
3945         return;
3946
3947     if (Passes_walls) {
3948         /* marked as trapped so they can pick things up */
3949 /*JP
3950         You("ascend from the pit.");
3951 */
3952         You("\97\8e\82µ\8c\8a\82ð\8fã\82Á\82Ä\82¢\82Á\82½\81D");
3953         reset_utrap(FALSE);
3954         fill_pit(u.ux, u.uy);
3955         vision_full_recalc = 1; /* vision limits change */
3956     } else if (!rn2(2) && sobj_at(BOULDER, u.ux, u.uy)) {
3957 /*JP
3958         Your("%s gets stuck in a crevice.", body_part(LEG));
3959 */
3960         Your("%s\82Í\8a\84\82ê\96Ú\82É\82Í\82Ü\82Á\82½\81D", body_part(LEG));
3961         display_nhwindow(WIN_MESSAGE, FALSE);
3962         clear_nhwindow(WIN_MESSAGE);
3963 /*JP
3964         You("free your %s.", body_part(LEG));
3965 */
3966         Your("%s\82Í\8e©\97R\82É\82È\82Á\82½\81D", body_part(LEG));
3967     } else if ((Flying || is_clinger(youmonst.data)) && !Sokoban) {
3968         /* eg fell in pit, then poly'd to a flying monster;
3969            or used '>' to deliberately enter it */
3970 /*JP
3971         You("%s from the pit.", Flying ? "fly" : "climb");
3972 */
3973         You("\97\8e\82µ\8c\8a\82©\82ç%s\82¢\82Á\82½\81D", Flying ? "\8fã\82Á\82Ä" : "\93o\82Á\82Ä");
3974         reset_utrap(FALSE);
3975         fill_pit(u.ux, u.uy);
3976         vision_full_recalc = 1; /* vision limits change */
3977     } else if (!(--u.utrap)) {
3978         reset_utrap(FALSE);
3979 #if 0 /*JP:T*/
3980         You("%s to the edge of the pit.",
3981             (Sokoban && Levitation)
3982                 ? "struggle against the air currents and float"
3983                 : u.usteed ? "ride" : "crawl");
3984 #else
3985         You("%s\97\8e\82µ\8c\8a\82Ì\92[\82É\82½\82Ç\82è\92\85\82¢\82½\81D",
3986             (Sokoban && Levitation)
3987                 ? "\8bó\8bC\82Ì\97¬\82ê\82Ì\92\86\82Å\82à\82ª\82«\82È\82ª\82ç" : "");
3988 #endif
3989         fill_pit(u.ux, u.uy);
3990         vision_full_recalc = 1; /* vision limits change */
3991     } else if (u.dz || flags.verbose) {
3992         if (u.usteed)
3993 /*JP
3994             Norep("%s is still in a pit.", upstart(y_monnam(u.usteed)));
3995 */
3996             Norep("%s\82Í\82Ü\82¾\97\8e\82µ\8c\8a\82Ì\92\86\82É\82¢\82é\81D", y_monnam(u.usteed));
3997         else
3998 #if 0 /*JP:T*/
3999             Norep((Hallucination && !rn2(5))
4000                       ? "You've fallen, and you can't get up."
4001                       : "You are still in a pit.");
4002 #else
4003             Norep((Hallucination && !rn2(5))
4004                       ? "\82 \82È\82½\82Í\97\8e\82¿\81C\8fã\82ª\82ê\82È\82¢\81D"
4005                       : "\82 \82È\82½\82Í\82Ü\82¾\97\8e\82µ\8c\8a\82Ì\92\86\82É\82¢\82é\81D");
4006 #endif
4007     }
4008 }
4009
4010 STATIC_OVL void
4011 dofiretrap(box)
4012 struct obj *box; /* null for floor trap */
4013 {
4014     boolean see_it = !Blind;
4015     int num, alt;
4016
4017     /* Bug: for box case, the equivalent of burn_floor_objects() ought
4018      * to be done upon its contents.
4019      */
4020
4021     if ((box && !carried(box)) ? is_pool(box->ox, box->oy) : Underwater) {
4022 /*JP
4023         pline("A cascade of steamy bubbles erupts from %s!",
4024 */
4025         pline("\8fö\8bC\82Ì\96A\82ª%s\82©\82ç\82µ\82ã\81[\82Á\82Æ\94­\90\82µ\82½\81I",
4026               the(box ? xname(box) : surface(u.ux, u.uy)));
4027         if (Fire_resistance)
4028 /*JP
4029             You("are uninjured.");
4030 */
4031             You("\8f\9d\82Â\82©\82È\82¢\81D");
4032         else
4033 /*JP
4034             losehp(rnd(3), "boiling water", KILLED_BY);
4035 */
4036             losehp(rnd(3), "\95¦\93«\82µ\82½\90\85\82Å", KILLED_BY);
4037         return;
4038     }
4039 #if 0 /*JP*/
4040     pline("A %s %s from %s!", tower_of_flame, box ? "bursts" : "erupts",
4041           the(box ? xname(box) : surface(u.ux, u.uy)));
4042 #else
4043     pline("\89Î\92\8c\82ª%s\82©\82ç%s\81I", box ? xname(box) : surface(u.ux,u.uy),
4044           box ? "\90\81\82«\8fo\82µ\82½" : "\97§\82¿\82Ì\82Ú\82Á\82½");
4045 #endif
4046     if (Fire_resistance) {
4047         shieldeff(u.ux, u.uy);
4048         num = rn2(2);
4049     } else if (Upolyd) {
4050         num = d(2, 4);
4051         switch (u.umonnum) {
4052         case PM_PAPER_GOLEM:
4053             alt = u.mhmax;
4054             break;
4055         case PM_STRAW_GOLEM:
4056             alt = u.mhmax / 2;
4057             break;
4058         case PM_WOOD_GOLEM:
4059             alt = u.mhmax / 4;
4060             break;
4061         case PM_LEATHER_GOLEM:
4062             alt = u.mhmax / 8;
4063             break;
4064         default:
4065             alt = 0;
4066             break;
4067         }
4068         if (alt > num)
4069             num = alt;
4070         if (u.mhmax > mons[u.umonnum].mlevel)
4071             u.mhmax -= rn2(min(u.mhmax, num + 1)), context.botl = 1;
4072     } else {
4073         num = d(2, 4);
4074         if (u.uhpmax > u.ulevel)
4075             u.uhpmax -= rn2(min(u.uhpmax, num + 1)), context.botl = 1;
4076     }
4077     if (!num)
4078 /*JP
4079         You("are uninjured.");
4080 */
4081         You("\8f\9d\82Â\82©\82È\82¢\81D");
4082     else
4083 #if 0 /*JP*/
4084         losehp(num, tower_of_flame, KILLED_BY_AN); /* fire damage */
4085 #else
4086         losehp(num, "\89Î\92\8c\82Å", KILLED_BY_AN); /* fire damage */
4087 #endif
4088     burn_away_slime();
4089
4090     if (burnarmor(&youmonst) || rn2(3)) {
4091         destroy_item(SCROLL_CLASS, AD_FIRE);
4092         destroy_item(SPBOOK_CLASS, AD_FIRE);
4093         destroy_item(POTION_CLASS, AD_FIRE);
4094     }
4095     if (!box && burn_floor_objects(u.ux, u.uy, see_it, TRUE) && !see_it)
4096 /*JP
4097         You("smell paper burning.");
4098 */
4099         You("\8e\86\82Ì\82±\82°\82é\93õ\82¢\82ª\82µ\82½\81D");
4100     if (is_ice(u.ux, u.uy))
4101         melt_ice(u.ux, u.uy, (char *) 0);
4102 }
4103
4104 STATIC_OVL void
4105 domagictrap()
4106 {
4107     register int fate = rnd(20);
4108
4109     /* What happened to the poor sucker? */
4110
4111     if (fate < 10) {
4112         /* Most of the time, it creates some monsters. */
4113         int cnt = rnd(4);
4114
4115         /* blindness effects */
4116         if (!resists_blnd(&youmonst)) {
4117 /*JP
4118             You("are momentarily blinded by a flash of light!");
4119 */
4120             You("\82Ü\82Î\82ä\82¢\8cõ\82Å\88ê\8fu\96Ú\82ª\82­\82ç\82ñ\82¾\81I");
4121             make_blinded((long) rn1(5, 10), FALSE);
4122             if (!Blind)
4123                 Your1(vision_clears);
4124         } else if (!Blind) {
4125 /*JP
4126             You_see("a flash of light!");
4127 */
4128             You("\82Ü\82Î\82ä\82¢\8cõ\82ð\97\81\82Ñ\82½\81I");
4129         }
4130
4131         /* deafness effects */
4132         if (!Deaf) {
4133 /*JP
4134             You_hear("a deafening roar!");
4135 */
4136             You_hear("\8e¨\82ð\82Â\82ñ\82´\82­\82æ\82¤\82È\99ô\9aK\82ð\95·\82¢\82½\81I");
4137             incr_itimeout(&HDeaf, rn1(20, 30));
4138             context.botl = TRUE;
4139         } else {
4140             /* magic vibrations still hit you */
4141             You_feel("rankled.");
4142             incr_itimeout(&HDeaf, rn1(5, 15));
4143             context.botl = TRUE;
4144         }
4145         while (cnt--)
4146             (void) makemon((struct permonst *) 0, u.ux, u.uy, NO_MM_FLAGS);
4147         /* roar: wake monsters in vicinity, after placing trap-created ones */
4148         wake_nearto(u.ux, u.uy, 7 * 7);
4149         /* [flash: should probably also hit nearby gremlins with light] */
4150     } else
4151         switch (fate) {
4152         case 10:
4153         case 11:
4154             /* sometimes nothing happens */
4155             break;
4156         case 12: /* a flash of fire */
4157             dofiretrap((struct obj *) 0);
4158             break;
4159
4160         /* odd feelings */
4161         case 13:
4162 /*JP
4163             pline("A shiver runs up and down your %s!", body_part(SPINE));
4164 */
4165             pline("\90k\82¦\82ª\82 \82È\82½\82Ì%s\82ð\91\96\82Á\82½\81I", body_part(SPINE));
4166             break;
4167         case 14:
4168 #if 0 /*JP*/
4169             You_hear(Hallucination ? "the moon howling at you."
4170                                    : "distant howling.");
4171 #else
4172             You_hear(Hallucination ? "\8c\8e\82ª\96i\82¦\82Ä\82¢\82é\82Ì\82ð\95·\82¢\82½\81D"
4173                                    : "\89\93\95û\82Ì\89\93\96i\82ð\95·\82¢\82½\81D");
4174 #endif
4175             break;
4176         case 15:
4177             if (on_level(&u.uz, &qstart_level))
4178 #if 0 /*JP*/
4179                 You_feel(
4180                     "%slike the prodigal son.",
4181                     (flags.female || (Upolyd && is_neuter(youmonst.data)))
4182                         ? "oddly "
4183                         : "");
4184 #else /*JP \90¹\8f\91\82Ì\83\8b\83J\93`\82æ\82è */
4185                 You("%s\95ú\93 \91§\8eq\82Ì\82æ\82¤\82É\82È\82Á\82½\82æ\82¤\82È\8bC\82ª\82µ\82½\81D",
4186                     (flags.female || (Upolyd && is_neuter(youmonst.data)))
4187                     ? "\88Ù\8fí\82É"
4188                     : "");
4189 #endif
4190             else
4191 #if 0 /*JP*/
4192                 You("suddenly yearn for %s.",
4193                     Hallucination
4194                         ? "Cleveland"
4195                         : (In_quest(&u.uz) || at_dgn_entrance("The Quest"))
4196                               ? "your nearby homeland"
4197                               : "your distant homeland");
4198 #else
4199                 You("\93Ë\91R%s\82ª\97ö\82µ\82­\82È\82Á\82½\81D",
4200                     Hallucination ? "\90Â\90X"
4201                         : (In_quest(&u.uz) || at_dgn_entrance("\83N\83G\83X\83g"))
4202                             ? "\82·\82®\82»\82±\82É\82 \82é\8cÌ\8b½"
4203                             : "\82Í\82é\82©\82©\82È\82½\82Ì\8cÌ\8b½");
4204 #endif
4205             break;
4206         case 16:
4207 /*JP
4208             Your("pack shakes violently!");
4209 */
4210             Your("\91Ü\82Í\8c\83\82µ\82­\97h\82ê\82½\81I");
4211             break;
4212         case 17:
4213 /*JP
4214             You(Hallucination ? "smell hamburgers." : "smell charred flesh.");
4215 */
4216             You(Hallucination ? "\83n\83\93\83o\81[\83K\81[\82Ì\93õ\82¢\82ª\82µ\82½\81D" : "\8d\95\8fÅ\82°\82Ì\93÷\82Ì\93õ\82¢\82ª\82µ\82½\81D");
4217             break;
4218         case 18:
4219 /*JP
4220             You_feel("tired.");
4221 */
4222             You("\94æ\82ê\82ð\8a´\82\82½\81D");
4223             break;
4224
4225         /* very occasionally something nice happens. */
4226         case 19: { /* tame nearby monsters */
4227             int i, j;
4228             struct monst *mtmp;
4229
4230             (void) adjattrib(A_CHA, 1, FALSE);
4231             for (i = -1; i <= 1; i++)
4232                 for (j = -1; j <= 1; j++) {
4233                     if (!isok(u.ux + i, u.uy + j))
4234                         continue;
4235                     mtmp = m_at(u.ux + i, u.uy + j);
4236                     if (mtmp)
4237                         (void) tamedog(mtmp, (struct obj *) 0);
4238                 }
4239             break;
4240         }
4241         case 20: { /* uncurse stuff */
4242             struct obj pseudo;
4243             long save_conf = HConfusion;
4244
4245             pseudo = zeroobj; /* neither cursed nor blessed,
4246                                  and zero out oextra */
4247             pseudo.otyp = SCR_REMOVE_CURSE;
4248             HConfusion = 0L;
4249             (void) seffects(&pseudo);
4250             HConfusion = save_conf;
4251             break;
4252         }
4253         default:
4254             break;
4255         }
4256 }
4257
4258 /* Set an item on fire.
4259  *   "force" means not to roll a luck-based protection check for the
4260  *     item.
4261  *   "x" and "y" are the coordinates to dump the contents of a
4262  *     container, if it burns up.
4263  *
4264  * Return whether the object was destroyed.
4265  */
4266 boolean
4267 fire_damage(obj, force, x, y)
4268 struct obj *obj;
4269 boolean force;
4270 xchar x, y;
4271 {
4272     int chance;
4273     struct obj *otmp, *ncobj;
4274     int in_sight = !Blind && couldsee(x, y); /* Don't care if it's lit */
4275     int dindx;
4276
4277     /* object might light in a controlled manner */
4278     if (catch_lit(obj))
4279         return FALSE;
4280
4281     if (Is_container(obj)) {
4282         switch (obj->otyp) {
4283         case ICE_BOX:
4284             return FALSE; /* Immune */
4285         case CHEST:
4286             chance = 40;
4287             break;
4288         case LARGE_BOX:
4289             chance = 30;
4290             break;
4291         default:
4292             chance = 20;
4293             break;
4294         }
4295         if ((!force && (Luck + 5) > rn2(chance))
4296             || (is_flammable(obj) && obj->oerodeproof))
4297             return FALSE;
4298         /* Container is burnt up - dump contents out */
4299         if (in_sight)
4300 /*JP
4301             pline("%s catches fire and burns.", Yname2(obj));
4302 */
4303             pline("%s\82Í\89Î\82ª\82Â\82¢\82Ä\94R\82¦\82½\81D", Yname2(obj));
4304         if (Has_contents(obj)) {
4305             if (in_sight)
4306 /*JP
4307                 pline("Its contents fall out.");
4308 */
4309                 pline("\92\86\90g\82ª\8fo\82Ä\82«\82½\81D");
4310             for (otmp = obj->cobj; otmp; otmp = ncobj) {
4311                 ncobj = otmp->nobj;
4312                 obj_extract_self(otmp);
4313                 if (!flooreffects(otmp, x, y, ""))
4314                     place_object(otmp, x, y);
4315             }
4316         }
4317         setnotworn(obj);
4318         delobj(obj);
4319         return TRUE;
4320     } else if (!force && (Luck + 5) > rn2(20)) {
4321         /*  chance per item of sustaining damage:
4322           *     max luck (Luck==13):    10%
4323           *     avg luck (Luck==0):     75%
4324           *     awful luck (Luck<-4):  100%
4325           */
4326         return FALSE;
4327     } else if (obj->oclass == SCROLL_CLASS || obj->oclass == SPBOOK_CLASS) {
4328         if (obj->otyp == SCR_FIRE || obj->otyp == SPE_FIREBALL)
4329             return FALSE;
4330         if (obj->otyp == SPE_BOOK_OF_THE_DEAD) {
4331             if (in_sight)
4332 /*JP
4333                 pline("Smoke rises from %s.", the(xname(obj)));
4334 */
4335                 pline("%s\82©\82ç\89\8c\82ª\82 \82ª\82Á\82½\81D", the(xname(obj)));
4336             return FALSE;
4337         }
4338         dindx = (obj->oclass == SCROLL_CLASS) ? 3 : 4;
4339         if (in_sight)
4340 #if 0 /*JP*/
4341             pline("%s %s.", Yname2(obj),
4342                   destroy_strings[dindx][(obj->quan > 1L)]);
4343 #else
4344             pline("%s\82Í%s\81D", Yname2(obj),
4345                   destroy_strings[dindx][(obj->quan > 1L)]);
4346 #endif
4347         setnotworn(obj);
4348         delobj(obj);
4349         return TRUE;
4350     } else if (obj->oclass == POTION_CLASS) {
4351         dindx = (obj->otyp != POT_OIL) ? 1 : 2;
4352         if (in_sight)
4353 #if 0 /*JP*/
4354             pline("%s %s.", Yname2(obj),
4355                   destroy_strings[dindx][(obj->quan > 1L)]);
4356 #else
4357             pline("%s\82Í%s\81D", Yname2(obj),
4358                   destroy_strings[dindx][(obj->quan > 1L)]);
4359 #endif
4360         setnotworn(obj);
4361         delobj(obj);
4362         return TRUE;
4363     } else if (erode_obj(obj, (char *) 0, ERODE_BURN, EF_DESTROY)
4364                == ER_DESTROYED) {
4365         return TRUE;
4366     }
4367     return FALSE;
4368 }
4369
4370 /*
4371  * Apply fire_damage() to an entire chain.
4372  *
4373  * Return number of objects destroyed. --ALI
4374  */
4375 int
4376 fire_damage_chain(chain, force, here, x, y)
4377 struct obj *chain;
4378 boolean force, here;
4379 xchar x, y;
4380 {
4381     struct obj *obj, *nobj;
4382     int num = 0;
4383
4384     for (obj = chain; obj; obj = nobj) {
4385         nobj = here ? obj->nexthere : obj->nobj;
4386         if (fire_damage(obj, force, x, y))
4387             ++num;
4388     }
4389
4390     if (num && (Blind && !couldsee(x, y)))
4391 /*JP
4392         You("smell smoke.");
4393 */
4394         You("\89\8c\82Ì\82É\82¨\82¢\82ª\82µ\82½\81D");
4395     return num;
4396 }
4397
4398 /* obj has been thrown or dropped into lava; damage is worse than mere fire */
4399 boolean
4400 lava_damage(obj, x, y)
4401 struct obj *obj;
4402 xchar x, y;
4403 {
4404     int otyp = obj->otyp, ocls = obj->oclass;
4405
4406     /* the Amulet, invocation items, and Rider corpses are never destroyed
4407        (let Book of the Dead fall through to fire_damage() to get feedback) */
4408     if (obj_resists(obj, 0, 0) && otyp != SPE_BOOK_OF_THE_DEAD)
4409         return FALSE;
4410     /* destroy liquid (venom), wax, veggy, flesh, paper (except for scrolls
4411        and books--let fire damage deal with them), cloth, leather, wood, bone
4412        unless it's inherently or explicitly fireproof or contains something;
4413        note: potions are glass so fall through to fire_damage() and boil */
4414     if (objects[otyp].oc_material < DRAGON_HIDE
4415         && ocls != SCROLL_CLASS && ocls != SPBOOK_CLASS
4416         && objects[otyp].oc_oprop != FIRE_RES
4417         && otyp != WAN_FIRE && otyp != FIRE_HORN
4418         /* assumes oerodeproof isn't overloaded for some other purpose on
4419            non-eroding items */
4420         && !obj->oerodeproof
4421         /* fire_damage() knows how to deal with containers and contents */
4422         && !Has_contents(obj)) {
4423         if (cansee(x, y)) {
4424             /* this feedback is pretty clunky and can become very verbose
4425                when former contents of a burned container get here via
4426                flooreffects() */
4427             if (obj == thrownobj || obj == kickedobj)
4428 #if 0 /*JP*/
4429                 pline("%s %s up!", is_plural(obj) ? "They" : "It",
4430                       otense(obj, "burn"));
4431 #else
4432                 pline("\82»\82ê\82Í\94R\82¦\82Â\82«\82½\81I");
4433 #endif
4434             else
4435 /*JP
4436                 You_see("%s hit lava and burn up!", doname(obj));
4437 */
4438                 You_see("%s\82Í\97n\8aâ\82É\93\96\82½\82Á\82Ä\94R\82¦\82Â\82«\82½\81I", doname(obj));
4439         }
4440         if (carried(obj)) { /* shouldn't happen */
4441             remove_worn_item(obj, TRUE);
4442             useupall(obj);
4443         } else
4444             delobj(obj);
4445         return TRUE;
4446     }
4447     return fire_damage(obj, TRUE, x, y);
4448 }
4449
4450 void
4451 acid_damage(obj)
4452 struct obj *obj;
4453 {
4454     /* Scrolls but not spellbooks can be erased by acid. */
4455     struct monst *victim;
4456     boolean vismon;
4457
4458     if (!obj)
4459         return;
4460
4461     victim = carried(obj) ? &youmonst : mcarried(obj) ? obj->ocarry : NULL;
4462     vismon = victim && (victim != &youmonst) && canseemon(victim);
4463
4464     if (obj->greased) {
4465         grease_protect(obj, (char *) 0, victim);
4466     } else if (obj->oclass == SCROLL_CLASS && obj->otyp != SCR_BLANK_PAPER) {
4467         if (obj->otyp != SCR_BLANK_PAPER
4468 #ifdef MAIL
4469             && obj->otyp != SCR_MAIL
4470 #endif
4471             ) {
4472             if (!Blind) {
4473                 if (victim == &youmonst)
4474 /*JP
4475                     pline("Your %s.", aobjnam(obj, "fade"));
4476 */
4477                     pline("%s\82Ì\95\8e\9a\82Í\94\96\82ê\82½\81D", xname(obj));
4478                 else if (vismon)
4479 #if 0 /*JP*/
4480                     pline("%s %s.", s_suffix(Monnam(victim)),
4481                           aobjnam(obj, "fade"));
4482 #else
4483                     pline("%s\82Ì%s\82Ì\95\8e\9a\82Í\94\96\82ê\82½\81D", Monnam(victim),
4484                           xname(obj));
4485 #endif
4486             }
4487         }
4488         obj->otyp = SCR_BLANK_PAPER;
4489         obj->spe = 0;
4490         obj->dknown = 0;
4491     } else
4492         erode_obj(obj, (char *) 0, ERODE_CORRODE, EF_GREASE | EF_VERBOSE);
4493 }
4494
4495 /* context for water_damage(), managed by water_damage_chain();
4496    when more than one stack of potions of acid explode while processing
4497    a chain of objects, use alternate phrasing after the first message */
4498 static struct h2o_ctx {
4499     int dkn_boom, unk_boom; /* track dknown, !dknown separately */
4500     boolean ctx_valid;
4501 } acid_ctx = { 0, 0, FALSE };
4502
4503 /* Get an object wet and damage it appropriately.
4504  *   "ostr", if present, is used instead of the object name in some
4505  *     messages.
4506  *   "force" means not to roll luck to protect some objects.
4507  * Returns an erosion return value (ER_*)
4508  */
4509 int
4510 water_damage(obj, ostr, force)
4511 struct obj *obj;
4512 const char *ostr;
4513 boolean force;
4514 {
4515     if (!obj)
4516         return ER_NOTHING;
4517
4518     if (snuff_lit(obj))
4519         return ER_DAMAGED;
4520
4521     if (!ostr)
4522         ostr = cxname(obj);
4523
4524     if (obj->otyp == CAN_OF_GREASE && obj->spe > 0) {
4525         return ER_NOTHING;
4526     } else if (obj->otyp == TOWEL && obj->spe < 7) {
4527         wet_a_towel(obj, rnd(7), TRUE);
4528         return ER_NOTHING;
4529     } else if (obj->greased) {
4530         if (!rn2(2))
4531             obj->greased = 0;
4532         if (carried(obj))
4533             update_inventory();
4534         return ER_GREASED;
4535     } else if (Is_container(obj) && !Is_box(obj)
4536                && (obj->otyp != OILSKIN_SACK || (obj->cursed && !rn2(3)))) {
4537         if (carried(obj))
4538 /*JP
4539             pline("Water gets into your %s!", ostr);
4540 */
4541             pline("\90\85\82ª%s\82Ì\92\86\82É\93ü\82Á\82½\81I", ostr);
4542
4543         water_damage_chain(obj->cobj, FALSE);
4544         return ER_DAMAGED; /* contents were damaged */
4545     } else if (obj->otyp == OILSKIN_SACK) {
4546         if (carried(obj))
4547 /*JP
4548             pline("Some water slides right off your %s.", ostr);
4549 */
4550             pline("%s\82Í\90\85\82ð\92e\82¢\82½\81D", ostr);
4551         makeknown(OILSKIN_SACK);
4552         /* not actually damaged, but because we /didn't/ get the "water
4553            gets into!" message, the player now has more information and
4554            thus we need to waste any potion they may have used (also,
4555            flavourwise the water is now on the floor) */
4556         return ER_DAMAGED;
4557     } else if (!force && (Luck + 5) > rn2(20)) {
4558         /*  chance per item of sustaining damage:
4559             *   max luck:               10%
4560             *   avg luck (Luck==0):     75%
4561             *   awful luck (Luck<-4):  100%
4562             */
4563         return ER_NOTHING;
4564     } else if (obj->oclass == SCROLL_CLASS) {
4565         if (obj->otyp == SCR_BLANK_PAPER
4566 #ifdef MAIL
4567             || obj->otyp == SCR_MAIL
4568 #endif
4569            ) return 0;
4570         if (carried(obj))
4571 /*JP
4572             pline("Your %s %s.", ostr, vtense(ostr, "fade"));
4573 */
4574             pline("%s\82Ì\95\8e\9a\82Í\94\96\82ê\82½\81D", ostr);
4575
4576         obj->otyp = SCR_BLANK_PAPER;
4577         obj->dknown = 0;
4578         obj->spe = 0;
4579         if (carried(obj))
4580             update_inventory();
4581         return ER_DAMAGED;
4582     } else if (obj->oclass == SPBOOK_CLASS) {
4583         if (obj->otyp == SPE_BOOK_OF_THE_DEAD) {
4584 /*JP
4585             pline("Steam rises from %s.", the(xname(obj)));
4586 */
4587             pline("\8fö\8bC\82ª%s\82©\82ç\97§\82¿\82Ì\82Ú\82Á\82½\81D", xname(obj));
4588             return 0;
4589         } else if (obj->otyp == SPE_BLANK_PAPER) {
4590             return 0;
4591         }
4592         if (carried(obj))
4593 /*JP
4594             pline("Your %s %s.", ostr, vtense(ostr, "fade"));
4595 */
4596             pline("%s\82Ì\95\8e\9a\82Í\94\96\82ê\82½\81D", ostr);
4597
4598         if (obj->otyp == SPE_NOVEL) {
4599             obj->novelidx = 0;
4600             free_oname(obj);
4601         }
4602
4603         obj->otyp = SPE_BLANK_PAPER;
4604         obj->dknown = 0;
4605         if (carried(obj))
4606             update_inventory();
4607         return ER_DAMAGED;
4608     } else if (obj->oclass == POTION_CLASS) {
4609         if (obj->otyp == POT_ACID) {
4610             char *bufp;
4611 #if 0 /*JP*/
4612             boolean one = (obj->quan == 1L), update = carried(obj),
4613                     exploded = FALSE;
4614 #else
4615             boolean update = carried(obj);
4616 #endif
4617
4618             if (Blind && !carried(obj))
4619                 obj->dknown = 0;
4620 #if 0 /*JP*/
4621             if (acid_ctx.ctx_valid)
4622                 exploded = ((obj->dknown ? acid_ctx.dkn_boom
4623                                          : acid_ctx.unk_boom) > 0);
4624 #endif
4625             /* First message is
4626              * "a [potion|<color> potion|potion of acid] explodes"
4627              * depending on obj->dknown (potion has been seen) and
4628              * objects[POT_ACID].oc_name_known (fully discovered),
4629              * or "some {plural version} explode" when relevant.
4630              * Second and subsequent messages for same chain and
4631              * matching dknown status are
4632              * "another [potion|<color> &c] explodes" or plural
4633              * variant.
4634              */
4635             bufp = simpleonames(obj);
4636 #if 0 /*JP*/
4637             pline("%s %s %s!", /* "A potion explodes!" */
4638                   !exploded ? (one ? "A" : "Some")
4639                             : (one ? "Another" : "More"),
4640                   bufp, vtense(bufp, "explode"));
4641 #else
4642             pline("%s\82Í\94\9a\94­\82µ\82½\81I", bufp);
4643 #endif
4644             if (acid_ctx.ctx_valid) {
4645                 if (obj->dknown)
4646                     acid_ctx.dkn_boom++;
4647                 else
4648                     acid_ctx.unk_boom++;
4649             }
4650             setnotworn(obj);
4651             delobj(obj);
4652             if (update)
4653                 update_inventory();
4654             return ER_DESTROYED;
4655         } else if (obj->odiluted) {
4656             if (carried(obj))
4657 /*JP
4658                 pline("Your %s %s further.", ostr, vtense(ostr, "dilute"));
4659 */
4660                 pline("%s\82Í\82³\82ç\82É\94\96\82Ü\82Á\82½\81D", ostr);
4661
4662             obj->otyp = POT_WATER;
4663             obj->dknown = 0;
4664             obj->blessed = obj->cursed = 0;
4665             obj->odiluted = 0;
4666             if (carried(obj))
4667                 update_inventory();
4668             return ER_DAMAGED;
4669         } else if (obj->otyp != POT_WATER) {
4670             if (carried(obj))
4671 /*JP
4672                 pline("Your %s %s.", ostr, vtense(ostr, "dilute"));
4673 */
4674                 pline("%s\82Í\94\96\82Ü\82Á\82½\81D", ostr);
4675
4676             obj->odiluted++;
4677             if (carried(obj))
4678                 update_inventory();
4679             return ER_DAMAGED;
4680         }
4681     } else {
4682         return erode_obj(obj, ostr, ERODE_RUST, EF_NONE);
4683     }
4684     return ER_NOTHING;
4685 }
4686
4687 void
4688 water_damage_chain(obj, here)
4689 struct obj *obj;
4690 boolean here;
4691 {
4692     struct obj *otmp;
4693
4694     /* initialize acid context: so far, neither seen (dknown) potions of
4695        acid nor unseen have exploded during this water damage sequence */
4696     acid_ctx.dkn_boom = acid_ctx.unk_boom = 0;
4697     acid_ctx.ctx_valid = TRUE;
4698
4699     for (; obj; obj = otmp) {
4700         otmp = here ? obj->nexthere : obj->nobj;
4701         water_damage(obj, (char *) 0, FALSE);
4702     }
4703
4704     /* reset acid context */
4705     acid_ctx.dkn_boom = acid_ctx.unk_boom = 0;
4706     acid_ctx.ctx_valid = FALSE;
4707 }
4708
4709 /*
4710  * This function is potentially expensive - rolling
4711  * inventory list multiple times.  Luckily it's seldom needed.
4712  * Returns TRUE if disrobing made player unencumbered enough to
4713  * crawl out of the current predicament.
4714  */
4715 STATIC_OVL boolean
4716 emergency_disrobe(lostsome)
4717 boolean *lostsome;
4718 {
4719     int invc = inv_cnt(TRUE);
4720
4721     while (near_capacity() > (Punished ? UNENCUMBERED : SLT_ENCUMBER)) {
4722         register struct obj *obj, *otmp = (struct obj *) 0;
4723         register int i;
4724
4725         /* Pick a random object */
4726         if (invc > 0) {
4727             i = rn2(invc);
4728             for (obj = invent; obj; obj = obj->nobj) {
4729                 /*
4730                  * Undroppables are: body armor, boots, gloves,
4731                  * amulets, and rings because of the time and effort
4732                  * in removing them + loadstone and other cursed stuff
4733                  * for obvious reasons.
4734                  */
4735                 if (!((obj->otyp == LOADSTONE && obj->cursed) || obj == uamul
4736                       || obj == uleft || obj == uright || obj == ublindf
4737                       || obj == uarm || obj == uarmc || obj == uarmg
4738                       || obj == uarmf || obj == uarmu
4739                       || (obj->cursed && (obj == uarmh || obj == uarms))
4740                       || welded(obj)))
4741                     otmp = obj;
4742                 /* reached the mark and found some stuff to drop? */
4743                 if (--i < 0 && otmp)
4744                     break;
4745
4746                 /* else continue */
4747             }
4748         }
4749         if (!otmp)
4750             return FALSE; /* nothing to drop! */
4751         if (otmp->owornmask)
4752             remove_worn_item(otmp, FALSE);
4753         *lostsome = TRUE;
4754         dropx(otmp);
4755         invc--;
4756     }
4757     return TRUE;
4758 }
4759
4760
4761 /*  return TRUE iff player relocated */
4762 boolean
4763 drown()
4764 {
4765     const char *pool_of_water;
4766     boolean inpool_ok = FALSE, crawl_ok;
4767     int i, x, y;
4768
4769     /* happily wading in the same contiguous pool */
4770     if (u.uinwater && is_pool(u.ux - u.dx, u.uy - u.dy)
4771         && (Swimming || Amphibious)) {
4772         /* water effects on objects every now and then */
4773         if (!rn2(5))
4774             inpool_ok = TRUE;
4775         else
4776             return FALSE;
4777     }
4778
4779     if (!u.uinwater) {
4780 #if 0 /*JP:T*/
4781         You("%s into the %s%c", Is_waterlevel(&u.uz) ? "plunge" : "fall",
4782             hliquid("water"),
4783             Amphibious || Swimming ? '.' : '!');
4784 #else
4785         You("%s\82Ì\92\86\82É%s%s", hliquid("\90\85"),
4786             Is_waterlevel(&u.uz) ? "\94ò\82Ñ\82±\82ñ\82¾" : "\97\8e\82¿\82½",
4787             Amphibious || Swimming ? "\81D" : "\81I");
4788 #endif
4789         if (!Swimming && !Is_waterlevel(&u.uz))
4790 /*JP
4791             You("sink like %s.", Hallucination ? "the Titanic" : "a rock");
4792 */
4793             You("%s\82Ì\82æ\82¤\82É\92¾\82ñ\82¾\81D", Hallucination ? "\83^\83C\83^\83j\83b\83N\8d\86" : "\8aâ");
4794     }
4795
4796     water_damage_chain(invent, FALSE);
4797
4798     if (u.umonnum == PM_GREMLIN && rn2(3))
4799         (void) split_mon(&youmonst, (struct monst *) 0);
4800     else if (u.umonnum == PM_IRON_GOLEM) {
4801 /*JP
4802         You("rust!");
4803 */
4804         You("\8eK\82Ñ\82½\81I");
4805         i = Maybe_Half_Phys(d(2, 6));
4806         if (u.mhmax > i)
4807             u.mhmax -= i;
4808 /*JP
4809         losehp(i, "rusting away", KILLED_BY);
4810 */
4811         losehp(i, "\8a®\91S\82É\8eK\82Ñ\82Ä", KILLED_BY);
4812     }
4813     if (inpool_ok)
4814         return FALSE;
4815
4816     if ((i = number_leashed()) > 0) {
4817 #if 0 /*JP*/
4818         pline_The("leash%s slip%s loose.", (i > 1) ? "es" : "",
4819                   (i > 1) ? "" : "s");
4820 #else
4821         pline("\95R\82ª\82ä\82é\82ñ\82¾\81D");
4822 #endif
4823         unleash_all();
4824     }
4825
4826     if (Amphibious || Swimming) {
4827         if (Amphibious) {
4828             if (flags.verbose)
4829 /*JP
4830                 pline("But you aren't drowning.");
4831 */
4832                 pline("\82µ\82©\82µ\81C\82 \82È\82½\82Í\93M\82ê\82È\82©\82Á\82½\81D");
4833             if (!Is_waterlevel(&u.uz)) {
4834                 if (Hallucination)
4835 /*JP
4836                     Your("keel hits the bottom.");
4837 */
4838                     You("\92ê\82É\83j\81[\83h\83\8d\83b\83v\82ð\8c\88\82ß\82½\81D");
4839                 else
4840 /*JP
4841                     You("touch bottom.");
4842 */
4843                     You("\92ê\82É\82Â\82¢\82½\81D");
4844             }
4845         }
4846         if (Punished) {
4847             unplacebc();
4848             placebc();
4849         }
4850         vision_recalc(2); /* unsee old position */
4851         u.uinwater = 1;
4852         under_water(1);
4853         vision_full_recalc = 1;
4854         return FALSE;
4855     }
4856     if ((Teleportation || can_teleport(youmonst.data)) && !Unaware
4857         && (Teleport_control || rn2(3) < Luck + 2)) {
4858 #if 0 /*JP*/
4859         You("attempt a teleport spell."); /* utcsri!carroll */
4860 #else
4861         You("\8fu\8aÔ\88Ú\93®\82Ì\8eô\95\82ð\8f¥\82¦\82Ä\82Ý\82½\81D");
4862 #endif
4863         if (!level.flags.noteleport) {
4864             (void) dotele(FALSE);
4865             if (!is_pool(u.ux, u.uy))
4866                 return TRUE;
4867         } else
4868 /*JP
4869             pline_The("attempted teleport spell fails.");
4870 */
4871             pline("\8fu\8aÔ\88Ú\93®\82Ì\8eô\95\82Í\8e¸\94s\82µ\82½\81D");
4872     }
4873     if (u.usteed) {
4874         dismount_steed(DISMOUNT_GENERIC);
4875         if (!is_pool(u.ux, u.uy))
4876             return TRUE;
4877     }
4878     crawl_ok = FALSE;
4879     x = y = 0; /* lint suppression */
4880     /* if sleeping, wake up now so that we don't crawl out of water
4881        while still asleep; we can't do that the same way that waking
4882        due to combat is handled; note unmul() clears u.usleep */
4883     if (u.usleep)
4884 /*JP
4885         unmul("Suddenly you wake up!");
4886 */
4887         unmul("\93Ë\91R\82 \82È\82½\82Í\96Ú\82ª\8ao\82ß\82½\81I");
4888     /* being doused will revive from fainting */
4889     if (is_fainted())
4890         reset_faint();
4891     /* can't crawl if unable to move (crawl_ok flag stays false) */
4892     if (multi < 0 || (Upolyd && !youmonst.data->mmove))
4893         goto crawl;
4894     /* look around for a place to crawl to */
4895     for (i = 0; i < 100; i++) {
4896         x = rn1(3, u.ux - 1);
4897         y = rn1(3, u.uy - 1);
4898         if (crawl_destination(x, y)) {
4899             crawl_ok = TRUE;
4900             goto crawl;
4901         }
4902     }
4903     /* one more scan */
4904     for (x = u.ux - 1; x <= u.ux + 1; x++)
4905         for (y = u.uy - 1; y <= u.uy + 1; y++)
4906             if (crawl_destination(x, y)) {
4907                 crawl_ok = TRUE;
4908                 goto crawl;
4909             }
4910 crawl:
4911     if (crawl_ok) {
4912         boolean lost = FALSE;
4913         /* time to do some strip-tease... */
4914         boolean succ = Is_waterlevel(&u.uz) ? TRUE : emergency_disrobe(&lost);
4915
4916 /*JP
4917         You("try to crawl out of the %s.", hliquid("water"));
4918 */
4919         You("%s\82©\82ç\82Í\82¢\82 \82ª\82ë\82¤\82Æ\82µ\82½\81D", hliquid("\90\85"));
4920         if (lost)
4921 /*JP
4922             You("dump some of your gear to lose weight...");
4923 */
4924             You("\91Ì\82ð\8cy\82­\82·\82é\82½\82ß\82¢\82­\82Â\82©\95¨\82ð\93\8a\82°\82·\82Ä\82½\81D\81D\81D");
4925         if (succ) {
4926 /*JP
4927             pline("Pheew!  That was close.");
4928 */
4929             pline("\83n\83@\83n\83@\81I\82 \82Ô\82È\82©\82Á\82½\81D");
4930             teleds(x, y, TRUE);
4931             return TRUE;
4932         }
4933         /* still too much weight */
4934 /*JP
4935         pline("But in vain.");
4936 */
4937         pline("\82ª\81C\96³\91Ê\82¾\82Á\82½\81D");
4938     }
4939     u.uinwater = 1;
4940 /*JP
4941     You("drown.");
4942 */
4943     You("\93M\82ê\82½\81D");
4944     for (i = 0; i < 5; i++) { /* arbitrary number of loops */
4945         /* killer format and name are reconstructed every iteration
4946            because lifesaving resets them */
4947         pool_of_water = waterbody_name(u.ux, u.uy);
4948         killer.format = KILLED_BY_AN;
4949 #if 0 /*JP*/
4950         /* avoid "drowned in [a] water" */
4951         if (!strcmp(pool_of_water, "water"))
4952             pool_of_water = "deep water", killer.format = KILLED_BY;
4953 #endif
4954         Strcpy(killer.name, pool_of_water);
4955         done(DROWNING);
4956         /* oops, we're still alive.  better get out of the water. */
4957         if (safe_teleds(TRUE))
4958             break; /* successful life-save */
4959         /* nowhere safe to land; repeat drowning loop... */
4960 /*JP
4961         pline("You're still drowning.");
4962 */
4963         You("\82Ü\82¾\93M\82ê\82Ä\82¢\82é\81D");
4964     }
4965     if (u.uinwater) {
4966         u.uinwater = 0;
4967 #if 0 /*JP*/
4968         You("find yourself back %s.",
4969             Is_waterlevel(&u.uz) ? "in an air bubble" : "on land");
4970 #else
4971         You("\82¢\82Â\82Ì\82Ü\82É\82©%s\82É\82¢\82é\82Ì\82É\8bC\82ª\82Â\82¢\82½\81D",
4972             Is_waterlevel(&u.uz) ? "\8bó\8bC\82Ì\96A\82Ì\92\86" : "\92n\96Ê");
4973 #endif
4974     }
4975     return TRUE;
4976 }
4977
4978 void
4979 drain_en(n)
4980 int n;
4981 {
4982     if (!u.uenmax) {
4983         /* energy is completely gone */
4984 /*JP
4985         You_feel("momentarily lethargic.");
4986 */
4987         You("\88ê\8fu\96³\8bC\97Í\8a´\82ð\8a´\82\82½\81D");
4988     } else {
4989         /* throttle further loss a bit when there's not much left to lose */
4990         if (n > u.uenmax || n > u.ulevel)
4991             n = rnd(n);
4992
4993 /*JP
4994         You_feel("your magical energy drain away%c", (n > u.uen) ? '!' : '.');
4995 */
4996         You("\96\82\96@\82Ì\83G\83l\83\8b\83M\81[\82ª\8bz\82¢\82Æ\82ç\82ê\82½\82æ\82¤\82È\8bC\82ª\82µ\82½%s", (n > u.uen) ? "\81I" : "\81D");
4997         u.uen -= n;
4998         if (u.uen < 0) {
4999             u.uenmax -= rnd(-u.uen);
5000             if (u.uenmax < 0)
5001                 u.uenmax = 0;
5002             u.uen = 0;
5003         }
5004         context.botl = 1;
5005     }
5006 }
5007
5008 /* disarm a trap */
5009 int
5010 dountrap()
5011 {
5012     if (near_capacity() >= HVY_ENCUMBER) {
5013 /*JP
5014         pline("You're too strained to do that.");
5015 */
5016         pline("ã©\82ð\89ð\8f\9c\82µ\82æ\82¤\82É\82à\95¨\82ð\8e\9d\82¿\82·\82¬\82Ä\82¢\82é\81D");
5017         return 0;
5018     }
5019     if ((nohands(youmonst.data) && !webmaker(youmonst.data))
5020         || !youmonst.data->mmove) {
5021 /*JP
5022         pline("And just how do you expect to do that?");
5023 */
5024         pline("\82¢\82Á\82½\82¢\89½\82ð\8aú\91Ò\82µ\82Ä\82¢\82é\82ñ\82¾\82¢\81H");
5025         return 0;
5026     } else if (u.ustuck && sticks(youmonst.data)) {
5027 /*JP
5028         pline("You'll have to let go of %s first.", mon_nam(u.ustuck));
5029 */
5030         pline("%s\82ð\8eè\97£\82³\82È\82¢\82±\82Æ\82É\82Í\82Å\82«\82È\82¢\81D", mon_nam(u.ustuck));
5031         return 0;
5032     }
5033     if (u.ustuck || (welded(uwep) && bimanual(uwep))) {
5034 /*JP
5035         Your("%s seem to be too busy for that.", makeplural(body_part(HAND)));
5036 */
5037         Your("\82»\82ñ\82È\82±\82Æ\82ð\82·\82é\97]\97T\82È\82ñ\82Ä\82È\82¢\81D");
5038         return 0;
5039     }
5040     return untrap(FALSE);
5041 }
5042
5043 /* Probability of disabling a trap.  Helge Hafting */
5044 STATIC_OVL int
5045 untrap_prob(ttmp)
5046 struct trap *ttmp;
5047 {
5048     int chance = 3;
5049
5050     /* Only spiders know how to deal with webs reliably */
5051     if (ttmp->ttyp == WEB && !webmaker(youmonst.data))
5052         chance = 30;
5053     if (Confusion || Hallucination)
5054         chance++;
5055     if (Blind)
5056         chance++;
5057     if (Stunned)
5058         chance += 2;
5059     if (Fumbling)
5060         chance *= 2;
5061     /* Your own traps are better known than others. */
5062     if (ttmp && ttmp->madeby_u)
5063         chance--;
5064     if (Role_if(PM_ROGUE)) {
5065         if (rn2(2 * MAXULEV) < u.ulevel)
5066             chance--;
5067         if (u.uhave.questart && chance > 1)
5068             chance--;
5069     } else if (Role_if(PM_RANGER) && chance > 1)
5070         chance--;
5071     return rn2(chance);
5072 }
5073
5074 /* Replace trap with object(s).  Helge Hafting */
5075 void
5076 cnv_trap_obj(otyp, cnt, ttmp, bury_it)
5077 int otyp;
5078 int cnt;
5079 struct trap *ttmp;
5080 boolean bury_it;
5081 {
5082     struct obj *otmp = mksobj(otyp, TRUE, FALSE);
5083
5084     otmp->quan = cnt;
5085     otmp->owt = weight(otmp);
5086     /* Only dart traps are capable of being poisonous */
5087     if (otyp != DART)
5088         otmp->opoisoned = 0;
5089     place_object(otmp, ttmp->tx, ttmp->ty);
5090     if (bury_it) {
5091         /* magical digging first disarms this trap, then will unearth it */
5092         (void) bury_an_obj(otmp, (boolean *) 0);
5093     } else {
5094         /* Sell your own traps only... */
5095         if (ttmp->madeby_u)
5096             sellobj(otmp, ttmp->tx, ttmp->ty);
5097         stackobj(otmp);
5098     }
5099     newsym(ttmp->tx, ttmp->ty);
5100     if (u.utrap && ttmp->tx == u.ux && ttmp->ty == u.uy)
5101         reset_utrap(TRUE);
5102     deltrap(ttmp);
5103 }
5104
5105 /* while attempting to disarm an adjacent trap, we've fallen into it */
5106 STATIC_OVL void
5107 move_into_trap(ttmp)
5108 struct trap *ttmp;
5109 {
5110     int bc = 0;
5111     xchar x = ttmp->tx, y = ttmp->ty, bx, by, cx, cy;
5112     boolean unused;
5113
5114     bx = by = cx = cy = 0; /* lint suppression */
5115     /* we know there's no monster in the way, and we're not trapped */
5116     if (!Punished
5117         || drag_ball(x, y, &bc, &bx, &by, &cx, &cy, &unused, TRUE)) {
5118         u.ux0 = u.ux, u.uy0 = u.uy;
5119         u.ux = x, u.uy = y;
5120         u.umoved = TRUE;
5121         newsym(u.ux0, u.uy0);
5122         vision_recalc(1);
5123         check_leash(u.ux0, u.uy0);
5124         if (Punished)
5125             move_bc(0, bc, bx, by, cx, cy);
5126         /* marking the trap unseen forces dotrap() to treat it like a new
5127            discovery and prevents pickup() -> look_here() -> check_here()
5128            from giving a redundant "there is a <trap> here" message when
5129            there are objects covering this trap */
5130         ttmp->tseen = 0; /* hack for check_here() */
5131         /* trigger the trap */
5132         iflags.failing_untrap++; /* spoteffects() -> dotrap(,FAILEDUNTRAP) */
5133         spoteffects(TRUE); /* pickup() + dotrap() */
5134         iflags.failing_untrap--;
5135         /* this should no longer be necessary; before the failing_untrap
5136            hack, Flying hero would not trigger an unseen bear trap and
5137            setting it not-yet-seen above resulted in leaving it hidden */
5138         if ((ttmp = t_at(u.ux, u.uy)) != 0)
5139             ttmp->tseen = 1;
5140         exercise(A_WIS, FALSE);
5141     }
5142 }
5143
5144 /* 0: doesn't even try
5145  * 1: tries and fails
5146  * 2: succeeds
5147  */
5148 STATIC_OVL int
5149 try_disarm(ttmp, force_failure)
5150 struct trap *ttmp;
5151 boolean force_failure;
5152 {
5153     struct monst *mtmp = m_at(ttmp->tx, ttmp->ty);
5154     int ttype = ttmp->ttyp;
5155     boolean under_u = (!u.dx && !u.dy);
5156     boolean holdingtrap = (ttype == BEAR_TRAP || ttype == WEB);
5157
5158     /* Test for monster first, monsters are displayed instead of trap. */
5159     if (mtmp && (!mtmp->mtrapped || !holdingtrap)) {
5160 /*JP
5161         pline("%s is in the way.", Monnam(mtmp));
5162 */
5163         pline("\82»\82±\82É\82Í%s\82ª\82¢\82é\81D", Monnam(mtmp));
5164         return 0;
5165     }
5166     /* We might be forced to move onto the trap's location. */
5167     if (sobj_at(BOULDER, ttmp->tx, ttmp->ty) && !Passes_walls && !under_u) {
5168 /*JP
5169         There("is a boulder in your way.");
5170 */
5171         pline("\82»\82±\82É\82Í\8aâ\82ª\82 \82é\81D");
5172         return 0;
5173     }
5174     /* duplicate tight-space checks from test_move */
5175     if (u.dx && u.dy && bad_rock(youmonst.data, u.ux, ttmp->ty)
5176         && bad_rock(youmonst.data, ttmp->tx, u.uy)) {
5177         if ((invent && (inv_weight() + weight_cap() > 600))
5178             || bigmonst(youmonst.data)) {
5179             /* don't allow untrap if they can't get thru to it */
5180 #if 0 /*JP*/
5181             You("are unable to reach the %s!",
5182                 defsyms[trap_to_defsym(ttype)].explanation);
5183 #else
5184             You("%s\82É\93Í\82©\82È\82¢\81I",
5185                 defsyms[trap_to_defsym(ttype)].explanation);
5186 #endif
5187             return 0;
5188         }
5189     }
5190     /* untrappable traps are located on the ground. */
5191     if (!can_reach_floor(under_u)) {
5192         if (u.usteed && P_SKILL(P_RIDING) < P_BASIC)
5193             rider_cant_reach();
5194         else
5195 #if 0 /*JP*/
5196             You("are unable to reach the %s!",
5197                 defsyms[trap_to_defsym(ttype)].explanation);
5198 #else
5199             You("%s\82É\93Í\82©\82È\82¢\81I",
5200                 defsyms[trap_to_defsym(ttype)].explanation);
5201 #endif
5202         return 0;
5203     }
5204
5205     /* Will our hero succeed? */
5206     if (force_failure || untrap_prob(ttmp)) {
5207         if (rnl(5)) {
5208 /*JP
5209             pline("Whoops...");
5210 */
5211             pline("\82¤\82í\82Á\81D\81D\81D");
5212             if (mtmp) { /* must be a trap that holds monsters */
5213                 if (ttype == BEAR_TRAP) {
5214                     if (mtmp->mtame)
5215                         abuse_dog(mtmp);
5216                     mtmp->mhp -= rnd(4);
5217                     if (DEADMONSTER(mtmp))
5218                         killed(mtmp);
5219                 } else if (ttype == WEB) {
5220                     if (!webmaker(youmonst.data)) {
5221                         struct trap *ttmp2 = maketrap(u.ux, u.uy, WEB);
5222
5223                         if (ttmp2) {
5224                             pline_The(
5225 /*JP
5226                                 "webbing sticks to you.  You're caught too!");
5227 */
5228                                 "\82­\82à\82Ì\91\83\82ª\82 \82È\82½\82É\82©\82ç\82ñ\82Å\82«\82½\81D\82Ü\82·\82Ü\82·\95ß\82Ü\82Á\82Ä\82µ\82Ü\82Á\82½\81I");
5229                             dotrap(ttmp2, NOWEBMSG);
5230                             if (u.usteed && u.utrap) {
5231                                 /* you, not steed, are trapped */
5232                                 dismount_steed(DISMOUNT_FELL);
5233                             }
5234                         }
5235                     } else
5236 /*JP
5237                         pline("%s remains entangled.", Monnam(mtmp));
5238 */
5239                         pline("%s\82Í\82©\82ç\82Ü\82Á\82½\82Ü\82Ü\82¾\81D", Monnam(mtmp));
5240                 }
5241             } else if (under_u) {
5242                 /* [don't need the iflags.failing_untrap hack here] */
5243                 dotrap(ttmp, FAILEDUNTRAP);
5244             } else {
5245                 move_into_trap(ttmp);
5246             }
5247         } else {
5248 #if 0 /*JP*/
5249             pline("%s %s is difficult to %s.",
5250                   ttmp->madeby_u ? "Your" : under_u ? "This" : "That",
5251                   defsyms[trap_to_defsym(ttype)].explanation,
5252                   (ttype == WEB) ? "remove" : "disarm");
5253 #else
5254             pline("%s%s\82ð\89ð\8f\9c\82·\82é\82Ì\82Í\8d¢\93ï\82¾\81D",
5255                   ttmp->madeby_u ? "\82 \82È\82½\82Ì\8ed\8a|\82¯\82½" : under_u ? "\82±\82Ì" : "\82»\82Ì",
5256                   defsyms[trap_to_defsym(ttype)].explanation);
5257 #endif
5258         }
5259         return 1;
5260     }
5261     return 2;
5262 }
5263
5264 STATIC_OVL void
5265 reward_untrap(ttmp, mtmp)
5266 struct trap *ttmp;
5267 struct monst *mtmp;
5268 {
5269     if (!ttmp->madeby_u) {
5270         if (rnl(10) < 8 && !mtmp->mpeaceful && !mtmp->msleeping
5271             && !mtmp->mfrozen && !mindless(mtmp->data)
5272             && mtmp->data->mlet != S_HUMAN) {
5273             mtmp->mpeaceful = 1;
5274             set_malign(mtmp); /* reset alignment */
5275 /*JP
5276             pline("%s is grateful.", Monnam(mtmp));
5277 */
5278             pline("%s\82Í\8aì\82ñ\82Å\82¢\82é\81D", Monnam(mtmp));
5279         }
5280         /* Helping someone out of a trap is a nice thing to do,
5281          * A lawful may be rewarded, but not too often.  */
5282         if (!rn2(3) && !rnl(8) && u.ualign.type == A_LAWFUL) {
5283             adjalign(1);
5284 /*JP
5285             You_feel("that you did the right thing.");
5286 */
5287             You("\90³\82µ\82¢\82±\82Æ\82ð\82µ\82½\82æ\82¤\82È\8bC\82ª\82µ\82½\81D");
5288         }
5289     }
5290 }
5291
5292 STATIC_OVL int
5293 disarm_holdingtrap(ttmp) /* Helge Hafting */
5294 struct trap *ttmp;
5295 {
5296     struct monst *mtmp;
5297     int fails = try_disarm(ttmp, FALSE);
5298
5299     if (fails < 2)
5300         return fails;
5301
5302     /* ok, disarm it. */
5303
5304     /* untrap the monster, if any.
5305        There's no need for a cockatrice test, only the trap is touched */
5306     if ((mtmp = m_at(ttmp->tx, ttmp->ty)) != 0) {
5307         mtmp->mtrapped = 0;
5308 #if 0 /*JP*/
5309         You("remove %s %s from %s.", the_your[ttmp->madeby_u],
5310             (ttmp->ttyp == BEAR_TRAP) ? "bear trap" : "webbing",
5311             mon_nam(mtmp));
5312 #else
5313         You("%s%s\82ð%s\82©\82ç\82Í\82¸\82µ\82½\81D", set_you[ttmp->madeby_u],
5314             (ttmp->ttyp == BEAR_TRAP) ? "\8cF\82Ìã©" : "\82­\82à\82Ì\91\83",
5315             mon_nam(mtmp));
5316 #endif
5317         reward_untrap(ttmp, mtmp);
5318     } else {
5319         if (ttmp->ttyp == BEAR_TRAP) {
5320 /*JP
5321             You("disarm %s bear trap.", the_your[ttmp->madeby_u]);
5322 */
5323             You("%s\8cF\82Ìã©\82ð\89ð\8f\9c\82µ\82½\81D", set_you[ttmp->madeby_u]);
5324             cnv_trap_obj(BEARTRAP, 1, ttmp, FALSE);
5325         } else /* if (ttmp->ttyp == WEB) */ {
5326 /*JP
5327             You("succeed in removing %s web.", the_your[ttmp->madeby_u]);
5328 */
5329             You("%s\82­\82à\82Ì\91\83\82ð\8eæ\82è\8f\9c\82¢\82½\81D", set_you[ttmp->madeby_u]);
5330             deltrap(ttmp);
5331         }
5332     }
5333     newsym(u.ux + u.dx, u.uy + u.dy);
5334     return 1;
5335 }
5336
5337 STATIC_OVL int
5338 disarm_landmine(ttmp) /* Helge Hafting */
5339 struct trap *ttmp;
5340 {
5341     int fails = try_disarm(ttmp, FALSE);
5342
5343     if (fails < 2)
5344         return fails;
5345 /*JP
5346     You("disarm %s land mine.", the_your[ttmp->madeby_u]);
5347 */
5348     You("%s\92n\97\8b\82ð\89ð\8f\9c\82µ\82½\81D", set_you[ttmp->madeby_u]);
5349     cnv_trap_obj(LAND_MINE, 1, ttmp, FALSE);
5350     return 1;
5351 }
5352
5353 /* getobj will filter down to cans of grease and known potions of oil */
5354 static NEARDATA const char oil[] = { ALL_CLASSES, TOOL_CLASS, POTION_CLASS,
5355                                      0 };
5356
5357 /* it may not make much sense to use grease on floor boards, but so what? */
5358 STATIC_OVL int
5359 disarm_squeaky_board(ttmp)
5360 struct trap *ttmp;
5361 {
5362     struct obj *obj;
5363     boolean bad_tool;
5364     int fails;
5365
5366     obj = getobj(oil, "untrap with");
5367     if (!obj)
5368         return 0;
5369
5370     bad_tool = (obj->cursed
5371                 || ((obj->otyp != POT_OIL || obj->lamplit)
5372                     && (obj->otyp != CAN_OF_GREASE || !obj->spe)));
5373     fails = try_disarm(ttmp, bad_tool);
5374     if (fails < 2)
5375         return fails;
5376
5377     /* successfully used oil or grease to fix squeaky board */
5378     if (obj->otyp == CAN_OF_GREASE) {
5379         consume_obj_charge(obj, TRUE);
5380     } else {
5381         useup(obj); /* oil */
5382         makeknown(POT_OIL);
5383     }
5384 #if 0 /*JP*/
5385     You("repair the squeaky board."); /* no madeby_u */
5386 #else
5387     You("\82«\82µ\82Þ\94Â\82ð\8fC\97\9d\82µ\82½\81D"); /* no madeby_u */
5388 #endif
5389     deltrap(ttmp);
5390     newsym(u.ux + u.dx, u.uy + u.dy);
5391     more_experienced(1, 5);
5392     newexplevel();
5393     return 1;
5394 }
5395
5396 /* removes traps that shoot arrows, darts, etc. */
5397 STATIC_OVL int
5398 disarm_shooting_trap(ttmp, otyp)
5399 struct trap *ttmp;
5400 int otyp;
5401 {
5402     int fails = try_disarm(ttmp, FALSE);
5403
5404     if (fails < 2)
5405         return fails;
5406 /*JP
5407     You("disarm %s trap.", the_your[ttmp->madeby_u]);
5408 */
5409     pline("%sã©\82ð\89ð\8f\9c\82µ\82½\81D", set_you[ttmp->madeby_u]);
5410     cnv_trap_obj(otyp, 50 - rnl(50), ttmp, FALSE);
5411     return 1;
5412 }
5413
5414 /* Is the weight too heavy?
5415  * Formula as in near_capacity() & check_capacity() */
5416 STATIC_OVL int
5417 try_lift(mtmp, ttmp, wt, stuff)
5418 struct monst *mtmp;
5419 struct trap *ttmp;
5420 int wt;
5421 boolean stuff;
5422 {
5423     int wc = weight_cap();
5424
5425     if (((wt * 2) / wc) >= HVY_ENCUMBER) {
5426 #if 0 /*JP*/
5427         pline("%s is %s for you to lift.", Monnam(mtmp),
5428               stuff ? "carrying too much" : "too heavy");
5429 #else
5430         pline("%s\82Í%s\8e\9d\82¿\82 \82°\82é\82±\82Æ\82ª\82Å\82«\82È\82¢\81D", Monnam(mtmp),
5431               stuff ? "\95¨\82ð\8e\9d\82¿\82·\82¬\82Ä\82¨\82è" : "\8fd\82·\82¬\82Ä");
5432 #endif
5433         if (!ttmp->madeby_u && !mtmp->mpeaceful && mtmp->mcanmove
5434             && !mindless(mtmp->data) && mtmp->data->mlet != S_HUMAN
5435             && rnl(10) < 3) {
5436             mtmp->mpeaceful = 1;
5437             set_malign(mtmp); /* reset alignment */
5438 /*JP
5439             pline("%s thinks it was nice of you to try.", Monnam(mtmp));
5440 */
5441             pline("%s\82Í\82 \82È\82½\82Ì\93w\97Í\82É\8a´\8eÓ\82µ\82Ä\82¢\82é\82æ\82¤\82¾\81D", Monnam(mtmp));
5442         }
5443         return 0;
5444     }
5445     return 1;
5446 }
5447
5448 /* Help trapped monster (out of a (spiked) pit) */
5449 STATIC_OVL int
5450 help_monster_out(mtmp, ttmp)
5451 struct monst *mtmp;
5452 struct trap *ttmp;
5453 {
5454     int wt;
5455     struct obj *otmp;
5456     boolean uprob;
5457
5458     /*
5459      * This works when levitating too -- consistent with the ability
5460      * to hit monsters while levitating.
5461      *
5462      * Should perhaps check that our hero has arms/hands at the
5463      * moment.  Helping can also be done by engulfing...
5464      *
5465      * Test the monster first - monsters are displayed before traps.
5466      */
5467     if (!mtmp->mtrapped) {
5468 /*JP
5469         pline("%s isn't trapped.", Monnam(mtmp));
5470 */
5471         pline("%s\82Íã©\82É\82©\82©\82Á\82Ä\82¢\82È\82¢\81D", Monnam(mtmp));
5472         return 0;
5473     }
5474     /* Do you have the necessary capacity to lift anything? */
5475     if (check_capacity((char *) 0))
5476         return 1;
5477
5478     /* Will our hero succeed? */
5479     if ((uprob = untrap_prob(ttmp)) && !mtmp->msleeping && mtmp->mcanmove) {
5480 #if 0 /*JP*/
5481         You("try to reach out your %s, but %s backs away skeptically.",
5482             makeplural(body_part(ARM)), mon_nam(mtmp));
5483 #else
5484         You("%s\82ð\8d·\82µ\89\84\82×\82æ\82¤\82Æ\82µ\82½\82ª%s\82Í\8cx\89ú\82µ\82Ä\82¢\82é\81D",
5485             body_part(ARM), mon_nam(mtmp));
5486 #endif
5487         return 1;
5488     }
5489
5490     /* is it a cockatrice?... */
5491     if (touch_petrifies(mtmp->data) && !uarmg && !Stone_resistance) {
5492 #if 0 /*JP*/
5493         You("grab the trapped %s using your bare %s.", mtmp->data->mname,
5494             makeplural(body_part(HAND)));
5495 #else
5496         You("ã©\82É\82©\82©\82Á\82Ä\82¢\82é%s\82ð\91f%s\82Å\92Í\82ñ\82¾\81D", mtmp->data->mname,
5497             body_part(HAND));
5498 #endif
5499
5500         if (poly_when_stoned(youmonst.data) && polymon(PM_STONE_GOLEM)) {
5501             display_nhwindow(WIN_MESSAGE, FALSE);
5502         } else {
5503             char kbuf[BUFSZ];
5504
5505 #if 0 /*JP*/
5506             Sprintf(kbuf, "trying to help %s out of a pit",
5507                     an(mtmp->data->mname));
5508 #else
5509             Sprintf(kbuf, "ã©\82É\82©\82©\82Á\82Ä\82¢\82é%s\82ð\8f\95\82¯\82æ\82¤\82Æ\82µ\82Ä",
5510                     a_monnam(mtmp));
5511 #endif
5512             instapetrify(kbuf);
5513             return 1;
5514         }
5515     }
5516     /* need to do cockatrice check first if sleeping or paralyzed */
5517     if (uprob) {
5518 /*JP
5519         You("try to grab %s, but cannot get a firm grasp.", mon_nam(mtmp));
5520 */
5521         You("%s\82ð\82Â\82©\82à\82¤\82Æ\82µ\82½\82ª\81C\82µ\82Á\82©\82è\82Æ\88¬\82ê\82È\82©\82Á\82½\81D", mon_nam(mtmp));
5522         if (mtmp->msleeping) {
5523             mtmp->msleeping = 0;
5524 /*JP
5525             pline("%s awakens.", Monnam(mtmp));
5526 */
5527             pline("%s\82Í\96Ú\82ð\8ao\82Ü\82µ\82½\81D", Monnam(mtmp));
5528         }
5529         return 1;
5530     }
5531
5532 #if 0 /*JP*/
5533     You("reach out your %s and grab %s.", makeplural(body_part(ARM)),
5534         mon_nam(mtmp));
5535 #else
5536     You("%s\82ð\90L\82Î\82µ\82Ä%s\82ð\82Â\82©\82ñ\82¾\81D", body_part(ARM),
5537         mon_nam(mtmp));
5538 #endif
5539
5540     if (mtmp->msleeping) {
5541         mtmp->msleeping = 0;
5542 /*JP
5543         pline("%s awakens.", Monnam(mtmp));
5544 */
5545         pline("%s\82Í\96Ú\82ð\8ao\82Ü\82µ\82½\81D", Monnam(mtmp));
5546     } else if (mtmp->mfrozen && !rn2(mtmp->mfrozen)) {
5547         /* After such manhandling, perhaps the effect wears off */
5548         mtmp->mcanmove = 1;
5549         mtmp->mfrozen = 0;
5550 /*JP
5551         pline("%s stirs.", Monnam(mtmp));
5552 */
5553         pline("%s\82Í\93®\82«\8en\82ß\82½\81D", Monnam(mtmp));
5554     }
5555
5556     /* is the monster too heavy? */
5557     wt = inv_weight() + mtmp->data->cwt;
5558     if (!try_lift(mtmp, ttmp, wt, FALSE))
5559         return 1;
5560
5561     /* is the monster with inventory too heavy? */
5562     for (otmp = mtmp->minvent; otmp; otmp = otmp->nobj)
5563         wt += otmp->owt;
5564     if (!try_lift(mtmp, ttmp, wt, TRUE))
5565         return 1;
5566
5567 /*JP
5568     You("pull %s out of the pit.", mon_nam(mtmp));
5569 */
5570     You("%s\82ð\97\8e\82µ\8c\8a\82©\82ç\82Ð\82Á\82Ï\82Á\82½\81D", mon_nam(mtmp));
5571     mtmp->mtrapped = 0;
5572     fill_pit(mtmp->mx, mtmp->my);
5573     reward_untrap(ttmp, mtmp);
5574     return 1;
5575 }
5576
5577 int
5578 untrap(force)
5579 boolean force;
5580 {
5581     register struct obj *otmp;
5582     register int x, y;
5583     int ch;
5584     struct trap *ttmp;
5585     struct monst *mtmp;
5586     const char *trapdescr;
5587 #if 0 /*JP*/
5588     boolean here, useplural, deal_with_floor_trap,
5589             confused = (Confusion || Hallucination),
5590             trap_skipped = FALSE;
5591 #else
5592     boolean here, deal_with_floor_trap,
5593             confused = (Confusion || Hallucination),
5594             trap_skipped = FALSE;
5595 #endif
5596     int boxcnt = 0;
5597     char the_trap[BUFSZ], qbuf[QBUFSZ];
5598
5599     if (!getdir((char *) 0))
5600         return 0;
5601     x = u.ux + u.dx;
5602     y = u.uy + u.dy;
5603     if (!isok(x, y)) {
5604 /*JP
5605         pline_The("perils lurking there are beyond your grasp.");
5606 */
5607         pline_The("\82»\82±\82É\82 \82é\8aë\8c¯\82Í\82 \82È\82½\82Ì\8eè\82É\95\89\82¦\82È\82¢\81D");
5608         return 0;
5609     }
5610     /* 'force' is true for #invoke; make it be true for #untrap if
5611        carrying MKoT */
5612     if (!force && has_magic_key(&youmonst))
5613         force = TRUE;
5614
5615     ttmp = t_at(x, y);
5616     if (ttmp && !ttmp->tseen)
5617         ttmp = 0;
5618     trapdescr = ttmp ? defsyms[trap_to_defsym(ttmp->ttyp)].explanation : 0;
5619     here = (x == u.ux && y == u.uy); /* !u.dx && !u.dy */
5620
5621     if (here) /* are there are one or more containers here? */
5622         for (otmp = level.objects[x][y]; otmp; otmp = otmp->nexthere)
5623             if (Is_box(otmp)) {
5624                 if (++boxcnt > 1)
5625                     break;
5626             }
5627
5628     deal_with_floor_trap = can_reach_floor(FALSE);
5629     if (!deal_with_floor_trap) {
5630         *the_trap = '\0';
5631         if (ttmp)
5632             Strcat(the_trap, an(trapdescr));
5633         if (ttmp && boxcnt)
5634 /*JP
5635             Strcat(the_trap, " and ");
5636 */
5637             Strcat(the_trap, "\82Æ");
5638         if (boxcnt)
5639 /*JP
5640             Strcat(the_trap, (boxcnt == 1) ? "a container" : "containers");
5641 */
5642             Strcat(the_trap, "\97e\8aí");
5643 #if 0 /*JP*/
5644         useplural = ((ttmp && boxcnt > 0) || boxcnt > 1);
5645 #endif
5646         /* note: boxcnt and useplural will always be 0 for !here case */
5647         if (ttmp || boxcnt)
5648 #if 0 /*JP*/
5649             There("%s %s %s but you can't reach %s%s.",
5650                   useplural ? "are" : "is", the_trap, here ? "here" : "there",
5651                   useplural ? "them" : "it",
5652                   u.usteed ? " while mounted" : "");
5653 #else
5654             pline("%s\82ª\82 \82é\82ª\81C%s\93Í\82©\82È\82¢\81D",
5655                   the_trap,
5656                   u.usteed ? "\8fæ\82Á\82Ä\82¢\82é\82Æ" : "");
5657 #endif
5658         trap_skipped = (ttmp != 0);
5659     } else { /* deal_with_floor_trap */
5660
5661         if (ttmp) {
5662             Strcpy(the_trap, the(trapdescr));
5663             if (boxcnt) {
5664                 if (is_pit(ttmp->ttyp)) {
5665 #if 0 /*JP:T*/
5666                     You_cant("do much about %s%s.", the_trap,
5667                              u.utrap ? " that you're stuck in"
5668                                      : " while standing on the edge of it");
5669 #else
5670                     pline("%s%s\82É\91Î\82µ\82Ä\82Í\82½\82¢\82µ\82½\82±\82Æ\82Í\82Å\82«\82È\82¢\81D",
5671                           u.utrap ? "\8e©\95ª\82ª\82Í\82Ü\82Á\82Ä\82¢\82é"
5672                                   : "\82·\82®\82»\82Î\82Ì",
5673                           the_trap);
5674 #endif
5675                     trap_skipped = TRUE;
5676                     deal_with_floor_trap = FALSE;
5677                 } else {
5678 #if 0 /*JP:T*/
5679                     Sprintf(
5680                         qbuf, "There %s and %s here.  %s %s?",
5681                         (boxcnt == 1) ? "is a container" : "are containers",
5682                         an(trapdescr),
5683                         (ttmp->ttyp == WEB) ? "Remove" : "Disarm", the_trap);
5684 #else
5685                     Sprintf(
5686                         qbuf, "\94 \82Æ%s\82ª\82 \82é\81D%s\81H",
5687                         trapdescr,
5688                         (ttmp->ttyp == WEB) ? "\8eæ\82è\8f\9c\82­" : "\89ð\8f\9c\82·\82é");
5689 #endif
5690                     switch (ynq(qbuf)) {
5691                     case 'q':
5692                         return 0;
5693                     case 'n':
5694                         trap_skipped = TRUE;
5695                         deal_with_floor_trap = FALSE;
5696                         break;
5697                     }
5698                 }
5699             }
5700             if (deal_with_floor_trap) {
5701                 if (u.utrap) {
5702 #if 0 /*JP*/
5703                     You("cannot deal with %s while trapped%s!", the_trap,
5704                         (x == u.ux && y == u.uy) ? " in it" : "");
5705 #else
5706                     pline("ã©\82É\82©\82©\82Á\82Ä\82¢\82é\8aÔ\82Íã©\82ð\89ð\8f\9c\82Å\82«\82È\82¢\81I");
5707 #endif
5708                     return 1;
5709                 }
5710                 if ((mtmp = m_at(x, y)) != 0
5711                     && (M_AP_TYPE(mtmp) == M_AP_FURNITURE
5712                         || M_AP_TYPE(mtmp) == M_AP_OBJECT)) {
5713                     stumble_onto_mimic(mtmp);
5714                     return 1;
5715                 }
5716                 switch (ttmp->ttyp) {
5717                 case BEAR_TRAP:
5718                 case WEB:
5719                     return disarm_holdingtrap(ttmp);
5720                 case LANDMINE:
5721                     return disarm_landmine(ttmp);
5722                 case SQKY_BOARD:
5723                     return disarm_squeaky_board(ttmp);
5724                 case DART_TRAP:
5725                     return disarm_shooting_trap(ttmp, DART);
5726                 case ARROW_TRAP:
5727                     return disarm_shooting_trap(ttmp, ARROW);
5728                 case PIT:
5729                 case SPIKED_PIT:
5730                     if (here) {
5731 /*JP
5732                         You("are already on the edge of the pit.");
5733 */
5734                         You("\82à\82¤\97\8e\82µ\8c\8a\82Ì\92[\82É\82¢\82é\81D");
5735                         return 0;
5736                     }
5737                     if (!mtmp) {
5738 /*JP
5739                         pline("Try filling the pit instead.");
5740 */
5741                         pline("\82È\82ñ\82Æ\82©\96\84\82ß\82é\82±\82Æ\82ð\8dl\82¦\82Ä\82Ý\82½\82ç\81H");
5742                         return 0;
5743                     }
5744                     return help_monster_out(mtmp, ttmp);
5745                 default:
5746 /*JP
5747                     You("cannot disable %s trap.", !here ? "that" : "this");
5748 */
5749                     pline("%sã©\82Í\89ð\8f\9c\82Å\82«\82È\82¢\81D", !here ? "\82»\82Ì" : "\82±\82Ì");
5750                     return 0;
5751                 }
5752             }
5753         } /* end if */
5754
5755         if (boxcnt) {
5756             for (otmp = level.objects[x][y]; otmp; otmp = otmp->nexthere)
5757                 if (Is_box(otmp)) {
5758 #if 0 /*JP*/
5759                     (void) safe_qbuf(qbuf, "There is ",
5760                                      " here.  Check it for traps?", otmp,
5761                                      doname, ansimpleoname, "a box");
5762 #else
5763                     (void) safe_qbuf(qbuf, "",
5764                                      "\82ª\82 \82é\81Dã©\82ð\92²\82×\82Ü\82·\82©\81H", otmp,
5765                                      doname, ansimpleoname, "\94 ");
5766 #endif
5767                     switch (ynq(qbuf)) {
5768                     case 'q':
5769                         return 0;
5770                     case 'n':
5771                         continue;
5772                     }
5773
5774                     if ((otmp->otrapped
5775                          && (force || (!confused
5776                                        && rn2(MAXULEV + 1 - u.ulevel) < 10)))
5777                         || (!force && confused && !rn2(3))) {
5778 /*JP
5779                         You("find a trap on %s!", the(xname(otmp)));
5780 */
5781                         pline("%s\82Éã©\82ð\94­\8c©\82µ\82½\81I", the(xname(otmp)));
5782                         if (!confused)
5783                             exercise(A_WIS, TRUE);
5784
5785 /*JP
5786                         switch (ynq("Disarm it?")) {
5787 */
5788                         switch (ynq("\89ð\8f\9c\82µ\82Ü\82·\82©\81H")) {
5789                         case 'q':
5790                             return 1;
5791                         case 'n':
5792                             trap_skipped = TRUE;
5793                             continue;
5794                         }
5795
5796                         if (otmp->otrapped) {
5797                             exercise(A_DEX, TRUE);
5798                             ch = ACURR(A_DEX) + u.ulevel;
5799                             if (Role_if(PM_ROGUE))
5800                                 ch *= 2;
5801                             if (!force && (confused || Fumbling
5802                                            || rnd(75 + level_difficulty() / 2)
5803                                                   > ch)) {
5804                                 (void) chest_trap(otmp, FINGER, TRUE);
5805                             } else {
5806 /*JP
5807                                 You("disarm it!");
5808 */
5809                                 You("\89ð\8f\9c\82µ\82½\81I");
5810                                 otmp->otrapped = 0;
5811                             }
5812                         } else
5813 /*JP
5814                             pline("That %s was not trapped.", xname(otmp));
5815 */
5816                             pline("\82»\82Ì%s\82Éã©\82Í\82È\82¢\81D", xname(otmp));
5817                         return 1;
5818                     } else {
5819 /*JP
5820                         You("find no traps on %s.", the(xname(otmp)));
5821 */
5822                         pline("ã©\82ð\94­\8c©\82Å\82«\82È\82©\82Á\82½\81D");
5823                         return 1;
5824                     }
5825                 }
5826
5827 #if 0 /*JP*/
5828             You(trap_skipped ? "find no other traps here."
5829                              : "know of no traps here.");
5830 #else
5831             You(trap_skipped ? "\91¼\82Ìã©\82ð\8c©\82Â\82¯\82ç\82ê\82È\82©\82Á\82½\81D"
5832                              : "\82±\82±\82Éã©\82ª\82È\82¢\82±\82Æ\82ð\92m\82Á\82Ä\82¢\82é\81D");
5833 #endif
5834             return 0;
5835         }
5836
5837         if (stumble_on_door_mimic(x, y))
5838             return 1;
5839
5840     } /* deal_with_floor_trap */
5841     /* doors can be manipulated even while levitating/unskilled riding */
5842
5843     if (!IS_DOOR(levl[x][y].typ)) {
5844         if (!trap_skipped)
5845 /*JP
5846             You("know of no traps there.");
5847 */
5848             You("\82»\82±\82Éã©\82ª\82È\82¢\82±\82Æ\82ð\92m\82Á\82Ä\82¢\82é\81D");
5849         return 0;
5850     }
5851
5852     switch (levl[x][y].doormask) {
5853     case D_NODOOR:
5854 /*JP
5855         You("%s no door there.", Blind ? "feel" : "see");
5856 */
5857         pline("\82»\82±\82É\82Í\94à\82ª\82È\82¢%s\81D", Blind ? "\82æ\82¤\82¾" : "\82æ\82¤\82É\8c©\82¦\82é");
5858         return 0;
5859     case D_ISOPEN:
5860 /*JP
5861         pline("This door is safely open.");
5862 */
5863         pline("\82»\82Ì\94à\82Í\88À\91S\82É\8aJ\82¢\82Ä\82¢\82é\81D");
5864         return 0;
5865     case D_BROKEN:
5866 /*JP
5867         pline("This door is broken.");
5868 */
5869         pline("\82»\82Ì\94à\82Í\89ó\82ê\82Ä\82¢\82é\81D");
5870         return 0;
5871     }
5872
5873     if (((levl[x][y].doormask & D_TRAPPED) != 0
5874          && (force || (!confused && rn2(MAXULEV - u.ulevel + 11) < 10)))
5875         || (!force && confused && !rn2(3))) {
5876 /*JP
5877         You("find a trap on the door!");
5878 */
5879         pline("\94à\82Éã©\82ð\94­\8c©\82µ\82½\81I");
5880         exercise(A_WIS, TRUE);
5881 /*JP
5882         if (ynq("Disarm it?") != 'y')
5883 */
5884         if (ynq("\89ð\8f\9c\82µ\82Ü\82·\82©\81H") != 'y')
5885             return 1;
5886         if (levl[x][y].doormask & D_TRAPPED) {
5887             ch = 15 + (Role_if(PM_ROGUE) ? u.ulevel * 3 : u.ulevel);
5888             exercise(A_DEX, TRUE);
5889             if (!force && (confused || Fumbling
5890                            || rnd(75 + level_difficulty() / 2) > ch)) {
5891 /*JP
5892                 You("set it off!");
5893 */
5894                 You("\83X\83C\83b\83`\82ð\93ü\82ê\82Ä\82µ\82Ü\82Á\82½\81I");
5895 /*JP
5896                 b_trapped("door", FINGER);
5897 */
5898                 b_trapped("\94à", FINGER);
5899                 levl[x][y].doormask = D_NODOOR;
5900                 unblock_point(x, y);
5901                 newsym(x, y);
5902                 /* (probably ought to charge for this damage...) */
5903                 if (*in_rooms(x, y, SHOPBASE))
5904                     add_damage(x, y, 0L);
5905             } else {
5906 /*JP
5907                 You("disarm it!");
5908 */
5909                 You("\89ð\8f\9c\82µ\82½\81I");
5910                 levl[x][y].doormask &= ~D_TRAPPED;
5911             }
5912         } else
5913 /*JP
5914             pline("This door was not trapped.");
5915 */
5916             pline("\94à\82Éã©\82Í\82È\82©\82Á\82½\81D");
5917         return 1;
5918     } else {
5919 /*JP
5920         You("find no traps on the door.");
5921 */
5922         pline("\94à\82Éã©\82ð\94­\8c©\82Å\82«\82È\82©\82Á\82½\81D");
5923         return 1;
5924     }
5925 }
5926
5927 /* for magic unlocking; returns true if targetted monster (which might
5928    be hero) gets untrapped; the trap remains intact */
5929 boolean
5930 openholdingtrap(mon, noticed)
5931 struct monst *mon;
5932 boolean *noticed; /* set to true iff hero notices the effect; */
5933 {                 /* otherwise left with its previous value intact */
5934     struct trap *t;
5935     char buf[BUFSZ], whichbuf[20];
5936     const char *trapdescr = 0, *which = 0;
5937     boolean ishero = (mon == &youmonst);
5938
5939     if (!mon)
5940         return FALSE;
5941     if (mon == u.usteed)
5942         ishero = TRUE;
5943
5944     t = t_at(ishero ? u.ux : mon->mx, ishero ? u.uy : mon->my);
5945
5946     if (ishero && u.utrap) { /* all u.utraptype values are holding traps */
5947         which = "";
5948         switch (u.utraptype) {
5949         case TT_LAVA:
5950             trapdescr = "molten lava";
5951             break;
5952         case TT_INFLOOR:
5953             /* solidified lava, so not "floor" even if within a room */
5954             trapdescr = "ground";
5955             break;
5956         case TT_BURIEDBALL:
5957             trapdescr = "your anchor";
5958             break;
5959         case TT_BEARTRAP:
5960         case TT_PIT:
5961         case TT_WEB:
5962             trapdescr = 0; /* use defsyms[].explanation */
5963             break;
5964         default:
5965             /* lint suppression in case 't' is unexpectedly Null
5966                or u.utraptype has new value we don't know about yet */
5967             trapdescr = "trap";
5968             break;
5969         }
5970     } else {
5971         /* if no trap here or it's not a holding trap, we're done */
5972         if (!t || (t->ttyp != BEAR_TRAP && t->ttyp != WEB))
5973             return FALSE;
5974     }
5975
5976     if (!trapdescr)
5977         trapdescr = defsyms[trap_to_defsym(t->ttyp)].explanation;
5978     if (!which)
5979 #if 0 /*JP*/
5980         which = t->tseen ? the_your[t->madeby_u]
5981                          : index(vowels, *trapdescr) ? "an" : "a";
5982 #else
5983         which = t->tseen ? set_you[t->madeby_u] : "";
5984 #endif
5985     if (*which)
5986         which = strcat(strcpy(whichbuf, which), " ");
5987
5988     if (ishero) {
5989         if (!u.utrap)
5990             return FALSE;
5991         *noticed = TRUE;
5992         if (u.usteed)
5993 /*JP
5994                 Sprintf(buf, "%s is", noit_Monnam(u.usteed));
5995 */
5996                 Strcpy(buf, noit_Monnam(u.usteed));
5997         else
5998 /*JP
5999                 Strcpy(buf, "You are");
6000 */
6001                 Strcpy(buf, "\82 \82È\82½");
6002 /*JP
6003         pline("%s released from %s%s.", buf, which, trapdescr);
6004 */
6005         pline("%s\82Í%s%s\82©\82ç\89ð\95ú\82³\82ê\82½\81D", buf, which, trapdescr);
6006         reset_utrap(TRUE);
6007     } else {
6008         if (!mon->mtrapped)
6009             return FALSE;
6010         mon->mtrapped = 0;
6011         if (canspotmon(mon)) {
6012             *noticed = TRUE;
6013 #if 0 /*JP*/
6014             pline("%s is released from %s%s.", Monnam(mon), which,
6015                   trapdescr);
6016 #else
6017             pline("%s\82Í%s%s\82©\82ç\89ð\95ú\82³\82ê\82½\81D", Monnam(mon), which,
6018                   trapdescr);
6019 #endif
6020         } else if (cansee(t->tx, t->ty) && t->tseen) {
6021             *noticed = TRUE;
6022             if (t->ttyp == WEB)
6023 #if 0 /*JP:T*/
6024                 pline("%s is released from %s%s.", Something, which,
6025                       trapdescr);
6026 #else
6027                 pline("\89½\8eÒ\82©\82Í%s%s\82©\82ç\89ð\95ú\82³\82ê\82½\81D", which,
6028                       trapdescr);
6029 #endif
6030             else /* BEAR_TRAP */
6031 /*JP
6032                 pline("%s%s opens.", upstart(strcpy(buf, which)), trapdescr);
6033 */
6034                 pline("%s%s\82Í\8aJ\82¢\82½\81D", which, trapdescr);
6035         }
6036         /* might pacify monster if adjacent */
6037         if (rn2(2) && distu(mon->mx, mon->my) <= 2)
6038             reward_untrap(t, mon);
6039     }
6040     return TRUE;
6041 }
6042
6043 /* for magic locking; returns true if targetted monster (which might
6044    be hero) gets hit by a trap (might avoid actually becoming trapped) */
6045 boolean
6046 closeholdingtrap(mon, noticed)
6047 struct monst *mon;
6048 boolean *noticed; /* set to true iff hero notices the effect; */
6049 {                 /* otherwise left with its previous value intact */
6050     struct trap *t;
6051     unsigned dotrapflags;
6052     boolean ishero = (mon == &youmonst), result;
6053
6054     if (!mon)
6055         return FALSE;
6056     if (mon == u.usteed)
6057         ishero = TRUE;
6058     t = t_at(ishero ? u.ux : mon->mx, ishero ? u.uy : mon->my);
6059     /* if no trap here or it's not a holding trap, we're done */
6060     if (!t || (t->ttyp != BEAR_TRAP && t->ttyp != WEB))
6061         return FALSE;
6062
6063     if (ishero) {
6064         if (u.utrap)
6065             return FALSE; /* already trapped */
6066         *noticed = TRUE;
6067         dotrapflags = FORCETRAP;
6068         /* dotrap calls mintrap when mounted hero encounters a web */
6069         if (u.usteed)
6070             dotrapflags |= NOWEBMSG;
6071         ++force_mintrap;
6072         dotrap(t, dotrapflags);
6073         --force_mintrap;
6074         result = (u.utrap != 0);
6075     } else {
6076         if (mon->mtrapped)
6077             return FALSE; /* already trapped */
6078         /* you notice it if you see the trap close/tremble/whatever
6079            or if you sense the monster who becomes trapped */
6080         *noticed = cansee(t->tx, t->ty) || canspotmon(mon);
6081         ++force_mintrap;
6082         result = (mintrap(mon) != 0);
6083         --force_mintrap;
6084     }
6085     return result;
6086 }
6087
6088 /* for magic unlocking; returns true if targetted monster (which might
6089    be hero) gets hit by a trap (target might avoid its effect) */
6090 boolean
6091 openfallingtrap(mon, trapdoor_only, noticed)
6092 struct monst *mon;
6093 boolean trapdoor_only;
6094 boolean *noticed; /* set to true iff hero notices the effect; */
6095 {                 /* otherwise left with its previous value intact */
6096     struct trap *t;
6097     boolean ishero = (mon == &youmonst), result;
6098
6099     if (!mon)
6100         return FALSE;
6101     if (mon == u.usteed)
6102         ishero = TRUE;
6103     t = t_at(ishero ? u.ux : mon->mx, ishero ? u.uy : mon->my);
6104     /* if no trap here or it's not a falling trap, we're done
6105        (note: falling rock traps have a trapdoor in the ceiling) */
6106     if (!t || ((t->ttyp != TRAPDOOR && t->ttyp != ROCKTRAP)
6107                && (trapdoor_only || (t->ttyp != HOLE && !is_pit(t->ttyp)))))
6108         return FALSE;
6109
6110     if (ishero) {
6111         if (u.utrap)
6112             return FALSE; /* already trapped */
6113         *noticed = TRUE;
6114         dotrap(t, FORCETRAP);
6115         result = (u.utrap != 0);
6116     } else {
6117         if (mon->mtrapped)
6118             return FALSE; /* already trapped */
6119         /* you notice it if you see the trap close/tremble/whatever
6120            or if you sense the monster who becomes trapped */
6121         *noticed = cansee(t->tx, t->ty) || canspotmon(mon);
6122         /* monster will be angered; mintrap doesn't handle that */
6123         wakeup(mon, TRUE);
6124         ++force_mintrap;
6125         result = (mintrap(mon) != 0);
6126         --force_mintrap;
6127         /* mon might now be on the migrating monsters list */
6128     }
6129     return result;
6130 }
6131
6132 /* only called when the player is doing something to the chest directly */
6133 boolean
6134 chest_trap(obj, bodypart, disarm)
6135 register struct obj *obj;
6136 register int bodypart;
6137 boolean disarm;
6138 {
6139     register struct obj *otmp = obj, *otmp2;
6140     char buf[80];
6141     const char *msg;
6142     coord cc;
6143
6144     if (get_obj_location(obj, &cc.x, &cc.y, 0)) /* might be carried */
6145         obj->ox = cc.x, obj->oy = cc.y;
6146
6147     otmp->otrapped = 0; /* trap is one-shot; clear flag first in case
6148                            chest kills you and ends up in bones file */
6149 /*JP
6150     You(disarm ? "set it off!" : "trigger a trap!");
6151 */
6152     You(disarm ? "\83X\83C\83b\83`\82ð\93ü\82ê\82Ä\82µ\82Ü\82Á\82½\81I" : "ã©\82É\82Ð\82Á\82©\82©\82Á\82½\81I");
6153     display_nhwindow(WIN_MESSAGE, FALSE);
6154     if (Luck > -13 && rn2(13 + Luck) > 7) { /* saved by luck */
6155         /* trap went off, but good luck prevents damage */
6156         switch (rn2(13)) {
6157         case 12:
6158         case 11:
6159 /*JP
6160             msg = "explosive charge is a dud";
6161 */
6162             msg = "\94\9a\94­\82Í\95s\94­\82¾\82Á\82½";
6163             break;
6164         case 10:
6165         case 9:
6166 /*JP
6167             msg = "electric charge is grounded";
6168 */
6169             msg = "\93d\8c\82\82ª\95ú\8fo\82³\82ê\82½\82ª\83A\81[\83X\82³\82ê\82Ä\82¢\82½";
6170             break;
6171         case 8:
6172         case 7:
6173 /*JP
6174             msg = "flame fizzles out";
6175 */
6176             msg = "\89\8a\82Í\83V\83\85\81[\82Á\82Æ\8fÁ\82¦\82½";
6177             break;
6178         case 6:
6179         case 5:
6180         case 4:
6181 /*JP
6182             msg = "poisoned needle misses";
6183 */
6184             msg = "\93Å\90j\82Í\8eh\82³\82ç\82È\82©\82Á\82½";
6185             break;
6186         case 3:
6187         case 2:
6188         case 1:
6189         case 0:
6190 /*JP
6191             msg = "gas cloud blows away";
6192 */
6193             msg = "\83K\83X\89_\82Í\90\81\82«\94ò\82ñ\82¾";
6194             break;
6195         default:
6196             impossible("chest disarm bug");
6197             msg = (char *) 0;
6198             break;
6199         }
6200         if (msg)
6201 /*JP
6202             pline("But luckily the %s!", msg);
6203 */
6204             pline("\82µ\82©\82µ\89^\82Ì\82æ\82¢\82±\82Æ\82É%s\81I", msg);
6205     } else {
6206         switch (rn2(20) ? ((Luck >= 13) ? 0 : rn2(13 - Luck)) : rn2(26)) {
6207         case 25:
6208         case 24:
6209         case 23:
6210         case 22:
6211         case 21: {
6212             struct monst *shkp = 0;
6213             long loss = 0L;
6214             boolean costly, insider;
6215             register xchar ox = obj->ox, oy = obj->oy;
6216
6217             /* the obj location need not be that of player */
6218             costly = (costly_spot(ox, oy)
6219                       && (shkp = shop_keeper(*in_rooms(ox, oy, SHOPBASE)))
6220                              != (struct monst *) 0);
6221             insider = (*u.ushops && inside_shop(u.ux, u.uy)
6222                        && *in_rooms(ox, oy, SHOPBASE) == *u.ushops);
6223
6224 /*JP
6225             pline("%s!", Tobjnam(obj, "explode"));
6226 */
6227             pline("%s\82Í\94\9a\94­\82µ\82½\81I", xname(obj));
6228 /*JP
6229             Sprintf(buf, "exploding %s", xname(obj));
6230 */
6231             Sprintf(buf, "%s\82Ì\94\9a\94­\82Å", xname(obj));
6232
6233             if (costly)
6234                 loss += stolen_value(obj, ox, oy, (boolean) shkp->mpeaceful,
6235                                      TRUE);
6236             delete_contents(obj);
6237             /* unpunish() in advance if either ball or chain (or both)
6238                is going to be destroyed */
6239             if (Punished && ((uchain->ox == u.ux && uchain->oy == u.uy)
6240                              || (uball->where == OBJ_FLOOR
6241                                  && uball->ox == u.ux && uball->oy == u.uy)))
6242                 unpunish();
6243
6244             for (otmp = level.objects[u.ux][u.uy]; otmp; otmp = otmp2) {
6245                 otmp2 = otmp->nexthere;
6246                 if (costly)
6247                     loss += stolen_value(otmp, otmp->ox, otmp->oy,
6248                                          (boolean) shkp->mpeaceful, TRUE);
6249                 delobj(otmp);
6250             }
6251             wake_nearby();
6252             losehp(Maybe_Half_Phys(d(6, 6)), buf, KILLED_BY_AN);
6253             exercise(A_STR, FALSE);
6254             if (costly && loss) {
6255                 if (insider)
6256 #if 0 /*JP*/
6257                     You("owe %ld %s for objects destroyed.", loss,
6258                         currency(loss));
6259 #else
6260                     You("\8aí\95¨\94j\91¹\82Å%ld%s\82Ì\8eØ\82è\82ð\82Â\82­\82Á\82½\81D", loss,
6261                         currency(loss));
6262 #endif
6263                 else {
6264 #if 0 /*JP*/
6265                     You("caused %ld %s worth of damage!", loss,
6266                         currency(loss));
6267 #else
6268                     You("%ld%s\95ª\82Ì\91¹\8aQ\82ð\88ø\82«\82¨\82±\82µ\82½\81I", loss,
6269                         currency(loss));
6270 #endif
6271                     make_angry_shk(shkp, ox, oy);
6272                 }
6273             }
6274             return TRUE;
6275         } /* case 21 */
6276         case 20:
6277         case 19:
6278         case 18:
6279         case 17:
6280 /*JP
6281             pline("A cloud of noxious gas billows from %s.", the(xname(obj)));
6282 */
6283             pline("\97L\93Å\83K\83X\82ª%s\82©\82ç\89Q\82Ü\82¢\82½\81D", the(xname(obj)));
6284 /*JP
6285             poisoned("gas cloud", A_STR, "cloud of poison gas", 15, FALSE);
6286 */
6287             poisoned("\83K\83X\89_", A_STR, "\83K\83X\89_", 15, FALSE);
6288             exercise(A_CON, FALSE);
6289             break;
6290         case 16:
6291         case 15:
6292         case 14:
6293         case 13:
6294 /*JP
6295             You_feel("a needle prick your %s.", body_part(bodypart));
6296 */
6297             You("%s\83`\83N\83b\82Æ\82¢\82¤\92É\82Ý\82ð\8a´\82\82½\81D", body_part(bodypart));
6298 /*JP
6299             poisoned("needle", A_CON, "poisoned needle", 10, FALSE);
6300 */
6301             poisoned("\90j", A_CON, "\93Å\90j", 10, FALSE);
6302             exercise(A_CON, FALSE);
6303             break;
6304         case 12:
6305         case 11:
6306         case 10:
6307         case 9:
6308             dofiretrap(obj);
6309             break;
6310         case 8:
6311         case 7:
6312         case 6: {
6313             int dmg;
6314
6315 /*JP
6316             You("are jolted by a surge of electricity!");
6317 */
6318             You("\93d\8bC\83V\83\87\83b\83N\82ð\82­\82ç\82Á\82½\81I");
6319             if (Shock_resistance) {
6320                 shieldeff(u.ux, u.uy);
6321 /*JP
6322                 You("don't seem to be affected.");
6323 */
6324                 pline("\82µ\82©\82µ\82 \82È\82½\82Í\89e\8b¿\82ð\8eó\82¯\82È\82¢\81D");
6325                 dmg = 0;
6326             } else
6327                 dmg = d(4, 4);
6328             destroy_item(RING_CLASS, AD_ELEC);
6329             destroy_item(WAND_CLASS, AD_ELEC);
6330             if (dmg)
6331 /*JP
6332                 losehp(dmg, "electric shock", KILLED_BY_AN);
6333 */
6334                 losehp(dmg, "\93d\8bC\83V\83\87\83b\83N\82Å", KILLED_BY_AN);
6335             break;
6336         } /* case 6 */
6337         case 5:
6338         case 4:
6339         case 3:
6340             if (!Free_action) {
6341 /*JP
6342                 pline("Suddenly you are frozen in place!");
6343 */
6344                 pline("\93Ë\91R\82»\82Ì\8fê\82Å\93®\82¯\82È\82­\82È\82Á\82½\81I");
6345                 nomul(-d(5, 6));
6346 /*JP
6347                 multi_reason = "frozen by a trap";
6348 */
6349                 multi_reason = "ã©\82Å\8dd\92¼\82µ\82Ä\82¢\82é\8e\9e\82É";
6350                 exercise(A_DEX, FALSE);
6351                 nomovemsg = You_can_move_again;
6352             } else
6353 /*JP
6354                 You("momentarily stiffen.");
6355 */
6356                 You("\88ê\8fu\8dd\92¼\82µ\82½\81D");
6357             break;
6358         case 2:
6359         case 1:
6360         case 0:
6361 #if 0 /*JP*/
6362             pline("A cloud of %s gas billows from %s.",
6363                   Blind ? blindgas[rn2(SIZE(blindgas))] : rndcolor(),
6364                   the(xname(obj)));
6365 #else
6366             pline("%s\83K\83X\89_\82ª%s\82Ì\92ê\82Å\89Q\82Ü\82¢\82½\81D",
6367                   Blind ? blindgas[rn2(SIZE(blindgas))] :
6368                   jconj_adj(rndcolor()), xname(obj));
6369 #endif
6370             if (!Stunned) {
6371                 if (Hallucination)
6372 /*JP
6373                     pline("What a groovy feeling!");
6374 */
6375                     pline("\82È\82ñ\82Ä\91f\93G\82È\82ñ\82¾\81I");
6376                 else
6377 #if 0 /*JP*/
6378                     You("%s%s...", stagger(youmonst.data, "stagger"),
6379                         Halluc_resistance ? ""
6380                                           : Blind ? " and get dizzy"
6381                                                   : " and your vision blurs");
6382 #else
6383                     You("\82­\82ç\82­\82ç\82µ%s\82½...",
6384                         Halluc_resistance ? ""
6385                                           : Blind ? "\81C\82ß\82Ü\82¢\82ª\82µ"
6386                                                   : "\81C\8ci\90F\82ª\82Ú\82â\82¯\82Ä\82«");
6387 #endif
6388             }
6389             make_stunned((HStun & TIMEOUT) + (long) rn1(7, 16), FALSE);
6390             (void) make_hallucinated(
6391                 (HHallucination & TIMEOUT) + (long) rn1(5, 16), FALSE, 0L);
6392             break;
6393         default:
6394             impossible("bad chest trap");
6395             break;
6396         }
6397         bot(); /* to get immediate botl re-display */
6398     }
6399
6400     return FALSE;
6401 }
6402
6403 struct trap *
6404 t_at(x, y)
6405 register int x, y;
6406 {
6407     register struct trap *trap = ftrap;
6408
6409     while (trap) {
6410         if (trap->tx == x && trap->ty == y)
6411             return trap;
6412         trap = trap->ntrap;
6413     }
6414     return (struct trap *) 0;
6415 }
6416
6417 void
6418 deltrap(trap)
6419 register struct trap *trap;
6420 {
6421     register struct trap *ttmp;
6422
6423     clear_conjoined_pits(trap);
6424     if (trap == ftrap) {
6425         ftrap = ftrap->ntrap;
6426     } else {
6427         for (ttmp = ftrap; ttmp; ttmp = ttmp->ntrap)
6428             if (ttmp->ntrap == trap)
6429                 break;
6430         if (!ttmp)
6431             panic("deltrap: no preceding trap!");
6432         ttmp->ntrap = trap->ntrap;
6433     }
6434     if (Sokoban && (trap->ttyp == PIT || trap->ttyp == HOLE))
6435         maybe_finish_sokoban();
6436     dealloc_trap(trap);
6437 }
6438
6439 boolean
6440 conjoined_pits(trap2, trap1, u_entering_trap2)
6441 struct trap *trap2, *trap1;
6442 boolean u_entering_trap2;
6443 {
6444     int dx, dy, diridx, adjidx;
6445
6446     if (!trap1 || !trap2)
6447         return FALSE;
6448     if (!isok(trap2->tx, trap2->ty) || !isok(trap1->tx, trap1->ty)
6449         || !is_pit(trap2->ttyp)
6450         || !is_pit(trap1->ttyp)
6451         || (u_entering_trap2 && !(u.utrap && u.utraptype == TT_PIT)))
6452         return FALSE;
6453     dx = sgn(trap2->tx - trap1->tx);
6454     dy = sgn(trap2->ty - trap1->ty);
6455     for (diridx = 0; diridx < 8; diridx++)
6456         if (xdir[diridx] == dx && ydir[diridx] == dy)
6457             break;
6458     /* diridx is valid if < 8 */
6459     if (diridx < 8) {
6460         adjidx = (diridx + 4) % 8;
6461         if ((trap1->conjoined & (1 << diridx))
6462             && (trap2->conjoined & (1 << adjidx)))
6463             return TRUE;
6464     }
6465     return FALSE;
6466 }
6467
6468 STATIC_OVL void
6469 clear_conjoined_pits(trap)
6470 struct trap *trap;
6471 {
6472     int diridx, adjidx, x, y;
6473     struct trap *t;
6474
6475     if (trap && is_pit(trap->ttyp)) {
6476         for (diridx = 0; diridx < 8; ++diridx) {
6477             if (trap->conjoined & (1 << diridx)) {
6478                 x = trap->tx + xdir[diridx];
6479                 y = trap->ty + ydir[diridx];
6480                 if (isok(x, y)
6481                     && (t = t_at(x, y)) != 0
6482                     && is_pit(t->ttyp)) {
6483                     adjidx = (diridx + 4) % 8;
6484                     t->conjoined &= ~(1 << adjidx);
6485                 }
6486                 trap->conjoined &= ~(1 << diridx);
6487             }
6488         }
6489     }
6490 }
6491
6492 STATIC_OVL boolean
6493 adj_nonconjoined_pit(adjtrap)
6494 struct trap *adjtrap;
6495 {
6496     struct trap *trap_with_u = t_at(u.ux0, u.uy0);
6497
6498     if (trap_with_u && adjtrap && u.utrap && u.utraptype == TT_PIT
6499         && is_pit(trap_with_u->ttyp) && is_pit(adjtrap->ttyp)) {
6500         int idx;
6501
6502         for (idx = 0; idx < 8; idx++) {
6503             if (xdir[idx] == u.dx && ydir[idx] == u.dy)
6504                 return TRUE;
6505         }
6506     }
6507     return FALSE;
6508 }
6509
6510 #if 0
6511 /*
6512  * Mark all neighboring pits as conjoined pits.
6513  * (currently not called from anywhere)
6514  */
6515 STATIC_OVL void
6516 join_adjacent_pits(trap)
6517 struct trap *trap;
6518 {
6519     struct trap *t;
6520     int diridx, x, y;
6521
6522     if (!trap)
6523         return;
6524     for (diridx = 0; diridx < 8; ++diridx) {
6525         x = trap->tx + xdir[diridx];
6526         y = trap->ty + ydir[diridx];
6527         if (isok(x, y)) {
6528             if ((t = t_at(x, y)) != 0 && is_pit(t->ttyp)) {
6529                 trap->conjoined |= (1 << diridx);
6530                 join_adjacent_pits(t);
6531             } else
6532                 trap->conjoined &= ~(1 << diridx);
6533         }
6534     }
6535 }
6536 #endif /*0*/
6537
6538 /*
6539  * Returns TRUE if you escaped a pit and are standing on the precipice.
6540  */
6541 boolean
6542 uteetering_at_seen_pit(trap)
6543 struct trap *trap;
6544 {
6545     if (trap && trap->tseen && (!u.utrap || u.utraptype != TT_PIT)
6546         && is_pit(trap->ttyp))
6547         return TRUE;
6548     else
6549         return FALSE;
6550 }
6551
6552 /* Destroy a trap that emanates from the floor. */
6553 boolean
6554 delfloortrap(ttmp)
6555 register struct trap *ttmp;
6556 {
6557     /* some of these are arbitrary -dlc */
6558     if (ttmp && ((ttmp->ttyp == SQKY_BOARD) || (ttmp->ttyp == BEAR_TRAP)
6559                  || (ttmp->ttyp == LANDMINE) || (ttmp->ttyp == FIRE_TRAP)
6560                  || is_pit(ttmp->ttyp)
6561                  || is_hole(ttmp->ttyp)
6562                  || (ttmp->ttyp == TELEP_TRAP) || (ttmp->ttyp == LEVEL_TELEP)
6563                  || (ttmp->ttyp == WEB) || (ttmp->ttyp == MAGIC_TRAP)
6564                  || (ttmp->ttyp == ANTI_MAGIC))) {
6565         register struct monst *mtmp;
6566
6567         if (ttmp->tx == u.ux && ttmp->ty == u.uy) {
6568             if (u.utraptype != TT_BURIEDBALL)
6569                 reset_utrap(TRUE);
6570         } else if ((mtmp = m_at(ttmp->tx, ttmp->ty)) != 0) {
6571             mtmp->mtrapped = 0;
6572         }
6573         deltrap(ttmp);
6574         return TRUE;
6575     }
6576     return FALSE;
6577 }
6578
6579 /* used for doors (also tins).  can be used for anything else that opens. */
6580 void
6581 b_trapped(item, bodypart)
6582 const char *item;
6583 int bodypart;
6584 {
6585     int lvl = level_difficulty(),
6586         dmg = rnd(5 + (lvl < 5 ? lvl : 2 + lvl / 2));
6587
6588 /*JP
6589     pline("KABOOM!!  %s was booby-trapped!", The(item));
6590 */
6591     pline("\82¿\82ã\82Ç\81[\82ñ\81I\81I%s\82É\83u\81[\83r\81[\83g\83\89\83b\83v\82ª\8ed\8a|\82¯\82ç\82ê\82Ä\82¢\82½\81I", item);
6592     wake_nearby();
6593 /*JP
6594     losehp(Maybe_Half_Phys(dmg), "explosion", KILLED_BY_AN);
6595 */
6596     losehp(Maybe_Half_Phys(dmg), "\83u\81[\83r\81[\83g\83\89\83b\83v\82Ì\94\9a\94­\82Å", KILLED_BY_AN);
6597     exercise(A_STR, FALSE);
6598     if (bodypart)
6599         exercise(A_CON, FALSE);
6600     make_stunned((HStun & TIMEOUT) + (long) dmg, TRUE);
6601 }
6602
6603 /* Monster is hit by trap. */
6604 /* Note: doesn't work if both obj and d_override are null */
6605 STATIC_OVL boolean
6606 thitm(tlev, mon, obj, d_override, nocorpse)
6607 int tlev;
6608 struct monst *mon;
6609 struct obj *obj;
6610 int d_override;
6611 boolean nocorpse;
6612 {
6613     int strike;
6614     boolean trapkilled = FALSE;
6615
6616     if (d_override)
6617         strike = 1;
6618     else if (obj)
6619         strike = (find_mac(mon) + tlev + obj->spe <= rnd(20));
6620     else
6621         strike = (find_mac(mon) + tlev <= rnd(20));
6622
6623     /* Actually more accurate than thitu, which doesn't take
6624      * obj->spe into account.
6625      */
6626     if (!strike) {
6627         if (obj && cansee(mon->mx, mon->my))
6628 /*JP
6629             pline("%s is almost hit by %s!", Monnam(mon), doname(obj));
6630 */
6631             pline("\82à\82¤\8f­\82µ\82Å%s\82ª%s\82É\96½\92\86\82·\82é\82Æ\82±\82ë\82¾\82Á\82½\81I", doname(obj), Monnam(mon));
6632     } else {
6633         int dam = 1;
6634
6635         if (obj && cansee(mon->mx, mon->my))
6636 /*JP
6637             pline("%s is hit by %s!", Monnam(mon), doname(obj));
6638 */
6639             pline("%s\82ª%s\82É\96½\92\86\82µ\82½\81I", doname(obj), Monnam(mon));
6640         if (d_override)
6641             dam = d_override;
6642         else if (obj) {
6643             dam = dmgval(obj, mon);
6644             if (dam < 1)
6645                 dam = 1;
6646         }
6647         mon->mhp -= dam;
6648         if (DEADMONSTER(mon)) {
6649             int xx = mon->mx, yy = mon->my;
6650
6651             monkilled(mon, "", nocorpse ? -AD_RBRE : AD_PHYS);
6652             if (DEADMONSTER(mon)) {
6653                 newsym(xx, yy);
6654                 trapkilled = TRUE;
6655             }
6656         }
6657     }
6658     if (obj && (!strike || d_override)) {
6659         place_object(obj, mon->mx, mon->my);
6660         stackobj(obj);
6661     } else if (obj)
6662         dealloc_obj(obj);
6663
6664     return trapkilled;
6665 }
6666
6667 boolean
6668 unconscious()
6669 {
6670     if (multi >= 0)
6671         return FALSE;
6672
6673 #if 0 /*JP*/
6674     return (boolean) (u.usleep
6675                       || (nomovemsg
6676                           && (!strncmp(nomovemsg, "You awake", 9)
6677                               || !strncmp(nomovemsg, "You regain con", 14)
6678                               || !strncmp(nomovemsg, "You are consci", 14))));
6679 #else
6680 /*JP 3.6.0 \82Å\82Ì\8fo\8c»\88Ê\92u/\89ñ\90\94
6681  "You awake"      : potion.c(1)
6682   "You regain con": eat.c(1)
6683   "You are consci": eat.c(1)
6684 */
6685     return (boolean) (u.usleep
6686                       || (nomovemsg
6687                           && (!strncmp(nomovemsg, "\96Ú\82ª\82³\82ß\82½\82ª\93ª\92É", 18)
6688                               || !strncmp(nomovemsg, "\82 \82È\82½\82Í\90³\8bC\82Ã\82¢\82½", 18)
6689                               || !strncmp(nomovemsg, "\82 \82È\82½\82Í\82Ü\82½\90³\8bC\82Ã", 18))));
6690 #endif
6691 }
6692
6693 /*JP
6694 static const char lava_killer[] = "molten lava";
6695 */
6696 static const char lava_killer[] = "\82Ç\82ë\82Ç\82ë\82Ì\97n\8aâ\82Å";
6697
6698 boolean
6699 lava_effects()
6700 {
6701     register struct obj *obj, *obj2;
6702     int dmg = d(6, 6); /* only applicable for water walking */
6703     boolean usurvive, boil_away;
6704
6705     burn_away_slime();
6706     if (likes_lava(youmonst.data))
6707         return FALSE;
6708
6709     usurvive = Fire_resistance || (Wwalking && dmg < u.uhp);
6710     /*
6711      * A timely interrupt might manage to salvage your life
6712      * but not your gear.  For scrolls and potions this
6713      * will destroy whole stacks, where fire resistant hero
6714      * survivor only loses partial stacks via destroy_item().
6715      *
6716      * Flag items to be destroyed before any messages so
6717      * that player causing hangup at --More-- won't get an
6718      * emergency save file created before item destruction.
6719      */
6720     if (!usurvive)
6721         for (obj = invent; obj; obj = obj->nobj)
6722             if ((is_organic(obj) || obj->oclass == POTION_CLASS)
6723                 && !obj->oerodeproof
6724                 && objects[obj->otyp].oc_oprop != FIRE_RES
6725                 && obj->otyp != SCR_FIRE && obj->otyp != SPE_FIREBALL
6726                 && !obj_resists(obj, 0, 0)) /* for invocation items */
6727                 obj->in_use = 1;
6728
6729     /* Check whether we should burn away boots *first* so we know whether to
6730      * make the player sink into the lava. Assumption: water walking only
6731      * comes from boots.
6732      */
6733     if (uarmf && is_organic(uarmf) && !uarmf->oerodeproof) {
6734         obj = uarmf;
6735 /*JP
6736         pline("%s into flame!", Yobjnam2(obj, "burst"));
6737 */
6738         Your("%s\82Í\94R\82¦\82½\81I", xname(obj));
6739         iflags.in_lava_effects++; /* (see above) */
6740         (void) Boots_off();
6741         useup(obj);
6742         iflags.in_lava_effects--;
6743     }
6744
6745     if (!Fire_resistance) {
6746         if (Wwalking) {
6747 /*JP
6748             pline_The("%s here burns you!", hliquid("lava"));
6749 */
6750             pline("%s\82ª\82 \82È\82½\82ð\8fÄ\82«\82Â\82­\82µ\82½\81I", hliquid("\97n\8aâ"));
6751             if (usurvive) {
6752                 losehp(dmg, lava_killer, KILLED_BY); /* lava damage */
6753                 goto burn_stuff;
6754             }
6755         } else
6756 /*JP
6757             You("fall into the %s!", hliquid("lava"));
6758 */
6759             You("%s\82É\97\8e\82¿\82½\81I", hliquid("\97n\8aâ"));
6760
6761         usurvive = Lifesaved || discover;
6762         if (wizard)
6763             usurvive = TRUE;
6764
6765         /* prevent remove_worn_item() -> Boots_off(WATER_WALKING_BOOTS) ->
6766            spoteffects() -> lava_effects() recursion which would
6767            successfully delete (via useupall) the no-longer-worn boots;
6768            once recursive call returned, we would try to delete them again
6769            here in the outer call (and access stale memory, probably panic) */
6770         iflags.in_lava_effects++;
6771
6772         for (obj = invent; obj; obj = obj2) {
6773             obj2 = obj->nobj;
6774             /* above, we set in_use for objects which are to be destroyed */
6775             if (obj->otyp == SPE_BOOK_OF_THE_DEAD && !Blind) {
6776                 if (usurvive)
6777 #if 0 /*JP*/
6778                     pline("%s glows a strange %s, but remains intact.",
6779                           The(xname(obj)), hcolor("dark red"));
6780 #else
6781                     pline("%s\82Í\95s\8ev\8bc\82É%s\8bP\82¢\82½\82ª\81C\96³\8f\9d\82Ì\82æ\82¤\82¾\81D",
6782                           xname(obj), jconj_adj(hcolor("\88Ã\90Ô\90F\82Ì")));
6783 #endif
6784             } else if (obj->in_use) {
6785                 if (obj->owornmask) {
6786                     if (usurvive)
6787 /*JP
6788                         pline("%s into flame!", Yobjnam2(obj, "burst"));
6789 */
6790                         Your("%s\82Í\94R\82¦\82½\81I", xname(obj));
6791                     remove_worn_item(obj, TRUE);
6792                 }
6793                 useupall(obj);
6794             }
6795         }
6796
6797         iflags.in_lava_effects--;
6798
6799         /* s/he died... */
6800         boil_away = (u.umonnum == PM_WATER_ELEMENTAL
6801                      || u.umonnum == PM_STEAM_VORTEX
6802                      || u.umonnum == PM_FOG_CLOUD);
6803         for (;;) {
6804             u.uhp = -1;
6805             /* killer format and name are reconstructed every iteration
6806                because lifesaving resets them */
6807             killer.format = KILLED_BY;
6808             Strcpy(killer.name, lava_killer);
6809 /*JP
6810             You("%s...", boil_away ? "boil away" : "burn to a crisp");
6811 */
6812             You("%s\81D\81D\81D", boil_away ? "\95¦\93«\82µ\82½" : "\94R\82¦\82Ä\83p\83\8a\83p\83\8a\82É\82È\82Á\82½");
6813             done(BURNING);
6814             if (safe_teleds(TRUE))
6815                 break; /* successful life-save */
6816             /* nowhere safe to land; repeat burning loop */
6817 /*JP
6818             pline("You're still burning.");
6819 */
6820             You("\82Ü\82¾\94R\82¦\82Ä\82¢\82é\81D");
6821         }
6822 /*JP
6823         You("find yourself back on solid %s.", surface(u.ux, u.uy));
6824 */
6825         You("\82¢\82Â\82Ì\82Ü\82É\82©\8cÅ\82¢%s\82É\96ß\82Á\82Ä\82¢\82½\81D", surface(u.ux, u.uy));
6826         return TRUE;
6827     } else if (!Wwalking && (!u.utrap || u.utraptype != TT_LAVA)) {
6828         boil_away = !Fire_resistance;
6829         /* if not fire resistant, sink_into_lava() will quickly be fatal;
6830            hero needs to escape immediately */
6831         set_utrap((unsigned) (rn1(4, 4) + ((boil_away ? 2 : rn1(4, 12)) << 8)),
6832                   TT_LAVA);
6833 #if 0 /*JP:T*/
6834         You("sink into the %s%s!", hliquid("lava"),
6835             !boil_away ? ", but it only burns slightly"
6836                        : " and are about to be immolated");
6837 #else
6838         You("%s\82É\92¾\82ñ%s\82¾\81I", hliquid("\97n\8aâ"),
6839             !boil_away ? "\82¾\82ª\81C\82¿\82å\82Á\82Æ\8fÅ\82°\82½\82¾\82¯"
6840                        : "\82Å\8fÄ\82«\8eE\82³\82ê\82»\82¤");
6841 #endif
6842         if (u.uhp > 1)
6843             losehp(!boil_away ? 1 : (u.uhp / 2), lava_killer,
6844                    KILLED_BY); /* lava damage */
6845     }
6846
6847 burn_stuff:
6848     destroy_item(SCROLL_CLASS, AD_FIRE);
6849     destroy_item(SPBOOK_CLASS, AD_FIRE);
6850     destroy_item(POTION_CLASS, AD_FIRE);
6851     return FALSE;
6852 }
6853
6854 /* called each turn when trapped in lava */
6855 void
6856 sink_into_lava()
6857 {
6858 /*JP
6859     static const char sink_deeper[] = "You sink deeper into the lava.";
6860 */
6861     static const char sink_deeper[] = "\82 \82È\82½\82Í\82æ\82è\90[\82­\97n\8aâ\82É\92¾\82ñ\82¾\81D";
6862
6863     if (!u.utrap || u.utraptype != TT_LAVA) {
6864         ; /* do nothing; this shouldn't happen */
6865     } else if (!is_lava(u.ux, u.uy)) {
6866         reset_utrap(FALSE); /* this shouldn't happen either */
6867     } else if (!u.uinvulnerable) {
6868         /* ordinarily we'd have to be fire resistant to survive long
6869            enough to become stuck in lava, but it can happen without
6870            resistance if water walking boots allow survival and then
6871            get burned up; u.utrap time will be quite short in that case */
6872         if (!Fire_resistance)
6873             u.uhp = (u.uhp + 2) / 3;
6874
6875         u.utrap -= (1 << 8);
6876         if (u.utrap < (1 << 8)) {
6877             killer.format = KILLED_BY;
6878 /*JP
6879             Strcpy(killer.name, "molten lava");
6880 */
6881             Strcpy(killer.name, "\82Ç\82ë\82Ç\82ë\82Ì\97n\8aâ\82Å");
6882 /*JP
6883             You("sink below the surface and die.");
6884 */
6885             You("\8a®\91S\82É\97n\8aâ\82Ì\92\86\82É\92¾\82ñ\82Å\81A\8e\80\82É\82Ü\82µ\82½\81D\81D\81D");
6886             burn_away_slime(); /* add insult to injury? */
6887             done(DISSOLVED);
6888             /* can only get here via life-saving; try to get away from lava */
6889             reset_utrap(TRUE);
6890             /* levitation or flight have become unblocked, otherwise Tport */
6891             if (!Levitation && !Flying)
6892                 (void) safe_teleds(TRUE);
6893         } else if (!u.umoved) {
6894             /* can't fully turn into slime while in lava, but might not
6895                have it be burned away until you've come awfully close */
6896             if (Slimed && rnd(10 - 1) >= (int) (Slimed & TIMEOUT)) {
6897                 pline(sink_deeper);
6898                 burn_away_slime();
6899             } else {
6900                 Norep(sink_deeper);
6901             }
6902             u.utrap += rnd(4);
6903         }
6904     }
6905 }
6906
6907 /* called when something has been done (breaking a boulder, for instance)
6908    which entails a luck penalty if performed on a sokoban level */
6909 void
6910 sokoban_guilt()
6911 {
6912     if (Sokoban) {
6913         change_luck(-1);
6914         /* TODO: issue some feedback so that player can learn that whatever
6915            he/she just did is a naughty thing to do in sokoban and should
6916            probably be avoided in future....
6917            Caveat: doing this might introduce message sequencing issues,
6918            depending upon feedback during the various actions which trigger
6919            Sokoban luck penalties. */
6920     }
6921 }
6922
6923 /* called when a trap has been deleted or had its ttyp replaced */
6924 STATIC_OVL void
6925 maybe_finish_sokoban()
6926 {
6927     struct trap *t;
6928
6929     if (Sokoban && !in_mklev) {
6930         /* scan all remaining traps, ignoring any created by the hero;
6931            if this level has no more pits or holes, the current sokoban
6932            puzzle has been solved */
6933         for (t = ftrap; t; t = t->ntrap) {
6934             if (t->madeby_u)
6935                 continue;
6936             if (t->ttyp == PIT || t->ttyp == HOLE)
6937                 break;
6938         }
6939         if (!t) {
6940             /* we've passed the last trap without finding a pit or hole;
6941                clear the sokoban_rules flag so that luck penalties for
6942                things like breaking boulders or jumping will no longer
6943                be given, and restrictions on diagonal moves are lifted */
6944             Sokoban = 0; /* clear level.flags.sokoban_rules */
6945             /* TODO: give some feedback about solving the sokoban puzzle
6946                (perhaps say "congratulations" in Japanese?) */
6947         }
6948     }
6949 }
6950
6951 /*trap.c*/