OSDN Git Service

update year to 2020
[jnethack/source.git] / src / mhitm.c
1 /* NetHack 3.6  mhitm.c $NHDT-Date: 1583606861 2020/03/07 18:47:41 $  $NHDT-Branch: NetHack-3.6-Mar2020 $:$NHDT-Revision: 1.119 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /*-Copyright (c) Robert Patrick Rankin, 2011. */
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-2020            */
9 /* JNetHack may be freely redistributed.  See license for details. */
10
11 #include "hack.h"
12 #include "artifact.h"
13
14 extern boolean notonhead;
15
16 static NEARDATA boolean vis, far_noise;
17 static NEARDATA long noisetime;
18 static NEARDATA struct obj *otmp;
19
20 static const char brief_feeling[] =
21 /*JP
22     "have a %s feeling for a moment, then it passes.";
23 */
24     "%s\8bC\8e\9d\82É\82¨\82»\82í\82ê\82½\82ª\81C\82·\82®\82É\89ß\82¬\82³\82Á\82½\81D";
25
26 STATIC_DCL int FDECL(hitmm, (struct monst *, struct monst *,
27                              struct attack *));
28 STATIC_DCL int FDECL(gazemm, (struct monst *, struct monst *,
29                               struct attack *));
30 STATIC_DCL int FDECL(gulpmm, (struct monst *, struct monst *,
31                               struct attack *));
32 STATIC_DCL int FDECL(explmm, (struct monst *, struct monst *,
33                               struct attack *));
34 STATIC_DCL int FDECL(mdamagem, (struct monst *, struct monst *,
35                                 struct attack *));
36 STATIC_DCL void FDECL(mswingsm, (struct monst *, struct monst *,
37                                  struct obj *));
38 STATIC_DCL void FDECL(noises, (struct monst *, struct attack *));
39 STATIC_DCL void FDECL(missmm, (struct monst *, struct monst *,
40                                struct attack *));
41 STATIC_DCL int FDECL(passivemm, (struct monst *, struct monst *,
42                                  BOOLEAN_P, int));
43
44 /* Needed for the special case of monsters wielding vorpal blades (rare).
45  * If we use this a lot it should probably be a parameter to mdamagem()
46  * instead of a global variable.
47  */
48 static int dieroll;
49
50 STATIC_OVL void
51 noises(magr, mattk)
52 register struct monst *magr;
53 register struct attack *mattk;
54 {
55     boolean farq = (distu(magr->mx, magr->my) > 15);
56
57     if (!Deaf && (farq != far_noise || moves - noisetime > 10)) {
58         far_noise = farq;
59         noisetime = moves;
60 #if 0 /*JP:T*/
61         You_hear("%s%s.",
62                  (mattk->aatyp == AT_EXPL) ? "an explosion" : "some noises",
63                  farq ? " in the distance" : "");
64 #else
65         You_hear("%s%s\82ð\95·\82¢\82½\81D",
66                  farq ? "\89\93\82­\82Å" : "",
67                  (mattk->aatyp == AT_EXPL) ? "\94\9a\94­\89¹" : "\89½\82©\82ª\90í\82¤\89¹"
68                  );
69 #endif
70     }
71 }
72
73 STATIC_OVL
74 void
75 missmm(magr, mdef, mattk)
76 register struct monst *magr, *mdef;
77 struct attack *mattk;
78 {
79     const char *fmt;
80     char buf[BUFSZ];
81     boolean showit = FALSE;
82
83     /* unhiding or unmimicking happens even if hero can't see it
84        because the formerly concealed monster is now in action */
85     if (M_AP_TYPE(mdef)) {
86         seemimic(mdef);
87         showit |= vis;
88     } else if (mdef->mundetected) {
89         mdef->mundetected = 0;
90         showit |= vis;
91     }
92     if (M_AP_TYPE(magr)) {
93         seemimic(magr);
94         showit |= vis;
95     } else if (magr->mundetected) {
96         magr->mundetected = 0;
97         showit |= vis;
98     }
99
100     if (vis) {
101         if (!canspotmon(magr))
102             map_invisible(magr->mx, magr->my);
103         else if (showit)
104             newsym(magr->mx, magr->my);
105         if (!canspotmon(mdef))
106             map_invisible(mdef->mx, mdef->my);
107         else if (showit)
108             newsym(mdef->mx, mdef->my);
109
110 #if 0 /*JP*/
111         fmt = (could_seduce(magr, mdef, mattk) && !magr->mcan)
112                   ? "%s pretends to be friendly to"
113                   : "%s misses";
114 #else /*JP:\89p\8cê\82Æ\95Ï\90\94\93W\8aJ\82Ì\83^\83C\83~\83\93\83O\82ª\88Ù\82È\82é\82Ì\82Å\92\8d\88Ó*/
115         fmt = (could_seduce(magr,mdef,mattk) && !magr->mcan)
116                   ? "%s\82Í%%s\82É\97F\8dD\93I\82È\82Ó\82è\82ð\82µ\82½\81D"
117                   : "%s\82Ì%%s\82Ö\82Ì\8dU\8c\82\82Í\8aO\82ê\82½\81D";
118 #endif
119         Sprintf(buf, fmt, Monnam(magr));
120 #if 0 /*JP*/
121         pline("%s %s.", buf, mon_nam_too(mdef, magr));
122 #else
123         pline(buf, mon_nam_too(mdef, magr));
124 #endif
125     } else
126         noises(magr, mattk);
127 }
128
129 /*
130  *  fightm()  -- fight some other monster
131  *
132  *  Returns:
133  *      0 - Monster did nothing.
134  *      1 - If the monster made an attack.  The monster might have died.
135  *
136  *  There is an exception to the above.  If mtmp has the hero swallowed,
137  *  then we report that the monster did nothing so it will continue to
138  *  digest the hero.
139  */
140  /* have monsters fight each other */
141 int
142 fightm(mtmp)
143 register struct monst *mtmp;
144 {
145     register struct monst *mon, *nmon;
146     int result, has_u_swallowed;
147 #ifdef LINT
148     nmon = 0;
149 #endif
150     /* perhaps the monster will resist Conflict */
151     if (resist(mtmp, RING_CLASS, 0, 0))
152         return 0;
153
154     if (u.ustuck == mtmp) {
155         /* perhaps we're holding it... */
156         if (itsstuck(mtmp))
157             return 0;
158     }
159     has_u_swallowed = (u.uswallow && (mtmp == u.ustuck));
160
161     for (mon = fmon; mon; mon = nmon) {
162         nmon = mon->nmon;
163         if (nmon == mtmp)
164             nmon = mtmp->nmon;
165         /* Be careful to ignore monsters that are already dead, since we
166          * might be calling this before we've cleaned them up.  This can
167          * happen if the monster attacked a cockatrice bare-handedly, for
168          * instance.
169          */
170         if (mon != mtmp && !DEADMONSTER(mon)) {
171             if (monnear(mtmp, mon->mx, mon->my)) {
172                 if (!u.uswallow && (mtmp == u.ustuck)) {
173                     if (!rn2(4)) {
174 /*JP
175                         pline("%s releases you!", Monnam(mtmp));
176 */
177                         pline("%s\82Í\82 \82È\82½\82ð\89ð\95ú\82µ\82½\81I", Monnam(mtmp));
178                         u.ustuck = 0;
179                     } else
180                         break;
181                 }
182
183                 /* mtmp can be killed */
184                 bhitpos.x = mon->mx;
185                 bhitpos.y = mon->my;
186                 notonhead = 0;
187                 result = mattackm(mtmp, mon);
188
189                 if (result & MM_AGR_DIED)
190                     return 1; /* mtmp died */
191                 /*
192                  * If mtmp has the hero swallowed, lie and say there
193                  * was no attack (this allows mtmp to digest the hero).
194                  */
195                 if (has_u_swallowed)
196                     return 0;
197
198                 /* Allow attacked monsters a chance to hit back. Primarily
199                  * to allow monsters that resist conflict to respond.
200                  */
201                 if ((result & MM_HIT) && !(result & MM_DEF_DIED) && rn2(4)
202                     && mon->movement >= NORMAL_SPEED) {
203                     mon->movement -= NORMAL_SPEED;
204                     notonhead = 0;
205                     (void) mattackm(mon, mtmp); /* return attack */
206                 }
207
208                 return (result & MM_HIT) ? 1 : 0;
209             }
210         }
211     }
212     return 0;
213 }
214
215 /*
216  * mdisplacem() -- attacker moves defender out of the way;
217  *                 returns same results as mattackm().
218  */
219 int
220 mdisplacem(magr, mdef, quietly)
221 register struct monst *magr, *mdef;
222 boolean quietly;
223 {
224     struct permonst *pa, *pd;
225     int tx, ty, fx, fy;
226
227     /* sanity checks; could matter if we unexpectedly get a long worm */
228     if (!magr || !mdef || magr == mdef)
229         return MM_MISS;
230     pa = magr->data, pd = mdef->data;
231     tx = mdef->mx, ty = mdef->my; /* destination */
232     fx = magr->mx, fy = magr->my; /* current location */
233     if (m_at(fx, fy) != magr || m_at(tx, ty) != mdef)
234         return MM_MISS;
235
236     /* The 1 in 7 failure below matches the chance in attack()
237      * for pet displacement.
238      */
239     if (!rn2(7))
240         return MM_MISS;
241
242     /* Grid bugs cannot displace at an angle. */
243     if (pa == &mons[PM_GRID_BUG] && magr->mx != mdef->mx
244         && magr->my != mdef->my)
245         return MM_MISS;
246
247     /* undetected monster becomes un-hidden if it is displaced */
248     if (mdef->mundetected)
249         mdef->mundetected = 0;
250     if (M_AP_TYPE(mdef) && M_AP_TYPE(mdef) != M_AP_MONSTER)
251         seemimic(mdef);
252     /* wake up the displaced defender */
253     mdef->msleeping = 0;
254     mdef->mstrategy &= ~STRAT_WAITMASK;
255     finish_meating(mdef);
256
257     /*
258      * Set up the visibility of action.
259      * You can observe monster displacement if you can see both of
260      * the monsters involved.
261      */
262     vis = (canspotmon(magr) && canspotmon(mdef));
263
264     if (touch_petrifies(pd) && !resists_ston(magr)) {
265         if (which_armor(magr, W_ARMG) != 0) {
266             if (poly_when_stoned(pa)) {
267                 mon_to_stone(magr);
268                 return MM_HIT; /* no damage during the polymorph */
269             }
270             if (!quietly && canspotmon(magr))
271 /*JP
272                 pline("%s turns to stone!", Monnam(magr));
273 */
274                 pline("%s\82Í\90Î\82É\82È\82Á\82½\81I", Monnam(magr));
275             monstone(magr);
276             if (!DEADMONSTER(magr))
277                 return MM_HIT; /* lifesaved */
278             else if (magr->mtame && !vis)
279 /*JP
280                 You(brief_feeling, "peculiarly sad");
281 */
282                 You(brief_feeling, "\82à\82Ì\94ß\82µ\82¢");
283             return MM_AGR_DIED;
284         }
285     }
286
287     remove_monster(fx, fy); /* pick up from orig position */
288     remove_monster(tx, ty);
289     place_monster(magr, tx, ty); /* put down at target spot */
290     place_monster(mdef, fx, fy);
291     if (vis && !quietly)
292 #if 0 /*JP:T*/
293         pline("%s moves %s out of %s way!", Monnam(magr), mon_nam(mdef),
294               is_rider(pa) ? "the" : mhis(magr));
295 #else
296         pline("%s\82Í%s\82ð\89\9f\82µ\82Ì\82¯\82½\81I", Monnam(magr), mon_nam(mdef));
297 #endif
298     newsym(fx, fy);  /* see it */
299     newsym(tx, ty);  /*   all happen */
300     flush_screen(0); /* make sure it shows up */
301
302     return MM_HIT;
303 }
304
305 /*
306  * mattackm() -- a monster attacks another monster.
307  *
308  *          --------- aggressor died
309  *         /  ------- defender died
310  *        /  /  ----- defender was hit
311  *       /  /  /
312  *      x  x  x
313  *
314  *      0x4     MM_AGR_DIED
315  *      0x2     MM_DEF_DIED
316  *      0x1     MM_HIT
317  *      0x0     MM_MISS
318  *
319  * Each successive attack has a lower probability of hitting.  Some rely on
320  * success of previous attacks.  ** this doen't seem to be implemented -dl **
321  *
322  * In the case of exploding monsters, the monster dies as well.
323  */
324 int
325 mattackm(magr, mdef)
326 register struct monst *magr, *mdef;
327 {
328     int i,          /* loop counter */
329         tmp,        /* amour class difference */
330         strike = 0, /* hit this attack */
331         attk,       /* attack attempted this time */
332         struck = 0, /* hit at least once */
333         res[NATTK]; /* results of all attacks */
334     struct attack *mattk, alt_attk;
335     struct permonst *pa, *pd;
336
337     if (!magr || !mdef)
338         return MM_MISS; /* mike@genat */
339     if (!magr->mcanmove || magr->msleeping)
340         return MM_MISS;
341     pa = magr->data;
342     pd = mdef->data;
343
344     /* Grid bugs cannot attack at an angle. */
345     if (pa == &mons[PM_GRID_BUG] && magr->mx != mdef->mx
346         && magr->my != mdef->my)
347         return MM_MISS;
348
349     /* Calculate the armour class differential. */
350     tmp = find_mac(mdef) + magr->m_lev;
351     if (mdef->mconf || !mdef->mcanmove || mdef->msleeping) {
352         tmp += 4;
353         mdef->msleeping = 0;
354     }
355
356     /* undetect monsters become un-hidden if they are attacked */
357     if (mdef->mundetected) {
358         mdef->mundetected = 0;
359         newsym(mdef->mx, mdef->my);
360         if (canseemon(mdef) && !sensemon(mdef)) {
361             if (Unaware) {
362 #if 0 /*JP*/
363                 boolean justone = (mdef->data->geno & G_UNIQ) != 0L;
364                 const char *montype;
365
366                 montype = noname_monnam(mdef, justone ? ARTICLE_THE
367                                                       : ARTICLE_NONE);
368                 if (!justone)
369                     montype = makeplural(montype);
370                 You("dream of %s.", montype);
371 #else
372                 You("%s\82Ì\96²\82ð\8c©\82½\81D", a_monnam(mdef));
373 #endif
374             } else
375 /*JP
376                 pline("Suddenly, you notice %s.", a_monnam(mdef));
377 */
378                 pline("\93Ë\91R\81C\82 \82È\82½\82Í%s\82É\8bC\82ª\82Â\82¢\82½\81D", a_monnam(mdef));
379         }
380     }
381
382     /* Elves hate orcs. */
383     if (is_elf(pa) && is_orc(pd))
384         tmp++;
385
386     /* Set up the visibility of action */
387     vis = (cansee(magr->mx, magr->my) && cansee(mdef->mx, mdef->my)
388            && (canspotmon(magr) || canspotmon(mdef)));
389
390     /* Set flag indicating monster has moved this turn.  Necessary since a
391      * monster might get an attack out of sequence (i.e. before its move) in
392      * some cases, in which case this still counts as its move for the round
393      * and it shouldn't move again.
394      */
395     magr->mlstmv = monstermoves;
396
397     /* Now perform all attacks for the monster. */
398     for (i = 0; i < NATTK; i++) {
399         res[i] = MM_MISS;
400         mattk = getmattk(magr, mdef, i, res, &alt_attk);
401         otmp = (struct obj *) 0;
402         attk = 1;
403         switch (mattk->aatyp) {
404         case AT_WEAP: /* "hand to hand" attacks */
405             if (distmin(magr->mx, magr->my, mdef->mx, mdef->my) > 1) {
406                 /* D: Do a ranged attack here! */
407                 strike = thrwmm(magr, mdef);
408                 if (DEADMONSTER(mdef))
409                     res[i] = MM_DEF_DIED;
410                 if (DEADMONSTER(magr))
411                     res[i] |= MM_AGR_DIED;
412                 break;
413             }
414             if (magr->weapon_check == NEED_WEAPON || !MON_WEP(magr)) {
415                 magr->weapon_check = NEED_HTH_WEAPON;
416                 if (mon_wield_item(magr) != 0)
417                     return 0;
418             }
419             possibly_unwield(magr, FALSE);
420             otmp = MON_WEP(magr);
421
422             if (otmp) {
423                 if (vis)
424                     mswingsm(magr, mdef, otmp);
425                 tmp += hitval(otmp, mdef);
426             }
427             /*FALLTHRU*/
428         case AT_CLAW:
429         case AT_KICK:
430         case AT_BITE:
431         case AT_STNG:
432         case AT_TUCH:
433         case AT_BUTT:
434         case AT_TENT:
435             /* Nymph that teleported away on first attack? */
436             if (distmin(magr->mx, magr->my, mdef->mx, mdef->my) > 1)
437                 /* Continue because the monster may have a ranged attack. */
438                 continue;
439             /* Monsters won't attack cockatrices physically if they
440              * have a weapon instead.  This instinct doesn't work for
441              * players, or under conflict or confusion.
442              */
443             if (!magr->mconf && !Conflict && otmp && mattk->aatyp != AT_WEAP
444                 && touch_petrifies(mdef->data)) {
445                 strike = 0;
446                 break;
447             }
448             dieroll = rnd(20 + i);
449             strike = (tmp > dieroll);
450             /* KMH -- don't accumulate to-hit bonuses */
451             if (otmp)
452                 tmp -= hitval(otmp, mdef);
453             if (strike) {
454                 res[i] = hitmm(magr, mdef, mattk);
455                 if ((mdef->data == &mons[PM_BLACK_PUDDING]
456                      || mdef->data == &mons[PM_BROWN_PUDDING])
457                     && (otmp && (objects[otmp->otyp].oc_material == IRON
458                                  || objects[otmp->otyp].oc_material == METAL))
459                     && mdef->mhp > 1 && !mdef->mcan) {
460                     struct monst *mclone;
461
462                     if ((mclone = clone_mon(mdef, 0, 0)) != 0) {
463                         if (vis && canspotmon(mdef)) {
464                             char buf[BUFSZ];
465
466                             Strcpy(buf, Monnam(mdef));
467 #if 0 /*JP:T*/
468                             pline("%s divides as %s hits it!", buf,
469                                   mon_nam(magr));
470 #else
471                             pline("%s\82Ì\8dU\8c\82\82Å%s\82ª\95ª\97ô\82µ\82½\81I",
472                                   mon_nam(magr), buf);
473 #endif
474                         }
475                         mintrap(mclone);
476                     }
477                 }
478             } else
479                 missmm(magr, mdef, mattk);
480             break;
481
482         case AT_HUGS: /* automatic if prev two attacks succeed */
483             strike = (i >= 2 && res[i - 1] == MM_HIT && res[i - 2] == MM_HIT);
484             if (strike)
485                 res[i] = hitmm(magr, mdef, mattk);
486
487             break;
488
489         case AT_GAZE:
490             strike = 0;
491             res[i] = gazemm(magr, mdef, mattk);
492             break;
493
494         case AT_EXPL:
495             /* D: Prevent explosions from a distance */
496             if (distmin(magr->mx,magr->my,mdef->mx,mdef->my) > 1)
497                 continue;
498
499             res[i] = explmm(magr, mdef, mattk);
500             if (res[i] == MM_MISS) { /* cancelled--no attack */
501                 strike = 0;
502                 attk = 0;
503             } else
504                 strike = 1; /* automatic hit */
505             break;
506
507         case AT_ENGL:
508             if (mdef->data == &mons[PM_SHADE]) { /* no silver teeth... */
509                 if (vis)
510 #if 0 /*JP:T*/
511                     pline("%s attempt to engulf %s is futile.",
512                           s_suffix(Monnam(magr)), mon_nam(mdef));
513 #else
514                     pline("%s\82Í%s\82ð\88ù\82Ý\8d\9e\82à\82¤\82Æ\82µ\82½\82ª\82Þ\82¾\82¾\82Á\82½\81D",
515                           Monnam(magr), mon_nam(mdef));
516 #endif
517                 strike = 0;
518                 break;
519             }
520             if (u.usteed && mdef == u.usteed) {
521                 strike = 0;
522                 break;
523             }
524             /* D: Prevent engulf from a distance */
525             if (distmin(magr->mx, magr->my, mdef->mx, mdef->my) > 1)
526                 continue;
527             /* Engulfing attacks are directed at the hero if possible. -dlc */
528             if (u.uswallow && magr == u.ustuck)
529                 strike = 0;
530             else if ((strike = (tmp > rnd(20 + i))) != 0)
531                 res[i] = gulpmm(magr, mdef, mattk);
532             else
533                 missmm(magr, mdef, mattk);
534             break;
535
536         case AT_BREA:
537             if (!monnear(magr, mdef->mx, mdef->my)) {
538                 strike = breamm(magr, mattk, mdef);
539
540                 /* We don't really know if we hit or not; pretend we did. */
541                 if (strike)
542                     res[i] |= MM_HIT;
543                 if (DEADMONSTER(mdef))
544                     res[i] = MM_DEF_DIED;
545                 if (DEADMONSTER(magr))
546                     res[i] |= MM_AGR_DIED;
547             }
548             else
549                 strike = 0;
550             break;
551
552         case AT_SPIT:
553             if (!monnear(magr, mdef->mx, mdef->my)) {
554                 strike = spitmm(magr, mattk, mdef);
555
556                 /* We don't really know if we hit or not; pretend we did. */
557                 if (strike)
558                     res[i] |= MM_HIT;
559                 if (DEADMONSTER(mdef))
560                     res[i] = MM_DEF_DIED;
561                 if (DEADMONSTER(magr))
562                     res[i] |= MM_AGR_DIED;
563             }
564             break;
565
566         default: /* no attack */
567             strike = 0;
568             attk = 0;
569             break;
570         }
571
572         if (attk && !(res[i] & MM_AGR_DIED)
573             && distmin(magr->mx, magr->my, mdef->mx, mdef->my) <= 1)
574             res[i] = passivemm(magr, mdef, strike, res[i] & MM_DEF_DIED);
575
576         if (res[i] & MM_DEF_DIED)
577             return res[i];
578         if (res[i] & MM_AGR_DIED)
579             return res[i];
580         /* return if aggressor can no longer attack */
581         if (!magr->mcanmove || magr->msleeping)
582             return res[i];
583         if (res[i] & MM_HIT)
584             struck = 1; /* at least one hit */
585     }
586
587     return (struck ? MM_HIT : MM_MISS);
588 }
589
590 /* Returns the result of mdamagem(). */
591 STATIC_OVL int
592 hitmm(magr, mdef, mattk)
593 register struct monst *magr, *mdef;
594 struct attack *mattk;
595 {
596     boolean weaponhit = ((mattk->aatyp == AT_WEAP
597                           || (mattk->aatyp == AT_CLAW && otmp))),
598             silverhit = (weaponhit && otmp
599                          && objects[otmp->otyp].oc_material == SILVER),
600             showit = FALSE;
601
602     /* unhiding or unmimicking happens even if hero can't see it
603        because the formerly concealed monster is now in action */
604     if (M_AP_TYPE(mdef)) {
605         seemimic(mdef);
606         showit |= vis;
607     } else if (mdef->mundetected) {
608         mdef->mundetected = 0;
609         showit |= vis;
610     }
611     if (M_AP_TYPE(magr)) {
612         seemimic(magr);
613         showit |= vis;
614     } else if (magr->mundetected) {
615         magr->mundetected = 0;
616         showit |= vis;
617     }
618
619     if (vis) {
620         int compat;
621         char buf[BUFSZ];
622
623         if (!canspotmon(magr))
624             map_invisible(magr->mx, magr->my);
625         else if (showit)
626             newsym(magr->mx, magr->my);
627         if (!canspotmon(mdef))
628             map_invisible(mdef->mx, mdef->my);
629         else if (showit)
630             newsym(mdef->mx, mdef->my);
631
632         if ((compat = could_seduce(magr, mdef, mattk)) && !magr->mcan) {
633 #if 0 /*JP:T*/
634             Sprintf(buf, "%s %s", Monnam(magr),
635                     mdef->mcansee ? "smiles at" : "talks to");
636             pline("%s %s %s.", buf, mon_nam(mdef),
637                   compat == 2 ? "engagingly" : "seductively");
638 #else
639             Sprintf(buf, "%s\82Í%%s\82É%%s%s\81D", Monnam(magr),
640                     mdef->mcansee ? "\94÷\8fÎ\82Ý\82©\82¯\82½" : "\98b\82µ\82©\82¯\82½");
641             pline(buf, mon_nam(mdef),
642                   compat == 2 ? "\96£\97Í\93I\82É" : "\97U\98f\93I\82É");
643 #endif
644         } else if (shade_miss(magr, mdef, otmp, FALSE, TRUE)) {
645             return MM_MISS; /* bypass mdamagem() */
646         } else {
647             char magr_name[BUFSZ];
648
649             Strcpy(magr_name, Monnam(magr));
650             switch (mattk->aatyp) {
651             case AT_BITE:
652 /*JP
653                 Sprintf(buf, "%s bites", magr_name);
654 */
655                 Sprintf(buf,"%s\82Í%%s\82É\8a\9a\82Ý\82Â\82¢\82½\81D", magr_name);
656                 break;
657             case AT_STNG:
658 /*JP
659                 Sprintf(buf, "%s stings", magr_name);
660 */
661                 Sprintf(buf,"%s\82Í%%s\82ð\93Ë\82«\82³\82µ\82½\81D", magr_name);
662                 break;
663             case AT_BUTT:
664 /*JP
665                 Sprintf(buf, "%s butts", magr_name);
666 */
667                 Sprintf(buf,"%s\82Í%%s\82É\93ª\93Ë\82«\82ð\82­\82ç\82í\82µ\82½\81D", magr_name);
668                 break;
669             case AT_TUCH:
670 /*JP
671                 Sprintf(buf, "%s touches", magr_name);
672 */
673                 Sprintf(buf,"%s\82Í%%s\82É\90G\82ê\82½\81D", magr_name);
674                 break;
675             case AT_TENT:
676 /*JP
677                 Sprintf(buf, "%s tentacles suck", s_suffix(magr_name));
678 */
679                 Sprintf(buf, "%s\82Ì\90G\8eè\82ª%%s\82Ì\91Ì\89t\82ð\8bz\82¢\82Æ\82Á\82½\81D", magr_name);
680                 break;
681             case AT_HUGS:
682                 if (magr != u.ustuck) {
683 /*JP
684                     Sprintf(buf, "%s squeezes", magr_name);
685 */
686                     Sprintf(buf,"%s\82Í%%s\82ð\8di\82ß\82½\81D", magr_name);
687                     break;
688                 }
689                 /*FALLTHRU*/
690             default:
691 /*JP
692                 Sprintf(buf, "%s hits", magr_name);
693 */
694                 Sprintf(buf, "%s\82Ì%%s\82Ö\82Ì\8dU\8c\82\82Í\96½\92\86\82µ\82½\81D", magr_name);
695             }
696 #if 0 /*JP*/
697             pline("%s %s.", buf, mon_nam_too(mdef, magr));
698 #else
699             pline(buf, mon_nam_too(mdef, magr));
700 #endif
701
702             if (mon_hates_silver(mdef) && silverhit) {
703                 char *mdef_name = mon_nam_too(mdef, magr);
704
705                 /* note: mon_nam_too returns a modifiable buffer; so
706                    does s_suffix, but it returns a single static buffer
707                    and we might be calling it twice for this message */
708                 Strcpy(magr_name, s_suffix(magr_name));
709                 if (!noncorporeal(mdef->data) && !amorphous(mdef->data)) {
710                     if (mdef != magr) {
711                         mdef_name = s_suffix(mdef_name);
712                     } else {
713                         (void) strsubst(mdef_name, "himself", "his own");
714                         (void) strsubst(mdef_name, "herself", "her own");
715                         (void) strsubst(mdef_name, "itself", "its own");
716                     }
717 /*JP
718                     Strcat(mdef_name, " flesh");
719 */
720                     Strcat(mdef_name, "\82Ì\93÷");
721                 }
722
723 #if 0 /*JP:T*/
724                 pline("%s %s sears %s!", magr_name, /*s_suffix(magr_name), */
725                       simpleonames(otmp), mdef_name);
726 #else
727                 pline("%s\82Ì%s\82ª%s\82ð\8fÄ\82¢\82½\81I", magr_name, /*s_suffix(magr_name), */
728                       simpleonames(otmp), mdef_name);
729 #endif
730             }
731         }
732     } else
733         noises(magr, mattk);
734
735     return mdamagem(magr, mdef, mattk);
736 }
737
738 /* Returns the same values as mdamagem(). */
739 STATIC_OVL int
740 gazemm(magr, mdef, mattk)
741 register struct monst *magr, *mdef;
742 struct attack *mattk;
743 {
744     char buf[BUFSZ];
745
746     if (vis) {
747         if (mdef->data->mlet == S_MIMIC
748             && M_AP_TYPE(mdef) != M_AP_NOTHING)
749             seemimic(mdef);
750 #if 0 /*JP:T*/
751         Sprintf(buf, "%s gazes at", Monnam(magr));
752         pline("%s %s...", buf,
753               canspotmon(mdef) ? mon_nam(mdef) : "something");
754 #else
755         Sprintf(buf, "%s\82Í%%s\82ð\82É\82ç\82Ý\82Â\82¯\82½\81D\81D\81D", Monnam(magr));
756         pline(buf, canspotmon(mdef) ? mon_nam(mdef) : "\89½\82©");
757 #endif
758     }
759
760     if (magr->mcan || !magr->mcansee || !mdef->mcansee
761         || (magr->minvis && !perceives(mdef->data)) || mdef->msleeping) {
762         if (vis && canspotmon(mdef))
763 /*JP
764             pline("but nothing happens.");
765 */
766             pline("\82µ\82©\82µ\89½\82à\82¨\82±\82ç\82È\82©\82Á\82½\81D");
767         return MM_MISS;
768     }
769     /* call mon_reflects 2x, first test, then, if visible, print message */
770     if (magr->data == &mons[PM_MEDUSA] && mon_reflects(mdef, (char *) 0)) {
771         if (canseemon(mdef))
772 /*JP
773             (void) mon_reflects(mdef, "The gaze is reflected away by %s %s.");
774 */
775             (void) mon_reflects(mdef, "\82É\82ç\82Ý\82Í%s\82Ì%s\82Å\94½\8eË\82µ\82½\81D");
776         if (mdef->mcansee) {
777             if (mon_reflects(magr, (char *) 0)) {
778                 if (canseemon(magr))
779 #if 0 /*JP:T*/
780                     (void) mon_reflects(magr,
781                                       "The gaze is reflected away by %s %s.");
782 #else
783                     (void) mon_reflects(magr,
784                                       "\82É\82ç\82Ý\82Í%s\82Ì%s\82Å\94½\8eË\82µ\82½\81D");
785 #endif
786                 return MM_MISS;
787             }
788             if (mdef->minvis && !perceives(magr->data)) {
789                 if (canseemon(magr)) {
790 #if 0 /*JP:T*/
791                     pline(
792                       "%s doesn't seem to notice that %s gaze was reflected.",
793                           Monnam(magr), mhis(magr));
794 #else
795                     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",
796                           Monnam(magr));
797 #endif
798                 }
799                 return MM_MISS;
800             }
801             if (canseemon(magr))
802 /*JP
803                 pline("%s is turned to stone!", Monnam(magr));
804 */
805                 pline("%s\82Í\90Î\82É\82È\82Á\82½\81I", Monnam(magr));
806             monstone(magr);
807             if (!DEADMONSTER(magr))
808                 return MM_MISS;
809             return MM_AGR_DIED;
810         }
811     }
812
813     return mdamagem(magr, mdef, mattk);
814 }
815
816 /* return True if magr is allowed to swallow mdef, False otherwise */
817 boolean
818 engulf_target(magr, mdef)
819 struct monst *magr, *mdef;
820 {
821     struct rm *lev;
822     int dx, dy;
823
824     /* can't swallow something that's too big */
825     if (mdef->data->msize >= MZ_HUGE)
826         return FALSE;
827
828     /* (hypothetical) engulfers who can pass through walls aren't
829      limited by rock|trees|bars */
830     if ((magr == &youmonst) ? Passes_walls : passes_walls(magr->data))
831         return TRUE;
832
833     /* don't swallow something in a spot where attacker wouldn't
834        otherwise be able to move onto; we don't want to engulf
835        a wall-phaser and end up with a non-phaser inside a wall */
836     dx = mdef->mx, dy = mdef->my;
837     if (mdef == &youmonst)
838         dx = u.ux, dy = u.uy;
839     lev = &levl[dx][dy];
840     if (IS_ROCK(lev->typ) || closed_door(dx, dy) || IS_TREE(lev->typ)
841         /* not passes_bars(); engulfer isn't squeezing through */
842         || (lev->typ == IRONBARS && !is_whirly(magr->data)))
843         return FALSE;
844
845     return TRUE;
846 }
847
848 /* Returns the same values as mattackm(). */
849 STATIC_OVL int
850 gulpmm(magr, mdef, mattk)
851 register struct monst *magr, *mdef;
852 register struct attack *mattk;
853 {
854     xchar ax, ay, dx, dy;
855     int status;
856     char buf[BUFSZ];
857     struct obj *obj;
858
859     if (!engulf_target(magr, mdef))
860         return MM_MISS;
861
862     if (vis) {
863         /* [this two-part formatting dates back to when only one x_monnam
864            result could be included in an expression because the next one
865            would overwrite first's result -- that's no longer the case] */
866 #if 0 /*JP:T*/
867         Sprintf(buf, "%s swallows", Monnam(magr));
868         pline("%s %s.", buf, mon_nam(mdef));
869 #else
870         Sprintf(buf, "%s\82Í%%s\82ð\82®\82Á\82Æ\88ù\82Ý\82±\82ñ\82¾\81D", Monnam(magr));
871         pline(buf, mon_nam(mdef));
872 #endif
873     }
874     for (obj = mdef->minvent; obj; obj = obj->nobj)
875         (void) snuff_lit(obj);
876
877     if (is_vampshifter(mdef)
878         && newcham(mdef, &mons[mdef->cham], FALSE, FALSE)) {
879         if (vis) {
880             /* 'it' -- previous form is no longer available and
881                using that would be excessively verbose */
882 #if 0 /*JP:T*/
883             pline("%s expels %s.", Monnam(magr),
884                   canspotmon(mdef) ? "it" : something);
885 #else
886             pline("%s\82Í%s\82ð\93f\82«\8fo\82µ\82½\81D", Monnam(magr),
887                   canspotmon(mdef) ? "\89½\82©" : something);
888 #endif
889             if (canspotmon(mdef))
890 /*JP
891                 pline("It turns into %s.", a_monnam(mdef));
892 */
893                 pline("\82»\82ê\82Í%s\82É\82È\82Á\82½\81D", a_monnam(mdef));
894         }
895         return MM_HIT; /* bypass mdamagem() */
896     }
897
898     /*
899      *  All of this manipulation is needed to keep the display correct.
900      *  There is a flush at the next pline().
901      */
902     ax = magr->mx;
903     ay = magr->my;
904     dx = mdef->mx;
905     dy = mdef->my;
906     /*
907      *  Leave the defender in the monster chain at it's current position,
908      *  but don't leave it on the screen.  Move the aggressor to the
909      *  defender's position.
910      */
911     remove_monster(dx, dy);
912     remove_monster(ax, ay);
913     place_monster(magr, dx, dy);
914     newsym(ax, ay); /* erase old position */
915     newsym(dx, dy); /* update new position */
916
917     status = mdamagem(magr, mdef, mattk);
918
919     if ((status & (MM_AGR_DIED | MM_DEF_DIED))
920         == (MM_AGR_DIED | MM_DEF_DIED)) {
921         ;                              /* both died -- do nothing  */
922     } else if (status & MM_DEF_DIED) { /* defender died */
923         /*
924          *  Note:  remove_monster() was called in relmon(), wiping out
925          *  magr from level.monsters[mdef->mx][mdef->my].  We need to
926          *  put it back and display it.  -kd
927          */
928         place_monster(magr, dx, dy);
929         newsym(dx, dy);
930         /* aggressor moves to <dx,dy> and might encounter trouble there */
931         if (minliquid(magr) || (t_at(dx, dy) && mintrap(magr) == 2))
932             status |= MM_AGR_DIED;
933     } else if (status & MM_AGR_DIED) { /* aggressor died */
934         place_monster(mdef, dx, dy);
935         newsym(dx, dy);
936     } else {                           /* both alive, put them back */
937         if (cansee(dx, dy))
938 /*JP
939             pline("%s is regurgitated!", Monnam(mdef));
940 */
941             pline("%s\82Í\93f\82«\96ß\82³\82ê\82½\81I", Monnam(mdef));
942
943         remove_monster(dx,dy);
944         place_monster(magr, ax, ay);
945         place_monster(mdef, dx, dy);
946         newsym(ax, ay);
947         newsym(dx, dy);
948     }
949
950     return status;
951 }
952
953 STATIC_OVL int
954 explmm(magr, mdef, mattk)
955 struct monst *magr, *mdef;
956 struct attack *mattk;
957 {
958     int result;
959
960     if (magr->mcan)
961         return MM_MISS;
962
963     if (cansee(magr->mx, magr->my))
964 /*JP
965         pline("%s explodes!", Monnam(magr));
966 */
967         pline("%s\82Í\94\9a\94­\82µ\82½\81I", Monnam(magr));
968     else
969         noises(magr, mattk);
970
971     result = mdamagem(magr, mdef, mattk);
972
973     /* Kill off aggressor if it didn't die. */
974     if (!(result & MM_AGR_DIED)) {
975         boolean was_leashed = (magr->mleashed != 0);
976
977         mondead(magr);
978         if (!DEADMONSTER(magr))
979             return result; /* life saved */
980         result |= MM_AGR_DIED;
981
982         /* mondead() -> m_detach() -> m_unleash() always suppresses
983            the m_unleash() slack message, so deliver it here instead */
984         if (was_leashed)
985 /*JP
986             Your("leash falls slack.");
987 */
988             Your("\95R\82ª\82½\82é\82ñ\82Å\97\8e\82¿\82½\81D");
989     }
990     if (magr->mtame) /* give this one even if it was visible */
991 /*JP
992         You(brief_feeling, "melancholy");
993 */
994         You(brief_feeling, "\97J\82¤\82Â\82È");
995
996     return result;
997 }
998
999 /*
1000  *  See comment at top of mattackm(), for return values.
1001  */
1002 STATIC_OVL int
1003 mdamagem(magr, mdef, mattk)
1004 register struct monst *magr, *mdef;
1005 register struct attack *mattk;
1006 {
1007     struct obj *obj;
1008     char buf[BUFSZ];
1009     struct permonst *pa = magr->data, *pd = mdef->data;
1010     int armpro, num,
1011         tmp = d((int) mattk->damn, (int) mattk->damd),
1012         res = MM_MISS;
1013     boolean cancelled;
1014
1015     if ((touch_petrifies(pd) /* or flesh_petrifies() */
1016          || (mattk->adtyp == AD_DGST && pd == &mons[PM_MEDUSA]))
1017         && !resists_ston(magr)) {
1018         long protector = attk_protection((int) mattk->aatyp),
1019              wornitems = magr->misc_worn_check;
1020
1021         /* wielded weapon gives same protection as gloves here */
1022         if (otmp != 0)
1023             wornitems |= W_ARMG;
1024
1025         if (protector == 0L
1026             || (protector != ~0L && (wornitems & protector) != protector)) {
1027             if (poly_when_stoned(pa)) {
1028                 mon_to_stone(magr);
1029                 return MM_HIT; /* no damage during the polymorph */
1030             }
1031             if (vis && canspotmon(magr))
1032 /*JP
1033                 pline("%s turns to stone!", Monnam(magr));
1034 */
1035                 pline("%s\82Í\90Î\82É\82È\82Á\82½\81I", Monnam(magr));
1036             monstone(magr);
1037             if (!DEADMONSTER(magr))
1038                 return MM_HIT; /* lifesaved */
1039             else if (magr->mtame && !vis)
1040 /*JP
1041                 You(brief_feeling, "peculiarly sad");
1042 */
1043                 You(brief_feeling, "\82à\82Ì\94ß\82µ\82¢");
1044             return MM_AGR_DIED;
1045         }
1046     }
1047
1048     /* cancellation factor is the same as when attacking the hero */
1049     armpro = magic_negation(mdef);
1050     cancelled = magr->mcan || !(rn2(10) >= 3 * armpro);
1051
1052     switch (mattk->adtyp) {
1053     case AD_DGST:
1054         /* eating a Rider or its corpse is fatal */
1055         if (is_rider(pd)) {
1056             if (vis && canseemon(magr))
1057 #if 0 /*JP:T*/
1058                 pline("%s %s!", Monnam(magr),
1059                       (pd == &mons[PM_FAMINE])
1060                           ? "belches feebly, shrivels up and dies"
1061                           : (pd == &mons[PM_PESTILENCE])
1062                                 ? "coughs spasmodically and collapses"
1063                                 : "vomits violently and drops dead");
1064 #else
1065                 pline("%s%s\81I", Monnam(magr),
1066                       (pd == &mons[PM_FAMINE])
1067                           ? "\8eã\81X\82µ\82­\93f\82«\82à\82Ç\82µ\82½\82©\82Æ\8ev\82¤\82Æ\81C\91Ì\82ª\82µ\82Ú\82Ý\8e\80\82ñ\82Å\82µ\82Ü\82Á\82½"
1068                           : (pd == &mons[PM_PESTILENCE])
1069                                 ? "áz\9d¹\82µ\82½\82æ\82¤\82É\82¹\82«\82±\82Ý\93|\82ê\82½"
1070                                 : "\8c\83\82µ\82­\9aq\93f\82µ\8e\80\82ñ\82¾");
1071 #endif
1072             mondied(magr);
1073             if (!DEADMONSTER(magr))
1074                 return 0; /* lifesaved */
1075             else if (magr->mtame && !vis)
1076 /*JP
1077                 You(brief_feeling, "queasy");
1078 */
1079                 You(brief_feeling, "\95s\88À\82È");
1080             return MM_AGR_DIED;
1081         }
1082         if (flags.verbose && !Deaf)
1083 /*JP
1084             verbalize("Burrrrp!");
1085 */
1086             verbalize("\82°\82Á\82Õ\81I");
1087         tmp = mdef->mhp;
1088         /* Use up amulet of life saving */
1089         if (!!(obj = mlifesaver(mdef)))
1090             m_useup(mdef, obj);
1091
1092         /* Is a corpse for nutrition possible?  It may kill magr */
1093         if (!corpse_chance(mdef, magr, TRUE) || DEADMONSTER(magr))
1094             break;
1095
1096         /* Pets get nutrition from swallowing monster whole.
1097          * No nutrition from G_NOCORPSE monster, eg, undead.
1098          * DGST monsters don't die from undead corpses
1099          */
1100         num = monsndx(pd);
1101         if (magr->mtame && !magr->isminion
1102             && !(mvitals[num].mvflags & G_NOCORPSE)) {
1103             struct obj *virtualcorpse = mksobj(CORPSE, FALSE, FALSE);
1104             int nutrit;
1105
1106             set_corpsenm(virtualcorpse, num);
1107             nutrit = dog_nutrition(magr, virtualcorpse);
1108             dealloc_obj(virtualcorpse);
1109
1110             /* only 50% nutrition, 25% of normal eating time */
1111             if (magr->meating > 1)
1112                 magr->meating = (magr->meating + 3) / 4;
1113             if (nutrit > 1)
1114                 nutrit /= 2;
1115             EDOG(magr)->hungrytime += nutrit;
1116         }
1117         break;
1118     case AD_STUN:
1119         if (magr->mcan)
1120             break;
1121         if (canseemon(mdef))
1122 #if 0 /*JP:T*/
1123             pline("%s %s for a moment.", Monnam(mdef),
1124                   makeplural(stagger(pd, "stagger")));
1125 #else
1126             pline("%s\82Í\82·\82±\82µ%s\81D", Monnam(mdef),
1127                   jpast(stagger(pd, "\82æ\82ë\82ß\82­")));
1128 #endif
1129         mdef->mstun = 1;
1130         goto physical;
1131     case AD_LEGS:
1132         if (magr->mcan) {
1133             tmp = 0;
1134             break;
1135         }
1136         goto physical;
1137     case AD_WERE:
1138     case AD_HEAL:
1139     case AD_PHYS:
1140  physical:
1141         obj = (mattk->aatyp == AT_WEAP || mattk->aatyp == AT_CLAW) ? otmp : 0;
1142         if (shade_miss(magr, mdef, obj, FALSE, TRUE)) {
1143             tmp = 0;
1144         } else if (mattk->aatyp == AT_KICK && thick_skinned(pd)) {
1145             tmp = 0;
1146         } else if (mattk->aatyp == AT_WEAP
1147                    || (mattk->aatyp == AT_CLAW && otmp)) {
1148             if (otmp) {
1149                 struct obj *marmg;
1150
1151                 if (otmp->otyp == CORPSE
1152                     && touch_petrifies(&mons[otmp->corpsenm]))
1153                     goto do_stone;
1154
1155                 tmp += dmgval(otmp, mdef);
1156                 if ((marmg = which_armor(magr, W_ARMG)) != 0
1157                     && marmg->otyp == GAUNTLETS_OF_POWER)
1158                     tmp += rn1(4, 3); /* 3..6 */
1159                 if (tmp < 1) /* is this necessary?  mhitu.c has it... */
1160                     tmp = 1;
1161                 if (otmp->oartifact) {
1162                     (void) artifact_hit(magr, mdef, otmp, &tmp, dieroll);
1163                     if (DEADMONSTER(mdef))
1164                         return (MM_DEF_DIED
1165                                 | (grow_up(magr, mdef) ? 0 : MM_AGR_DIED));
1166                 }
1167                 if (tmp)
1168                     rustm(mdef, otmp);
1169             }
1170         } else if (pa == &mons[PM_PURPLE_WORM] && pd == &mons[PM_SHRIEKER]) {
1171             /* hack to enhance mm_aggression(); we don't want purple
1172                worm's bite attack to kill a shrieker because then it
1173                won't swallow the corpse; but if the target survives,
1174                the subsequent engulf attack should accomplish that */
1175             if (tmp >= mdef->mhp && mdef->mhp > 1)
1176                 tmp = mdef->mhp - 1;
1177         }
1178         break;
1179     case AD_FIRE:
1180         if (cancelled) {
1181             tmp = 0;
1182             break;
1183         }
1184         if (vis && canseemon(mdef))
1185 /*JP
1186             pline("%s is %s!", Monnam(mdef), on_fire(pd, mattk));
1187 */
1188             pline("%s\82Í%s\81I", Monnam(mdef), on_fire(pd, mattk));
1189         if (completelyburns(pd)) { /* paper golem or straw golem */
1190             if (vis && canseemon(mdef))
1191 /*JP
1192                 pline("%s burns completely!", Monnam(mdef));
1193 */
1194                 pline("%s\82Í\8aD\82É\82È\82Á\82½\81I", Monnam(mdef));
1195             mondead(mdef); /* was mondied() but that dropped paper scrolls */
1196             if (!DEADMONSTER(mdef))
1197                 return 0;
1198             else if (mdef->mtame && !vis)
1199 /*JP
1200                 pline("May %s roast in peace.", mon_nam(mdef));
1201 */
1202                 pline("%s\82æ\81C\88À\82ç\82©\82É\94R\82¦\82ñ\8e\96\82ð\81D", mon_nam(mdef));
1203             return (MM_DEF_DIED | (grow_up(magr, mdef) ? 0 : MM_AGR_DIED));
1204         }
1205         tmp += destroy_mitem(mdef, SCROLL_CLASS, AD_FIRE);
1206         tmp += destroy_mitem(mdef, SPBOOK_CLASS, AD_FIRE);
1207         if (resists_fire(mdef)) {
1208             if (vis && canseemon(mdef))
1209 /*JP
1210                 pline_The("fire doesn't seem to burn %s!", mon_nam(mdef));
1211 */
1212                 pline("%s\82Í\89\8a\82Å\94R\82¦\82È\82¢\82æ\82¤\82¾\81I", mon_nam(mdef));
1213             shieldeff(mdef->mx, mdef->my);
1214             golemeffects(mdef, AD_FIRE, tmp);
1215             tmp = 0;
1216         }
1217         /* only potions damage resistant players in destroy_item */
1218         tmp += destroy_mitem(mdef, POTION_CLASS, AD_FIRE);
1219         break;
1220     case AD_COLD:
1221         if (cancelled) {
1222             tmp = 0;
1223             break;
1224         }
1225         if (vis && canseemon(mdef))
1226 /*JP
1227             pline("%s is covered in frost!", Monnam(mdef));
1228 */
1229             pline("%s\82Í\95X\82Å\95¢\82í\82ê\82½\81I", Monnam(mdef));
1230         if (resists_cold(mdef)) {
1231             if (vis && canseemon(mdef))
1232 /*JP
1233                 pline_The("frost doesn't seem to chill %s!", mon_nam(mdef));
1234 */
1235                 pline("\95X\82Í%s\82ð\93\80\82ç\82¹\82é\82±\82Æ\82ª\82Å\82«\82È\82¢\82æ\82¤\82¾\81I", mon_nam(mdef));
1236             shieldeff(mdef->mx, mdef->my);
1237             golemeffects(mdef, AD_COLD, tmp);
1238             tmp = 0;
1239         }
1240         tmp += destroy_mitem(mdef, POTION_CLASS, AD_COLD);
1241         break;
1242     case AD_ELEC:
1243         if (cancelled) {
1244             tmp = 0;
1245             break;
1246         }
1247         if (vis && canseemon(mdef))
1248 /*JP
1249             pline("%s gets zapped!", Monnam(mdef));
1250 */
1251             pline("%s\82Í\8fÕ\8c\82\82ð\82­\82ç\82Á\82½\81I", Monnam(mdef));
1252         tmp += destroy_mitem(mdef, WAND_CLASS, AD_ELEC);
1253         if (resists_elec(mdef)) {
1254             if (vis && canseemon(mdef))
1255 /*JP
1256                 pline_The("zap doesn't shock %s!", mon_nam(mdef));
1257 */
1258                 pline("\8fÕ\8c\82\82Í%s\82É\89e\8b¿\82ð\97^\82¦\82È\82¢\81I", mon_nam(mdef));
1259             shieldeff(mdef->mx, mdef->my);
1260             golemeffects(mdef, AD_ELEC, tmp);
1261             tmp = 0;
1262         }
1263         /* only rings damage resistant players in destroy_item */
1264         tmp += destroy_mitem(mdef, RING_CLASS, AD_ELEC);
1265         break;
1266     case AD_ACID:
1267         if (magr->mcan) {
1268             tmp = 0;
1269             break;
1270         }
1271         if (resists_acid(mdef)) {
1272             if (vis && canseemon(mdef))
1273 #if 0 /*JP:T*/
1274                 pline("%s is covered in %s, but it seems harmless.",
1275                       Monnam(mdef), hliquid("acid"));
1276 #else
1277                 pline("%s\82Í%s\82É\82Â\82Â\82Ü\82ê\82½\81D\82µ\82©\82µ\82È\82ñ\82Æ\82à\82È\82¢\82æ\82¤\82¾\81D",
1278                       Monnam(mdef), hliquid("\8e_"));
1279 #endif
1280             tmp = 0;
1281         } else if (vis && canseemon(mdef)) {
1282 /*JP
1283             pline("%s is covered in %s!", Monnam(mdef), hliquid("acid"));
1284 */
1285             pline("%s\82Í%s\82É\82Â\82Â\82Ü\82ê\82½\81I", Monnam(mdef), hliquid("\8e_"));
1286 /*JP
1287             pline("It burns %s!", mon_nam(mdef));
1288 */
1289             pline("%s\82Í\8fÄ\82©\82ê\82½\81I", mon_nam(mdef));
1290         }
1291         if (!rn2(30))
1292             erode_armor(mdef, ERODE_CORRODE);
1293         if (!rn2(6))
1294             acid_damage(MON_WEP(mdef));
1295         break;
1296     case AD_RUST:
1297         if (magr->mcan)
1298             break;
1299         if (pd == &mons[PM_IRON_GOLEM]) {
1300             if (vis && canseemon(mdef))
1301 /*JP
1302                 pline("%s falls to pieces!", Monnam(mdef));
1303 */
1304                 pline("%s\82Í\83o\83\89\83o\83\89\82É\82È\82Á\82½\81I", Monnam(mdef));
1305             mondied(mdef);
1306             if (!DEADMONSTER(mdef))
1307                 return 0;
1308             else if (mdef->mtame && !vis)
1309 /*JP
1310                 pline("May %s rust in peace.", mon_nam(mdef));
1311 */
1312                 pline("%s\82æ\81C\88À\82ç\82©\82É\8eK\82Ñ\82ñ\8e\96\82ð\81D", mon_nam(mdef));
1313             return (MM_DEF_DIED | (grow_up(magr, mdef) ? 0 : MM_AGR_DIED));
1314         }
1315         erode_armor(mdef, ERODE_RUST);
1316         mdef->mstrategy &= ~STRAT_WAITFORU;
1317         tmp = 0;
1318         break;
1319     case AD_CORR:
1320         if (magr->mcan)
1321             break;
1322         erode_armor(mdef, ERODE_CORRODE);
1323         mdef->mstrategy &= ~STRAT_WAITFORU;
1324         tmp = 0;
1325         break;
1326     case AD_DCAY:
1327         if (magr->mcan)
1328             break;
1329         if (pd == &mons[PM_WOOD_GOLEM] || pd == &mons[PM_LEATHER_GOLEM]) {
1330             if (vis && canseemon(mdef))
1331 /*JP
1332                 pline("%s falls to pieces!", Monnam(mdef));
1333 */
1334                 pline("%s\82Í\83o\83\89\83o\83\89\82É\82È\82Á\82½\81I", Monnam(mdef));
1335             mondied(mdef);
1336             if (!DEADMONSTER(mdef))
1337                 return 0;
1338             else if (mdef->mtame && !vis)
1339 /*JP
1340                 pline("May %s rot in peace.", mon_nam(mdef));
1341 */
1342                 pline("%s\82æ\81C\88À\82ç\82©\82É\95\85\82ç\82ñ\8e\96\82ð\81D", mon_nam(mdef));
1343             return (MM_DEF_DIED | (grow_up(magr, mdef) ? 0 : MM_AGR_DIED));
1344         }
1345         erode_armor(mdef, ERODE_CORRODE);
1346         mdef->mstrategy &= ~STRAT_WAITFORU;
1347         tmp = 0;
1348         break;
1349     case AD_STON:
1350         if (magr->mcan)
1351             break;
1352  do_stone:
1353         /* may die from the acid if it eats a stone-curing corpse */
1354         if (munstone(mdef, FALSE))
1355             goto post_stone;
1356         if (poly_when_stoned(pd)) {
1357             mon_to_stone(mdef);
1358             tmp = 0;
1359             break;
1360         }
1361         if (!resists_ston(mdef)) {
1362             if (vis && canseemon(mdef))
1363 /*JP
1364                 pline("%s turns to stone!", Monnam(mdef));
1365 */
1366                 pline("%s\82Í\90Î\82É\82È\82Á\82½\81I", Monnam(mdef));
1367             monstone(mdef);
1368  post_stone:
1369             if (!DEADMONSTER(mdef))
1370                 return 0;
1371             else if (mdef->mtame && !vis)
1372 /*JP
1373                 You(brief_feeling, "peculiarly sad");
1374 */
1375                 You(brief_feeling, "\82à\82Ì\94ß\82µ\82¢");
1376             return (MM_DEF_DIED | (grow_up(magr, mdef) ? 0 : MM_AGR_DIED));
1377         }
1378         tmp = (mattk->adtyp == AD_STON ? 0 : 1);
1379         break;
1380     case AD_TLPT:
1381         if (!cancelled && tmp < mdef->mhp && !tele_restrict(mdef)) {
1382             char mdef_Monnam[BUFSZ];
1383             boolean wasseen = canspotmon(mdef);
1384
1385             /* save the name before monster teleports, otherwise
1386                we'll get "it" in the suddenly disappears message */
1387             if (vis && wasseen)
1388                 Strcpy(mdef_Monnam, Monnam(mdef));
1389             mdef->mstrategy &= ~STRAT_WAITFORU;
1390             (void) rloc(mdef, TRUE);
1391             if (vis && wasseen && !canspotmon(mdef) && mdef != u.usteed)
1392 /*JP
1393                 pline("%s suddenly disappears!", mdef_Monnam);
1394 */
1395                 pline("%s\82Í\93Ë\91R\8fÁ\82¦\82½\81I", mdef_Monnam);
1396             if (tmp >= mdef->mhp) { /* see hitmu(mhitu.c) */
1397                 if (mdef->mhp == 1)
1398                     ++mdef->mhp;
1399                 tmp = mdef->mhp - 1;
1400             }
1401         }
1402         break;
1403     case AD_SLEE:
1404         if (!cancelled && !mdef->msleeping
1405             && sleep_monst(mdef, rnd(10), -1)) {
1406             if (vis && canspotmon(mdef)) {
1407                 Strcpy(buf, Monnam(mdef));
1408 /*JP
1409                 pline("%s is put to sleep by %s.", buf, mon_nam(magr));
1410 */
1411                 pline("%s\82Í%s\82É\82æ\82Á\82Ä\96°\82ç\82³\82ê\82½\81D", buf, mon_nam(magr));
1412             }
1413             mdef->mstrategy &= ~STRAT_WAITFORU;
1414             slept_monst(mdef);
1415         }
1416         break;
1417     case AD_PLYS:
1418         if (!cancelled && mdef->mcanmove) {
1419             if (vis && canspotmon(mdef)) {
1420                 Strcpy(buf, Monnam(mdef));
1421 /*JP
1422                 pline("%s is frozen by %s.", buf, mon_nam(magr));
1423 */
1424                 pline("%s\82Í%s\82É\82æ\82Á\82Ä\93®\82¯\82È\82­\82È\82Á\82½\81D", buf, mon_nam(magr));
1425             }
1426             paralyze_monst(mdef, rnd(10));
1427         }
1428         break;
1429     case AD_SLOW:
1430         if (!cancelled && mdef->mspeed != MSLOW) {
1431             unsigned int oldspeed = mdef->mspeed;
1432
1433             mon_adjust_speed(mdef, -1, (struct obj *) 0);
1434             mdef->mstrategy &= ~STRAT_WAITFORU;
1435             if (mdef->mspeed != oldspeed && vis && canspotmon(mdef))
1436 /*JP
1437                 pline("%s slows down.", Monnam(mdef));
1438 */
1439                 pline("%s\82Í\93®\8dì\82ª\82Ì\82ë\82­\82È\82Á\82½\81D", Monnam(mdef));
1440         }
1441         break;
1442     case AD_CONF:
1443         /* Since confusing another monster doesn't have a real time
1444          * limit, setting spec_used would not really be right (though
1445          * we still should check for it).
1446          */
1447         if (!magr->mcan && !mdef->mconf && !magr->mspec_used) {
1448             if (vis && canseemon(mdef))
1449 /*JP
1450                 pline("%s looks confused.", Monnam(mdef));
1451 */
1452                 pline("%s\82Í\8d¬\97\90\82µ\82Ä\82¢\82é\82æ\82¤\82É\8c©\82¦\82é\81D", Monnam(mdef));
1453             mdef->mconf = 1;
1454             mdef->mstrategy &= ~STRAT_WAITFORU;
1455         }
1456         break;
1457     case AD_BLND:
1458         if (can_blnd(magr, mdef, mattk->aatyp, (struct obj *) 0)) {
1459             register unsigned rnd_tmp;
1460
1461             if (vis && mdef->mcansee && canspotmon(mdef))
1462 /*JP
1463                 pline("%s is blinded.", Monnam(mdef));
1464 */
1465                 pline("%s\82Í\96Ú\82ª\8c©\82¦\82È\82­\82È\82Á\82½\81D", Monnam(mdef));
1466             rnd_tmp = d((int) mattk->damn, (int) mattk->damd);
1467             if ((rnd_tmp += mdef->mblinded) > 127)
1468                 rnd_tmp = 127;
1469             mdef->mblinded = rnd_tmp;
1470             mdef->mcansee = 0;
1471             mdef->mstrategy &= ~STRAT_WAITFORU;
1472         }
1473         tmp = 0;
1474         break;
1475     case AD_HALU:
1476         if (!magr->mcan && haseyes(pd) && mdef->mcansee) {
1477             if (vis && canseemon(mdef))
1478 #if 0 /*JP:T*/
1479                 pline("%s looks %sconfused.", Monnam(mdef),
1480                       mdef->mconf ? "more " : "");
1481 #else
1482                 pline("%s\82Í%s\8d¬\97\90\82µ\82Ä\82¢\82é\82æ\82¤\82É\8c©\82¦\82é\81D", Monnam(mdef),
1483                       mdef->mconf ? "\82Ü\82·\82Ü\82·" : "");
1484 #endif
1485             mdef->mconf = 1;
1486             mdef->mstrategy &= ~STRAT_WAITFORU;
1487         }
1488         tmp = 0;
1489         break;
1490     case AD_CURS:
1491         if (!night() && (pa == &mons[PM_GREMLIN]))
1492             break;
1493         if (!magr->mcan && !rn2(10)) {
1494             mdef->mcan = 1; /* cancelled regardless of lifesave */
1495             mdef->mstrategy &= ~STRAT_WAITFORU;
1496             if (is_were(pd) && pd->mlet != S_HUMAN)
1497                 were_change(mdef);
1498             if (pd == &mons[PM_CLAY_GOLEM]) {
1499                 if (vis && canseemon(mdef)) {
1500 #if 0 /*JP:T*/
1501                     pline("Some writing vanishes from %s head!",
1502                           s_suffix(mon_nam(mdef)));
1503 #else
1504                     pline("\82¢\82­\82Â\82©\82Ì\95\8e\9a\82ª%s\82Ì\93ª\82©\82ç\8fÁ\82¦\82½\81I",
1505                           mon_nam(mdef));
1506 #endif
1507 /*JP
1508                     pline("%s is destroyed!", Monnam(mdef));
1509 */
1510                     pline("%s\82Í\94j\89ó\82³\82ê\82½\81I", Monnam(mdef));
1511                 }
1512                 mondied(mdef);
1513                 if (!DEADMONSTER(mdef))
1514                     return 0;
1515                 else if (mdef->mtame && !vis)
1516 /*JP
1517                     You(brief_feeling, "strangely sad");
1518 */
1519                     You(brief_feeling, "\96­\82É\94ß\82µ\82¢");
1520                 return (MM_DEF_DIED
1521                         | (grow_up(magr, mdef) ? 0 : MM_AGR_DIED));
1522             }
1523             if (!Deaf) {
1524                 if (!vis)
1525 /*JP
1526                     You_hear("laughter.");
1527 */
1528                     You_hear("\8fÎ\82¢\90º\82ð\95·\82¢\82½\81D");
1529                 else if (canseemon(magr))
1530 /*JP
1531                     pline("%s chuckles.", Monnam(magr));
1532 */
1533                     pline("%s\82Í\82­\82·\82­\82·\8fÎ\82Á\82½\81D", Monnam(magr));
1534             }
1535         }
1536         break;
1537     case AD_SGLD:
1538         tmp = 0;
1539         if (magr->mcan)
1540             break;
1541         /* technically incorrect; no check for stealing gold from
1542          * between mdef's feet...
1543          */
1544         {
1545             struct obj *gold = findgold(mdef->minvent);
1546
1547             if (!gold)
1548                 break;
1549             obj_extract_self(gold);
1550             add_to_minv(magr, gold);
1551         }
1552         mdef->mstrategy &= ~STRAT_WAITFORU;
1553         if (vis && canseemon(mdef)) {
1554             Strcpy(buf, Monnam(magr));
1555 /*JP
1556             pline("%s steals some gold from %s.", buf, mon_nam(mdef));
1557 */
1558             pline("%s\82Í%s\82©\82ç\8bà\82ð\93\90\82ñ\82¾\81D", buf, mon_nam(mdef));
1559         }
1560         if (!tele_restrict(magr)) {
1561             boolean couldspot = canspotmon(magr);
1562             (void) rloc(magr, TRUE);
1563             if (vis && couldspot && !canspotmon(magr))
1564 /*JP
1565                 pline("%s suddenly disappears!", buf);
1566 */
1567                 pline("%s\82Í\93Ë\91R\8fÁ\82¦\82½\81I", buf);
1568         }
1569         break;
1570     case AD_DRLI:
1571         if (!cancelled && !rn2(3) && !resists_drli(mdef)) {
1572             tmp = d(2, 6);
1573             if (vis && canspotmon(mdef))
1574 /*JP
1575                 pline("%s suddenly seems weaker!", Monnam(mdef));
1576 */
1577                 pline("%s\82Í\93Ë\91R\8eã\82­\82È\82Á\82½\82æ\82¤\82É\8c©\82¦\82½\81I", Monnam(mdef));
1578             mdef->mhpmax -= tmp;
1579             if (mdef->m_lev == 0)
1580                 tmp = mdef->mhp;
1581             else
1582                 mdef->m_lev--;
1583             /* Automatic kill if drained past level 0 */
1584         }
1585         break;
1586     case AD_SSEX:
1587     case AD_SITM: /* for now these are the same */
1588     case AD_SEDU:
1589         if (magr->mcan)
1590             break;
1591         /* find an object to steal, non-cursed if magr is tame */
1592         for (obj = mdef->minvent; obj; obj = obj->nobj)
1593             if (!magr->mtame || !obj->cursed)
1594                 break;
1595
1596         if (obj) {
1597             char onambuf[BUFSZ], mdefnambuf[BUFSZ];
1598
1599             /* make a special x_monnam() call that never omits
1600                the saddle, and save it for later messages */
1601             Strcpy(mdefnambuf,
1602                    x_monnam(mdef, ARTICLE_THE, (char *) 0, 0, FALSE));
1603
1604             otmp = obj;
1605             if (u.usteed == mdef && otmp == which_armor(mdef, W_SADDLE))
1606                 /* "You can no longer ride <steed>." */
1607                 dismount_steed(DISMOUNT_POLY);
1608             obj_extract_self(otmp);
1609             if (otmp->owornmask) {
1610                 mdef->misc_worn_check &= ~otmp->owornmask;
1611                 if (otmp->owornmask & W_WEP)
1612                     mwepgone(mdef);
1613                 otmp->owornmask = 0L;
1614                 update_mon_intrinsics(mdef, otmp, FALSE, FALSE);
1615                 /* give monster a chance to wear other equipment on its next
1616                    move instead of waiting until it picks something up */
1617                 mdef->misc_worn_check |= I_SPECIAL;
1618             }
1619             /* add_to_minv() might free otmp [if it merges] */
1620             if (vis)
1621                 Strcpy(onambuf, doname(otmp));
1622             (void) add_to_minv(magr, otmp);
1623             if (vis && canseemon(mdef)) {
1624                 Strcpy(buf, Monnam(magr));
1625 /*JP
1626                 pline("%s steals %s from %s!", buf, onambuf, mdefnambuf);
1627 */
1628                 pline("%s\82Í%s\82©\82ç%s\82ð\93\90\82ñ\82¾\81I", buf, mdefnambuf, onambuf);
1629             }
1630             possibly_unwield(mdef, FALSE);
1631             mdef->mstrategy &= ~STRAT_WAITFORU;
1632             mselftouch(mdef, (const char *) 0, FALSE);
1633             if (DEADMONSTER(mdef))
1634                 return (MM_DEF_DIED
1635                         | (grow_up(magr, mdef) ? 0 : MM_AGR_DIED));
1636             if (pa->mlet == S_NYMPH && !tele_restrict(magr)) {
1637                 boolean couldspot = canspotmon(magr);
1638
1639                 (void) rloc(magr, TRUE);
1640                 if (vis && couldspot && !canspotmon(magr))
1641 /*JP
1642                     pline("%s suddenly disappears!", buf);
1643 */
1644                     pline("%s\82Í\93Ë\91R\8fÁ\82¦\82½\81I", buf);
1645             }
1646         }
1647         tmp = 0;
1648         break;
1649     case AD_DREN:
1650         if (!cancelled && !rn2(4))
1651             xdrainenergym(mdef, (boolean) (vis && canspotmon(mdef)
1652                                            && mattk->aatyp != AT_ENGL));
1653         tmp = 0;
1654         break;
1655     case AD_DRST:
1656     case AD_DRDX:
1657     case AD_DRCO:
1658         if (!cancelled && !rn2(8)) {
1659             if (vis && canspotmon(magr))
1660 #if 0 /*JP:T*/
1661                 pline("%s %s was poisoned!", s_suffix(Monnam(magr)),
1662                       mpoisons_subj(magr, mattk));
1663 #else
1664                 pline("%s\82Ì%s\82Í\93Å\82³\82ê\82Ä\82¢\82é\81I", Monnam(magr),
1665                       mpoisons_subj(magr, mattk));
1666 #endif
1667             if (resists_poison(mdef)) {
1668                 if (vis && canspotmon(mdef) && canspotmon(magr))
1669 /*JP
1670                     pline_The("poison doesn't seem to affect %s.",
1671 */
1672                     pline("%s\82Í\93Å\82Ì\89e\8b¿\82ð\8eó\82¯\82È\82¢\81D",
1673                               mon_nam(mdef));
1674             } else {
1675                 if (rn2(10))
1676                     tmp += rn1(10, 6);
1677                 else {
1678                     if (vis && canspotmon(mdef))
1679 /*JP
1680                         pline_The("poison was deadly...");
1681 */
1682                         pline("\93Å\82Í\92v\8e\80\97Ê\82¾\82Á\82½\81D\81D\81D");
1683                     tmp = mdef->mhp;
1684                 }
1685             }
1686         }
1687         break;
1688     case AD_DRIN:
1689         if (notonhead || !has_head(pd)) {
1690             if (vis && canspotmon(mdef))
1691 /*JP
1692                 pline("%s doesn't seem harmed.", Monnam(mdef));
1693 */
1694                 pline("%s\82Í\8f\9d\82Â\82¢\82½\82æ\82¤\82É\82Í\8c©\82¦\82È\82¢\81D", Monnam(mdef));
1695             /* Not clear what to do for green slimes */
1696             tmp = 0;
1697             break;
1698         }
1699         if ((mdef->misc_worn_check & W_ARMH) && rn2(8)) {
1700             if (vis && canspotmon(magr) && canseemon(mdef)) {
1701                 Strcpy(buf, s_suffix(Monnam(mdef)));
1702 #if 0 /*JP:T*/
1703                 pline("%s helmet blocks %s attack to %s head.", buf,
1704                       s_suffix(mon_nam(magr)), mhis(mdef));
1705 #else
1706                 pline("%s\82Ì\8a\95\82Í%s\82Ì\93ª\82Ö\82Ì\8dU\8c\82\82ð\96h\82¢\82¾\81D", buf,
1707                       mon_nam(magr));
1708 #endif
1709             }
1710             break;
1711         }
1712         res = eat_brains(magr, mdef, vis, &tmp);
1713         break;
1714     case AD_SLIM:
1715         if (cancelled)
1716             break; /* physical damage only */
1717         if (!rn2(4) && !slimeproof(pd)) {
1718             if (!munslime(mdef, FALSE) && !DEADMONSTER(mdef)) {
1719                 if (newcham(mdef, &mons[PM_GREEN_SLIME], FALSE,
1720                             (boolean) (vis && canseemon(mdef))))
1721                     pd = mdef->data;
1722                 mdef->mstrategy &= ~STRAT_WAITFORU;
1723                 res = MM_HIT;
1724             }
1725             /* munslime attempt could have been fatal,
1726                potentially to multiple monsters (SCR_FIRE) */
1727             if (DEADMONSTER(magr))
1728                 res |= MM_AGR_DIED;
1729             if (DEADMONSTER(mdef))
1730                 res |= MM_DEF_DIED;
1731             tmp = 0;
1732         }
1733         break;
1734     case AD_STCK:
1735         if (cancelled)
1736             tmp = 0;
1737         break;
1738     case AD_WRAP: /* monsters cannot grab one another, it's too hard */
1739         if (magr->mcan)
1740             tmp = 0;
1741         break;
1742     case AD_ENCH:
1743         /* there's no msomearmor() function, so just do damage */
1744         /* if (cancelled) break; */
1745         break;
1746     default:
1747         tmp = 0;
1748         break;
1749     }
1750     if (!tmp)
1751         return res;
1752
1753     if ((mdef->mhp -= tmp) < 1) {
1754         if (m_at(mdef->mx, mdef->my) == magr) { /* see gulpmm() */
1755             remove_monster(mdef->mx, mdef->my);
1756             mdef->mhp = 1; /* otherwise place_monster will complain */
1757             place_monster(mdef, mdef->mx, mdef->my);
1758             mdef->mhp = 0;
1759         }
1760         monkilled(mdef, "", (int) mattk->adtyp);
1761         if (!DEADMONSTER(mdef))
1762             return res; /* mdef lifesaved */
1763         else if (res == MM_AGR_DIED)
1764             return (MM_DEF_DIED | MM_AGR_DIED);
1765
1766         if (mattk->adtyp == AD_DGST) {
1767             /* various checks similar to dog_eat and meatobj.
1768              * after monkilled() to provide better message ordering */
1769             if (mdef->cham >= LOW_PM) {
1770                 (void) newcham(magr, (struct permonst *) 0, FALSE, TRUE);
1771             } else if (pd == &mons[PM_GREEN_SLIME] && !slimeproof(pa)) {
1772                 (void) newcham(magr, &mons[PM_GREEN_SLIME], FALSE, TRUE);
1773             } else if (pd == &mons[PM_WRAITH]) {
1774                 (void) grow_up(magr, (struct monst *) 0);
1775                 /* don't grow up twice */
1776                 return (MM_DEF_DIED | (!DEADMONSTER(magr) ? 0 : MM_AGR_DIED));
1777             } else if (pd == &mons[PM_NURSE]) {
1778                 magr->mhp = magr->mhpmax;
1779             }
1780         }
1781         /* caveat: above digestion handling doesn't keep `pa' up to date */
1782
1783         return (MM_DEF_DIED | (grow_up(magr, mdef) ? 0 : MM_AGR_DIED));
1784     }
1785     return (res == MM_AGR_DIED) ? MM_AGR_DIED : MM_HIT;
1786 }
1787
1788 void
1789 paralyze_monst(mon, amt)
1790 struct monst *mon;
1791 int amt;
1792 {
1793     if (amt > 127)
1794         amt = 127;
1795
1796     mon->mcanmove = 0;
1797     mon->mfrozen = amt;
1798     mon->meating = 0; /* terminate any meal-in-progress */
1799     mon->mstrategy &= ~STRAT_WAITFORU;
1800 }
1801
1802 /* `mon' is hit by a sleep attack; return 1 if it's affected, 0 otherwise */
1803 int
1804 sleep_monst(mon, amt, how)
1805 struct monst *mon;
1806 int amt, how;
1807 {
1808     if (resists_sleep(mon)
1809         || (how >= 0 && resist(mon, (char) how, 0, NOTELL))) {
1810         shieldeff(mon->mx, mon->my);
1811     } else if (mon->mcanmove) {
1812         finish_meating(mon); /* terminate any meal-in-progress */
1813         amt += (int) mon->mfrozen;
1814         if (amt > 0) { /* sleep for N turns */
1815             mon->mcanmove = 0;
1816             mon->mfrozen = min(amt, 127);
1817         } else { /* sleep until awakened */
1818             mon->msleeping = 1;
1819         }
1820         return 1;
1821     }
1822     return 0;
1823 }
1824
1825 /* sleeping grabber releases, engulfer doesn't; don't use for paralysis! */
1826 void
1827 slept_monst(mon)
1828 struct monst *mon;
1829 {
1830     if ((mon->msleeping || !mon->mcanmove) && mon == u.ustuck
1831         && !sticks(youmonst.data) && !u.uswallow) {
1832 /*JP
1833         pline("%s grip relaxes.", s_suffix(Monnam(mon)));
1834 */
1835         pline("%s\82Ì\88¬\82é\97Í\82ª\8eã\82­\82È\82Á\82½\81D", Monnam(mon));
1836         unstuck(mon);
1837     }
1838 }
1839
1840 void
1841 rustm(mdef, obj)
1842 struct monst *mdef;
1843 struct obj *obj;
1844 {
1845     int dmgtyp = -1, chance = 1;
1846
1847     if (!mdef || !obj)
1848         return; /* just in case */
1849     /* AD_ACID and AD_ENCH are handled in passivemm() and passiveum() */
1850     if (dmgtype(mdef->data, AD_CORR)) {
1851         dmgtyp = ERODE_CORRODE;
1852     } else if (dmgtype(mdef->data, AD_RUST)) {
1853         dmgtyp = ERODE_RUST;
1854     } else if (dmgtype(mdef->data, AD_FIRE)
1855                /* steam vortex: fire resist applies, fire damage doesn't */
1856                && mdef->data != &mons[PM_STEAM_VORTEX]) {
1857         dmgtyp = ERODE_BURN;
1858         chance = 6;
1859     }
1860
1861     if (dmgtyp >= 0 && !rn2(chance))
1862         (void) erode_obj(obj, (char *) 0, dmgtyp, EF_GREASE | EF_VERBOSE);
1863 }
1864
1865 STATIC_OVL void
1866 mswingsm(magr, mdef, otemp)
1867 struct monst *magr, *mdef;
1868 struct obj *otemp;
1869 {
1870     if (flags.verbose && !Blind && mon_visible(magr)) {
1871 #if 0 /*JP*/
1872         pline("%s %s %s%s %s at %s.", Monnam(magr),
1873               (objects[otemp->otyp].oc_dir & PIERCE) ? "thrusts" : "swings",
1874               (otemp->quan > 1L) ? "one of " : "", mhis(magr), xname(otemp),
1875               mon_nam(mdef));
1876 #else
1877         pline((objects[otemp->otyp].oc_dir & PIERCE) ?
1878               "%s\82Í%s\82Å%s\82ð\93Ë\82¢\82½\81D" :
1879               "%s\82Í%s\82ð\90U\82è\82Ü\82í\82µ%s\82ð\8dU\8c\82\82µ\82½\81D", Monnam(magr),
1880               xname(otemp), mon_nam(mdef));
1881 #endif
1882     }
1883 }
1884
1885 /*
1886  * Passive responses by defenders.  Does not replicate responses already
1887  * handled above.  Returns same values as mattackm.
1888  */
1889 STATIC_OVL int
1890 passivemm(magr, mdef, mhit, mdead)
1891 register struct monst *magr, *mdef;
1892 boolean mhit;
1893 int mdead;
1894 {
1895     register struct permonst *mddat = mdef->data;
1896     register struct permonst *madat = magr->data;
1897     char buf[BUFSZ];
1898     int i, tmp;
1899
1900     for (i = 0;; i++) {
1901         if (i >= NATTK)
1902             return (mdead | mhit); /* no passive attacks */
1903         if (mddat->mattk[i].aatyp == AT_NONE)
1904             break;
1905     }
1906     if (mddat->mattk[i].damn)
1907         tmp = d((int) mddat->mattk[i].damn, (int) mddat->mattk[i].damd);
1908     else if (mddat->mattk[i].damd)
1909         tmp = d((int) mddat->mlevel + 1, (int) mddat->mattk[i].damd);
1910     else
1911         tmp = 0;
1912
1913     /* These affect the enemy even if defender killed */
1914     switch (mddat->mattk[i].adtyp) {
1915     case AD_ACID:
1916         if (mhit && !rn2(2)) {
1917             Strcpy(buf, Monnam(magr));
1918             if (canseemon(magr))
1919 #if 0 /*JP:T*/
1920                 pline("%s is splashed by %s %s!", buf,
1921                       s_suffix(mon_nam(mdef)), hliquid("acid"));
1922 #else
1923                 pline("%s\82Í%s\82Ì%s\82ð\97\81\82Ñ\82½\81I", buf,
1924                       mon_nam(mdef), hliquid("\8e_"));
1925 #endif
1926             if (resists_acid(magr)) {
1927                 if (canseemon(magr))
1928 /*JP
1929                     pline("%s is not affected.", Monnam(magr));
1930 */
1931                     pline("%s\82Í\89e\8b¿\82ð\8eó\82¯\82È\82¢\81D", Monnam(magr));
1932                 tmp = 0;
1933             }
1934         } else
1935             tmp = 0;
1936         if (!rn2(30))
1937             erode_armor(magr, ERODE_CORRODE);
1938         if (!rn2(6))
1939             acid_damage(MON_WEP(magr));
1940         goto assess_dmg;
1941     case AD_ENCH: /* KMH -- remove enchantment (disenchanter) */
1942         if (mhit && !mdef->mcan && otmp) {
1943             (void) drain_item(otmp, FALSE);
1944             /* No message */
1945         }
1946         break;
1947     default:
1948         break;
1949     }
1950     if (mdead || mdef->mcan)
1951         return (mdead | mhit);
1952
1953     /* These affect the enemy only if defender is still alive */
1954     if (rn2(3))
1955         switch (mddat->mattk[i].adtyp) {
1956         case AD_PLYS: /* Floating eye */
1957             if (tmp > 127)
1958                 tmp = 127;
1959             if (mddat == &mons[PM_FLOATING_EYE]) {
1960                 if (!rn2(4))
1961                     tmp = 127;
1962                 if (magr->mcansee && haseyes(madat) && mdef->mcansee
1963                     && (perceives(madat) || !mdef->minvis)) {
1964                     /* construct format string; guard against '%' in Monnam */
1965 #if 0 /*JP*/
1966                     Strcpy(buf, s_suffix(Monnam(mdef)));
1967 #else
1968                     Strcpy(buf, Monnam(mdef));
1969 #endif
1970                     (void) strNsubst(buf, "%", "%%", 0);
1971 /*JP
1972                     Strcat(buf, " gaze is reflected by %s %s.");
1973 */
1974                     Strcat(buf, "\82Ì\82É\82ç\82Ý\82Í%s\82É\82æ\82Á\82Ä%s\81D");
1975                     if (mon_reflects(magr,
1976                                      canseemon(magr) ? buf : (char *) 0))
1977                         return (mdead | mhit);
1978                     Strcpy(buf, Monnam(magr));
1979                     if (canseemon(magr))
1980 #if 0 /*JP:T*/
1981                         pline("%s is frozen by %s gaze!", buf,
1982                               s_suffix(mon_nam(mdef)));
1983 #else
1984                         pline("%s\82Í%s\82Ì\82É\82ç\82Ý\82Å\93®\82¯\82È\82­\82È\82Á\82½\81I", buf,
1985                               mon_nam(mdef));
1986 #endif
1987                     paralyze_monst(magr, tmp);
1988                     return (mdead | mhit);
1989                 }
1990             } else { /* gelatinous cube */
1991                 Strcpy(buf, Monnam(magr));
1992                 if (canseemon(magr))
1993 /*JP
1994                     pline("%s is frozen by %s.", buf, mon_nam(mdef));
1995 */
1996                     pline("%s\82Í%s\82É\82æ\82Á\82Ä\93®\82¯\82È\82­\82È\82Á\82½\81D", buf, mon_nam(mdef));
1997                 paralyze_monst(magr, tmp);
1998                 return (mdead | mhit);
1999             }
2000             return 1;
2001         case AD_COLD:
2002             if (resists_cold(magr)) {
2003                 if (canseemon(magr)) {
2004 /*JP
2005                     pline("%s is mildly chilly.", Monnam(magr));
2006 */
2007                     pline("%s\82Í\97â\82¦\82½\81D", Monnam(magr));
2008                     golemeffects(magr, AD_COLD, tmp);
2009                 }
2010                 tmp = 0;
2011                 break;
2012             }
2013             if (canseemon(magr))
2014 /*JP
2015                 pline("%s is suddenly very cold!", Monnam(magr));
2016 */
2017                 pline("%s\82Í\93Ë\91R\93\80\82è\82Ã\82¯\82É\82È\82Á\82½\81I", Monnam(magr));
2018             mdef->mhp += tmp / 2;
2019             if (mdef->mhpmax < mdef->mhp)
2020                 mdef->mhpmax = mdef->mhp;
2021             if (mdef->mhpmax > ((int) (mdef->m_lev + 1) * 8))
2022                 (void) split_mon(mdef, magr);
2023             break;
2024         case AD_STUN:
2025             if (!magr->mstun) {
2026                 magr->mstun = 1;
2027                 if (canseemon(magr))
2028 #if 0 /*JP:T*/
2029                     pline("%s %s...", Monnam(magr),
2030                           makeplural(stagger(magr->data, "stagger")));
2031 #else
2032                     pline("%s\82Í%s\81D\81D\81D", Monnam(magr),
2033                           jpast(stagger(magr->data, "\82æ\82ë\82ß\82­")));
2034 #endif
2035             }
2036             tmp = 0;
2037             break;
2038         case AD_FIRE:
2039             if (resists_fire(magr)) {
2040                 if (canseemon(magr)) {
2041 /*JP
2042                     pline("%s is mildly warmed.", Monnam(magr));
2043 */
2044                     pline("%s\82Í\92g\82©\82­\82È\82Á\82½\81D", Monnam(magr));
2045                     golemeffects(magr, AD_FIRE, tmp);
2046                 }
2047                 tmp = 0;
2048                 break;
2049             }
2050             if (canseemon(magr))
2051 /*JP
2052                 pline("%s is suddenly very hot!", Monnam(magr));
2053 */
2054                 pline("%s\82Í\93Ë\91R\82Æ\82Ä\82à\94M\82­\82È\82Á\82½\81I", Monnam(magr));
2055             break;
2056         case AD_ELEC:
2057             if (resists_elec(magr)) {
2058                 if (canseemon(magr)) {
2059 /*JP
2060                     pline("%s is mildly tingled.", Monnam(magr));
2061 */
2062                     pline("%s\82Í\83s\83\8a\83s\83\8a\82µ\82Ä\82¢\82é\81D", Monnam(magr));
2063                     golemeffects(magr, AD_ELEC, tmp);
2064                 }
2065                 tmp = 0;
2066                 break;
2067             }
2068             if (canseemon(magr))
2069 /*JP
2070                 pline("%s is jolted with electricity!", Monnam(magr));
2071 */
2072                 pline("%s\82Í\93d\8bC\83V\83\87\83b\83N\82ð\82¤\82¯\82½\81I", Monnam(magr));
2073             break;
2074         default:
2075             tmp = 0;
2076             break;
2077         }
2078     else
2079         tmp = 0;
2080
2081  assess_dmg:
2082     if ((magr->mhp -= tmp) <= 0) {
2083         monkilled(magr, "", (int) mddat->mattk[i].adtyp);
2084         return (mdead | mhit | MM_AGR_DIED);
2085     }
2086     return (mdead | mhit);
2087 }
2088
2089 /* hero or monster has successfully hit target mon with drain energy attack */
2090 void
2091 xdrainenergym(mon, givemsg)
2092 struct monst *mon;
2093 boolean givemsg;
2094 {
2095     if (mon->mspec_used < 20 /* limit draining */
2096         && (attacktype(mon->data, AT_MAGC)
2097             || attacktype(mon->data, AT_BREA))) {
2098         mon->mspec_used += d(2, 2);
2099         if (givemsg)
2100 /*JP
2101             pline("%s seems lethargic.", Monnam(mon));
2102 */
2103             pline("%s\82Í\96³\8bC\97Í\82É\82È\82Á\82½\82æ\82¤\82¾\81D", Monnam(mon));
2104     }
2105 }
2106
2107 /* "aggressive defense"; what type of armor prevents specified attack
2108    from touching its target? */
2109 long
2110 attk_protection(aatyp)
2111 int aatyp;
2112 {
2113     long w_mask = 0L;
2114
2115     switch (aatyp) {
2116     case AT_NONE:
2117     case AT_SPIT:
2118     case AT_EXPL:
2119     case AT_BOOM:
2120     case AT_GAZE:
2121     case AT_BREA:
2122     case AT_MAGC:
2123         w_mask = ~0L; /* special case; no defense needed */
2124         break;
2125     case AT_CLAW:
2126     case AT_TUCH:
2127     case AT_WEAP:
2128         w_mask = W_ARMG; /* caller needs to check for weapon */
2129         break;
2130     case AT_KICK:
2131         w_mask = W_ARMF;
2132         break;
2133     case AT_BUTT:
2134         w_mask = W_ARMH;
2135         break;
2136     case AT_HUGS:
2137         w_mask = (W_ARMC | W_ARMG); /* attacker needs both to be protected */
2138         break;
2139     case AT_BITE:
2140     case AT_STNG:
2141     case AT_ENGL:
2142     case AT_TENT:
2143     default:
2144         w_mask = 0L; /* no defense available */
2145         break;
2146     }
2147     return w_mask;
2148 }
2149
2150 /*mhitm.c*/