OSDN Git Service

upgrade to 3.6.2
[jnethack/source.git] / src / mhitu.c
1 /* NetHack 3.6  mhitu.c $NHDT-Date: 1556649298 2019/04/30 18:34:58 $  $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.164 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /*-Copyright (c) Robert Patrick Rankin, 2012. */
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 #include "artifact.h"
13
14 STATIC_VAR NEARDATA struct obj *mon_currwep = (struct obj *) 0;
15
16 STATIC_DCL boolean FDECL(u_slip_free, (struct monst *, struct attack *));
17 STATIC_DCL int FDECL(passiveum, (struct permonst *, struct monst *,
18                                  struct attack *));
19 STATIC_DCL void FDECL(mayberem, (struct monst *, const char *,
20                                  struct obj *, const char *));
21 STATIC_DCL boolean FDECL(diseasemu, (struct permonst *));
22 STATIC_DCL int FDECL(hitmu, (struct monst *, struct attack *));
23 STATIC_DCL int FDECL(gulpmu, (struct monst *, struct attack *));
24 STATIC_DCL int FDECL(explmu, (struct monst *, struct attack *, BOOLEAN_P));
25 STATIC_DCL void FDECL(missmu, (struct monst *, BOOLEAN_P, struct attack *));
26 STATIC_DCL void FDECL(mswings, (struct monst *, struct obj *));
27 STATIC_DCL void FDECL(wildmiss, (struct monst *, struct attack *));
28 STATIC_DCL void FDECL(hitmsg, (struct monst *, struct attack *));
29
30 /* See comment in mhitm.c.  If we use this a lot it probably should be */
31 /* changed to a parameter to mhitu. */
32 static int dieroll;
33
34 STATIC_OVL void
35 hitmsg(mtmp, mattk)
36 struct monst *mtmp;
37 struct attack *mattk;
38 {
39     int compat;
40     const char *pfmt = 0;
41     char *Monst_name = Monnam(mtmp);
42
43     /* Note: if opposite gender, "seductively" */
44     /* If same gender, "engagingly" for nymph, normal msg for others */
45     if ((compat = could_seduce(mtmp, &youmonst, mattk)) != 0
46         && !mtmp->mcan && !mtmp->mspec_used) {
47 #if 0 /*JP:T*/
48         pline("%s %s you %s.", Monst_name,
49               !Blind ? "smiles at" : !Deaf ? "talks to" : "touches",
50               (compat == 2) ? "engagingly" : "seductively");
51 #else
52         pline("%s\82Í\82 \82È\82½%s%s\81D", Monst_name,
53               (compat == 2) ? "\82ð\88ø\82«\82Â\82¯\82é\82æ\82¤\82É" : "\82É\8dD\88Ó\82ð\82æ\82¹\82é\82æ\82¤\82É",
54               !Blind ? "\94÷\8fÎ\82ñ\82¾" : !Deaf ? "\98b\82µ\82©\82¯\82½" : "\90G\82ê\82½");
55 #endif
56     } else {
57         switch (mattk->aatyp) {
58         case AT_BITE:
59 /*JP
60             pfmt = "%s bites!";
61 */
62             pfmt = "%s\82Í\8a\9a\82Ý\82Â\82¢\82½\81I";
63             break;
64         case AT_KICK:
65 #if 0 /*JP:T*/
66             pline("%s kicks%c", Monst_name,
67                   thick_skinned(youmonst.data) ? '.' : '!');
68 #else
69             pline("%s\82Í\8fR\82Æ\82Î\82µ\82½%s",Monnam(mtmp), 
70                   thick_skinned(youmonst.data) ? "\81D" : "\81I");
71 #endif
72             break;
73         case AT_STNG:
74 /*JP
75             pfmt = "%s stings!";
76 */
77             pfmt = "%s\82Í\93Ë\82«\82³\82µ\82½\81I";
78             break;
79         case AT_BUTT:
80 /*JP
81             pfmt = "%s butts!";
82 */
83             pfmt = "%s\82Í\93ª\93Ë\82«\82ð\82­\82ç\82í\82µ\82½\81I";
84             break;
85         case AT_TUCH:
86 /*JP
87             pfmt = "%s touches you!";
88 */
89             pfmt = "%s\82Í\82 \82È\82½\82É\90G\82ê\82½\81I";
90             break;
91         case AT_TENT:
92 /*JP
93             pfmt = "%s tentacles suck you!";
94 */
95             pfmt = "%s\82Ì\90G\8eè\82ª\82 \82È\82½\82Ì\91Ì\89t\82ð\8bz\82¢\82Æ\82Á\82½\81I";
96 #if 0 /*JP*/
97             Monst_name = s_suffix(Monst_name);
98 #endif
99             break;
100         case AT_EXPL:
101         case AT_BOOM:
102 /*JP
103             pfmt = "%s explodes!";
104 */
105             pfmt = "%s\82Í\94\9a\94­\82µ\82½\81I";
106             break;
107         default:
108 /*JP
109             pfmt = "%s hits!";
110 */
111             pfmt = "%s\82Ì\8dU\8c\82\82Í\96½\92\86\82µ\82½\81I";
112         }
113         if (pfmt)
114             pline(pfmt, Monst_name);
115     }
116 }
117
118 /* monster missed you */
119 STATIC_OVL void
120 missmu(mtmp, nearmiss, mattk)
121 struct monst *mtmp;
122 boolean nearmiss;
123 struct attack *mattk;
124 {
125     if (!canspotmon(mtmp))
126         map_invisible(mtmp->mx, mtmp->my);
127
128     if (could_seduce(mtmp, &youmonst, mattk) && !mtmp->mcan)
129 /*JP
130         pline("%s pretends to be friendly.", Monnam(mtmp));
131 */
132         pline("%s\82Í\97F\8dD\93I\82È\82Ó\82è\82ð\82µ\82Ä\82¢\82é\81D",Monnam(mtmp));
133     else
134 #if 0 /*JP*/
135         pline("%s %smisses!", Monnam(mtmp),
136               (nearmiss && flags.verbose) ? "just " : "");
137 #else
138         pline("%s\82Ì\8dU\8c\82\82Í%s\82½\81D", Monnam(mtmp),
139               (nearmiss && flags.verbose) ? "\8bó\82ð\90Ø\82Á" : "\82Í\82¸\82ê");
140 #endif
141
142     stop_occupation();
143 }
144
145 /* monster swings obj */
146 STATIC_OVL void
147 mswings(mtmp, otemp)
148 struct monst *mtmp;
149 struct obj *otemp;
150 {
151     if (flags.verbose && !Blind && mon_visible(mtmp)) {
152 #if 0 /*JP*/
153         pline("%s %s %s%s %s.", Monnam(mtmp),
154               (objects[otemp->otyp].oc_dir & PIERCE) ? "thrusts" : "swings",
155               (otemp->quan > 1L) ? "one of " : "", mhis(mtmp), xname(otemp));
156 #else
157         pline("%s\82Í%s%s\81D", Monnam(mtmp),
158               xname(otemp),
159               (objects[otemp->otyp].oc_dir & PIERCE) ? "\82ð\93Ë\82¢\82½" : "\82ð\90U\82è\82Ü\82í\82µ\82½");
160 #endif
161     }
162 }
163
164 /* return how a poison attack was delivered */
165 const char *
166 mpoisons_subj(mtmp, mattk)
167 struct monst *mtmp;
168 struct attack *mattk;
169 {
170     if (mattk->aatyp == AT_WEAP) {
171         struct obj *mwep = (mtmp == &youmonst) ? uwep : MON_WEP(mtmp);
172         /* "Foo's attack was poisoned." is pretty lame, but at least
173            it's better than "sting" when not a stinging attack... */
174 /*JP
175         return (!mwep || !mwep->opoisoned) ? "attack" : "weapon";
176 */
177         return (!mwep || !mwep->opoisoned) ? "\8dU\8c\82" : "\95\90\8aí";
178     } else {
179 #if 0 /*JP*/
180         return (mattk->aatyp == AT_TUCH) ? "contact"
181                   : (mattk->aatyp == AT_GAZE) ? "gaze"
182                        : (mattk->aatyp == AT_BITE) ? "bite" : "sting";
183 #else
184         return (mattk->aatyp == AT_TUCH) ? "\90Ú\90G"
185                   : (mattk->aatyp == AT_GAZE) ? "\82É\82ç\82Ý"
186                        : (mattk->aatyp == AT_BITE) ? "\8a\9a\82Ý\82Â\82«" : "\93Ë\82«\82³\82µ";
187 #endif
188     }
189 }
190
191 /* called when your intrinsic speed is taken away */
192 void
193 u_slow_down()
194 {
195     HFast = 0L;
196     if (!Fast)
197 /*JP
198         You("slow down.");
199 */
200         You("\93®\82«\82ª\92x\82­\82È\82Á\82½\81D");
201     else /* speed boots */
202 /*JP
203         Your("quickness feels less natural.");
204 */
205         You("\91¬\82³\82É\82Â\82¢\82Ä\82¢\82¯\82È\82­\82È\82Á\82½\81D");
206     exercise(A_DEX, FALSE);
207 }
208
209 /* monster attacked your displaced image */
210 STATIC_OVL void
211 wildmiss(mtmp, mattk)
212 struct monst *mtmp;
213 struct attack *mattk;
214 {
215     int compat;
216     const char *Monst_name; /* Monnam(mtmp) */
217
218     /* no map_invisible() -- no way to tell where _this_ is coming from */
219
220     if (!flags.verbose)
221         return;
222     if (!cansee(mtmp->mx, mtmp->my))
223         return;
224     /* maybe it's attacking an image around the corner? */
225
226     compat = ((mattk->adtyp == AD_SEDU || mattk->adtyp == AD_SSEX)
227               ? could_seduce(mtmp, &youmonst, mattk) : 0);
228     Monst_name = Monnam(mtmp);
229
230     if (!mtmp->mcansee || (Invis && !perceives(mtmp->data))) {
231 #if 0 /*JP:T*/
232         const char *swings = (mattk->aatyp == AT_BITE) ? "snaps"
233                              : (mattk->aatyp == AT_KICK) ? "kicks"
234                                : (mattk->aatyp == AT_STNG
235                                   || mattk->aatyp == AT_BUTT
236                                   || nolimbs(mtmp->data)) ? "lunges"
237                                  : "swings";
238 #else
239         const char *swings = (mattk->aatyp == AT_BITE) ? "\8a\9a\82Ý\82Â\82­"
240                              : (mattk->aatyp == AT_KICK) ? "\8fR\82Æ\82Î\82·"
241                                : (mattk->aatyp == AT_STNG
242                                   || mattk->aatyp == AT_BUTT
243                                   || nolimbs(mtmp->data)) ? "\93Ë\90i\82·\82é"
244                                  : "\90U\82è\89ñ\82·";
245 #endif
246
247         if (compat)
248 /*JP
249             pline("%s tries to touch you and misses!", Monst_name);
250 */
251             pline("%s\82Í\82 \82È\82½\82É\90G\82ë\82¤\82Æ\82µ\82½\82ª\8e¸\94s\82µ\82½\81I", Monst_name);
252         else
253             switch (rn2(3)) {
254             case 0:
255 /*JP
256                 pline("%s %s wildly and misses!", Monst_name, swings);
257 */
258                 pline("%s\82Í\8c\83\82µ\82­%s\82ª\81C\82Í\82¸\82µ\82½\81I", Monst_name, swings);
259                 break;
260             case 1:
261 /*JP
262                 pline("%s attacks a spot beside you.", Monst_name);
263 */
264                 pline("%s\82Ì\8dU\8c\82\82Í\82 \82È\82½\82Ì\98e\95 \82ð\82©\82·\82ß\82½\81D", Monst_name);
265                 break;
266             case 2:
267 #if 0 /*JP*/
268                 pline("%s strikes at %s!", Monst_name,
269                       (levl[mtmp->mux][mtmp->muy].typ == WATER)
270                         ? "empty water"
271                         : "thin air");
272 #else
273                 pline("%s\82Í%s\82ð\91Å\82¿\82Â\82¯\82½\81I", Monst_name,
274                       (levl[mtmp->mux][mtmp->muy].typ == WATER)
275                         ? "\90\85"
276                         : "\89½\82à\82È\82¢\82Æ\82±\82ë");
277 #endif
278                 break;
279             default:
280 /*JP
281                 pline("%s %s wildly!", Monst_name, swings);
282 */
283                 pline("%s\82Í\8c\83\82µ\82­%s\81I", Monst_name, swings);
284                 break;
285             }
286
287     } else if (Displaced) {
288         /* give 'displaced' message even if hero is Blind */
289         if (compat)
290 #if 0 /*JP*/
291             pline("%s smiles %s at your %sdisplaced image...", Monst_name,
292                   (compat == 2) ? "engagingly" : "seductively",
293                   Invis ? "invisible " : "");
294 #else
295             pline("%s\82Í%s\82 \82È\82½\82Ì\8c\89e\82É\91Î\82µ\82Ä%s\94÷\8fÎ\82ñ\82¾\81D\81D\81D", Monst_name,
296                   Invis ? "\93§\96¾\82È" : "",
297                   (compat == 2) ? "\96£\97Í\93I\82É" : "\97U\98f\93I\82É");
298 #endif
299         else
300 #if 0 /*JP*/
301             pline("%s strikes at your %sdisplaced image and misses you!",
302                   /* Note:  if you're both invisible and displaced, only
303                    * monsters which see invisible will attack your displaced
304                    * image, since the displaced image is also invisible. */
305                   Monst_name, Invis ? "invisible " : "");
306 #else
307             pline("%s\82Í\82 \82È\82½\82Ì%s\8c\89e\82ð\8dU\8c\82\82µ\81C\82Í\82¸\82µ\82½\81I",
308                   Monst_name, Invis ? "\93§\96¾\82È" : "");
309 #endif
310
311     } else if (Underwater) {
312         /* monsters may miss especially on water level where
313            bubbles shake the player here and there */
314         if (compat)
315 /*JP
316             pline("%s reaches towards your distorted image.", Monst_name);
317 */
318             pline("%s\82Í\82 \82È\82½\82Ì\98c\82ñ\82¾\8c\89e\82Ì\95û\82Ö\8cü\82©\82Á\82½\81D", Monst_name);
319         else
320 /*JP
321             pline("%s is fooled by water reflections and misses!",
322 */
323             pline("%s\82Í\90\85\82Ì\94½\8eË\82É\82¾\82Ü\82³\82ê\81C\82Í\82¸\82µ\82½\81I",
324                   Monst_name);
325
326     } else
327         impossible("%s attacks you without knowing your location?",
328                    Monst_name);
329 }
330
331 void
332 expels(mtmp, mdat, message)
333 struct monst *mtmp;
334 struct permonst *mdat; /* if mtmp is polymorphed, mdat != mtmp->data */
335 boolean message;
336 {
337     if (message) {
338         if (is_animal(mdat)) {
339 /*JP
340             You("get regurgitated!");
341 */
342             You("\93f\82«\82¾\82³\82ê\82½\81I");
343         } else {
344             char blast[40];
345             struct attack *attk = attacktype_fordmg(mdat, AT_ENGL, AD_ANY);
346
347             blast[0] = '\0';
348             if (!attk) {
349                 impossible("Swallower has no engulfing attack?");
350             } else {
351                 if (is_whirly(mdat)) {
352                     switch (attk->adtyp) {
353                     case AD_ELEC:
354 /*JP
355                         Strcpy(blast, " in a shower of sparks");
356 */
357                         Strcpy(blast, "\82Ì\89Î\89Ô\82Ì\89J\82Ì\92\86\82©\82ç");
358                         break;
359                     case AD_COLD:
360 /*JP
361                         Strcpy(blast, " in a blast of frost");
362 */
363                         Strcpy(blast, "\82Ì\97â\8bC\82Ì\95\97\82Ì\92\86\82©\82ç");
364                         break;
365                     }
366                 } else {
367 /*JP
368                     Strcpy(blast, " with a squelch");
369 */
370                     Strcpy(blast, "\82©\82ç\93f\82«\8fo\82³\82ê\82é\82æ\82¤\82É");
371                 }
372 /*JP
373                 You("get expelled from %s%s!", mon_nam(mtmp), blast);
374 */
375                 You("%s%s\92E\8fo\82µ\82½\81I", mon_nam(mtmp), blast);
376             }
377         }
378     }
379     unstuck(mtmp); /* ball&chain returned in unstuck() */
380     mnexto(mtmp);
381     newsym(u.ux, u.uy);
382     spoteffects(TRUE);
383     /* to cover for a case where mtmp is not in a next square */
384     if (um_dist(mtmp->mx, mtmp->my, 1))
385 /*JP
386         pline("Brrooaa...  You land hard at some distance.");
387 */
388         pline("\83u\83\8d\83\8d\83\8d\81D\81D\89\93\82­\82É\92\85\97¤\82·\82é\82Ì\82Í\93ï\82µ\82¢\81D");
389 }
390
391 /* select a monster's next attack, possibly substituting for its usual one */
392 struct attack *
393 getmattk(magr, mdef, indx, prev_result, alt_attk_buf)
394 struct monst *magr, *mdef;
395 int indx, prev_result[];
396 struct attack *alt_attk_buf;
397 {
398     struct permonst *mptr = magr->data;
399     struct attack *attk = &mptr->mattk[indx];
400     struct obj *weap = (magr == &youmonst) ? uwep : MON_WEP(magr);
401
402     /* honor SEDUCE=0 */
403     if (!SYSOPT_SEDUCE) {
404         extern const struct attack sa_no[NATTK];
405
406         /* if the first attack is for SSEX damage, all six attacks will be
407            substituted (expected succubus/incubus handling); if it isn't
408            but another one is, only that other one will be substituted */
409         if (mptr->mattk[0].adtyp == AD_SSEX) {
410             *alt_attk_buf = sa_no[indx];
411             attk = alt_attk_buf;
412         } else if (attk->adtyp == AD_SSEX) {
413             *alt_attk_buf = *attk;
414             attk = alt_attk_buf;
415             attk->adtyp = AD_DRLI;
416         }
417     }
418
419     /* prevent a monster with two consecutive disease or hunger attacks
420        from hitting with both of them on the same turn; if the first has
421        already hit, switch to a stun attack for the second */
422     if (indx > 0 && prev_result[indx - 1] > 0
423         && (attk->adtyp == AD_DISE || attk->adtyp == AD_PEST
424             || attk->adtyp == AD_FAMN)
425         && attk->adtyp == mptr->mattk[indx - 1].adtyp) {
426         *alt_attk_buf = *attk;
427         attk = alt_attk_buf;
428         attk->adtyp = AD_STUN;
429
430     /* make drain-energy damage be somewhat in proportion to energy */
431     } else if (attk->adtyp == AD_DREN && mdef == &youmonst) {
432         int ulev = max(u.ulevel, 6);
433
434         *alt_attk_buf = *attk;
435         attk = alt_attk_buf;
436         /* 3.6.0 used 4d6 but since energy drain came out of max energy
437            once current energy was gone, that tended to have a severe
438            effect on low energy characters; it's now 2d6 with ajustments */
439         if (u.uen <= 5 * ulev && attk->damn > 1) {
440             attk->damn -= 1; /* low energy: 2d6 -> 1d6 */
441             if (u.uenmax <= 2 * ulev && attk->damd > 3)
442                 attk->damd -= 3; /* very low energy: 1d6 -> 1d3 */
443         } else if (u.uen > 12 * ulev) {
444             attk->damn += 1; /* high energy: 2d6 -> 3d6 */
445             if (u.uenmax > 20 * ulev)
446                 attk->damd += 3; /* very high energy: 3d6 -> 3d9 */
447             /* note: 3d9 is slightly higher than previous 4d6 */
448         }
449
450     } else if (attk->aatyp == AT_ENGL && magr->mspec_used) {
451         /* can't re-engulf yet; switch to simpler attack */
452         *alt_attk_buf = *attk;
453         attk = alt_attk_buf;
454         if (attk->adtyp == AD_ACID || attk->adtyp == AD_ELEC
455             || attk->adtyp == AD_COLD || attk->adtyp == AD_FIRE) {
456             attk->aatyp = AT_TUCH;
457         } else {
458             attk->aatyp = AT_CLAW; /* attack message will be "<foo> hits" */
459             attk->adtyp = AD_PHYS;
460         }
461         attk->damn = 1; /* relatively weak: 1d6 */
462         attk->damd = 6;
463
464     /* barrow wight, Nazgul, erinys have weapon attack for non-physical
465        damage; force physical damage if attacker has been cancelled or
466        if weapon is sufficiently interesting; a few unique creatures
467        have two weapon attacks where one does physical damage and other
468        doesn't--avoid forcing physical damage for those */
469     } else if (indx == 0 && magr != &youmonst
470                && attk->aatyp == AT_WEAP && attk->adtyp != AD_PHYS
471                && !(mptr->mattk[1].aatyp == AT_WEAP
472                     && mptr->mattk[1].adtyp == AD_PHYS)
473                && (magr->mcan
474                    || (weap && ((weap->otyp == CORPSE
475                                  && touch_petrifies(&mons[weap->corpsenm]))
476                                 || weap->oartifact == ART_STORMBRINGER
477                                 || weap->oartifact == ART_VORPAL_BLADE)))) {
478         *alt_attk_buf = *attk;
479         attk = alt_attk_buf;
480         attk->adtyp = AD_PHYS;
481     }
482     return attk;
483 }
484
485 /*
486  * mattacku: monster attacks you
487  *      returns 1 if monster dies (e.g. "yellow light"), 0 otherwise
488  *      Note: if you're displaced or invisible the monster might attack the
489  *              wrong position...
490  *      Assumption: it's attacking you or an empty square; if there's another
491  *              monster which it attacks by mistake, the caller had better
492  *              take care of it...
493  */
494 int
495 mattacku(mtmp)
496 register struct monst *mtmp;
497 {
498     struct attack *mattk, alt_attk;
499     int i, j = 0, tmp, sum[NATTK];
500     struct permonst *mdat = mtmp->data;
501     boolean ranged = (distu(mtmp->mx, mtmp->my) > 3);
502     /* Is it near you?  Affects your actions */
503     boolean range2 = !monnear(mtmp, mtmp->mux, mtmp->muy);
504     /* Does it think it's near you?  Affects its actions */
505     boolean foundyou = (mtmp->mux == u.ux && mtmp->muy == u.uy);
506     /* Is it attacking you or your image? */
507     boolean youseeit = canseemon(mtmp);
508     /* Might be attacking your image around the corner, or
509      * invisible, or you might be blind....
510      */
511     boolean skipnonmagc = FALSE;
512     /* Are further physical attack attempts useless? */
513
514     if (!ranged)
515         nomul(0);
516     if (DEADMONSTER(mtmp) || (Underwater && !is_swimmer(mtmp->data)))
517         return 0;
518
519     /* If swallowed, can only be affected by u.ustuck */
520     if (u.uswallow) {
521         if (mtmp != u.ustuck)
522             return 0;
523         u.ustuck->mux = u.ux;
524         u.ustuck->muy = u.uy;
525         range2 = 0;
526         foundyou = 1;
527         if (u.uinvulnerable)
528             return 0; /* stomachs can't hurt you! */
529
530     } else if (u.usteed) {
531         if (mtmp == u.usteed)
532             /* Your steed won't attack you */
533             return 0;
534         /* Orcs like to steal and eat horses and the like */
535         if (!rn2(is_orc(mtmp->data) ? 2 : 4)
536             && distu(mtmp->mx, mtmp->my) <= 2) {
537             /* Attack your steed instead */
538             i = mattackm(mtmp, u.usteed);
539             if ((i & MM_AGR_DIED))
540                 return 1;
541             /* make sure steed is still alive and within range */
542             if ((i & MM_DEF_DIED) || !u.usteed
543                 || distu(mtmp->mx, mtmp->my) > 2)
544                 return 0;
545             /* Let your steed retaliate */
546             return !!(mattackm(u.usteed, mtmp) & MM_DEF_DIED);
547         }
548     }
549
550     if (u.uundetected && !range2 && foundyou && !u.uswallow) {
551         if (!canspotmon(mtmp))
552             map_invisible(mtmp->mx, mtmp->my);
553         u.uundetected = 0;
554         if (is_hider(youmonst.data) && u.umonnum != PM_TRAPPER) {
555             /* ceiling hider */
556             coord cc; /* maybe we need a unexto() function? */
557             struct obj *obj;
558
559 /*JP
560             You("fall from the %s!", ceiling(u.ux, u.uy));
561 */
562             You("%s\82©\82ç\97\8e\82¿\82½\81I", ceiling(u.ux,u.uy));
563             /* take monster off map now so that its location
564                is eligible for placing hero; we assume that a
565                removed monster remembers its old spot <mx,my> */
566             remove_monster(mtmp->mx, mtmp->my);
567             if (!enexto(&cc, u.ux, u.uy, youmonst.data)
568                 /* a fish won't voluntarily swap positions
569                    when it's in water and hero is over land */
570                 || (mtmp->data->mlet == S_EEL
571                     && is_pool(mtmp->mx, mtmp->my)
572                     && !is_pool(u.ux, u.uy))) {
573                 /* couldn't find any spot for hero; this used to
574                    kill off attacker, but now we just give a "miss"
575                    message and keep both mtmp and hero at their
576                    original positions; hero has become unconcealed
577                    so mtmp's next move will be a regular attack */
578                 place_monster(mtmp, mtmp->mx, mtmp->my); /* put back */
579                 newsym(u.ux, u.uy); /* u.uundetected was toggled */
580 /*JP
581                 pline("%s draws back as you drop!", Monnam(mtmp));
582 */
583                 pline("\82 \82È\82½\82ª\97\8e\82¿\82é\82±\82Æ\82Å%s\82Í\88ø\82«\96ß\82³\82ê\82½\81I", Monnam(mtmp));
584                 return 0;
585             }
586
587             /* put mtmp at hero's spot and move hero to <cc.x,.y> */
588             newsym(mtmp->mx, mtmp->my); /* finish removal */
589             place_monster(mtmp, u.ux, u.uy);
590             if (mtmp->wormno) {
591                 worm_move(mtmp);
592                 /* tail hasn't grown, so if it now occupies <cc.x,.y>
593                    then one of its original spots must be free */
594                 if (m_at(cc.x, cc.y))
595                     (void) enexto(&cc, u.ux, u.uy, youmonst.data);
596             }
597             teleds(cc.x, cc.y, TRUE); /* move hero */
598             set_apparxy(mtmp);
599             newsym(u.ux, u.uy);
600
601             if (youmonst.data->mlet != S_PIERCER)
602                 return 0; /* lurkers don't attack */
603
604             obj = which_armor(mtmp, WORN_HELMET);
605             if (obj && is_metallic(obj)) {
606 #if 0 /*JP*/
607                 Your("blow glances off %s %s.", s_suffix(mon_nam(mtmp)),
608                      helm_simple_name(obj));
609 #else
610                 Your("\8dU\8c\82\82Í%s\82Ì%s\82ð\82©\82·\82ß\82½\82¾\82¯\82¾\82Á\82½\81D", mon_nam(mtmp),
611                       helm_simple_name(obj));
612 #endif
613             } else {
614                 if (3 + find_mac(mtmp) <= rnd(20)) {
615 /*JP
616                     pline("%s is hit by a falling piercer (you)!",
617 */
618                     pline("%s\82Í\97\8e\82¿\82Ä\82«\82½\90j(\82 \82È\82½)\82Å\8f\9d\82Â\82¢\82½\81I",
619                           Monnam(mtmp));
620                     if ((mtmp->mhp -= d(3, 6)) < 1)
621                         killed(mtmp);
622                 } else
623 /*JP
624                     pline("%s is almost hit by a falling piercer (you)!",
625 */
626                     pline("%s\82Í\82à\82¤\8f­\82µ\82Å\97\8e\82¿\82Ä\82«\82½\90j(\82 \82È\82½)\82Å\8f\9d\82Â\82­\82Æ\82±\82ë\82¾\82Á\82½\81I",
627                           Monnam(mtmp));
628             }
629
630         } else {
631             /* surface hider */
632             if (!youseeit) {
633 /*JP
634                 pline("It tries to move where you are hiding.");
635 */
636                 pline("\89½\8eÒ\82©\82ª\82 \82È\82½\82ª\89B\82ê\82Ä\82¢\82é\82Æ\82±\82ë\82ð\88Ú\93®\82µ\82æ\82¤\82Æ\82µ\82½\81D");
637             } else {
638                 /* Ugly kludge for eggs.  The message is phrased so as
639                  * to be directed at the monster, not the player,
640                  * which makes "laid by you" wrong.  For the
641                  * parallelism to work, we can't rephrase it, so we
642                  * zap the "laid by you" momentarily instead.
643                  */
644                 struct obj *obj = level.objects[u.ux][u.uy];
645
646                 if (obj || u.umonnum == PM_TRAPPER
647                     || (youmonst.data->mlet == S_EEL
648                         && is_pool(u.ux, u.uy))) {
649                     int save_spe = 0; /* suppress warning */
650
651                     if (obj) {
652                         save_spe = obj->spe;
653                         if (obj->otyp == EGG)
654                             obj->spe = 0;
655                     }
656                     /* note that m_monnam() overrides hallucination, which is
657                        what we want when message is from mtmp's perspective */
658                     if (youmonst.data->mlet == S_EEL
659                         || u.umonnum == PM_TRAPPER)
660                         pline(
661 #if 0 /*JP*/
662                              "Wait, %s!  There's a hidden %s named %s there!",
663                               m_monnam(mtmp), youmonst.data->mname, plname);
664 #else
665                               "\91Ò\82Ä\81C%s\81I%s\82Æ\82¢\82¤\96¼\82Ì%s\82ª\89B\82ê\82Ä\82¢\82é\81I",
666                               m_monnam(mtmp), plname, youmonst.data->mname);
667 #endif
668                     else
669                         pline(
670 #if 0 /*JP*/
671                           "Wait, %s!  There's a %s named %s hiding under %s!",
672                               m_monnam(mtmp), youmonst.data->mname, plname,
673                               doname(level.objects[u.ux][u.uy]));
674 #else
675                           "\91Ò\82Ä\81C%s\81I%s\82Æ\82¢\82¤\96¼\82Ì%s\82ª%s\82Ì\89º\82É\89B\82ê\82Ä\82¢\82é\81I",
676                               m_monnam(mtmp), plname, youmonst.data->mname, 
677                               doname(level.objects[u.ux][u.uy]));
678 #endif
679                     if (obj)
680                         obj->spe = save_spe;
681                 } else
682                     impossible("hiding under nothing?");
683             }
684             newsym(u.ux, u.uy);
685         }
686         return 0;
687     }
688
689     /* hero might be a mimic, concealed via #monster */
690     if (youmonst.data->mlet == S_MIMIC && U_AP_TYPE && !range2
691         && foundyou && !u.uswallow) {
692         boolean sticky = sticks(youmonst.data);
693
694         if (!canspotmon(mtmp))
695             map_invisible(mtmp->mx, mtmp->my);
696         if (sticky && !youseeit)
697 /*JP
698             pline("It gets stuck on you.");
699 */
700             pline("\89½\8eÒ\82©\82ª\82 \82È\82½\82Ì\8fã\82É\82Ì\82µ\82©\82©\82Á\82½\81D");
701         else /* see note about m_monnam() above */
702 #if 0 /*JP*/
703             pline("Wait, %s!  That's a %s named %s!", m_monnam(mtmp),
704                   youmonst.data->mname, plname);
705 #else
706             pline("\91Ò\82Ä\81C%s\81I\82»\82ê\82Í%s\82Æ\82¢\82¤\96¼\82Ì%s\82¾\81I", m_monnam(mtmp), 
707                   plname, youmonst.data->mname);
708 #endif
709         if (sticky)
710             u.ustuck = mtmp;
711         youmonst.m_ap_type = M_AP_NOTHING;
712         youmonst.mappearance = 0;
713         newsym(u.ux, u.uy);
714         return 0;
715     }
716
717     /* non-mimic hero might be mimicking an object after eating m corpse */
718     if (U_AP_TYPE == M_AP_OBJECT && !range2 && foundyou && !u.uswallow) {
719         if (!canspotmon(mtmp))
720             map_invisible(mtmp->mx, mtmp->my);
721         if (!youseeit)
722 #if 0 /*JP*/
723             pline("%s %s!", Something, (likes_gold(mtmp->data)
724                                         && youmonst.mappearance == GOLD_PIECE)
725                                            ? "tries to pick you up"
726                                            : "disturbs you");
727 #else
728             pline("%s\82Í%s\81I", Something, (likes_gold(mtmp->data)
729                                         && youmonst.mappearance == GOLD_PIECE)
730                                            ? "\82 \82È\82½\82ð\8fE\82¨\82¤\82Æ\82µ\82½"
731                                            : "\96³\8e\8b\82µ\82½");
732 #endif
733         else /* see note about m_monnam() above */
734 #if 0 /*JP*/
735             pline("Wait, %s!  That %s is really %s named %s!", m_monnam(mtmp),
736                   mimic_obj_name(&youmonst), an(mons[u.umonnum].mname),
737                   plname);
738 #else
739             pline("\91Ò\82Ä\81C%s\81I\82»\82Ì%s\82Í%s\82Æ\82¢\82¤\96¼\82Ì%s\82¾\81I", m_monnam(mtmp),
740                   mimic_obj_name(&youmonst), plname,
741                   mons[u.umonnum].mname);
742 #endif
743         if (multi < 0) { /* this should always be the case */
744             char buf[BUFSZ];
745
746 #if 0 /*JP*/
747             Sprintf(buf, "You appear to be %s again.",
748                     Upolyd ? (const char *) an(youmonst.data->mname)
749                            : (const char *) "yourself");
750 #else
751             Sprintf(buf, "\82 \82È\82½\82Í\82Ó\82½\82½\82Ñ%s\82É\82È\82Á\82½\81D",
752                     Upolyd ? (const char *) youmonst.data->mname
753                            : (const char *) "\8e©\95ª\8e©\90g");
754 #endif
755             unmul(buf); /* immediately stop mimicking */
756         }
757         return 0;
758     }
759
760     /*  Work out the armor class differential   */
761     tmp = AC_VALUE(u.uac) + 10; /* tmp ~= 0 - 20 */
762     tmp += mtmp->m_lev;
763     if (multi < 0)
764         tmp += 4;
765     if ((Invis && !perceives(mdat)) || !mtmp->mcansee)
766         tmp -= 2;
767     if (mtmp->mtrapped)
768         tmp -= 2;
769     if (tmp <= 0)
770         tmp = 1;
771
772     /* make eels visible the moment they hit/miss us */
773     if (mdat->mlet == S_EEL && mtmp->minvis && cansee(mtmp->mx, mtmp->my)) {
774         mtmp->minvis = 0;
775         newsym(mtmp->mx, mtmp->my);
776     }
777
778     /*  Special demon handling code */
779     if ((mtmp->cham == NON_PM) && is_demon(mdat) && !range2
780         && mtmp->data != &mons[PM_BALROG] && mtmp->data != &mons[PM_SUCCUBUS]
781         && mtmp->data != &mons[PM_INCUBUS])
782         if (!mtmp->mcan && !rn2(13))
783             (void) msummon(mtmp);
784
785     /*  Special lycanthrope handling code */
786     if ((mtmp->cham == NON_PM) && is_were(mdat) && !range2) {
787         if (is_human(mdat)) {
788             if (!rn2(5 - (night() * 2)) && !mtmp->mcan)
789                 new_were(mtmp);
790         } else if (!rn2(30) && !mtmp->mcan)
791             new_were(mtmp);
792         mdat = mtmp->data;
793
794         if (!rn2(10) && !mtmp->mcan) {
795             int numseen, numhelp;
796 #if 0 /*JP*/
797             char buf[BUFSZ], genericwere[BUFSZ];
798 #else
799             char genericwere[BUFSZ];
800 #endif
801
802 /*JP
803             Strcpy(genericwere, "creature");
804 */
805             Strcpy(genericwere, "\89½\82©");
806             numhelp = were_summon(mdat, FALSE, &numseen, genericwere);
807             if (youseeit) {
808 /*JP
809                 pline("%s summons help!", Monnam(mtmp));
810 */
811                 pline("%s\82Í\8f\95\82¯\82ð\8cÄ\82ñ\82¾\81I", Monnam(mtmp));
812                 if (numhelp > 0) {
813                     if (numseen == 0)
814 /*JP
815                         You_feel("hemmed in.");
816 */
817                         pline("\89½\8eÒ\82©\82É\88Í\82Ü\82ê\82½\82æ\82¤\82È\8bC\82ª\82·\82é\81D");
818                 } else
819 /*JP
820                     pline("But none comes.");
821 */
822                     pline("\82µ\82©\82µ\89½\82à\97\88\82È\82©\82Á\82½\81D");
823             } else {
824                 const char *from_nowhere;
825
826                 if (!Deaf) {
827 /*JP
828                     pline("%s %s!", Something, makeplural(growl_sound(mtmp)));
829 */
830                     pline("\89½\82©\82ª%s\81I", growl_sound(mtmp));
831                     from_nowhere = "";
832                 } else
833 /*JP
834                     from_nowhere = " from nowhere";
835 */
836                     from_nowhere = "\82Ç\82±\82©\82ç\82Æ\82à\82È\82­";
837                 if (numhelp > 0) {
838                     if (numseen < 1)
839 /*JP
840                         You_feel("hemmed in.");
841 */
842                         pline("\89½\8eÒ\82©\82É\88Í\82Ü\82ê\82½\82æ\82¤\82È\8bC\82ª\82·\82é\81D");
843                     else {
844 #if 0 /*JP*/
845                         if (numseen == 1)
846                             Sprintf(buf, "%s appears", an(genericwere));
847                         else
848                             Sprintf(buf, "%s appear",
849                                     makeplural(genericwere));
850                         pline("%s%s!", upstart(buf), from_nowhere);
851 #else
852                         pline("%s\82ª%s\8c»\82ê\82½\81I",
853                               genericwere, from_nowhere);
854 #endif
855                     }
856                 } /* else no help came; but you didn't know it tried */
857             }
858         }
859     }
860
861     if (u.uinvulnerable) {
862         /* monsters won't attack you */
863         if (mtmp == u.ustuck) {
864 /*JP
865             pline("%s loosens its grip slightly.", Monnam(mtmp));
866 */
867             pline("%s\82Í\92÷\82ß\82Â\82¯\82ð\82í\82¸\82©\82É\8aÉ\82ß\82½\81D", Monnam(mtmp));
868         } else if (!range2) {
869             if (youseeit || sensemon(mtmp))
870 /*JP
871                 pline("%s starts to attack you, but pulls back.",
872 */
873                 pline("%s\82Í\82 \82È\82½\82ð\8dU\8c\82\82µ\82©\82¯\82½\82ª\81C\82Ð\82Á\82±\82ß\82½\81D",
874                       Monnam(mtmp));
875             else
876 /*JP
877                 You_feel("%s move nearby.", something);
878 */
879                 pline("\89½\8eÒ\82©\82ª\82 \82È\82½\82Ì\82»\82Î\82ð\92Ê\82è\82Ê\82¯\82½\82æ\82¤\82È\8bC\82ª\82µ\82½\81D");
880         }
881         return 0;
882     }
883
884     /* Unlike defensive stuff, don't let them use item _and_ attack. */
885     if (find_offensive(mtmp)) {
886         int foo = use_offensive(mtmp);
887
888         if (foo != 0)
889             return (foo == 1);
890     }
891
892     for (i = 0; i < NATTK; i++) {
893         sum[i] = 0;
894         mon_currwep = (struct obj *)0;
895         mattk = getmattk(mtmp, &youmonst, i, sum, &alt_attk);
896         if ((u.uswallow && mattk->aatyp != AT_ENGL)
897             || (skipnonmagc && mattk->aatyp != AT_MAGC))
898             continue;
899
900         switch (mattk->aatyp) {
901         case AT_CLAW: /* "hand to hand" attacks */
902         case AT_KICK:
903         case AT_BITE:
904         case AT_STNG:
905         case AT_TUCH:
906         case AT_BUTT:
907         case AT_TENT:
908             if (!range2 && (!MON_WEP(mtmp) || mtmp->mconf || Conflict
909                             || !touch_petrifies(youmonst.data))) {
910                 if (foundyou) {
911                     if (tmp > (j = rnd(20 + i))) {
912                         if (mattk->aatyp != AT_KICK
913                             || !thick_skinned(youmonst.data))
914                             sum[i] = hitmu(mtmp, mattk);
915                     } else
916                         missmu(mtmp, (tmp == j), mattk);
917                 } else {
918                     wildmiss(mtmp, mattk);
919                     /* skip any remaining non-spell attacks */
920                     skipnonmagc = TRUE;
921                 }
922             }
923             break;
924
925         case AT_HUGS: /* automatic if prev two attacks succeed */
926             /* Note: if displaced, prev attacks never succeeded */
927             if ((!range2 && i >= 2 && sum[i - 1] && sum[i - 2])
928                 || mtmp == u.ustuck)
929                 sum[i] = hitmu(mtmp, mattk);
930             break;
931
932         case AT_GAZE: /* can affect you either ranged or not */
933             /* Medusa gaze already operated through m_respond in
934                dochug(); don't gaze more than once per round. */
935             if (mdat != &mons[PM_MEDUSA])
936                 sum[i] = gazemu(mtmp, mattk);
937             break;
938
939         case AT_EXPL: /* automatic hit if next to, and aimed at you */
940             if (!range2)
941                 sum[i] = explmu(mtmp, mattk, foundyou);
942             break;
943
944         case AT_ENGL:
945             if (!range2) {
946                 if (foundyou) {
947                     if (u.uswallow
948                         || (!mtmp->mspec_used && tmp > (j = rnd(20 + i)))) {
949                         /* force swallowing monster to be displayed
950                            even when hero is moving away */
951                         flush_screen(1);
952                         sum[i] = gulpmu(mtmp, mattk);
953                     } else {
954                         missmu(mtmp, (tmp == j), mattk);
955                     }
956                 } else if (is_animal(mtmp->data)) {
957 /*JP
958                     pline("%s gulps some air!", Monnam(mtmp));
959 */
960                     pline("%s\82Í\91§\82ð\8bz\82¢\82±\82ñ\82¾\81I", Monnam(mtmp));
961                 } else {
962                     if (youseeit)
963 /*JP
964                         pline("%s lunges forward and recoils!", Monnam(mtmp));
965 */
966                         pline("%s\82Í\93Ë\90i\82µ\81C\96ß\82Á\82½\81I", Monnam(mtmp));
967                     else
968 #if 0 /*JP*/
969                         You_hear("a %s nearby.",
970                                  is_whirly(mtmp->data) ? "rushing noise"
971                                                        : "splat");
972 #else
973                         You_hear("\82·\82®\82»\82Î\82Å%s\89¹\82ð\95·\82¢\82½\81D",
974                                  is_whirly(mtmp->data) ? "\93Ë\8c\82\82µ\82Ä\82­\82é"
975                                                        : "\83s\83V\83\83\83b\82Æ\82¢\82¤");
976 #endif
977                 }
978             }
979             break;
980         case AT_BREA:
981             if (range2)
982                 sum[i] = breamu(mtmp, mattk);
983             /* Note: breamu takes care of displacement */
984             break;
985         case AT_SPIT:
986             if (range2)
987                 sum[i] = spitmu(mtmp, mattk);
988             /* Note: spitmu takes care of displacement */
989             break;
990         case AT_WEAP:
991             if (range2) {
992                 if (!Is_rogue_level(&u.uz))
993                     thrwmu(mtmp);
994             } else {
995                 int hittmp = 0;
996
997                 /* Rare but not impossible.  Normally the monster
998                  * wields when 2 spaces away, but it can be
999                  * teleported or whatever....
1000                  */
1001                 if (mtmp->weapon_check == NEED_WEAPON || !MON_WEP(mtmp)) {
1002                     mtmp->weapon_check = NEED_HTH_WEAPON;
1003                     /* mon_wield_item resets weapon_check as appropriate */
1004                     if (mon_wield_item(mtmp) != 0)
1005                         break;
1006                 }
1007                 if (foundyou) {
1008                     mon_currwep = MON_WEP(mtmp);
1009                     if (mon_currwep) {
1010                         hittmp = hitval(mon_currwep, &youmonst);
1011                         tmp += hittmp;
1012                         mswings(mtmp, mon_currwep);
1013                     }
1014                     if (tmp > (j = dieroll = rnd(20 + i)))
1015                         sum[i] = hitmu(mtmp, mattk);
1016                     else
1017                         missmu(mtmp, (tmp == j), mattk);
1018                     /* KMH -- Don't accumulate to-hit bonuses */
1019                     if (mon_currwep)
1020                         tmp -= hittmp;
1021                 } else {
1022                     wildmiss(mtmp, mattk);
1023                     /* skip any remaining non-spell attacks */
1024                     skipnonmagc = TRUE;
1025                 }
1026             }
1027             break;
1028         case AT_MAGC:
1029             if (range2)
1030                 sum[i] = buzzmu(mtmp, mattk);
1031             else
1032                 sum[i] = castmu(mtmp, mattk, TRUE, foundyou);
1033             break;
1034
1035         default: /* no attack */
1036             break;
1037         }
1038         if (context.botl)
1039             bot();
1040         /* give player a chance of waking up before dying -kaa */
1041         if (sum[i] == 1) { /* successful attack */
1042             if (u.usleep && u.usleep < monstermoves && !rn2(10)) {
1043                 multi = -1;
1044 /*JP
1045                 nomovemsg = "The combat suddenly awakens you.";
1046 */
1047                 nomovemsg = "\82 \82È\82½\82Í\8bN\82±\82³\82ê\82½\81D";
1048             }
1049         }
1050         if (sum[i] == 2)
1051             return 1; /* attacker dead */
1052         if (sum[i] == 3)
1053             break; /* attacker teleported, no more attacks */
1054         /* sum[i] == 0: unsuccessful attack */
1055     }
1056     return 0;
1057 }
1058
1059 STATIC_OVL boolean
1060 diseasemu(mdat)
1061 struct permonst *mdat;
1062 {
1063     if (Sick_resistance) {
1064 /*JP
1065         You_feel("a slight illness.");
1066 */
1067         You("\82·\82±\82µ\8bC\95ª\82ª\88«\82­\82È\82Á\82½\82æ\82¤\82È\8bC\82ª\82µ\82½\81D");
1068         return FALSE;
1069     } else {
1070         make_sick(Sick ? Sick / 3L + 1L : (long) rn1(ACURR(A_CON), 20),
1071                   mdat->mname, TRUE, SICK_NONVOMITABLE);
1072         return TRUE;
1073     }
1074 }
1075
1076 /* check whether slippery clothing protects from hug or wrap attack */
1077 STATIC_OVL boolean
1078 u_slip_free(mtmp, mattk)
1079 struct monst *mtmp;
1080 struct attack *mattk;
1081 {
1082     struct obj *obj = (uarmc ? uarmc : uarm);
1083
1084     if (!obj)
1085         obj = uarmu;
1086     if (mattk->adtyp == AD_DRIN)
1087         obj = uarmh;
1088
1089     /* if your cloak/armor is greased, monster slips off; this
1090        protection might fail (33% chance) when the armor is cursed */
1091     if (obj && (obj->greased || obj->otyp == OILSKIN_CLOAK)
1092         && (!obj->cursed || rn2(3))) {
1093 #if 0 /*JP*/
1094         pline("%s %s your %s %s!", Monnam(mtmp),
1095               (mattk->adtyp == AD_WRAP) ? "slips off of"
1096                                         : "grabs you, but cannot hold onto",
1097               obj->greased ? "greased" : "slippery",
1098               /* avoid "slippery slippery cloak"
1099                  for undiscovered oilskin cloak */
1100               (obj->greased || objects[obj->otyp].oc_name_known)
1101                   ? xname(obj)
1102                   : cloak_simple_name(obj));
1103 #else
1104         pline("%s\82Í%s%s%s\81I", Monnam(mtmp),
1105               obj->greased ? "\96û\82Ì\93h\82ç\82ê\82½" : "\8a\8a\82è\82â\82·\82¢",
1106               (obj->greased || objects[obj->otyp].oc_name_known)
1107                   ? xname(obj)
1108                   : cloak_simple_name(obj),
1109               (mattk->adtyp == AD_WRAP) ? "\82Å\8a\8a\82Á\82½"
1110                                         : "\82ð\82Â\82©\82Ü\82¦\82æ\82¤\82Æ\82µ\82½\82ª\81C\82Å\82«\82È\82©\82Á\82½");
1111 #endif
1112
1113         if (obj->greased && !rn2(2)) {
1114 /*JP
1115             pline_The("grease wears off.");
1116 */
1117             pline("\8e\89\82Í\97\8e\82¿\82Ä\82µ\82Ü\82Á\82½\81D");
1118             obj->greased = 0;
1119             update_inventory();
1120         }
1121         return TRUE;
1122     }
1123     return FALSE;
1124 }
1125
1126 /* armor that sufficiently covers the body might be able to block magic */
1127 int
1128 magic_negation(mon)
1129 struct monst *mon;
1130 {
1131     struct obj *o;
1132     long wearmask;
1133     int armpro, mc = 0;
1134     boolean is_you = (mon == &youmonst),
1135             gotprot = is_you ? (EProtection != 0L)
1136                              /* high priests have innate protection */
1137                              : (mon->data == &mons[PM_HIGH_PRIEST]);
1138
1139     for (o = is_you ? invent : mon->minvent; o; o = o->nobj) {
1140         /* a_can field is only applicable for armor (which must be worn) */
1141         if ((o->owornmask & W_ARMOR) != 0L) {
1142             armpro = objects[o->otyp].a_can;
1143             if (armpro > mc)
1144                 mc = armpro;
1145         }
1146         /* if we've already confirmed Protection, skip additional checks */
1147         if (is_you || gotprot)
1148             continue;
1149
1150         /* omit W_SWAPWEP+W_QUIVER; W_ART+W_ARTI handled by protects() */
1151         wearmask = W_ARMOR | W_ACCESSORY;
1152         if (o->oclass == WEAPON_CLASS || is_weptool(o))
1153             wearmask |= W_WEP;
1154         if (protects(o, ((o->owornmask & wearmask) != 0L) ? TRUE : FALSE))
1155             gotprot = TRUE;
1156     }
1157
1158     if (gotprot) {
1159         /* extrinsic Protection increases mc by 1 */
1160         if (mc < 3)
1161             mc += 1;
1162     } else if (mc < 1) {
1163         /* intrinsic Protection is weaker (play balance; obtaining divine
1164            protection is too easy); it confers minimum mc 1 instead of 0 */
1165         if ((is_you && ((HProtection && u.ublessed > 0) || u.uspellprot))
1166             /* aligned priests and angels have innate intrinsic Protection */
1167             || (mon->data == &mons[PM_ALIGNED_PRIEST] || is_minion(mon->data)))
1168             mc = 1;
1169     }
1170     return mc;
1171 }
1172
1173 /*
1174  * hitmu: monster hits you
1175  *        returns 2 if monster dies (e.g. "yellow light"), 1 otherwise
1176  *        3 if the monster lives but teleported/paralyzed, so it can't keep
1177  *             attacking you
1178  */
1179 STATIC_OVL int
1180 hitmu(mtmp, mattk)
1181 register struct monst *mtmp;
1182 register struct attack *mattk;
1183 {
1184     struct permonst *mdat = mtmp->data;
1185     int uncancelled, ptmp;
1186     int dmg, armpro, permdmg, tmphp;
1187     char buf[BUFSZ];
1188     struct permonst *olduasmon = youmonst.data;
1189     int res;
1190
1191     if (!canspotmon(mtmp))
1192         map_invisible(mtmp->mx, mtmp->my);
1193
1194     /*  If the monster is undetected & hits you, you should know where
1195      *  the attack came from.
1196      */
1197     if (mtmp->mundetected && (hides_under(mdat) || mdat->mlet == S_EEL)) {
1198         mtmp->mundetected = 0;
1199         if (!(Blind ? Blind_telepat : Unblind_telepat)) {
1200             struct obj *obj;
1201 #if 0 /*JP*/
1202             const char *what;
1203 #endif
1204
1205             if ((obj = level.objects[mtmp->mx][mtmp->my]) != 0) {
1206 #if 0 /*JP*/
1207                 if (Blind && !obj->dknown)
1208                     what = something;
1209                 else if (is_pool(mtmp->mx, mtmp->my) && !Underwater)
1210                     what = "the water";
1211                 else
1212                     what = doname(obj);
1213
1214                 pline("%s was hidden under %s!", Amonnam(mtmp), what);
1215 #else
1216                 if (Blind && !obj->dknown)
1217                     pline("%s\82ª\89½\82©\82Ì\89º\82É\89B\82ê\82Ä\82¢\82é\81I", Amonnam(mtmp));
1218                 else if (is_pool(mtmp->mx, mtmp->my) && !Underwater)
1219                     pline("%s\82ª\90\85\92\86\82É\89B\82ê\82Ä\82¢\82é\81I", Amonnam(mtmp));
1220                 else
1221                     pline("%s\82ª%s\82Ì\89º\82É\89B\82ê\82Ä\82¢\82é\81I", Amonnam(mtmp), doname(obj));
1222 #endif
1223             }
1224             newsym(mtmp->mx, mtmp->my);
1225         }
1226     }
1227
1228     /*  First determine the base damage done */
1229     dmg = d((int) mattk->damn, (int) mattk->damd);
1230     if ((is_undead(mdat) || is_vampshifter(mtmp)) && midnight())
1231         dmg += d((int) mattk->damn, (int) mattk->damd); /* extra damage */
1232
1233     /*  Next a cancellation factor.
1234      *  Use uncancelled when cancellation factor takes into account certain
1235      *  armor's special magic protection.  Otherwise just use !mtmp->mcan.
1236      */
1237     armpro = magic_negation(&youmonst);
1238     uncancelled = !mtmp->mcan && (rn2(10) >= 3 * armpro);
1239
1240     permdmg = 0;
1241     /*  Now, adjust damages via resistances or specific attacks */
1242     switch (mattk->adtyp) {
1243     case AD_PHYS:
1244         if (mattk->aatyp == AT_HUGS && !sticks(youmonst.data)) {
1245             if (!u.ustuck && rn2(2)) {
1246                 if (u_slip_free(mtmp, mattk)) {
1247                     dmg = 0;
1248                 } else {
1249                     u.ustuck = mtmp;
1250 /*JP
1251                     pline("%s grabs you!", Monnam(mtmp));
1252 */
1253                     pline("%s\82É\82Â\82©\82Ü\82¦\82ç\82ê\82Ä\82¢\82é\81I", Monnam(mtmp));
1254                 }
1255             } else if (u.ustuck == mtmp) {
1256                 exercise(A_STR, FALSE);
1257 #if 0 /*JP*/
1258                 You("are being %s.", (mtmp->data == &mons[PM_ROPE_GOLEM])
1259                                          ? "choked"
1260                                          : "crushed");
1261 #else
1262                 You("%s\82Ä\82¢\82é\81D", (mtmp->data == &mons[PM_ROPE_GOLEM])
1263                                          ? "\8eñ\82ð\8di\82ß\82ç\82ê"
1264                                          : "\89\9f\82µ\82Â\82Ô\82³\82ê");
1265 #endif
1266             }
1267         } else { /* hand to hand weapon */
1268             struct obj *otmp = mon_currwep;
1269
1270             if (mattk->aatyp == AT_WEAP && otmp) {
1271                 struct obj *marmg;
1272                 int tmp;
1273
1274                 if (otmp->otyp == CORPSE
1275                     && touch_petrifies(&mons[otmp->corpsenm])) {
1276                     dmg = 1;
1277 #if 0 /*JP*/
1278                     pline("%s hits you with the %s corpse.", Monnam(mtmp),
1279                           mons[otmp->corpsenm].mname);
1280 #else
1281                     pline("%s\82Í%s\82Ì\8e\80\91Ì\82Å\8dU\8c\82\82µ\82½\81D", Monnam(mtmp),
1282                           mons[otmp->corpsenm].mname);
1283 #endif
1284                     if (!Stoned)
1285                         goto do_stone;
1286                 }
1287                 dmg += dmgval(otmp, &youmonst);
1288                 if ((marmg = which_armor(mtmp, W_ARMG)) != 0
1289                     && marmg->otyp == GAUNTLETS_OF_POWER)
1290                     dmg += rn1(4, 3); /* 3..6 */
1291                 if (dmg <= 0)
1292                     dmg = 1;
1293                 if (!(otmp->oartifact
1294                       && artifact_hit(mtmp, &youmonst, otmp, &dmg, dieroll)))
1295                     hitmsg(mtmp, mattk);
1296                 if (!dmg)
1297                     break;
1298                 if (objects[otmp->otyp].oc_material == SILVER
1299                     && Hate_silver) {
1300 /*JP
1301                     pline_The("silver sears your flesh!");
1302 */
1303                     pline("\82 \82È\82½\82Ì\91Ì\82Í\8bâ\82Å\8fÄ\82©\82ê\82½\81I");
1304                     exercise(A_CON, FALSE);
1305                 }
1306                 /* this redundancy necessary because you have
1307                    to take the damage _before_ being cloned;
1308                    need to have at least 2 hp left to split */
1309                 tmp = dmg;
1310                 if (u.uac < 0)
1311                     tmp -= rnd(-u.uac);
1312                 if (tmp < 1)
1313                     tmp = 1;
1314                 if (u.mh - tmp > 1
1315                     && (objects[otmp->otyp].oc_material == IRON
1316                         /* relevant 'metal' objects are scalpel and tsurugi */
1317                         || objects[otmp->otyp].oc_material == METAL)
1318                     && (u.umonnum == PM_BLACK_PUDDING
1319                         || u.umonnum == PM_BROWN_PUDDING)) {
1320                     if (tmp > 1)
1321                         exercise(A_STR, FALSE);
1322                     /* inflict damage now; we know it can't be fatal */
1323                     u.mh -= tmp;
1324                     context.botl = 1;
1325                     dmg = 0; /* don't inflict more damage below */
1326                     if (cloneu())
1327 /*JP
1328                         You("divide as %s hits you!", mon_nam(mtmp));
1329 */
1330                         pline("%s\82Ì\8dU\8c\82\82É\82æ\82Á\82Ä\82 \82È\82½\82Í\95ª\97ô\82µ\82½\81I", mon_nam(mtmp));
1331                 }
1332                 rustm(&youmonst, otmp);
1333             } else if (mattk->aatyp != AT_TUCH || dmg != 0
1334                        || mtmp != u.ustuck)
1335                 hitmsg(mtmp, mattk);
1336         }
1337         break;
1338     case AD_DISE:
1339         hitmsg(mtmp, mattk);
1340         if (!diseasemu(mdat))
1341             dmg = 0;
1342         break;
1343     case AD_FIRE:
1344         hitmsg(mtmp, mattk);
1345         if (uncancelled) {
1346 /*JP
1347             pline("You're %s!", on_fire(youmonst.data, mattk));
1348 */
1349             pline("\82 \82È\82½\82Í%s\81I", on_fire(youmonst.data, mattk));
1350             if (completelyburns(youmonst.data)) { /* paper or straw golem */
1351 /*JP
1352                 You("go up in flames!");
1353 */
1354                 You("\89\8a\82É\95ï\82Ü\82ê\82½\81I");
1355                 /* KMH -- this is okay with unchanging */
1356                 rehumanize();
1357                 break;
1358             } else if (Fire_resistance) {
1359 /*JP
1360                 pline_The("fire doesn't feel hot!");
1361 */
1362                 pline("\89Î\82Í\82º\82ñ\82º\82ñ\94M\82­\82È\82¢\81I");
1363                 dmg = 0;
1364             }
1365             if ((int) mtmp->m_lev > rn2(20))
1366                 destroy_item(SCROLL_CLASS, AD_FIRE);
1367             if ((int) mtmp->m_lev > rn2(20))
1368                 destroy_item(POTION_CLASS, AD_FIRE);
1369             if ((int) mtmp->m_lev > rn2(25))
1370                 destroy_item(SPBOOK_CLASS, AD_FIRE);
1371             burn_away_slime();
1372         } else
1373             dmg = 0;
1374         break;
1375     case AD_COLD:
1376         hitmsg(mtmp, mattk);
1377         if (uncancelled) {
1378 /*JP
1379             pline("You're covered in frost!");
1380 */
1381             You("\95X\82Å\95¢\82í\82ê\82½\81I");
1382             if (Cold_resistance) {
1383 /*JP
1384                 pline_The("frost doesn't seem cold!");
1385 */
1386                 pline("\95X\82Í\97â\82³\82ð\8a´\82\82³\82¹\82È\82¢\81I");
1387                 dmg = 0;
1388             }
1389             if ((int) mtmp->m_lev > rn2(20))
1390                 destroy_item(POTION_CLASS, AD_COLD);
1391         } else
1392             dmg = 0;
1393         break;
1394     case AD_ELEC:
1395         hitmsg(mtmp, mattk);
1396         if (uncancelled) {
1397 /*JP
1398             You("get zapped!");
1399 */
1400             You("\93d\8c\82\82ð\82­\82ç\82Á\82½\81I");
1401             if (Shock_resistance) {
1402 /*JP
1403                 pline_The("zap doesn't shock you!");
1404 */
1405                 pline("\93d\8c\82\82Í\82µ\82Ñ\82ê\82ð\8a´\82\82³\82¹\82È\82¢\81I");
1406                 dmg = 0;
1407             }
1408             if ((int) mtmp->m_lev > rn2(20))
1409                 destroy_item(WAND_CLASS, AD_ELEC);
1410             if ((int) mtmp->m_lev > rn2(20))
1411                 destroy_item(RING_CLASS, AD_ELEC);
1412         } else
1413             dmg = 0;
1414         break;
1415     case AD_SLEE:
1416         hitmsg(mtmp, mattk);
1417         if (uncancelled && multi >= 0 && !rn2(5)) {
1418             if (Sleep_resistance)
1419                 break;
1420             fall_asleep(-rnd(10), TRUE);
1421             if (Blind)
1422 /*JP
1423                 You("are put to sleep!");
1424 */
1425                 You("\96°\82è\82É\82¨\82¿\82½\81I");
1426             else
1427 /*JP
1428                 You("are put to sleep by %s!", mon_nam(mtmp));
1429 */
1430                 You("%s\82É\96°\82ç\82³\82ê\82½\81I", mon_nam(mtmp));
1431         }
1432         break;
1433     case AD_BLND:
1434         if (can_blnd(mtmp, &youmonst, mattk->aatyp, (struct obj *) 0)) {
1435             if (!Blind)
1436 /*JP
1437                 pline("%s blinds you!", Monnam(mtmp));
1438 */
1439                 pline("%s\82Ì\8dU\8c\82\82Å\96Ú\82ª\8c©\82¦\82È\82­\82È\82Á\82½\81I", Monnam(mtmp));
1440             make_blinded(Blinded + (long) dmg, FALSE);
1441             if (!Blind)
1442                 Your1(vision_clears);
1443         }
1444         dmg = 0;
1445         break;
1446     case AD_DRST:
1447         ptmp = A_STR;
1448         goto dopois;
1449     case AD_DRDX:
1450         ptmp = A_DEX;
1451         goto dopois;
1452     case AD_DRCO:
1453         ptmp = A_CON;
1454  dopois:
1455         hitmsg(mtmp, mattk);
1456         if (uncancelled && !rn2(8)) {
1457 #if 0 /*JP*/
1458             Sprintf(buf, "%s %s", s_suffix(Monnam(mtmp)),
1459                     mpoisons_subj(mtmp, mattk));
1460 #else
1461             Sprintf(buf, "%s\82Ì%s", Monnam(mtmp),
1462                     mpoisons_subj(mtmp, mattk));
1463 #endif
1464             poisoned(buf, ptmp, mdat->mname, 30, FALSE);
1465         }
1466         break;
1467     case AD_DRIN:
1468         hitmsg(mtmp, mattk);
1469         if (defends(AD_DRIN, uwep) || !has_head(youmonst.data)) {
1470 /*JP
1471             You("don't seem harmed.");
1472 */
1473             You("\8f\9d\82Â\82¢\82Ä\82¢\82È\82¢\82æ\82¤\82¾\81D");
1474             /* Not clear what to do for green slimes */
1475             break;
1476         }
1477         if (u_slip_free(mtmp, mattk))
1478             break;
1479
1480         if (uarmh && rn2(8)) {
1481             /* not body_part(HEAD) */
1482 /*JP
1483             Your("%s blocks the attack to your head.",
1484 */
1485             Your("%s\82ª\93ª\82Ö\82Ì\8dU\8c\82\82ð\96h\82¢\82¾\81D",
1486                  helm_simple_name(uarmh));
1487             break;
1488         }
1489         /* negative armor class doesn't reduce this damage */
1490         if (Half_physical_damage)
1491             dmg = (dmg + 1) / 2;
1492         mdamageu(mtmp, dmg);
1493         dmg = 0; /* don't inflict a second dose below */
1494
1495         if (!uarmh || uarmh->otyp != DUNCE_CAP) {
1496             /* eat_brains() will miss if target is mindless (won't
1497                happen here; hero is considered to retain his mind
1498                regardless of current shape) or is noncorporeal
1499                (can't happen here; no one can poly into a ghost
1500                or shade) so this check for missing is academic */
1501             if (eat_brains(mtmp, &youmonst, TRUE, (int *) 0) == MM_MISS)
1502                 break;
1503         }
1504         /* adjattrib gives dunce cap message when appropriate */
1505         (void) adjattrib(A_INT, -rnd(2), FALSE);
1506         forget_levels(25);  /* lose memory of 25% of levels */
1507         forget_objects(25); /* lose memory of 25% of objects */
1508         break;
1509     case AD_PLYS:
1510         hitmsg(mtmp, mattk);
1511         if (uncancelled && multi >= 0 && !rn2(3)) {
1512             if (Free_action) {
1513 /*JP
1514                 You("momentarily stiffen.");
1515 */
1516                 You("\88ê\8fu\8dd\92¼\82µ\82½\81D");
1517             } else {
1518                 if (Blind)
1519 /*JP
1520                     You("are frozen!");
1521 */
1522                     You("\93®\82¯\82È\82¢\81I");
1523                 else
1524 /*JP
1525                     You("are frozen by %s!", mon_nam(mtmp));
1526 */
1527                     pline("%s\82É\82æ\82Á\82Ä\93®\82¯\82È\82­\82È\82Á\82½\81I", mon_nam(mtmp));
1528                 nomovemsg = You_can_move_again;
1529                 nomul(-rnd(10));
1530 /*JP
1531                 multi_reason = "paralyzed by a monster";
1532 */
1533                 multi_reason = "\89ö\95¨\82É\96\83á\83\82³\82¹\82ç\82ê\82½\8c\84\82É";
1534                 exercise(A_DEX, FALSE);
1535             }
1536         }
1537         break;
1538     case AD_DRLI:
1539         hitmsg(mtmp, mattk);
1540         if (uncancelled && !rn2(3) && !Drain_resistance) {
1541 /*JP
1542             losexp("life drainage");
1543 */
1544             losexp("\90\96½\97Í\82ð\8bz\8eû\82³\82ê\82Ä");
1545         }
1546         break;
1547     case AD_LEGS: {
1548         long side = rn2(2) ? RIGHT_SIDE : LEFT_SIDE;
1549 /*JP
1550         const char *sidestr = (side == RIGHT_SIDE) ? "right" : "left",
1551 */
1552         const char *sidestr = (side == RIGHT_SIDE) ? "\89E" : "\8d¶",
1553                    *Monst_name = Monnam(mtmp), *leg = body_part(LEG);
1554
1555         /* This case is too obvious to ignore, but Nethack is not in
1556          * general very good at considering height--most short monsters
1557          * still _can_ attack you when you're flying or mounted.
1558          * [FIXME: why can't a flying attacker overcome this?]
1559          */
1560         if (u.usteed || Levitation || Flying) {
1561 /*JP
1562             pline("%s tries to reach your %s %s!", Monst_name, sidestr, leg);
1563 */
1564             pline("%s\82Í\82 \82È\82½\82Ì%s%s\82É\8dU\8c\82\82µ\82æ\82¤\82Æ\82µ\82½\81I", Monst_name, sidestr, leg);
1565             dmg = 0;
1566         } else if (mtmp->mcan) {
1567 #if 0 /*JP:T*/
1568             pline("%s nuzzles against your %s %s!", Monnam(mtmp),
1569                   sidestr, leg);
1570 #else
1571             pline("%s\82Í\82 \82È\82½\82Ì%s%s\82É\95@\82ð\82·\82è\82æ\82¹\82½\81I", Monnam(mtmp),
1572                   sidestr, leg);
1573 #endif
1574             dmg = 0;
1575         } else {
1576             if (uarmf) {
1577                 if (rn2(2) && (uarmf->otyp == LOW_BOOTS
1578                                || uarmf->otyp == IRON_SHOES)) {
1579 #if 0 /*JP:T*/
1580                     pline("%s pricks the exposed part of your %s %s!",
1581                           Monst_name, sidestr, leg);
1582 #else
1583                     pline("%s\82Í\82 \82È\82½\82Ì%s%s\82ð\82¿\82­\82è\82Æ\8eh\82µ\82½\81I",
1584                           Monst_name, sidestr, leg);
1585 #endif
1586                 } else if (!rn2(5)) {
1587 #if 0 /*JP*/
1588                     pline("%s pricks through your %s boot!", Monst_name,
1589                           sidestr);
1590 #else
1591                     pline("%s\82Í\82 \82È\82½\82Ì%s\82Ì\8cC\82²\82µ\82É\82¿\82­\82è\82Æ\8eh\82µ\82½\81I", Monst_name,
1592                           sidestr);
1593 #endif
1594                 } else {
1595 #if 0 /*JP*/
1596                     pline("%s scratches your %s boot!", Monst_name,
1597                           sidestr);
1598 #else
1599                     pline("%s\82Í\82 \82È\82½\82Ì%s\82Ì\8cC\82ð\82Ð\82Á\82©\82¢\82½\81I", Monst_name,
1600                           sidestr);
1601 #endif
1602                     dmg = 0;
1603                     break;
1604                 }
1605             } else
1606 /*JP
1607                 pline("%s pricks your %s %s!", Monst_name, sidestr, leg);
1608 */
1609                 pline("%s\82Í\82 \82È\82½\82Ì%s%s\82ð\82¿\82­\82è\82Æ\8eh\82µ\82½\81I", Monst_name, sidestr, leg);
1610
1611             set_wounded_legs(side, rnd(60 - ACURR(A_DEX)));
1612             exercise(A_STR, FALSE);
1613             exercise(A_DEX, FALSE);
1614         }
1615         break;
1616     }
1617     case AD_STON: /* cockatrice */
1618         hitmsg(mtmp, mattk);
1619         if (!rn2(3)) {
1620             if (mtmp->mcan) {
1621                 if (!Deaf)
1622 /*JP
1623                     You_hear("a cough from %s!", mon_nam(mtmp));
1624 */
1625                     You_hear("%s\82ª\83S\83z\83b\83S\83z\83b\82Æ\82¢\82¤\89¹\82ð\95·\82¢\82½\81I", mon_nam(mtmp));
1626             } else {
1627                 if (!Deaf)
1628 /*JP
1629                     You_hear("%s hissing!", s_suffix(mon_nam(mtmp)));
1630 */
1631                     You_hear("%s\82ª\83V\83\85\81[\83b\82Æ\82¢\82¤\90º\82ð\95·\82¢\82½\81I", mon_nam(mtmp));
1632                 if (!rn2(10)
1633                     || (flags.moonphase == NEW_MOON && !have_lizard())) {
1634  do_stone:
1635                     if (!Stoned && !Stone_resistance
1636                         && !(poly_when_stoned(youmonst.data)
1637                              && polymon(PM_STONE_GOLEM))) {
1638                         int kformat = KILLED_BY_AN;
1639                         const char *kname = mtmp->data->mname;
1640
1641                         if (mtmp->data->geno & G_UNIQ) {
1642                             if (!type_is_pname(mtmp->data))
1643                                 kname = the(kname);
1644                             kformat = KILLED_BY;
1645                         }
1646                         make_stoned(5L, (char *) 0, kformat, kname);
1647                         return 1;
1648                         /* done_in_by(mtmp, STONING); */
1649                     }
1650                 }
1651             }
1652         }
1653         break;
1654     case AD_STCK:
1655         hitmsg(mtmp, mattk);
1656         if (uncancelled && !u.ustuck && !sticks(youmonst.data))
1657             u.ustuck = mtmp;
1658         break;
1659     case AD_WRAP:
1660         if ((!mtmp->mcan || u.ustuck == mtmp) && !sticks(youmonst.data)) {
1661             if (!u.ustuck && !rn2(10)) {
1662                 if (u_slip_free(mtmp, mattk)) {
1663                     dmg = 0;
1664                 } else {
1665 /*JP
1666                     pline("%s swings itself around you!", Monnam(mtmp));
1667 */
1668                     pline("%s\82Í\82 \82È\82½\82É\91Ì\82ð\97\8d\82Ý\82Â\82©\82¹\82½\81I", Monnam(mtmp));
1669                     u.ustuck = mtmp;
1670                 }
1671             } else if (u.ustuck == mtmp) {
1672                 if (is_pool(mtmp->mx, mtmp->my) && !Swimming && !Amphibious) {
1673                     boolean moat = (levl[mtmp->mx][mtmp->my].typ != POOL)
1674                                    && (levl[mtmp->mx][mtmp->my].typ != WATER)
1675                                    && !Is_medusa_level(&u.uz)
1676                                    && !Is_waterlevel(&u.uz);
1677
1678 /*JP
1679                     pline("%s drowns you...", Monnam(mtmp));
1680 */
1681                     pline("\82 \82È\82½\82Í%s\82É\97\8d\82Ý\82Â\82©\82ê\82Ä\93M\82ê\82½\81D\81D\81D", Monnam(mtmp));
1682                     killer.format = KILLED_BY_AN;
1683 #if 0 /*JP*/
1684                     Sprintf(killer.name, "%s by %s",
1685                             moat ? "moat" : "pool of water",
1686                             an(mtmp->data->mname));
1687 #else
1688                     Sprintf(buf, "%s\82Ì%s\82É\97\8d\82Ý\82Â\82©\82ê\82Ä",
1689                             moat ? "\96x" : "\92r",
1690                             mtmp->data->mname);
1691 #endif
1692                     done(DROWNING);
1693                 } else if (mattk->aatyp == AT_HUGS)
1694 /*JP
1695                     You("are being crushed.");
1696 */
1697                     You("\82Â\82Ô\82³\82ê\82Â\82Â\82 \82é\81D");
1698             } else {
1699                 dmg = 0;
1700                 if (flags.verbose)
1701 #if 0 /*JP*/
1702                     pline("%s brushes against your %s.", Monnam(mtmp),
1703                           body_part(LEG));
1704 #else
1705                     pline("%s\82Í\82 \82È\82½\82Ì%s\82É\90G\82ê\82½\81D", Monnam(mtmp),
1706                           body_part(LEG));
1707 #endif
1708             }
1709         } else
1710             dmg = 0;
1711         break;
1712     case AD_WERE:
1713         hitmsg(mtmp, mattk);
1714         if (uncancelled && !rn2(4) && u.ulycn == NON_PM
1715             && !Protection_from_shape_changers && !defends(AD_WERE, uwep)) {
1716 /*JP
1717             You_feel("feverish.");
1718 */
1719             You("\94M\82ª\82 \82é\82æ\82¤\82È\8bC\82ª\82µ\82½\81D");
1720             exercise(A_CON, FALSE);
1721             set_ulycn(monsndx(mdat));
1722             retouch_equipment(2);
1723         }
1724         break;
1725     case AD_SGLD:
1726         hitmsg(mtmp, mattk);
1727         if (youmonst.data->mlet == mdat->mlet)
1728             break;
1729         if (!mtmp->mcan)
1730             stealgold(mtmp);
1731         break;
1732
1733     case AD_SSEX:
1734         if (SYSOPT_SEDUCE) {
1735             if (could_seduce(mtmp, &youmonst, mattk) == 1 && !mtmp->mcan)
1736                 if (doseduce(mtmp))
1737                     return 3;
1738             break;
1739         }
1740         /*FALLTHRU*/
1741     case AD_SITM: /* for now these are the same */
1742     case AD_SEDU:
1743         if (is_animal(mtmp->data)) {
1744             hitmsg(mtmp, mattk);
1745             if (mtmp->mcan)
1746                 break;
1747             /* Continue below */
1748         } else if (dmgtype(youmonst.data, AD_SEDU)
1749                    /* !SYSOPT_SEDUCE: when hero is attacking and AD_SSEX
1750                       is disabled, it would be changed to another damage
1751                       type, but when defending, it remains as-is */
1752                    || dmgtype(youmonst.data, AD_SSEX)) {
1753 #if 0 /*JP:T*/
1754             pline("%s %s.", Monnam(mtmp),
1755                   Deaf ? "says something but you can't hear it"
1756                        : mtmp->minvent
1757                       ? "brags about the goods some dungeon explorer provided"
1758                   : "makes some remarks about how difficult theft is lately");
1759 #else
1760             pline("%s\82Í%s\81D", Monnam(mtmp),
1761                   Deaf ? "\89½\82©\82ð\8c¾\82Á\82½\82ª\95·\82±\82¦\82È\82©\82Á\82½"
1762                        : mtmp->minvent
1763                       ? "\82 \82é\96À\8b{\92T\8c\9f\89Æ\82ª\92u\82¢\82Ä\82Á\82½\95i\95¨\82ð\8e©\96\9d\82µ\82½"
1764                   : "\8dÅ\8bß\90Þ\93\90\82ª\82¢\82©\82É\8d¢\93ï\82©\92W\81X\82Æ\8fq\82×\82½");
1765 #endif
1766             if (!tele_restrict(mtmp))
1767                 (void) rloc(mtmp, TRUE);
1768             return 3;
1769         } else if (mtmp->mcan) {
1770             if (!Blind)
1771 #if 0 /*JP:T*/
1772                 pline("%s tries to %s you, but you seem %s.",
1773                       Adjmonnam(mtmp, "plain"),
1774                       flags.female ? "charm" : "seduce",
1775                       flags.female ? "unaffected" : "uninterested");
1776 #else
1777                 pline("%s\82Í\82 \82È\82½\82ð%s\82µ\82æ\82¤\82Æ\82µ\82½\81C\82µ\82©\82µ\82 \82È\82½\82Í%s\81D",
1778                       Adjmonnam(mtmp, "\92n\96¡\82È"),
1779                       flags.female ? "\96£\97¹" : "\97U\98f",
1780                       flags.female ? "\89e\8b¿\82ð\8eó\82¯\82È\82¢" : "\8b»\96¡\82ª\82È\82¢");
1781 #endif
1782             if (rn2(3)) {
1783                 if (!tele_restrict(mtmp))
1784                     (void) rloc(mtmp, TRUE);
1785                 return 3;
1786             }
1787             break;
1788         }
1789         buf[0] = '\0';
1790         switch (steal(mtmp, buf)) {
1791         case -1:
1792             return 2;
1793         case 0:
1794             break;
1795         default:
1796             if (!is_animal(mtmp->data) && !tele_restrict(mtmp))
1797                 (void) rloc(mtmp, TRUE);
1798             if (is_animal(mtmp->data) && *buf) {
1799                 if (canseemon(mtmp))
1800 #if 0 /*JP*/
1801                     pline("%s tries to %s away with %s.", Monnam(mtmp),
1802                           locomotion(mtmp->data, "run"), buf);
1803 #else
1804                     pline("%s\82Í%s\82ð\8e\9d\82Á\82Ä\93¦\82°\8fo\82µ\82½\81D", Monnam(mtmp),
1805                           buf);
1806 #endif
1807             }
1808             monflee(mtmp, 0, FALSE, FALSE);
1809             return 3;
1810         }
1811         break;
1812
1813     case AD_SAMU:
1814         hitmsg(mtmp, mattk);
1815         /* when the Wizard or quest nemesis hits, there's a 1/20 chance
1816            to steal a quest artifact (any, not just the one for the hero's
1817            own role) or the Amulet or one of the invocation tools */
1818         if (!rn2(20))
1819             stealamulet(mtmp);
1820         break;
1821
1822     case AD_TLPT:
1823         hitmsg(mtmp, mattk);
1824         if (uncancelled) {
1825             if (flags.verbose)
1826 #if 0 /*JP:T*/
1827                 Your("position suddenly seems %suncertain!",
1828                      (Teleport_control && !Stunned && !unconscious()) ? ""
1829                      : "very ");
1830 #else
1831                 pline("\8e©\95ª\82Ì\82¢\82é\88Ê\92u\82ª\93Ë\91R%s\95s\96¾\8am\82É\82È\82Á\82½\81I",
1832                      (Teleport_control && !Stunned && !unconscious()) ? ""
1833                      : "\82Æ\82Ä\82à");
1834 #endif
1835             tele();
1836             /* 3.6.2:  make sure damage isn't fatal; previously, it
1837                was possible to be teleported and then drop dead at
1838                the destination when QM's 1d4 damage gets applied below;
1839                even though that wasn't "wrong", it seemed strange,
1840                particularly if the teleportation had been controlled
1841                [applying the damage first and not teleporting if fatal
1842                is another alternative but it has its own complications] */
1843             if ((Half_physical_damage ? (dmg - 1) / 2 : dmg)
1844                 >= (tmphp = (Upolyd ? u.mh : u.uhp))) {
1845                 dmg = tmphp - 1;
1846                 if (Half_physical_damage)
1847                     dmg *= 2; /* doesn't actually increase damage; we only
1848                                * get here if half the original damage would
1849                                * would have been fatal, so double reduced
1850                                * damage will be less than original damage */
1851                 if (dmg < 1) { /* implies (tmphp <= 1) */
1852                     dmg = 1;
1853                     /* this might increase current HP beyond maximum HP but
1854                        it will be immediately reduced below, so that should
1855                        be indistinguishable from zero damage; we don't drop
1856                        damage all the way to zero because that inhibits any
1857                        passive counterattack if poly'd hero has one */
1858                     if (Upolyd && u.mh == 1)
1859                         ++u.mh;
1860                     else if (!Upolyd && u.uhp == 1)
1861                         ++u.uhp;
1862                     /* [don't set context.botl here] */
1863                 }
1864             }
1865         }
1866         break;
1867     case AD_RUST:
1868         hitmsg(mtmp, mattk);
1869         if (mtmp->mcan)
1870             break;
1871         if (u.umonnum == PM_IRON_GOLEM) {
1872 /*JP
1873             You("rust!");
1874 */
1875             You("\8eK\82Ñ\82Â\82¢\82½\81I");
1876             /* KMH -- this is okay with unchanging */
1877             rehumanize();
1878             break;
1879         }
1880         erode_armor(&youmonst, ERODE_RUST);
1881         break;
1882     case AD_CORR:
1883         hitmsg(mtmp, mattk);
1884         if (mtmp->mcan)
1885             break;
1886         erode_armor(&youmonst, ERODE_CORRODE);
1887         break;
1888     case AD_DCAY:
1889         hitmsg(mtmp, mattk);
1890         if (mtmp->mcan)
1891             break;
1892         if (u.umonnum == PM_WOOD_GOLEM || u.umonnum == PM_LEATHER_GOLEM) {
1893 /*JP
1894             You("rot!");
1895 */
1896             You("\95\85\82Á\82½\81I");
1897             /* KMH -- this is okay with unchanging */
1898             rehumanize();
1899             break;
1900         }
1901         erode_armor(&youmonst, ERODE_ROT);
1902         break;
1903     case AD_HEAL:
1904         /* a cancelled nurse is just an ordinary monster,
1905          * nurses don't heal those that cause petrification */
1906         if (mtmp->mcan || (Upolyd && touch_petrifies(youmonst.data))) {
1907             hitmsg(mtmp, mattk);
1908             break;
1909         }
1910         if (!uwep && !uarmu && !uarm && !uarmc
1911             && !uarms && !uarmg && !uarmf && !uarmh) {
1912             boolean goaway = FALSE;
1913
1914 /*JP
1915             pline("%s hits!  (I hope you don't mind.)", Monnam(mtmp));
1916 */
1917             pline("%s\82Ì\8dU\8c\82\82Í\96½\92\86\82µ\82½\81D(\8bC\82É\82µ\82È\82¢\82æ\82¤\82É\81D)", Monnam(mtmp));
1918             if (Upolyd) {
1919                 u.mh += rnd(7);
1920                 if (!rn2(7)) {
1921                     /* no upper limit necessary; effect is temporary */
1922                     u.mhmax++;
1923                     if (!rn2(13))
1924                         goaway = TRUE;
1925                 }
1926                 if (u.mh > u.mhmax)
1927                     u.mh = u.mhmax;
1928             } else {
1929                 u.uhp += rnd(7);
1930                 if (!rn2(7)) {
1931                     /* hard upper limit via nurse care: 25 * ulevel */
1932                     if (u.uhpmax < 5 * u.ulevel + d(2 * u.ulevel, 10))
1933                         u.uhpmax++;
1934                     if (!rn2(13))
1935                         goaway = TRUE;
1936                 }
1937                 if (u.uhp > u.uhpmax)
1938                     u.uhp = u.uhpmax;
1939             }
1940             if (!rn2(3))
1941                 exercise(A_STR, TRUE);
1942             if (!rn2(3))
1943                 exercise(A_CON, TRUE);
1944             if (Sick)
1945                 make_sick(0L, (char *) 0, FALSE, SICK_ALL);
1946             context.botl = 1;
1947             if (goaway) {
1948                 mongone(mtmp);
1949                 return 2;
1950             } else if (!rn2(33)) {
1951                 if (!tele_restrict(mtmp))
1952                     (void) rloc(mtmp, TRUE);
1953                 monflee(mtmp, d(3, 6), TRUE, FALSE);
1954                 return 3;
1955             }
1956             dmg = 0;
1957         } else {
1958             if (Role_if(PM_HEALER)) {
1959                 if (!Deaf && !(moves % 5))
1960 /*JP
1961                     verbalize("Doc, I can't help you unless you cooperate.");
1962 */
1963                     verbalize("\83h\83N\83^\81[\81I\8b¦\97Í\82ð\82¨\82Ë\82ª\82¢\82µ\82Ü\82·\82í\81D");
1964                 dmg = 0;
1965             } else
1966                 hitmsg(mtmp, mattk);
1967         }
1968         break;
1969     case AD_CURS:
1970         hitmsg(mtmp, mattk);
1971         if (!night() && mdat == &mons[PM_GREMLIN])
1972             break;
1973         if (!mtmp->mcan && !rn2(10)) {
1974             if (!Deaf) {
1975                 if (Blind)
1976 /*JP
1977                     You_hear("laughter.");
1978 */
1979                     You_hear("\8fÎ\82¢\90º\82ð\95·\82¢\82½\81D");
1980                 else
1981 /*JP
1982                     pline("%s chuckles.", Monnam(mtmp));
1983 */
1984                     pline("%s\82Í\83N\83X\83N\83X\8fÎ\82Á\82½\81D", Monnam(mtmp));
1985             }
1986             if (u.umonnum == PM_CLAY_GOLEM) {
1987 /*JP
1988                 pline("Some writing vanishes from your head!");
1989 */
1990                 pline("\82¢\82­\82Â\82©\82Ì\95\8e\9a\82ª\82 \82È\82½\82Ì\93ª\82©\82ç\8fÁ\82¦\82½\81I");
1991                 /* KMH -- this is okay with unchanging */
1992                 rehumanize();
1993                 break;
1994             }
1995             attrcurse();
1996         }
1997         break;
1998     case AD_STUN:
1999         hitmsg(mtmp, mattk);
2000         if (!mtmp->mcan && !rn2(4)) {
2001             make_stunned((HStun & TIMEOUT) + (long) dmg, TRUE);
2002             dmg /= 2;
2003         }
2004         break;
2005     case AD_ACID:
2006         hitmsg(mtmp, mattk);
2007         if (!mtmp->mcan && !rn2(3))
2008             if (Acid_resistance) {
2009 #if 0 /*JP:T*/
2010                 pline("You're covered in %s, but it seems harmless.",
2011                       hliquid("acid"));
2012 #else
2013                 pline("%s\82Å\95¢\82í\82ê\82½\81D\82µ\82©\82µ\8f\9d\82Â\82©\82È\82¢\81D",
2014                       hliquid("\8e_"));
2015 #endif
2016                 dmg = 0;
2017             } else {
2018 /*JP
2019                 pline("You're covered in %s!  It burns!", hliquid("acid"));
2020 */
2021                 pline("%s\82Å\95¢\82í\82ê\8fÄ\82¯\82½\81I", hliquid("\8e_"));
2022                 exercise(A_STR, FALSE);
2023             }
2024         else
2025             dmg = 0;
2026         break;
2027     case AD_SLOW:
2028         hitmsg(mtmp, mattk);
2029         if (uncancelled && HFast && !defends(AD_SLOW, uwep) && !rn2(4))
2030             u_slow_down();
2031         break;
2032     case AD_DREN:
2033         hitmsg(mtmp, mattk);
2034         if (uncancelled && !rn2(4)) /* 25% chance */
2035             drain_en(dmg);
2036         dmg = 0;
2037         break;
2038     case AD_CONF:
2039         hitmsg(mtmp, mattk);
2040         if (!mtmp->mcan && !rn2(4) && !mtmp->mspec_used) {
2041             mtmp->mspec_used = mtmp->mspec_used + (dmg + rn2(6));
2042             if (Confusion)
2043 /*JP
2044                 You("are getting even more confused.");
2045 */
2046                 You("\82Ü\82·\82Ü\82·\8d¬\97\90\82µ\82½\81D");
2047             else
2048 /*JP
2049                 You("are getting confused.");
2050 */
2051                 You("\8d¬\97\90\82µ\82Ä\82«\82½\81D");
2052             make_confused(HConfusion + dmg, FALSE);
2053         }
2054         dmg = 0;
2055         break;
2056     case AD_DETH:
2057 /*JP
2058         pline("%s reaches out with its deadly touch.", Monnam(mtmp));
2059 */
2060         pline("%s\82Í\8e\80\82Ì\98r\82ð\82Ì\82Î\82µ\82½\81D", Monnam(mtmp));
2061         if (is_undead(youmonst.data)) {
2062             /* Still does normal damage */
2063 /*JP
2064             pline("Was that the touch of death?");
2065 */
2066             pline("\8d¡\82Ì\82Í\8e\80\82Ì\90é\8d\90\82¾\82Á\82½\82Ì\82©\82È\81H");
2067             break;
2068         }
2069         switch (rn2(20)) {
2070         case 19:
2071         case 18:
2072         case 17:
2073             if (!Antimagic) {
2074                 killer.format = KILLED_BY_AN;
2075 /*JP
2076                 Strcpy(killer.name, "touch of death");
2077 */
2078                 Strcpy(killer.name, "\8e\80\82Ì\90é\8d\90\82Å");
2079                 done(DIED);
2080                 dmg = 0;
2081                 break;
2082             }
2083             /*FALLTHRU*/
2084         default: /* case 16: ... case 5: */
2085 /*JP
2086             You_feel("your life force draining away...");
2087 */
2088             You("\91Ì\97Í\82ª\92D\82í\82ê\82Ä\82¢\82­\82æ\82¤\82È\8bC\82ª\82µ\82½\81D\81D\81D");
2089             permdmg = 1; /* actual damage done below */
2090             break;
2091         case 4:
2092         case 3:
2093         case 2:
2094         case 1:
2095         case 0:
2096             if (Antimagic)
2097                 shieldeff(u.ux, u.uy);
2098 /*JP
2099             pline("Lucky for you, it didn't work!");
2100 */
2101             pline("\89^\82Ì\82æ\82¢\82±\82Æ\82É\82È\82ñ\82Æ\82à\82È\82©\82Á\82½\81I");
2102             dmg = 0;
2103             break;
2104         }
2105         break;
2106     case AD_PEST:
2107 /*JP
2108         pline("%s reaches out, and you feel fever and chills.", Monnam(mtmp));
2109 */
2110         pline("%s\82Í\98r\82ð\82Ì\82Î\82µ\82½\81C\82 \82È\82½\82Í\88«\8a¦\82ð\8a´\82\82½\81D", Monnam(mtmp));
2111         (void) diseasemu(mdat); /* plus the normal damage */
2112         break;
2113     case AD_FAMN:
2114 /*JP
2115         pline("%s reaches out, and your body shrivels.", Monnam(mtmp));
2116 */
2117         pline("%s\82Í\98r\82ð\90L\82Î\82µ\82½\81C\82 \82È\82½\82Ì\91Ì\82Í\82µ\82È\82Ñ\82½\81D", Monnam(mtmp));
2118         exercise(A_CON, FALSE);
2119         if (!is_fainted())
2120             morehungry(rn1(40, 40));
2121         /* plus the normal damage */
2122         break;
2123     case AD_SLIM:
2124         hitmsg(mtmp, mattk);
2125         if (!uncancelled)
2126             break;
2127         if (flaming(youmonst.data)) {
2128 /*JP
2129             pline_The("slime burns away!");
2130 */
2131             pline_The("\83X\83\89\83C\83\80\82Í\94R\82¦\82½\81I");
2132             dmg = 0;
2133         } else if (Unchanging || noncorporeal(youmonst.data)
2134                    || youmonst.data == &mons[PM_GREEN_SLIME]) {
2135 /*JP
2136             You("are unaffected.");
2137 */
2138             You("\89e\8b¿\82ð\8eó\82¯\82È\82¢\81D");
2139             dmg = 0;
2140         } else if (!Slimed) {
2141 /*JP
2142             You("don't feel very well.");
2143 */
2144             You("\8bC\95ª\82ª\88«\82¢\81D");
2145             make_slimed(10L, (char *) 0);
2146             delayed_killer(SLIMED, KILLED_BY_AN, mtmp->data->mname);
2147         } else
2148 /*JP
2149             pline("Yuck!");
2150 */
2151             pline("\83E\83Q\83F\81[\81I");
2152         break;
2153     case AD_ENCH: /* KMH -- remove enchantment (disenchanter) */
2154         hitmsg(mtmp, mattk);
2155         /* uncancelled is sufficient enough; please
2156            don't make this attack less frequent */
2157         if (uncancelled) {
2158             struct obj *obj = some_armor(&youmonst);
2159
2160             if (!obj) {
2161                 /* some rings are susceptible;
2162                    amulets and blindfolds aren't (at present) */
2163                 switch (rn2(5)) {
2164                 case 0:
2165                     break;
2166                 case 1:
2167                     obj = uright;
2168                     break;
2169                 case 2:
2170                     obj = uleft;
2171                     break;
2172                 case 3:
2173                     obj = uamul;
2174                     break;
2175                 case 4:
2176                     obj = ublindf;
2177                     break;
2178                 }
2179             }
2180             if (drain_item(obj, FALSE)) {
2181 /*JP
2182                 pline("%s less effective.", Yobjnam2(obj, "seem"));
2183 */
2184                 Your("%s\82©\82ç\96\82\97Í\82ª\8fÁ\82¦\82½\82æ\82¤\82¾\81D", xname(obj));
2185             }
2186         }
2187         break;
2188     default:
2189         dmg = 0;
2190         break;
2191     }
2192     if ((Upolyd ? u.mh : u.uhp) < 1) {
2193         /* already dead? call rehumanize() or done_in_by() as appropriate */
2194         mdamageu(mtmp, 1);
2195         dmg = 0;
2196     }
2197
2198     /*  Negative armor class reduces damage done instead of fully protecting
2199      *  against hits.
2200      */
2201     if (dmg && u.uac < 0) {
2202         dmg -= rnd(-u.uac);
2203         if (dmg < 1)
2204             dmg = 1;
2205     }
2206
2207     if (dmg) {
2208         if (Half_physical_damage
2209             /* Mitre of Holiness */
2210             || (Role_if(PM_PRIEST) && uarmh && is_quest_artifact(uarmh)
2211                 && (is_undead(mtmp->data) || is_demon(mtmp->data)
2212                     || is_vampshifter(mtmp))))
2213             dmg = (dmg + 1) / 2;
2214
2215         if (permdmg) { /* Death's life force drain */
2216             int lowerlimit, *hpmax_p;
2217             /*
2218              * Apply some of the damage to permanent hit points:
2219              *  polymorphed         100% against poly'd hpmax
2220              *  hpmax > 25*lvl      100% against normal hpmax
2221              *  hpmax > 10*lvl  50..100%
2222              *  hpmax >  5*lvl  25..75%
2223              *  otherwise        0..50%
2224              * Never reduces hpmax below 1 hit point per level.
2225              */
2226             permdmg = rn2(dmg / 2 + 1);
2227             if (Upolyd || u.uhpmax > 25 * u.ulevel)
2228                 permdmg = dmg;
2229             else if (u.uhpmax > 10 * u.ulevel)
2230                 permdmg += dmg / 2;
2231             else if (u.uhpmax > 5 * u.ulevel)
2232                 permdmg += dmg / 4;
2233
2234             if (Upolyd) {
2235                 hpmax_p = &u.mhmax;
2236                 /* [can't use youmonst.m_lev] */
2237                 lowerlimit = min((int) youmonst.data->mlevel, u.ulevel);
2238             } else {
2239                 hpmax_p = &u.uhpmax;
2240                 lowerlimit = u.ulevel;
2241             }
2242             if (*hpmax_p - permdmg > lowerlimit)
2243                 *hpmax_p -= permdmg;
2244             else if (*hpmax_p > lowerlimit)
2245                 *hpmax_p = lowerlimit;
2246             /* else unlikely...
2247              * already at or below minimum threshold; do nothing */
2248             context.botl = 1;
2249         }
2250
2251         mdamageu(mtmp, dmg);
2252     }
2253
2254     if (dmg)
2255         res = passiveum(olduasmon, mtmp, mattk);
2256     else
2257         res = 1;
2258     stop_occupation();
2259     return res;
2260 }
2261
2262 /* An interface for use when taking a blindfold off, for example,
2263  * to see if an engulfing attack should immediately take affect, like
2264  * a passive attack. TRUE if engulfing blindness occurred */
2265 boolean
2266 gulp_blnd_check()
2267 {
2268     struct attack *mattk;
2269
2270     if (!Blinded && u.uswallow
2271         && (mattk = attacktype_fordmg(u.ustuck->data, AT_ENGL, AD_BLND))
2272         && can_blnd(u.ustuck, &youmonst, mattk->aatyp, (struct obj *) 0)) {
2273         ++u.uswldtim; /* compensate for gulpmu change */
2274         (void) gulpmu(u.ustuck, mattk);
2275         return TRUE;
2276     }
2277     return FALSE;
2278 }
2279
2280 /* monster swallows you, or damage if u.uswallow */
2281 STATIC_OVL int
2282 gulpmu(mtmp, mattk)
2283 struct monst *mtmp;
2284 struct attack *mattk;
2285 {
2286     struct trap *t = t_at(u.ux, u.uy);
2287     int tmp = d((int) mattk->damn, (int) mattk->damd);
2288     int tim_tmp;
2289     struct obj *otmp2;
2290     int i;
2291     boolean physical_damage = FALSE;
2292
2293     if (!u.uswallow) { /* swallows you */
2294         int omx = mtmp->mx, omy = mtmp->my;
2295
2296         if (!engulf_target(mtmp, &youmonst))
2297             return 0;
2298         if ((t && is_pit(t->ttyp))
2299             && sobj_at(BOULDER, u.ux, u.uy))
2300             return 0;
2301
2302         if (Punished)
2303             unplacebc(); /* ball&chain go away */
2304         remove_monster(omx, omy);
2305         mtmp->mtrapped = 0; /* no longer on old trap */
2306         place_monster(mtmp, u.ux, u.uy);
2307         u.ustuck = mtmp;
2308         newsym(mtmp->mx, mtmp->my);
2309         if (is_animal(mtmp->data) && u.usteed) {
2310             char buf[BUFSZ];
2311
2312             /* Too many quirks presently if hero and steed
2313              * are swallowed. Pretend purple worms don't
2314              * like horses for now :-)
2315              */
2316             Strcpy(buf, mon_nam(u.usteed));
2317 #if 0 /*JP*/
2318             pline("%s lunges forward and plucks you off %s!", Monnam(mtmp),
2319                   buf);
2320 #else
2321             pline("%s\82Í\93Ë\90i\82µ\82 \82È\82½\82ð%s\82©\82ç\88ø\82«\97\8e\82µ\82½\81I", Monnam(mtmp),
2322                   buf);
2323 #endif
2324             dismount_steed(DISMOUNT_ENGULFED);
2325         } else
2326 /*JP
2327             pline("%s engulfs you!", Monnam(mtmp));
2328 */
2329             pline("%s\82Í\82 \82È\82½\82ð\88ù\82Ý\82±\82ñ\82¾\81I", Monnam(mtmp));
2330         stop_occupation();
2331         reset_occupations(); /* behave as if you had moved */
2332
2333         if (u.utrap) {
2334 #if 0 /*JP:T*/
2335             You("are released from the %s!",
2336                 u.utraptype == TT_WEB ? "web" : "trap");
2337 #else
2338             You("%s\82©\82ç\89ð\95ú\82³\82ê\82½\81I",
2339                 u.utraptype == TT_WEB ? "\82­\82à\82Ì\91\83" : "ã©");
2340 #endif
2341             reset_utrap(FALSE);
2342         }
2343
2344         i = number_leashed();
2345         if (i > 0) {
2346 #if 0 /*JP*/
2347             const char *s = (i > 1) ? "leashes" : "leash";
2348
2349             pline_The("%s %s loose.", s, vtense(s, "snap"));
2350 #else
2351             pline("\95R\82Í\83p\83`\83\93\82Æ\82Í\82¸\82ê\82½\81D");
2352 #endif
2353             unleash_all();
2354         }
2355
2356         if (touch_petrifies(youmonst.data) && !resists_ston(mtmp)) {
2357             /* put the attacker back where it started;
2358                the resulting statue will end up there */
2359             remove_monster(mtmp->mx, mtmp->my); /* u.ux,u.uy */
2360             place_monster(mtmp, omx, omy);
2361             minstapetrify(mtmp, TRUE);
2362             /* normally unstuck() would do this, but we're not
2363                fully swallowed yet so that won't work here */
2364             if (Punished)
2365                 placebc();
2366             u.ustuck = 0;
2367             return (!DEADMONSTER(mtmp)) ? 0 : 2;
2368         }
2369
2370         display_nhwindow(WIN_MESSAGE, FALSE);
2371         vision_recalc(2); /* hero can't see anything */
2372         u.uswallow = 1;
2373         /* for digestion, shorter time is more dangerous;
2374            for other swallowings, longer time means more
2375            chances for the swallower to attack */
2376         if (mattk->adtyp == AD_DGST) {
2377             tim_tmp = 25 - (int) mtmp->m_lev;
2378             if (tim_tmp > 0)
2379                 tim_tmp = rnd(tim_tmp) / 2;
2380             else if (tim_tmp < 0)
2381                 tim_tmp = -(rnd(-tim_tmp) / 2);
2382             /* having good armor & high constitution makes
2383                it take longer for you to be digested, but
2384                you'll end up trapped inside for longer too */
2385             tim_tmp += -u.uac + 10 + (ACURR(A_CON) / 3 - 1);
2386         } else {
2387             /* higher level attacker takes longer to eject hero */
2388             tim_tmp = rnd((int) mtmp->m_lev + 10 / 2);
2389         }
2390         /* u.uswldtim always set > 1 */
2391         u.uswldtim = (unsigned) ((tim_tmp < 2) ? 2 : tim_tmp);
2392         swallowed(1);
2393         for (otmp2 = invent; otmp2; otmp2 = otmp2->nobj)
2394             (void) snuff_lit(otmp2);
2395     }
2396
2397     if (mtmp != u.ustuck)
2398         return 0;
2399     if (u.uswldtim > 0)
2400         u.uswldtim -= 1;
2401
2402     switch (mattk->adtyp) {
2403     case AD_DGST:
2404         physical_damage = TRUE;
2405         if (Slow_digestion) {
2406             /* Messages are handled below */
2407             u.uswldtim = 0;
2408             tmp = 0;
2409         } else if (u.uswldtim == 0) {
2410 /*JP
2411             pline("%s totally digests you!", Monnam(mtmp));
2412 */
2413             pline("%s\82Í\82 \82È\82½\82ð\8a®\91S\82É\8fÁ\89»\82µ\82½\81I", Monnam(mtmp));
2414             tmp = u.uhp;
2415             if (Half_physical_damage)
2416                 tmp *= 2; /* sorry */
2417         } else {
2418 #if 0 /*JP*/
2419             pline("%s%s digests you!", Monnam(mtmp),
2420                   (u.uswldtim == 2) ? " thoroughly"
2421                                     : (u.uswldtim == 1) ? " utterly" : "");
2422 #else
2423             pline("%s\82Í\82 \82È\82½\82ð%s\8fÁ\89»\82µ\82Ä\82¢\82é\81I", Monnam(mtmp),
2424                   (u.uswldtim == 2) ? "\93O\92ê\93I\82É"
2425                                     : (u.uswldtim == 1) ? "\8a®\91S\82É" : "");
2426 #endif
2427             exercise(A_STR, FALSE);
2428         }
2429         break;
2430     case AD_PHYS:
2431         physical_damage = TRUE;
2432         if (mtmp->data == &mons[PM_FOG_CLOUD]) {
2433 #if 0 /*JP*/
2434             You("are laden with moisture and %s",
2435                 flaming(youmonst.data)
2436                     ? "are smoldering out!"
2437                     : Breathless ? "find it mildly uncomfortable."
2438                                  : amphibious(youmonst.data)
2439                                        ? "feel comforted."
2440                                        : "can barely breathe!");
2441 #else
2442             You("\8e¼\8bC\82É\8bê\82µ\82ß\82ç\82ê\81C%s",
2443                 flaming(youmonst.data)
2444                     ? "\82­\82·\82Ô\82Á\82½\81I"
2445                     : Breathless ? "\8f­\81X\95s\89õ\82É\8a´\82\82½\81D"
2446                                  : amphibious(youmonst.data)
2447                                        ? "\88À\82ç\82¬\82ð\8a´\82\82½\81D"
2448                                        : "\91§\82ð\82·\82é\82Ì\82ª\82â\82Á\82Æ\82¾\81I");
2449 #endif
2450             /* NB: Amphibious includes Breathless */
2451             if (Amphibious && !flaming(youmonst.data))
2452                 tmp = 0;
2453         } else {
2454 /*JP
2455             You("are pummeled with debris!");
2456 */
2457             You("\8a¢âI\82Å\92É\82ß\82Â\82¯\82ç\82ê\82½\81I");
2458             exercise(A_STR, FALSE);
2459         }
2460         break;
2461     case AD_ACID:
2462         if (Acid_resistance) {
2463 /*JP
2464             You("are covered with a seemingly harmless goo.");
2465 */
2466             You("\96³\8aQ\82Á\82Û\82¢\82Ë\82Î\82Â\82­\82à\82Ì\82Å\82¨\82¨\82í\82ê\82½\81D");
2467             tmp = 0;
2468         } else {
2469             if (Hallucination)
2470 /*JP
2471                 pline("Ouch!  You've been slimed!");
2472 */
2473                 pline("\82°\82°\82ñ\81I\82 \82È\82½\82Í\82Ê\82é\82Ê\82é\82¾\81I");
2474             else
2475 /*JP
2476                 You("are covered in slime!  It burns!");
2477 */
2478                 You("\82×\82Æ\82×\82Æ\82É\82È\82Á\82½\81D\82»\82µ\82Ä\8e_\82É\8fÄ\82©\82ê\82½\81I");
2479             exercise(A_STR, FALSE);
2480         }
2481         break;
2482     case AD_BLND:
2483         if (can_blnd(mtmp, &youmonst, mattk->aatyp, (struct obj *) 0)) {
2484             if (!Blind) {
2485                 long was_blinded = Blinded;
2486
2487                 if (!Blinded)
2488 /*JP
2489                     You_cant("see in here!");
2490 */
2491                     You("\89½\82à\8c©\82¦\82È\82¢\81I");
2492                 make_blinded((long) tmp, FALSE);
2493                 if (!was_blinded && !Blind)
2494                     Your1(vision_clears);
2495             } else
2496                 /* keep him blind until disgorged */
2497                 make_blinded(Blinded + 1, FALSE);
2498         }
2499         tmp = 0;
2500         break;
2501     case AD_ELEC:
2502         if (!mtmp->mcan && rn2(2)) {
2503 /*JP
2504             pline_The("air around you crackles with electricity.");
2505 */
2506             pline("\82 \82È\82½\82Ì\89ñ\82è\82Ì\8bó\8bC\82Í\93d\8bC\82Å\83s\83\8a\83s\83\8a\82µ\82Ä\82¢\82é\81D");
2507             if (Shock_resistance) {
2508                 shieldeff(u.ux, u.uy);
2509 /*JP
2510                 You("seem unhurt.");
2511 */
2512                 You("\8f\9d\82Â\82©\82È\82¢\82æ\82¤\82¾\81D");
2513                 ugolemeffects(AD_ELEC, tmp);
2514                 tmp = 0;
2515             }
2516         } else
2517             tmp = 0;
2518         break;
2519     case AD_COLD:
2520         if (!mtmp->mcan && rn2(2)) {
2521             if (Cold_resistance) {
2522                 shieldeff(u.ux, u.uy);
2523 /*JP
2524                 You_feel("mildly chilly.");
2525 */
2526                 pline("\82Ð\82ñ\82â\82è\82µ\82½\81D");
2527                 ugolemeffects(AD_COLD, tmp);
2528                 tmp = 0;
2529             } else
2530 /*JP
2531                 You("are freezing to death!");
2532 */
2533                 You("\93\80\8e\80\82µ\82»\82¤\82¾\81I");
2534         } else
2535             tmp = 0;
2536         break;
2537     case AD_FIRE:
2538         if (!mtmp->mcan && rn2(2)) {
2539             if (Fire_resistance) {
2540                 shieldeff(u.ux, u.uy);
2541 /*JP
2542                 You_feel("mildly hot.");
2543 */
2544                 pline("\83|\83J\83|\83J\82µ\82½\81D");
2545                 ugolemeffects(AD_FIRE, tmp);
2546                 tmp = 0;
2547             } else
2548 /*JP
2549                 You("are burning to a crisp!");
2550 */
2551                 You("\94R\82¦\82Ä\83J\83\89\83J\83\89\82É\82È\82Á\82½\81I");
2552             burn_away_slime();
2553         } else
2554             tmp = 0;
2555         break;
2556     case AD_DISE:
2557         if (!diseasemu(mtmp->data))
2558             tmp = 0;
2559         break;
2560     case AD_DREN:
2561         /* AC magic cancellation doesn't help when engulfed */
2562         if (!mtmp->mcan && rn2(4)) /* 75% chance */
2563             drain_en(tmp);
2564         tmp = 0;
2565         break;
2566     default:
2567         physical_damage = TRUE;
2568         tmp = 0;
2569         break;
2570     }
2571
2572     if (physical_damage)
2573         tmp = Maybe_Half_Phys(tmp);
2574
2575     mdamageu(mtmp, tmp);
2576     if (tmp)
2577         stop_occupation();
2578
2579     if (!u.uswallow) {
2580         ; /* life-saving has already expelled swallowed hero */
2581     } else if (touch_petrifies(youmonst.data) && !resists_ston(mtmp)) {
2582 #if 0 /*JP:T*/
2583         pline("%s very hurriedly %s you!", Monnam(mtmp),
2584               is_animal(mtmp->data) ? "regurgitates" : "expels");
2585 #else
2586         pline("%s\82Í\8dQ\82Ä\82Ä\82 \82È\82½\82ð%s\82µ\82½\81I", Monnam(mtmp),
2587               is_animal(mtmp->data)? "\93f\82«\96ß" : "\94r\8fo");
2588 #endif
2589         expels(mtmp, mtmp->data, FALSE);
2590     } else if (!u.uswldtim || youmonst.data->msize >= MZ_HUGE) {
2591         /* 3.6.2: u.uswldtim used to be set to 0 by life-saving but it
2592            expels now so the !u.uswldtim case is no longer possible;
2593            however, polymorphing into a huge form while already
2594            swallowed is still possible */
2595 /*JP
2596         You("get %s!", is_animal(mtmp->data) ? "regurgitated" : "expelled");
2597 */
2598         You("%s\82³\82ê\82½\81I", is_animal(mtmp->data)? "\93f\82«\96ß" : "\94r\8fo");
2599         if (flags.verbose
2600             && (is_animal(mtmp->data)
2601                 || (dmgtype(mtmp->data, AD_DGST) && Slow_digestion)))
2602 /*JP
2603             pline("Obviously %s doesn't like your taste.", mon_nam(mtmp));
2604 */
2605             You("\82Ç\82¤\82à%s\8dD\82Ý\82Ì\96¡\82\82á\82È\82¢\82æ\82¤\82¾\81D", mon_nam(mtmp));
2606         expels(mtmp, mtmp->data, FALSE);
2607     }
2608     return 1;
2609 }
2610
2611 /* monster explodes in your face */
2612 STATIC_OVL int
2613 explmu(mtmp, mattk, ufound)
2614 struct monst *mtmp;
2615 struct attack *mattk;
2616 boolean ufound;
2617 {
2618     boolean physical_damage = TRUE, kill_agr = TRUE;
2619
2620     if (mtmp->mcan)
2621         return 0;
2622
2623     if (!ufound) {
2624 #if 0 /*JP:T*/
2625         pline("%s explodes at a spot in %s!",
2626               canseemon(mtmp) ? Monnam(mtmp) : "It",
2627               levl[mtmp->mux][mtmp->muy].typ == WATER ? "empty water"
2628                                                       : "thin air");
2629 #else
2630         pline("%s\82Í\89½\82à\82È\82¢%s\82Å\94\9a\94­\82µ\82½\81I",
2631               canseemon(mtmp) ? Monnam(mtmp) : "\89½\8eÒ\82©",
2632               levl[mtmp->mux][mtmp->muy].typ == WATER ? "\90\85\92\86"
2633                                                       : "\8bó\8aÔ");
2634 #endif
2635     } else {
2636         int tmp = d((int) mattk->damn, (int) mattk->damd);
2637         boolean not_affected = defends((int) mattk->adtyp, uwep);
2638
2639         hitmsg(mtmp, mattk);
2640
2641         switch (mattk->adtyp) {
2642         case AD_COLD:
2643             physical_damage = FALSE;
2644             not_affected |= Cold_resistance;
2645             goto common;
2646         case AD_FIRE:
2647             physical_damage = FALSE;
2648             not_affected |= Fire_resistance;
2649             goto common;
2650         case AD_ELEC:
2651             physical_damage = FALSE;
2652             not_affected |= Shock_resistance;
2653             goto common;
2654         case AD_PHYS:
2655             /* there aren't any exploding creatures with AT_EXPL attack
2656                for AD_PHYS damage but there might be someday; without this,
2657                static analysis complains that 'physical_damage' is always
2658                False when tested below; it's right, but having that in
2659                place means one less thing to update if AD_PHYS gets added */
2660  common:
2661
2662             if (!not_affected) {
2663                 if (ACURR(A_DEX) > rnd(20)) {
2664 /*JP
2665                     You("duck some of the blast.");
2666 */
2667                     You("\8fÕ\8c\82\82ð\82³\82¯\82½\81D");
2668                     tmp = (tmp + 1) / 2;
2669                 } else {
2670                     if (flags.verbose)
2671 /*JP
2672                         You("get blasted!");
2673 */
2674                         You("\8fÕ\8c\82\82ð\82­\82ç\82Á\82½\81I");
2675                 }
2676                 if (mattk->adtyp == AD_FIRE)
2677                     burn_away_slime();
2678                 if (physical_damage)
2679                     tmp = Maybe_Half_Phys(tmp);
2680                 mdamageu(mtmp, tmp);
2681             }
2682             break;
2683
2684         case AD_BLND:
2685             not_affected = resists_blnd(&youmonst);
2686             if (!not_affected) {
2687                 /* sometimes you're affected even if it's invisible */
2688                 if (mon_visible(mtmp) || (rnd(tmp /= 2) > u.ulevel)) {
2689 /*JP
2690                     You("are blinded by a blast of light!");
2691 */
2692                     You("\82Ü\82Î\82ä\82¢\8cõ\82É\96Ú\82ª\82­\82ç\82ñ\82¾\81I");
2693                     make_blinded((long) tmp, FALSE);
2694                     if (!Blind)
2695                         Your1(vision_clears);
2696                 } else if (flags.verbose)
2697 /*JP
2698                     You("get the impression it was not terribly bright.");
2699 */
2700                     You("\82»\82ê\82Í\8b°\82ë\82µ\82­\82Ü\82Ô\82µ\82¢\82Æ\82¢\82¤\82Ù\82Ç\82\82á\82È\82¢\82Æ\8ev\82Á\82½\81D");
2701             }
2702             break;
2703
2704         case AD_HALU:
2705             not_affected |= Blind || (u.umonnum == PM_BLACK_LIGHT
2706                                       || u.umonnum == PM_VIOLET_FUNGUS
2707                                       || dmgtype(youmonst.data, AD_STUN));
2708             if (!not_affected) {
2709                 boolean chg;
2710                 if (!Hallucination)
2711 /*JP
2712                     You("are caught in a blast of kaleidoscopic light!");
2713 */
2714                     You("\96\9c\89Ø\8b¾\82Ì\8cõ\82É\95ß\82ç\82¦\82ç\82ê\82½\81I");
2715                 /* avoid hallucinating the black light as it dies */
2716                 mondead(mtmp);    /* remove it from map now */
2717                 kill_agr = FALSE; /* already killed (maybe lifesaved) */
2718                 chg =
2719                     make_hallucinated(HHallucination + (long) tmp, FALSE, 0L);
2720 /*JP
2721                 You("%s.", chg ? "are freaked out" : "seem unaffected");
2722 */
2723                 You("%s\81D", chg ? "\90\8c\82¢\82µ\82ê\82½" : "\89e\8b¿\82ð\8eó\82¯\82È\82©\82Á\82½");
2724             }
2725             break;
2726
2727         default:
2728             break;
2729         }
2730         if (not_affected) {
2731 /*JP
2732             You("seem unaffected by it.");
2733 */
2734             You("\89e\8b¿\82ð\8eó\82¯\82È\82¢\82æ\82¤\82¾\81D");
2735             ugolemeffects((int) mattk->adtyp, tmp);
2736         }
2737     }
2738     if (kill_agr)
2739         mondead(mtmp);
2740     wake_nearto(mtmp->mx, mtmp->my, 7 * 7);
2741     return (!DEADMONSTER(mtmp)) ? 0 : 2;
2742 }
2743
2744 /* monster gazes at you */
2745 int
2746 gazemu(mtmp, mattk)
2747 struct monst *mtmp;
2748 struct attack *mattk;
2749 {
2750     static const char *const reactions[] = {
2751 #if 0 /*JP*/
2752         "confused",              /* [0] */
2753         "stunned",               /* [1] */
2754         "puzzled",   "dazzled",  /* [2,3] */
2755         "irritated", "inflamed", /* [4,5] */
2756         "tired",                 /* [6] */
2757         "dulled",                /* [7] */
2758 #else
2759         "\8d¬\97\90\82µ\82½",                 /* [0] */
2760         "\9eN\9eO\82Æ\82µ\82½",               /* [1] */
2761         "\8d¢\98f\82µ\82½",   "\8c\98f\82³\82ê\82½", /* [2,3] */
2762         "\83C\83\89\83C\83\89\82µ\82½", "\8b»\95±\82µ\82½", /* [4,5] */
2763         "\94æ\82ê\82½",                   /* [6] */
2764         "\82Ú\82ñ\82â\82è\82µ\82½",             /* [7] */
2765 #endif
2766     };
2767     int react = -1;
2768     boolean cancelled = (mtmp->mcan != 0), already = FALSE;
2769
2770     /* assumes that hero has to see monster's gaze in order to be
2771        affected, rather than monster just having to look at hero;
2772        when hallucinating, hero's brain doesn't register what
2773        it's seeing correctly so the gaze is usually ineffective
2774        [this could be taken a lot farther and select a gaze effect
2775        appropriate to what's currently being displayed, giving
2776        ordinary monsters a gaze attack when hero thinks he or she
2777        is facing a gazing creature, but let's not go that far...] */
2778     if (Hallucination && rn2(4))
2779         cancelled = TRUE;
2780
2781     switch (mattk->adtyp) {
2782     case AD_STON:
2783         if (cancelled || !mtmp->mcansee) {
2784             if (!canseemon(mtmp))
2785                 break; /* silently */
2786 #if 0 /*JP*/
2787             pline("%s %s.", Monnam(mtmp),
2788                   (mtmp->data == &mons[PM_MEDUSA] && mtmp->mcan)
2789                       ? "doesn't look all that ugly"
2790                       : "gazes ineffectually");
2791 #else
2792             pline("%s\82Í%s\81D", Monnam(mtmp),
2793                   (mtmp->data == &mons[PM_MEDUSA] && mtmp->mcan)
2794                       ? "\82»\82ê\82Ù\82Ç\8fX\82­\82È\82¢\82±\82Æ\82É\8bC\82ª\82Â\82¢\82½"
2795                       : "\96³\88Ó\96¡\82É\82É\82ç\82ñ\82¾");
2796 #endif
2797             break;
2798         }
2799         if (Reflecting && couldsee(mtmp->mx, mtmp->my)
2800             && mtmp->data == &mons[PM_MEDUSA]) {
2801             /* hero has line of sight to Medusa and she's not blind */
2802             boolean useeit = canseemon(mtmp);
2803
2804             if (useeit)
2805 #if 0 /*JP:T*/
2806                 (void) ureflects("%s gaze is reflected by your %s.",
2807                                  s_suffix(Monnam(mtmp)));
2808 #else
2809                 (void) ureflects("%s\82Ì\82É\82ç\82Ý\82Í%s\82Å\94½\8eË\82³\82ê\82½\81D",
2810                                  Monnam(mtmp));
2811 #endif
2812             if (mon_reflects(
2813                     mtmp, !useeit ? (char *) 0
2814 /*JP
2815                                   : "The gaze is reflected away by %s %s!"))
2816 */
2817                                   : "\82É\82ç\82Ý\82Í%s\82Ì%s\82É\82æ\82Á\82Ä\94½\8eË\82³\82ê\82½\81I"))
2818                 break;
2819             if (!m_canseeu(mtmp)) { /* probably you're invisible */
2820                 if (useeit)
2821 #if 0 /*JP*/
2822                     pline(
2823                       "%s doesn't seem to notice that %s gaze was reflected.",
2824                           Monnam(mtmp), mhis(mtmp));
2825 #else
2826                     pline("\82É\82ç\82Ý\82ª\94½\8eË\82µ\82Ä\82¢\82é\82±\82Æ\82É%s\82Í\8bC\95t\82¢\82Ä\82¢\82È\82¢\82æ\82¤\82¾\81D",
2827                           Monnam(mtmp));
2828 #endif
2829                 break;
2830             }
2831             if (useeit)
2832 /*JP
2833                 pline("%s is turned to stone!", Monnam(mtmp));
2834 */
2835                 pline("%s\82Í\90Î\82É\82È\82Á\82½\81I", Monnam(mtmp));
2836             stoned = TRUE;
2837             killed(mtmp);
2838
2839             if (!DEADMONSTER(mtmp))
2840                 break;
2841             return 2;
2842         }
2843         if (canseemon(mtmp) && couldsee(mtmp->mx, mtmp->my)
2844             && !Stone_resistance) {
2845 /*JP
2846             You("meet %s gaze.", s_suffix(mon_nam(mtmp)));
2847 */
2848             You("%s\82É\82É\82ç\82Ü\82ê\82½\81D", mon_nam(mtmp));
2849             stop_occupation();
2850             if (poly_when_stoned(youmonst.data) && polymon(PM_STONE_GOLEM))
2851                 break;
2852 /*JP
2853             You("turn to stone...");
2854 */
2855             You("\90Î\82É\82È\82Á\82½\81D\81D\81D");
2856             killer.format = KILLED_BY;
2857             Strcpy(killer.name, mtmp->data->mname);
2858             done(STONING);
2859         }
2860         break;
2861     case AD_CONF:
2862         if (canseemon(mtmp) && couldsee(mtmp->mx, mtmp->my) && mtmp->mcansee
2863             && !mtmp->mspec_used && rn2(5)) {
2864             if (cancelled) {
2865                 react = 0; /* "confused" */
2866                 already = (mtmp->mconf != 0);
2867             } else {
2868                 int conf = d(3, 4);
2869
2870                 mtmp->mspec_used = mtmp->mspec_used + (conf + rn2(6));
2871                 if (!Confusion)
2872 /*JP
2873                     pline("%s gaze confuses you!", s_suffix(Monnam(mtmp)));
2874 */
2875                     pline("%s\82Ì\82É\82ç\82Ý\82Å\82 \82È\82½\82Í\8d¬\97\90\82µ\82½\81I", Monnam(mtmp));
2876                 else
2877 /*JP
2878                     You("are getting more and more confused.");
2879 */
2880                     You("\82Ü\82·\82Ü\82·\8d¬\97\90\82µ\82½\81D");
2881                 make_confused(HConfusion + conf, FALSE);
2882                 stop_occupation();
2883             }
2884         }
2885         break;
2886     case AD_STUN:
2887         if (canseemon(mtmp) && couldsee(mtmp->mx, mtmp->my) && mtmp->mcansee
2888             && !mtmp->mspec_used && rn2(5)) {
2889             if (cancelled) {
2890                 react = 1; /* "stunned" */
2891                 already = (mtmp->mstun != 0);
2892             } else {
2893                 int stun = d(2, 6);
2894
2895                 mtmp->mspec_used = mtmp->mspec_used + (stun + rn2(6));
2896 /*JP
2897                 pline("%s stares piercingly at you!", Monnam(mtmp));
2898 */
2899                 pline("%s\82Í\97â\82½\82¢\82Ü\82È\82´\82µ\82ð\82 \82È\82½\82É\8cü\82¯\82½\81I", Monnam(mtmp));
2900                 make_stunned((HStun & TIMEOUT) + (long) stun, TRUE);
2901                 stop_occupation();
2902             }
2903         }
2904         break;
2905     case AD_BLND:
2906         if (canseemon(mtmp) && !resists_blnd(&youmonst)
2907             && distu(mtmp->mx, mtmp->my) <= BOLT_LIM * BOLT_LIM) {
2908             if (cancelled) {
2909                 react = rn1(2, 2); /* "puzzled" || "dazzled" */
2910                 already = (mtmp->mcansee == 0);
2911                 /* Archons gaze every round; we don't want cancelled ones
2912                    giving the "seems puzzled/dazzled" message that often */
2913                 if (mtmp->mcan && mtmp->data == &mons[PM_ARCHON] && rn2(5))
2914                     react = -1;
2915             } else {
2916                 int blnd = d((int) mattk->damn, (int) mattk->damd);
2917
2918 /*JP
2919                 You("are blinded by %s radiance!", s_suffix(mon_nam(mtmp)));
2920 */
2921                 You("%s\82Ì\8cõ\82Å\96Ú\82ª\8c©\82¦\82È\82­\82È\82Á\82½\81I", mon_nam(mtmp));
2922                 make_blinded((long) blnd, FALSE);
2923                 stop_occupation();
2924                 /* not blind at this point implies you're wearing
2925                    the Eyes of the Overworld; make them block this
2926                    particular stun attack too */
2927                 if (!Blind) {
2928                     Your1(vision_clears);
2929                 } else {
2930                     long oldstun = (HStun & TIMEOUT), newstun = (long) rnd(3);
2931
2932                     /* we don't want to increment stun duration every time
2933                        or sighted hero will become incapacitated */
2934                     make_stunned(max(oldstun, newstun), TRUE);
2935                 }
2936             }
2937         }
2938         break;
2939     case AD_FIRE:
2940         if (canseemon(mtmp) && couldsee(mtmp->mx, mtmp->my) && mtmp->mcansee
2941             && !mtmp->mspec_used && rn2(5)) {
2942             if (cancelled) {
2943                 react = rn1(2, 4); /* "irritated" || "inflamed" */
2944             } else {
2945                 int dmg = d(2, 6), lev = (int) mtmp->m_lev;
2946
2947 /*JP
2948                 pline("%s attacks you with a fiery gaze!", Monnam(mtmp));
2949 */
2950                 pline("%s\82Í\89\8a\82Ì\82É\82ç\82Ý\8dU\8c\82\82ð\82µ\82Ä\82«\82½\81I", Monnam(mtmp));
2951                 stop_occupation();
2952                 if (Fire_resistance) {
2953 /*JP
2954                     pline_The("fire doesn't feel hot!");
2955 */
2956                     pline("\89Î\82Í\82º\82ñ\82º\82ñ\94M\82­\82È\82¢\81I");
2957                     dmg = 0;
2958                 }
2959                 burn_away_slime();
2960                 if (lev > rn2(20))
2961                     destroy_item(SCROLL_CLASS, AD_FIRE);
2962                 if (lev > rn2(20))
2963                     destroy_item(POTION_CLASS, AD_FIRE);
2964                 if (lev > rn2(25))
2965                     destroy_item(SPBOOK_CLASS, AD_FIRE);
2966                 if (dmg)
2967                     mdamageu(mtmp, dmg);
2968             }
2969         }
2970         break;
2971 #ifdef PM_BEHOLDER /* work in progress */
2972     case AD_SLEE:
2973         if (canseemon(mtmp) && couldsee(mtmp->mx, mtmp->my) && mtmp->mcansee
2974             && multi >= 0 && !rn2(5) && !Sleep_resistance) {
2975             if (cancelled) {
2976                 react = 6;                      /* "tired" */
2977                 already = (mtmp->mfrozen != 0); /* can't happen... */
2978             } else {
2979                 fall_asleep(-rnd(10), TRUE);
2980 #if 0 /*JP:T*/
2981                 pline("%s gaze makes you very sleepy...",
2982                       s_suffix(Monnam(mtmp)));
2983 #else
2984                 pline("%s\82Ì\82É\82ç\82Ý\82Å\82 \82È\82½\82Í\96°\82­\82È\82Á\82½\81D\81D\81D",
2985                       Monnam(mtmp));
2986 #endif
2987             }
2988         }
2989         break;
2990     case AD_SLOW:
2991         if (canseemon(mtmp) && couldsee(mtmp->mx, mtmp->my) && mtmp->mcansee
2992             && (HFast & (INTRINSIC | TIMEOUT)) && !defends(AD_SLOW, uwep)
2993             && !rn2(4)) {
2994             if (cancelled) {
2995                 react = 7; /* "dulled" */
2996                 already = (mtmp->mspeed == MSLOW);
2997             } else {
2998                 u_slow_down();
2999                 stop_occupation();
3000             }
3001         }
3002         break;
3003 #endif /* BEHOLDER */
3004     default:
3005         impossible("Gaze attack %d?", mattk->adtyp);
3006         break;
3007     }
3008     if (react >= 0) {
3009         if (Hallucination && rn2(3))
3010             react = rn2(SIZE(reactions));
3011         /* cancelled/hallucinatory feedback; monster might look "confused",
3012            "stunned",&c but we don't actually set corresponding attribute */
3013 #if 0 /*JP*/
3014         pline("%s looks %s%s.", Monnam(mtmp),
3015               !rn2(3) ? "" : already ? "quite "
3016                                      : (!rn2(2) ? "a bit " : "somewhat "),
3017               reactions[react]);
3018 #else
3019         pline("%s\82Í%s%s\82æ\82¤\82¾\81D", Monnam(mtmp),
3020               !rn2(3) ? "" : already ? "\82©\82È\82è"
3021                                      : (!rn2(2) ? "\8f­\82µ" : "\82¢\82­\82ç\82©"),
3022               reactions[react]);
3023 #endif
3024     }
3025     return 0;
3026 }
3027
3028 /* mtmp hits you for n points damage */
3029 void
3030 mdamageu(mtmp, n)
3031 struct monst *mtmp;
3032 int n;
3033 {
3034     context.botl = 1;
3035     if (Upolyd) {
3036         u.mh -= n;
3037         if (u.mh < 1)
3038             rehumanize();
3039     } else {
3040         u.uhp -= n;
3041         if (u.uhp < 1)
3042             done_in_by(mtmp, DIED);
3043     }
3044 }
3045
3046 /* returns 0 if seduction impossible,
3047  *         1 if fine,
3048  *         2 if wrong gender for nymph
3049  */
3050 int
3051 could_seduce(magr, mdef, mattk)
3052 struct monst *magr, *mdef;
3053 struct attack *mattk; /* non-Null: current attack; Null: general capability */
3054 {
3055     struct permonst *pagr;
3056     boolean agrinvis, defperc;
3057     xchar genagr, gendef;
3058     int adtyp;
3059
3060     if (is_animal(magr->data))
3061         return 0;
3062     if (magr == &youmonst) {
3063         pagr = youmonst.data;
3064         agrinvis = (Invis != 0);
3065         genagr = poly_gender();
3066     } else {
3067         pagr = magr->data;
3068         agrinvis = magr->minvis;
3069         genagr = gender(magr);
3070     }
3071     if (mdef == &youmonst) {
3072         defperc = (See_invisible != 0);
3073         gendef = poly_gender();
3074     } else {
3075         defperc = perceives(mdef->data);
3076         gendef = gender(mdef);
3077     }
3078
3079     adtyp = mattk ? mattk->adtyp
3080             : dmgtype(pagr, AD_SSEX) ? AD_SSEX
3081               : dmgtype(pagr, AD_SEDU) ? AD_SEDU
3082                 : AD_PHYS;
3083     if (adtyp == AD_SSEX && !SYSOPT_SEDUCE)
3084         adtyp = AD_SEDU;
3085
3086     if (agrinvis && !defperc && adtyp == AD_SEDU)
3087         return 0;
3088
3089     if ((pagr->mlet != S_NYMPH
3090          && pagr != &mons[PM_INCUBUS] && pagr != &mons[PM_SUCCUBUS])
3091         || (adtyp != AD_SEDU && adtyp != AD_SSEX))
3092         return 0;
3093
3094     return (genagr == 1 - gendef) ? 1 : (pagr->mlet == S_NYMPH) ? 2 : 0;
3095 }
3096
3097 /* returns 1 if monster teleported (or hero leaves monster's vicinity) */
3098 int
3099 doseduce(mon)
3100 struct monst *mon;
3101 {
3102     struct obj *ring, *nring;
3103     boolean fem = (mon->data == &mons[PM_SUCCUBUS]); /* otherwise incubus */
3104     boolean seewho, naked; /* True iff no armor */
3105     int attr_tot, tried_gloves = 0;
3106     char qbuf[QBUFSZ], Who[QBUFSZ];
3107
3108     if (mon->mcan || mon->mspec_used) {
3109 #if 0 /*JP*/
3110         pline("%s acts as though %s has got a %sheadache.", Monnam(mon),
3111               mhe(mon), mon->mcan ? "severe " : "");
3112 #else
3113         pline("%s\82Í%s\93ª\82ª\92É\82¢\82Ó\82è\82ð\82µ\82½\81D", Monnam(mon),
3114               mon->mcan ? "\82Ð\82Ç\82­" : "");
3115 #endif
3116         return 0;
3117     }
3118     if (unconscious()) {
3119 /*JP
3120         pline("%s seems dismayed at your lack of response.", Monnam(mon));
3121 */
3122         pline("%s\82Í\95Ô\8e\96\82ª\82È\82¢\82Ì\82Å\8bC\82ª\88Þ\82¦\82½\82æ\82¤\82¾\81D", Monnam(mon));
3123         return 0;
3124     }
3125     seewho = canseemon(mon);
3126     if (!seewho)
3127 /*JP
3128         pline("Someone caresses you...");
3129 */
3130         pline("\89½\8eÒ\82©\82ª\82 \82È\82½\82ð\95ø\82«\82µ\82ß\82Ä\82¢\82é\81D\81D\81D");
3131     else
3132 /*JP
3133         You_feel("very attracted to %s.", mon_nam(mon));
3134 */
3135         You("%s\82É\88ø\82«\82Â\82¯\82ç\82ê\82Ä\82é\82æ\82¤\82È\8bC\82ª\82µ\82½\81D", mon_nam(mon));
3136     /* cache the seducer's name in a local buffer */
3137 /*JP
3138     Strcpy(Who, (!seewho ? (fem ? "She" : "He") : Monnam(mon)));
3139 */
3140     Strcpy(Who, (!seewho ? (fem ? "\94Þ\8f\97" : "\94Þ") : Monnam(mon)));
3141
3142     /* if in the process of putting armor on or taking armor off,
3143        interrupt that activity now */
3144     (void) stop_donning((struct obj *) 0);
3145     /* don't try to take off gloves if cursed weapon blocks them */
3146     if (welded(uwep))
3147         tried_gloves = 1;
3148
3149     for (ring = invent; ring; ring = nring) {
3150         nring = ring->nobj;
3151         if (ring->otyp != RIN_ADORNMENT)
3152             continue;
3153         if (fem) {
3154             if (ring->owornmask && uarmg) {
3155                 /* don't take off worn ring if gloves are in the way */
3156                 if (!tried_gloves++)
3157 /*JP
3158                     mayberem(mon, Who, uarmg, "gloves");
3159 */
3160                     mayberem(mon, Who, uarmg, "\8f¬\8eè");
3161                 if (uarmg)
3162                     continue; /* next ring might not be worn */
3163             }
3164             /* confirmation prompt when charisma is high bypassed if deaf */
3165             if (!Deaf && rn2(20) < ACURR(A_CHA)) {
3166 #if 0 /*JP:T*/
3167                 (void) safe_qbuf(qbuf, "\"That ",
3168                                  " looks pretty.  May I have it?\"", ring,
3169                                  xname, simpleonames, "ring");
3170 #else
3171                 (void) safe_qbuf(qbuf, "\81u\82È\82ñ\82Ä\91f\93G\82È",
3172                                  "\82Å\82µ\82å\82¤\81D\82í\82½\82µ\82É\82­\82ê\82Ü\82¹\82ñ\81H\81v", ring,
3173                                  xname, simpleonames, "\8ew\97Ö");
3174 #endif
3175                 makeknown(RIN_ADORNMENT);
3176                 if (yn(qbuf) == 'n')
3177                     continue;
3178             } else
3179 #if 0 /*JP:T*/
3180                 pline("%s decides she'd like %s, and takes it.",
3181                       Who, yname(ring));
3182 #else
3183                 pline("%s\82Í%s\82ª\82Æ\82Ä\82à\8bC\82É\82¢\82Á\82Ä\81C\82»\82ê\82ð\8eæ\82è\82 \82°\82½\81D",
3184                       Who, xname(ring));
3185 #endif
3186             makeknown(RIN_ADORNMENT);
3187             /* might be in left or right ring slot or weapon/alt-wep/quiver */
3188             if (ring->owornmask)
3189                 remove_worn_item(ring, FALSE);
3190             freeinv(ring);
3191             (void) mpickobj(mon, ring);
3192         } else {
3193             if (uleft && uright && uleft->otyp == RIN_ADORNMENT
3194                 && uright->otyp == RIN_ADORNMENT)
3195                 break;
3196             if (ring == uleft || ring == uright)
3197                 continue;
3198             if (uarmg) {
3199                 /* don't put on ring if gloves are in the way */
3200                 if (!tried_gloves++)
3201 /*JP
3202                     mayberem(mon, Who, uarmg, "gloves");
3203 */
3204                     mayberem(mon, Who, uarmg, "\8f¬\8eè");
3205                 if (uarmg)
3206                     break; /* no point trying further rings */
3207             }
3208             /* confirmation prompt when charisma is high bypassed if deaf */
3209             if (!Deaf && rn2(20) < ACURR(A_CHA)) {
3210 #if 0 /*JP:T*/
3211                 (void) safe_qbuf(qbuf, "\"That ",
3212                                  " looks pretty.  Would you wear it for me?\"",
3213                                  ring, xname, simpleonames, "ring");
3214 #else
3215                 (void) safe_qbuf(qbuf, "\81u\82¨\82â\82È\82ñ\82Ä\82·\82Î\82ç\82µ\82¢",
3216                                 "\82¾\81D\8e\84\82Ì\82½\82ß\82É\8ew\82É\82Í\82ß\82Ä\82­\82ê\82È\82¢\82©\82¢\81H\81v",
3217                                  ring, xname, simpleonames, "\8ew\97Ö");
3218 #endif
3219                 makeknown(RIN_ADORNMENT);
3220                 if (yn(qbuf) == 'n')
3221                     continue;
3222             } else {
3223 #if 0 /*JP:T*/
3224                 pline("%s decides you'd look prettier wearing %s,",
3225                       Who, yname(ring));
3226 #else
3227                 pline("%s\82Í%s\82ð\82Â\82¯\82½\82 \82È\82½\82ª\82æ\82è\96£\97Í\93I\82¾\82Æ\8dl\82¦\81C",
3228                       Who, xname(ring));
3229 #endif
3230 /*JP
3231                 pline("and puts it on your finger.");
3232 */
3233                 pline("\82 \82È\82½\82Ì\8ew\82É\82»\82ê\82ð\82Í\82ß\82½\81D");
3234             }
3235             makeknown(RIN_ADORNMENT);
3236             if (!uright) {
3237 #if 0 /*JP:T*/
3238                 pline("%s puts %s on your right %s.",
3239                       Who, the(xname(ring)), body_part(HAND));
3240 #else
3241                 pline("%s\82Í%s\82ð\82 \82È\82½\82Ì\89E%s\82É\82Í\82ß\82½\81D",
3242                       Who, the(xname(ring)), body_part(HAND));
3243 #endif
3244                 setworn(ring, RIGHT_RING);
3245             } else if (!uleft) {
3246 #if 0 /*JP:T*/
3247                 pline("%s puts %s on your left %s.",
3248                       Who, the(xname(ring)), body_part(HAND));
3249 #else
3250                 pline("%s\82Í%s\82ð\82 \82È\82½\82Ì\8d¶%s\82É\82Í\82ß\82½\81D",
3251                       Who, the(xname(ring)), body_part(HAND));
3252 #endif
3253                 setworn(ring, LEFT_RING);
3254             } else if (uright && uright->otyp != RIN_ADORNMENT) {
3255                 /* note: the "replaces" message might be inaccurate if
3256                    hero's location changes and the process gets interrupted,
3257                    but trying to figure that out in advance in order to use
3258                    alternate wording is not worth the effort */
3259 #if 0 /*JP:T*/
3260                 pline("%s replaces %s with %s.",
3261                       Who, yname(uright), yname(ring));
3262 #else
3263                 pline("%s\82Í%s\82ð%s\82É\82Æ\82è\82©\82¦\82½\81D",
3264                       Who, yname(uright), xname(ring));
3265 #endif
3266                 Ring_gone(uright);
3267                 /* ring removal might cause loss of levitation which could
3268                    drop hero onto trap that transports hero somewhere else */
3269                 if (u.utotype || distu(mon->mx, mon->my) > 2)
3270                     return 1;
3271                 setworn(ring, RIGHT_RING);
3272             } else if (uleft && uleft->otyp != RIN_ADORNMENT) {
3273                 /* see "replaces" note above */
3274 #if 0 /*JP:T*/
3275                 pline("%s replaces %s with %s.",
3276                       Who, yname(uleft), yname(ring));
3277 #else
3278                 pline("%s\82Í%s\82ð%s\82É\82Æ\82è\82©\82¦\82½\81D",
3279                       Who, yname(uleft), xname(ring));
3280 #endif
3281                 Ring_gone(uleft);
3282                 if (u.utotype || distu(mon->mx, mon->my) > 2)
3283                     return 1;
3284                 setworn(ring, LEFT_RING);
3285             } else
3286                 impossible("ring replacement");
3287             Ring_on(ring);
3288             prinv((char *) 0, ring, 0L);
3289         }
3290     }
3291
3292     naked = (!uarmc && !uarmf && !uarmg && !uarms && !uarmh && !uarmu);
3293 #if 0 /*JP:T*/
3294     pline("%s %s%s.", Who,
3295           Deaf ? "seems to murmur into your ear"
3296                : naked ? "murmurs sweet nothings into your ear"
3297                        : "murmurs in your ear",
3298           naked ? "" : ", while helping you undress");
3299 #else
3300     pline("%s\82Í%s%s\81D", Who,
3301           naked ? "" : "\82 \82È\82½\82Ì\95\9e\82ð\92E\82ª\82¹\82È\82ª\82ç",
3302           Deaf ? "\8e¨\82à\82Æ\82Å\89½\82©\82Â\82Ô\82â\82¢\82½\82æ\82¤\82¾"
3303                : naked ? "\8e¨\82à\82Æ\82Å\8aÃ\82¢\82³\82³\82â\82«\82ð\82Â\82Ô\82â\82¢\82½"
3304                        : "\82 \82È\82½\82Ì\8e¨\82à\82Æ\82Å\82Â\82Ô\82â\82¢\82½");
3305 #endif
3306     mayberem(mon, Who, uarmc, cloak_simple_name(uarmc));
3307     if (!uarmc)
3308         mayberem(mon, Who, uarm, suit_simple_name(uarm));
3309 /*JP
3310     mayberem(mon, Who, uarmf, "boots");
3311 */
3312     mayberem(mon, Who, uarmf, "\83u\81[\83c");
3313     if (!tried_gloves)
3314 /*JP
3315         mayberem(mon, Who, uarmg, "gloves");
3316 */
3317         mayberem(mon, Who, uarmg, "\8f¬\8eè");
3318 /*JP
3319     mayberem(mon, Who, uarms, "shield");
3320 */
3321     mayberem(mon, Who, uarms, "\8f\82");
3322     mayberem(mon, Who, uarmh, helm_simple_name(uarmh));
3323     if (!uarmc && !uarm)
3324 /*JP
3325         mayberem(mon, Who, uarmu, "shirt");
3326 */
3327         mayberem(mon, Who, uarmu, "\83V\83\83\83c");
3328
3329     /* removing armor (levitation boots, or levitation ring to make
3330        room for adornment ring with incubus case) might result in the
3331        hero falling through a trap door or landing on a teleport trap
3332        and changing location, so hero might not be adjacent to seducer
3333        any more (mayberem() has its own adjacency test so we don't need
3334        to check after each potential removal) */
3335     if (u.utotype || distu(mon->mx, mon->my) > 2)
3336         return 1;
3337
3338     if (uarm || uarmc) {
3339         if (!Deaf)
3340 #if 0 /*JP:T*/
3341             verbalize("You're such a %s; I wish...",
3342                       flags.female ? "sweet lady" : "nice guy");
3343 #else
3344             verbalize("%s\82¾\81D\81D\81D\82Æ\82¢\82¢\82Ì\82É\81D",
3345                       flags.female ? "\83`\83\83\81[\83~\83\93\83O" : "\82·\82Ä\82«");
3346 #endif
3347         else if (seewho)
3348             pline("%s appears to sigh.", Monnam(mon));
3349         /* else no regret message if can't see or hear seducer */
3350
3351         if (!tele_restrict(mon))
3352             (void) rloc(mon, TRUE);
3353         return 1;
3354     }
3355     if (u.ualign.type == A_CHAOTIC)
3356         adjalign(1);
3357
3358     /* by this point you have discovered mon's identity, blind or not... */
3359 /*JP
3360     pline("Time stands still while you and %s lie in each other's arms...",
3361 */
3362     pline("\82 \82È\82½\82Æ%s\82ª\95ø\82«\8d\87\82¤\82Æ\81C\8e\9e\82ª\8e~\82Ü\82Á\82½\82æ\82¤\82É\8a´\82\82½\81D\81D\81D",
3363           noit_mon_nam(mon));
3364     /* 3.6.1: a combined total for charisma plus intelligence of 35-1
3365        used to guarantee successful outcome; now total maxes out at 32
3366        as far as deciding what will happen; chance for bad outcome when
3367        Cha+Int is 32 or more is 2/35, a bit over 5.7% */
3368     attr_tot = ACURR(A_CHA) + ACURR(A_INT);
3369     if (rn2(35) > min(attr_tot, 32)) {
3370         /* Don't bother with mspec_used here... it didn't get tired! */
3371 /*JP
3372         pline("%s seems to have enjoyed it more than you...",
3373 */
3374         pline("%s\82Í\82 \82È\82½\82æ\82è\8ay\82µ\82ñ\82¾\82æ\82¤\82¾\81D\81D\81D",
3375               noit_Monnam(mon));
3376         switch (rn2(5)) {
3377         case 0:
3378 /*JP
3379             You_feel("drained of energy.");
3380 */
3381             You("\91Ì\97Í\82ª\8fÁ\96Õ\82µ\82½\82æ\82¤\82È\8bC\82ª\82µ\82½\81D");
3382             u.uen = 0;
3383             u.uenmax -= rnd(Half_physical_damage ? 5 : 10);
3384             exercise(A_CON, FALSE);
3385             if (u.uenmax < 0)
3386                 u.uenmax = 0;
3387             break;
3388         case 1:
3389 /*JP
3390             You("are down in the dumps.");
3391 */
3392             You("\88Ó\8bC\8fÁ\92¾\82µ\82½\81D");
3393             (void) adjattrib(A_CON, -1, TRUE);
3394             exercise(A_CON, FALSE);
3395             context.botl = 1;
3396             break;
3397         case 2:
3398 /*JP
3399             Your("senses are dulled.");
3400 */
3401             Your("\8cÜ\8a´\82Í\93Ý\82Á\82½\81D");
3402             (void) adjattrib(A_WIS, -1, TRUE);
3403             exercise(A_WIS, FALSE);
3404             context.botl = 1;
3405             break;
3406         case 3:
3407             if (!resists_drli(&youmonst)) {
3408 /*JP
3409                 You_feel("out of shape.");
3410 */
3411                 You("\82­\82½\82Ñ\82ê\82½\81D");
3412 /*JP
3413                 losexp("overexertion");
3414 */
3415                 losexp("\89ß\98J\82Å");
3416             } else {
3417 /*JP
3418                 You("have a curious feeling...");
3419 */
3420                 You("\95Ï\82È\8a´\82\82ª\82µ\82½\81D\81D\81D");
3421             }
3422             exercise(A_CON, FALSE);
3423             exercise(A_DEX, FALSE);
3424             exercise(A_WIS, FALSE);
3425             break;
3426         case 4: {
3427             int tmp;
3428
3429 /*JP
3430             You_feel("exhausted.");
3431 */
3432             You("\94æ\82ê\82ð\8a´\82\82½\81D");
3433             exercise(A_STR, FALSE);
3434             tmp = rn1(10, 6);
3435 /*JP
3436             losehp(Maybe_Half_Phys(tmp), "exhaustion", KILLED_BY);
3437 */
3438             losehp(Maybe_Half_Phys(tmp), "\90¸\97Í\82Ì\8eg\82¢\82·\82¬\82Å", KILLED_BY);
3439             break;
3440         } /* case 4 */
3441         } /* switch */
3442     } else {
3443         mon->mspec_used = rnd(100); /* monster is worn out */
3444 /*JP
3445         You("seem to have enjoyed it more than %s...", noit_mon_nam(mon));
3446 */
3447         You("%s\82æ\82è\82à\8ay\82µ\82ñ\82¾\82æ\82¤\82¾\81D\81D\81D", noit_mon_nam(mon));
3448         switch (rn2(5)) {
3449         case 0:
3450 /*JP
3451             You_feel("raised to your full potential.");
3452 */
3453             You("\90ö\8dÝ\94\\97Í\82ª\8d\82\82Ü\82Á\82½\82æ\82¤\82É\8a´\82\82½\81D");
3454             exercise(A_CON, TRUE);
3455             u.uen = (u.uenmax += rnd(5));
3456             break;
3457         case 1:
3458 /*JP
3459             You_feel("good enough to do it again.");
3460 */
3461             You("\82à\82¤\88ê\93x\82Å\82«\82é\82Æ\8ev\82Á\82½\81D");
3462             (void) adjattrib(A_CON, 1, TRUE);
3463             exercise(A_CON, TRUE);
3464             context.botl = 1;
3465             break;
3466         case 2:
3467 /*JP
3468             You("will always remember %s...", noit_mon_nam(mon));
3469 */
3470             You("\82¢\82Â\82Ü\82Å\82à%s\82ð\8ao\82¦\82Ä\82é\82¾\82ë\82¤\81D\81D\81D", mon_nam(mon));
3471             (void) adjattrib(A_WIS, 1, TRUE);
3472             exercise(A_WIS, TRUE);
3473             context.botl = 1;
3474             break;
3475         case 3:
3476 /*JP
3477             pline("That was a very educational experience.");
3478 */
3479             pline("\82Æ\82Ä\82à\8bM\8fd\82È\8co\8c±\82¾\82Á\82½\81D");
3480             pluslvl(FALSE);
3481             exercise(A_WIS, TRUE);
3482             break;
3483         case 4:
3484 /*JP
3485             You_feel("restored to health!");
3486 */
3487             You("\82Æ\82Ä\82à\8c\92\8dN\82É\82È\82Á\82½\81I");
3488             u.uhp = u.uhpmax;
3489             if (Upolyd)
3490                 u.mh = u.mhmax;
3491             exercise(A_STR, TRUE);
3492             context.botl = 1;
3493             break;
3494         }
3495     }
3496
3497     if (mon->mtame) { /* don't charge */
3498         ;
3499     } else if (rn2(20) < ACURR(A_CHA)) {
3500 #if 0 /*JP:T*/
3501         pline("%s demands that you pay %s, but you refuse...",
3502               noit_Monnam(mon), noit_mhim(mon));
3503 #else
3504         pline("%s\82Í\82 \82È\82½\82É\8bà\82ð\95¥\82¤\82æ\82¤\97v\8b\81\82µ\82½\82ª\81C\82 \82È\82½\82Í\8b\91\82ñ\82¾\81D\81D\81D",
3505               noit_Monnam(mon));
3506 #endif
3507     } else if (u.umonnum == PM_LEPRECHAUN) {
3508 /*JP
3509         pline("%s tries to take your money, but fails...", noit_Monnam(mon));
3510 */
3511         pline("%s\82Í\8bà\82ð\8eæ\82ë\82¤\82Æ\82µ\82½\82ª\81C\8e¸\94s\82µ\82½\81D\81D\81D", noit_Monnam(mon));
3512     } else {
3513         long cost;
3514         long umoney = money_cnt(invent);
3515
3516         if (umoney > (long) LARGEST_INT - 10L)
3517             cost = (long) rnd(LARGEST_INT) + 500L;
3518         else
3519             cost = (long) rnd((int) umoney + 10) + 500L;
3520         if (mon->mpeaceful) {
3521             cost /= 5L;
3522             if (!cost)
3523                 cost = 1L;
3524         }
3525         if (cost > umoney)
3526             cost = umoney;
3527         if (!cost) {
3528 /*JP
3529             verbalize("It's on the house!");
3530 */
3531             verbalize("\82±\82ê\82Í\82¨\82²\82è%s\81I", fem ? "\82æ" : "\82³");
3532         } else {
3533 #if 0 /*JP*/
3534             pline("%s takes %ld %s for services rendered!", noit_Monnam(mon),
3535                   cost, currency(cost));
3536 #else
3537             pline("%s\82Í\83T\81[\83r\83X\97¿\82Æ\82µ\82Ä%ld%s\92D\82¢\8eæ\82Á\82½\81I", noit_Monnam(mon),
3538                   cost, currency(cost));
3539 #endif
3540             money2mon(mon, cost);
3541             context.botl = 1;
3542         }
3543     }
3544     if (!rn2(25))
3545         mon->mcan = 1; /* monster is worn out */
3546     if (!tele_restrict(mon))
3547         (void) rloc(mon, TRUE);
3548     return 1;
3549 }
3550
3551 STATIC_OVL void
3552 mayberem(mon, seducer, obj, str)
3553 struct monst *mon;
3554 const char *seducer; /* only used for alternate message */
3555 struct obj *obj;
3556 const char *str;
3557 {
3558     char qbuf[QBUFSZ];
3559
3560     if (!obj || !obj->owornmask)
3561         return;
3562     /* removal of a previous item might have sent the hero elsewhere
3563        (loss of levitation that leads to landing on a transport trap) */
3564     if (u.utotype || distu(mon->mx, mon->my) > 2)
3565         return;
3566
3567     /* being deaf overrides confirmation prompt for high charisma */
3568     if (Deaf) {
3569         pline("%s takes off your %s.", seducer, str);
3570     } else if (rn2(20) < ACURR(A_CHA)) {
3571 #if 0 /*JP:T*/
3572         Sprintf(qbuf, "\"Shall I remove your %s, %s?\"", str,
3573                 (!rn2(2) ? "lover" : !rn2(2) ? "dear" : "sweetheart"));
3574 #else
3575         Sprintf(qbuf,"\81u%s\82ð\8eæ\82Á\82Ä\82¢\82¢\81C%s\81H\81v", str,
3576                 (!rn2(2) ? "\82Ë\82¥" : flags.female ? "\83n\83j\81[" : "\83_\81[\83\8a\83\93" ));
3577 #endif
3578         if (yn(qbuf) == 'n')
3579             return;
3580     } else {
3581         char hairbuf[BUFSZ];
3582
3583 #if 0 /*JP:T*/
3584         Sprintf(hairbuf, "let me run my fingers through your %s",
3585                 body_part(HAIR));
3586 #else
3587         Sprintf(hairbuf,
3588                 flags.female ? "\82È\82ñ\82ÄãY\97í\82È%s\82È\82ñ\82¾" : "\8a\95\82ð\8eæ\82Á\82½\82ç\82È\82©\82È\82©\83C\83J\83X\82\82á\82È\82¢",
3589                 body_part(HAIR));
3590 #endif
3591 #if 0 /*JP*/
3592         verbalize("Take off your %s; %s.", str,
3593                   (obj == uarm)
3594                      ? "let's get a little closer"
3595                      : (obj == uarmc || obj == uarms)
3596                         ? "it's in the way"
3597                         : (obj == uarmf)
3598                            ? "let me rub your feet"
3599                            : (obj == uarmg)
3600                               ? "they're too clumsy"
3601                               : (obj == uarmu)
3602                                  ? "let me massage you"
3603                                  /* obj == uarmh */
3604                                  : hairbuf);
3605 #else
3606         verbalize("%s\82ð\92E\82¢\82Å\81D\81D\81D%s\81D", str,
3607                   (obj == uarm)
3608                   ? "\82à\82¤\82¿\82å\82Á\82Æ\8añ\82è\82»\82Á\82Ä"
3609                   : (obj == uarmc || obj == uarms)
3610                   ? "\82»\82¤\82»\82¤"
3611                   : (obj == uarmf)
3612                   ? (flags.female ? "ãY\97í\82È\91«\82¾\82Ë" : "\82¤\82Ó\82Á\81C\82½\82­\82Ü\82µ\82¢\91«\82Ë")
3613                   : (obj == uarmg)
3614                   ? (flags.female ? "\82È\82ñ\82Ä\91f\93G\82È\8eè\82¾" : "\82½\82­\82Ü\82µ\82¢\98r\82Ë")
3615                   : (obj == uarmu)
3616                   ? (flags.female ? "\82«\82ê\82¢\82È\91Ì\82¾" : "\82½\82­\82Ü\82µ\82¢\82Ì\82Ë")
3617                   /* obj == uarmh */
3618                   : hairbuf);
3619 #endif
3620     }
3621     remove_worn_item(obj, TRUE);
3622 }
3623
3624 /* FIXME:
3625  *  sequencing issue:  a monster's attack might cause poly'd hero
3626  *  to revert to normal form.  The messages for passive counterattack
3627  *  would look better if they came before reverting form, but we need
3628  *  to know whether hero reverted in order to decide whether passive
3629  *  damage applies.
3630  */
3631 STATIC_OVL int
3632 passiveum(olduasmon, mtmp, mattk)
3633 struct permonst *olduasmon;
3634 struct monst *mtmp;
3635 struct attack *mattk;
3636 {
3637     int i, tmp;
3638     struct attack *oldu_mattk = 0;
3639
3640     /*
3641      * mattk      == mtmp's attack that hit you;
3642      * oldu_mattk == your passive counterattack (even if mtmp's attack
3643      *               has already caused you to revert to normal form).
3644      */
3645     for (i = 0; !oldu_mattk; i++) {
3646         if (i >= NATTK)
3647             return 1;
3648         if (olduasmon->mattk[i].aatyp == AT_NONE
3649             || olduasmon->mattk[i].aatyp == AT_BOOM)
3650             oldu_mattk = &olduasmon->mattk[i];
3651     }
3652     if (oldu_mattk->damn)
3653         tmp = d((int) oldu_mattk->damn, (int) oldu_mattk->damd);
3654     else if (oldu_mattk->damd)
3655         tmp = d((int) olduasmon->mlevel + 1, (int) oldu_mattk->damd);
3656     else
3657         tmp = 0;
3658
3659     /* These affect the enemy even if you were "killed" (rehumanized) */
3660     switch (oldu_mattk->adtyp) {
3661     case AD_ACID:
3662         if (!rn2(2)) {
3663 #if 0 /*JP*/
3664             pline("%s is splashed by %s%s!", Monnam(mtmp),
3665                   /* temporary? hack for sequencing issue:  "your acid"
3666                      looks strange coming immediately after player has
3667                      been told that hero has reverted to normal form */
3668                   !Upolyd ? "" : "your ", hliquid("acid"));
3669 #else
3670             pline("%s\82Í%s%s\82ð\90H\82ç\82Á\82½\81I", Monnam(mtmp),
3671                   /* temporary? hack for sequencing issue:  "your acid"
3672                      looks strange coming immediately after player has
3673                      been told that hero has reverted to normal form */
3674                   !Upolyd ? "" : "\82 \82È\82½\82Ì", hliquid("\8e_"));
3675 #endif
3676             if (resists_acid(mtmp)) {
3677 /*JP
3678                 pline("%s is not affected.", Monnam(mtmp));
3679 */
3680                 pline("%s\82Í\89e\8b¿\82ð\8eó\82¯\82È\82¢\81D", Monnam(mtmp));
3681                 tmp = 0;
3682             }
3683         } else
3684             tmp = 0;
3685         if (!rn2(30))
3686             erode_armor(mtmp, ERODE_CORRODE);
3687         if (!rn2(6))
3688             acid_damage(MON_WEP(mtmp));
3689         goto assess_dmg;
3690     case AD_STON: /* cockatrice */
3691     {
3692         long protector = attk_protection((int) mattk->aatyp),
3693              wornitems = mtmp->misc_worn_check;
3694
3695         /* wielded weapon gives same protection as gloves here */
3696         if (MON_WEP(mtmp) != 0)
3697             wornitems |= W_ARMG;
3698
3699         if (!resists_ston(mtmp)
3700             && (protector == 0L
3701                 || (protector != ~0L
3702                     && (wornitems & protector) != protector))) {
3703             if (poly_when_stoned(mtmp->data)) {
3704                 mon_to_stone(mtmp);
3705                 return 1;
3706             }
3707 /*JP
3708             pline("%s turns to stone!", Monnam(mtmp));
3709 */
3710             pline("%s\82Í\90Î\82É\82È\82Á\82½\81I", Monnam(mtmp));
3711             stoned = 1;
3712             xkilled(mtmp, XKILL_NOMSG);
3713             if (!DEADMONSTER(mtmp))
3714                 return 1;
3715             return 2;
3716         }
3717         return 1;
3718     }
3719     case AD_ENCH: /* KMH -- remove enchantment (disenchanter) */
3720         if (mon_currwep) {
3721             /* by_you==True: passive counterattack to hero's action
3722                is hero's fault */
3723             (void) drain_item(mon_currwep, TRUE);
3724             /* No message */
3725         }
3726         return 1;
3727     default:
3728         break;
3729     }
3730     if (!Upolyd)
3731         return 1;
3732
3733     /* These affect the enemy only if you are still a monster */
3734     if (rn2(3))
3735         switch (oldu_mattk->adtyp) {
3736         case AD_PHYS:
3737             if (oldu_mattk->aatyp == AT_BOOM) {
3738 /*JP
3739                 You("explode!");
3740 */
3741                 pline("\82 \82È\82½\82Í\94\9a\94­\82µ\82½\81I");
3742                 /* KMH, balance patch -- this is okay with unchanging */
3743                 rehumanize();
3744                 goto assess_dmg;
3745             }
3746             break;
3747         case AD_PLYS: /* Floating eye */
3748             if (tmp > 127)
3749                 tmp = 127;
3750             if (u.umonnum == PM_FLOATING_EYE) {
3751                 if (!rn2(4))
3752                     tmp = 127;
3753                 if (mtmp->mcansee && haseyes(mtmp->data) && rn2(3)
3754                     && (perceives(mtmp->data) || !Invis)) {
3755                     if (Blind)
3756 /*JP
3757                         pline("As a blind %s, you cannot defend yourself.",
3758 */
3759                         pline("%s\82Í\96Ú\82ª\8c©\82¦\82È\82¢\82Ì\82Å\81C\82 \82È\82½\82Í\82É\82ç\82Ý\82Å\96h\8cä\82Å\82«\82È\82¢\81D",
3760                               youmonst.data->mname);
3761                     else {
3762                         if (mon_reflects(mtmp,
3763 /*JP
3764                                          "Your gaze is reflected by %s %s."))
3765 */
3766                                          "\82 \82È\82½\82Ì\82É\82ç\82Ý\82Í%s\82Ì%s\82Å\94½\8eË\82µ\82½\81D"))
3767                             return 1;
3768 /*JP
3769                         pline("%s is frozen by your gaze!", Monnam(mtmp));
3770 */
3771                         pline("%s\82Í\82 \82È\82½\82Ì\82É\82ç\82Ý\82Å\93®\82¯\82È\82­\82È\82Á\82½\81I", Monnam(mtmp));
3772                         paralyze_monst(mtmp, tmp);
3773                         return 3;
3774                     }
3775                 }
3776             } else { /* gelatinous cube */
3777 /*JP
3778                 pline("%s is frozen by you.", Monnam(mtmp));
3779 */
3780                 pline("%s\82Í\93®\82¯\82È\82¢\81D", Monnam(mtmp));
3781                 paralyze_monst(mtmp, tmp);
3782                 return 3;
3783             }
3784             return 1;
3785         case AD_COLD: /* Brown mold or blue jelly */
3786             if (resists_cold(mtmp)) {
3787                 shieldeff(mtmp->mx, mtmp->my);
3788 /*JP
3789                 pline("%s is mildly chilly.", Monnam(mtmp));
3790 */
3791                 pline("%s\82Í\97â\82¦\82½\81D", Monnam(mtmp));
3792                 golemeffects(mtmp, AD_COLD, tmp);
3793                 tmp = 0;
3794                 break;
3795             }
3796 /*JP
3797             pline("%s is suddenly very cold!", Monnam(mtmp));
3798 */
3799             pline("%s\82Í\93Ë\91R\93\80\82è\82Ã\82¯\82É\82È\82Á\82½\81I", Monnam(mtmp));
3800             u.mh += tmp / 2;
3801             if (u.mhmax < u.mh)
3802                 u.mhmax = u.mh;
3803             if (u.mhmax > ((youmonst.data->mlevel + 1) * 8))
3804                 (void) split_mon(&youmonst, mtmp);
3805             break;
3806         case AD_STUN: /* Yellow mold */
3807             if (!mtmp->mstun) {
3808                 mtmp->mstun = 1;
3809 #if 0 /*JP*/
3810                 pline("%s %s.", Monnam(mtmp),
3811                       makeplural(stagger(mtmp->data, "stagger")));
3812 #else
3813                 pline("%s\82Í%s\81D", Monnam(mtmp),
3814                       jpast(stagger(mtmp->data, "\82æ\82ë\82ß\82­")));
3815 #endif
3816             }
3817             tmp = 0;
3818             break;
3819         case AD_FIRE: /* Red mold */
3820             if (resists_fire(mtmp)) {
3821                 shieldeff(mtmp->mx, mtmp->my);
3822 #if 0 /*JP*/
3823                 pline("%s is mildly warm.", Monnam(mtmp));
3824 #else
3825                 pline("%s\82Í\92g\82©\82­\82È\82Á\82½\81D", Monnam(mtmp));
3826 #endif
3827                 golemeffects(mtmp, AD_FIRE, tmp);
3828                 tmp = 0;
3829                 break;
3830             }
3831 #if 0 /*JP*/
3832             pline("%s is suddenly very hot!", Monnam(mtmp));
3833 #else
3834             pline("%s\82Í\93Ë\91R\94M\82­\82È\82Á\82½\81I", Monnam(mtmp));
3835 #endif
3836             break;
3837         case AD_ELEC:
3838             if (resists_elec(mtmp)) {
3839                 shieldeff(mtmp->mx, mtmp->my);
3840 #if 0 /*JP*/
3841                 pline("%s is slightly tingled.", Monnam(mtmp));
3842 #else
3843                 pline("%s\82Í\82¿\82å\82Á\82Æ\83s\83\8a\83s\83\8a\82µ\82½\81D", Monnam(mtmp));
3844 #endif
3845                 golemeffects(mtmp, AD_ELEC, tmp);
3846                 tmp = 0;
3847                 break;
3848             }
3849 #if 0 /*JP*/
3850             pline("%s is jolted with your electricity!", Monnam(mtmp));
3851 #else
3852             pline("%s\82Í\93d\8bC\83V\83\87\83b\83N\82ð\82¤\82¯\82½\81I", Monnam(mtmp));
3853 #endif
3854             break;
3855         default:
3856             tmp = 0;
3857             break;
3858         }
3859     else
3860         tmp = 0;
3861
3862  assess_dmg:
3863     if ((mtmp->mhp -= tmp) <= 0) {
3864 /*JP
3865         pline("%s dies!", Monnam(mtmp));
3866 */
3867         pline("%s\82Í\8e\80\82ñ\82¾\81I", Monnam(mtmp));
3868         xkilled(mtmp, XKILL_NOMSG);
3869         if (!DEADMONSTER(mtmp))
3870             return 1;
3871         return 2;
3872     }
3873     return 1;
3874 }
3875
3876 struct monst *
3877 cloneu()
3878 {
3879     struct monst *mon;
3880     int mndx = monsndx(youmonst.data);
3881
3882     if (u.mh <= 1)
3883         return (struct monst *) 0;
3884     if (mvitals[mndx].mvflags & G_EXTINCT)
3885         return (struct monst *) 0;
3886     mon = makemon(youmonst.data, u.ux, u.uy, NO_MINVENT | MM_EDOG);
3887     if (!mon)
3888         return NULL;
3889     mon->mcloned = 1;
3890     mon = christen_monst(mon, plname);
3891     initedog(mon);
3892     mon->m_lev = youmonst.data->mlevel;
3893     mon->mhpmax = u.mhmax;
3894     mon->mhp = u.mh / 2;
3895     u.mh -= mon->mhp;
3896     context.botl = 1;
3897     return mon;
3898 }
3899
3900 /*mhitu.c*/