OSDN Git Service

upgrade to 3.6.6
[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-2019            */
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                     pline("%s attempt to engulf %s is futile.",
511                           s_suffix(Monnam(magr)), mon_nam(mdef));
512                 strike = 0;
513                 break;
514             }
515             if (u.usteed && mdef == u.usteed) {
516                 strike = 0;
517                 break;
518             }
519             /* D: Prevent engulf from a distance */
520             if (distmin(magr->mx, magr->my, mdef->mx, mdef->my) > 1)
521                 continue;
522             /* Engulfing attacks are directed at the hero if possible. -dlc */
523             if (u.uswallow && magr == u.ustuck)
524                 strike = 0;
525             else if ((strike = (tmp > rnd(20 + i))) != 0)
526                 res[i] = gulpmm(magr, mdef, mattk);
527             else
528                 missmm(magr, mdef, mattk);
529             break;
530
531         case AT_BREA:
532             if (!monnear(magr, mdef->mx, mdef->my)) {
533                 strike = breamm(magr, mattk, mdef);
534
535                 /* We don't really know if we hit or not; pretend we did. */
536                 if (strike)
537                     res[i] |= MM_HIT;
538                 if (DEADMONSTER(mdef))
539                     res[i] = MM_DEF_DIED;
540                 if (DEADMONSTER(magr))
541                     res[i] |= MM_AGR_DIED;
542             }
543             else
544                 strike = 0;
545             break;
546
547         case AT_SPIT:
548             if (!monnear(magr, mdef->mx, mdef->my)) {
549                 strike = spitmm(magr, mattk, mdef);
550
551                 /* We don't really know if we hit or not; pretend we did. */
552                 if (strike)
553                     res[i] |= MM_HIT;
554                 if (DEADMONSTER(mdef))
555                     res[i] = MM_DEF_DIED;
556                 if (DEADMONSTER(magr))
557                     res[i] |= MM_AGR_DIED;
558             }
559             break;
560
561         default: /* no attack */
562             strike = 0;
563             attk = 0;
564             break;
565         }
566
567         if (attk && !(res[i] & MM_AGR_DIED)
568             && distmin(magr->mx, magr->my, mdef->mx, mdef->my) <= 1)
569             res[i] = passivemm(magr, mdef, strike, res[i] & MM_DEF_DIED);
570
571         if (res[i] & MM_DEF_DIED)
572             return res[i];
573         if (res[i] & MM_AGR_DIED)
574             return res[i];
575         /* return if aggressor can no longer attack */
576         if (!magr->mcanmove || magr->msleeping)
577             return res[i];
578         if (res[i] & MM_HIT)
579             struck = 1; /* at least one hit */
580     }
581
582     return (struck ? MM_HIT : MM_MISS);
583 }
584
585 /* Returns the result of mdamagem(). */
586 STATIC_OVL int
587 hitmm(magr, mdef, mattk)
588 register struct monst *magr, *mdef;
589 struct attack *mattk;
590 {
591     boolean weaponhit = ((mattk->aatyp == AT_WEAP
592                           || (mattk->aatyp == AT_CLAW && otmp))),
593             silverhit = (weaponhit && otmp
594                          && objects[otmp->otyp].oc_material == SILVER),
595             showit = FALSE;
596
597     /* unhiding or unmimicking happens even if hero can't see it
598        because the formerly concealed monster is now in action */
599     if (M_AP_TYPE(mdef)) {
600         seemimic(mdef);
601         showit |= vis;
602     } else if (mdef->mundetected) {
603         mdef->mundetected = 0;
604         showit |= vis;
605     }
606     if (M_AP_TYPE(magr)) {
607         seemimic(magr);
608         showit |= vis;
609     } else if (magr->mundetected) {
610         magr->mundetected = 0;
611         showit |= vis;
612     }
613
614     if (vis) {
615         int compat;
616         char buf[BUFSZ];
617
618         if (!canspotmon(magr))
619             map_invisible(magr->mx, magr->my);
620         else if (showit)
621             newsym(magr->mx, magr->my);
622         if (!canspotmon(mdef))
623             map_invisible(mdef->mx, mdef->my);
624         else if (showit)
625             newsym(mdef->mx, mdef->my);
626
627         if ((compat = could_seduce(magr, mdef, mattk)) && !magr->mcan) {
628 #if 0 /*JP:T*/
629             Sprintf(buf, "%s %s", Monnam(magr),
630                     mdef->mcansee ? "smiles at" : "talks to");
631             pline("%s %s %s.", buf, mon_nam(mdef),
632                   compat == 2 ? "engagingly" : "seductively");
633 #else
634             Sprintf(buf, "%s\82Í%%s\82É%%s%s\81D", Monnam(magr),
635                     mdef->mcansee ? "\94÷\8fÎ\82Ý\82©\82¯\82½" : "\98b\82µ\82©\82¯\82½");
636             pline(buf, mon_nam(mdef),
637                   compat == 2 ? "\96£\97Í\93I\82É" : "\97U\98f\93I\82É");
638 #endif
639         } else if (shade_miss(magr, mdef, otmp, FALSE, TRUE)) {
640             return MM_MISS; /* bypass mdamagem() */
641         } else {
642             char magr_name[BUFSZ];
643
644             Strcpy(magr_name, Monnam(magr));
645             switch (mattk->aatyp) {
646             case AT_BITE:
647 /*JP
648                 Sprintf(buf, "%s bites", magr_name);
649 */
650                 Sprintf(buf,"%s\82Í%%s\82É\8a\9a\82Ý\82Â\82¢\82½\81D", magr_name);
651                 break;
652             case AT_STNG:
653 /*JP
654                 Sprintf(buf, "%s stings", magr_name);
655 */
656                 Sprintf(buf,"%s\82Í%%s\82ð\93Ë\82«\82³\82µ\82½\81D", magr_name);
657                 break;
658             case AT_BUTT:
659 /*JP
660                 Sprintf(buf, "%s butts", magr_name);
661 */
662                 Sprintf(buf,"%s\82Í%%s\82É\93ª\93Ë\82«\82ð\82­\82ç\82í\82µ\82½\81D", magr_name);
663                 break;
664             case AT_TUCH:
665 /*JP
666                 Sprintf(buf, "%s touches", magr_name);
667 */
668                 Sprintf(buf,"%s\82Í%%s\82É\90G\82ê\82½\81D", magr_name);
669                 break;
670             case AT_TENT:
671 /*JP
672                 Sprintf(buf, "%s tentacles suck", s_suffix(magr_name));
673 */
674                 Sprintf(buf, "%s\82Ì\90G\8eè\82ª%%s\82Ì\91Ì\89t\82ð\8bz\82¢\82Æ\82Á\82½\81D", magr_name);
675                 break;
676             case AT_HUGS:
677                 if (magr != u.ustuck) {
678 /*JP
679                     Sprintf(buf, "%s squeezes", magr_name);
680 */
681                     Sprintf(buf,"%s\82Í%%s\82ð\8di\82ß\82½\81D", magr_name);
682                     break;
683                 }
684                 /*FALLTHRU*/
685             default:
686 /*JP
687                 Sprintf(buf, "%s hits", magr_name);
688 */
689                 Sprintf(buf,"%s\82Ì%%s\82Ö\82Ì\8dU\8c\82\82Í\96½\92\86\82µ\82½\81D", magr_name);
690             }
691 #if 0 /*JP*/
692             pline("%s %s.", buf, mon_nam_too(mdef, magr));
693 #else
694             pline(buf, mon_nam_too(mdef, magr));
695 #endif
696
697             if (mon_hates_silver(mdef) && silverhit) {
698                 char *mdef_name = mon_nam_too(mdef, magr);
699
700                 /* note: mon_nam_too returns a modifiable buffer; so
701                    does s_suffix, but it returns a single static buffer
702                    and we might be calling it twice for this message */
703                 Strcpy(magr_name, s_suffix(magr_name));
704                 if (!noncorporeal(mdef->data) && !amorphous(mdef->data)) {
705                     if (mdef != magr) {
706                         mdef_name = s_suffix(mdef_name);
707                     } else {
708                         (void) strsubst(mdef_name, "himself", "his own");
709                         (void) strsubst(mdef_name, "herself", "her own");
710                         (void) strsubst(mdef_name, "itself", "its own");
711                     }
712                     Strcat(mdef_name, " flesh");
713                 }
714
715                 pline("%s %s sears %s!", magr_name, /*s_suffix(magr_name), */
716                       simpleonames(otmp), mdef_name);
717             }
718         }
719     } else
720         noises(magr, mattk);
721
722     return mdamagem(magr, mdef, mattk);
723 }
724
725 /* Returns the same values as mdamagem(). */
726 STATIC_OVL int
727 gazemm(magr, mdef, mattk)
728 register struct monst *magr, *mdef;
729 struct attack *mattk;
730 {
731     char buf[BUFSZ];
732
733     if (vis) {
734         if (mdef->data->mlet == S_MIMIC
735             && M_AP_TYPE(mdef) != M_AP_NOTHING)
736             seemimic(mdef);
737 #if 0 /*JP:T*/
738         Sprintf(buf, "%s gazes at", Monnam(magr));
739         pline("%s %s...", buf,
740               canspotmon(mdef) ? mon_nam(mdef) : "something");
741 #else
742         Sprintf(buf, "%s\82Í%%s\82ð\82É\82ç\82Ý\82Â\82¯\82½\81D\81D\81D", Monnam(magr));
743         pline(buf, canspotmon(mdef) ? mon_nam(mdef) : "\89½\82©");
744 #endif
745     }
746
747     if (magr->mcan || !magr->mcansee || !mdef->mcansee
748         || (magr->minvis && !perceives(mdef->data)) || mdef->msleeping) {
749         if (vis && canspotmon(mdef))
750 /*JP
751             pline("but nothing happens.");
752 */
753             pline("\82µ\82©\82µ\89½\82à\82¨\82±\82ç\82È\82©\82Á\82½\81D");
754         return MM_MISS;
755     }
756     /* call mon_reflects 2x, first test, then, if visible, print message */
757     if (magr->data == &mons[PM_MEDUSA] && mon_reflects(mdef, (char *) 0)) {
758         if (canseemon(mdef))
759 /*JP
760             (void) mon_reflects(mdef, "The gaze is reflected away by %s %s.");
761 */
762             (void) mon_reflects(mdef, "\82É\82ç\82Ý\82Í%s\82Ì%s\82Å\94½\8eË\82µ\82½\81D");
763         if (mdef->mcansee) {
764             if (mon_reflects(magr, (char *) 0)) {
765                 if (canseemon(magr))
766 #if 0 /*JP:T*/
767                     (void) mon_reflects(magr,
768                                       "The gaze is reflected away by %s %s.");
769 #else
770                     (void) mon_reflects(magr,
771                                       "\82É\82ç\82Ý\82Í%s\82Ì%s\82Å\94½\8eË\82µ\82½\81D");
772 #endif
773                 return MM_MISS;
774             }
775             if (mdef->minvis && !perceives(magr->data)) {
776                 if (canseemon(magr)) {
777 #if 0 /*JP:T*/
778                     pline(
779                       "%s doesn't seem to notice that %s gaze was reflected.",
780                           Monnam(magr), mhis(magr));
781 #else
782                     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",
783                           Monnam(magr));
784 #endif
785                 }
786                 return MM_MISS;
787             }
788             if (canseemon(magr))
789 /*JP
790                 pline("%s is turned to stone!", Monnam(magr));
791 */
792                 pline("%s\82Í\90Î\82É\82È\82Á\82½\81I", Monnam(magr));
793             monstone(magr);
794             if (!DEADMONSTER(magr))
795                 return MM_MISS;
796             return MM_AGR_DIED;
797         }
798     }
799
800     return mdamagem(magr, mdef, mattk);
801 }
802
803 /* return True if magr is allowed to swallow mdef, False otherwise */
804 boolean
805 engulf_target(magr, mdef)
806 struct monst *magr, *mdef;
807 {
808     struct rm *lev;
809     int dx, dy;
810
811     /* can't swallow something that's too big */
812     if (mdef->data->msize >= MZ_HUGE)
813         return FALSE;
814
815     /* (hypothetical) engulfers who can pass through walls aren't
816      limited by rock|trees|bars */
817     if ((magr == &youmonst) ? Passes_walls : passes_walls(magr->data))
818         return TRUE;
819
820     /* don't swallow something in a spot where attacker wouldn't
821        otherwise be able to move onto; we don't want to engulf
822        a wall-phaser and end up with a non-phaser inside a wall */
823     dx = mdef->mx, dy = mdef->my;
824     if (mdef == &youmonst)
825         dx = u.ux, dy = u.uy;
826     lev = &levl[dx][dy];
827     if (IS_ROCK(lev->typ) || closed_door(dx, dy) || IS_TREE(lev->typ)
828         /* not passes_bars(); engulfer isn't squeezing through */
829         || (lev->typ == IRONBARS && !is_whirly(magr->data)))
830         return FALSE;
831
832     return TRUE;
833 }
834
835 /* Returns the same values as mattackm(). */
836 STATIC_OVL int
837 gulpmm(magr, mdef, mattk)
838 register struct monst *magr, *mdef;
839 register struct attack *mattk;
840 {
841     xchar ax, ay, dx, dy;
842     int status;
843     char buf[BUFSZ];
844     struct obj *obj;
845
846     if (!engulf_target(magr, mdef))
847         return MM_MISS;
848
849     if (vis) {
850         /* [this two-part formatting dates back to when only one x_monnam
851            result could be included in an expression because the next one
852            would overwrite first's result -- that's no longer the case] */
853 #if 0 /*JP:T*/
854         Sprintf(buf, "%s swallows", Monnam(magr));
855         pline("%s %s.", buf, mon_nam(mdef));
856 #else
857         Sprintf(buf, "%s\82Í%%s\82ð\82®\82Á\82Æ\88ù\82Ý\82±\82ñ\82¾\81D", Monnam(magr));
858         pline(buf, mon_nam(mdef));
859 #endif
860     }
861     for (obj = mdef->minvent; obj; obj = obj->nobj)
862         (void) snuff_lit(obj);
863
864     if (is_vampshifter(mdef)
865         && newcham(mdef, &mons[mdef->cham], FALSE, FALSE)) {
866         if (vis) {
867             /* 'it' -- previous form is no longer available and
868                using that would be excessively verbose */
869 #if 0 /*JP:T*/
870             pline("%s expels %s.", Monnam(magr),
871                   canspotmon(mdef) ? "it" : something);
872 #else
873             pline("%s\82Í%s\82ð\93f\82«\8fo\82µ\82½\81D", Monnam(magr),
874                   canspotmon(mdef) ? "\89½\82©" : something);
875 #endif
876             if (canspotmon(mdef))
877 /*JP
878                 pline("It turns into %s.", a_monnam(mdef));
879 */
880                 pline("\82»\82ê\82Í%s\82É\82È\82Á\82½\81D", a_monnam(mdef));
881         }
882         return MM_HIT; /* bypass mdamagem() */
883     }
884
885     /*
886      *  All of this manipulation is needed to keep the display correct.
887      *  There is a flush at the next pline().
888      */
889     ax = magr->mx;
890     ay = magr->my;
891     dx = mdef->mx;
892     dy = mdef->my;
893     /*
894      *  Leave the defender in the monster chain at it's current position,
895      *  but don't leave it on the screen.  Move the aggressor to the
896      *  defender's position.
897      */
898     remove_monster(dx, dy);
899     remove_monster(ax, ay);
900     place_monster(magr, dx, dy);
901     newsym(ax, ay); /* erase old position */
902     newsym(dx, dy); /* update new position */
903
904     status = mdamagem(magr, mdef, mattk);
905
906     if ((status & (MM_AGR_DIED | MM_DEF_DIED))
907         == (MM_AGR_DIED | MM_DEF_DIED)) {
908         ;                              /* both died -- do nothing  */
909     } else if (status & MM_DEF_DIED) { /* defender died */
910         /*
911          *  Note:  remove_monster() was called in relmon(), wiping out
912          *  magr from level.monsters[mdef->mx][mdef->my].  We need to
913          *  put it back and display it.  -kd
914          */
915         place_monster(magr, dx, dy);
916         newsym(dx, dy);
917         /* aggressor moves to <dx,dy> and might encounter trouble there */
918         if (minliquid(magr) || (t_at(dx, dy) && mintrap(magr) == 2))
919             status |= MM_AGR_DIED;
920     } else if (status & MM_AGR_DIED) { /* aggressor died */
921         place_monster(mdef, dx, dy);
922         newsym(dx, dy);
923     } else {                           /* both alive, put them back */
924         if (cansee(dx, dy))
925 /*JP
926             pline("%s is regurgitated!", Monnam(mdef));
927 */
928             pline("%s\82Í\93f\82«\96ß\82³\82ê\82½\81I", Monnam(mdef));
929
930         remove_monster(dx,dy);
931         place_monster(magr, ax, ay);
932         place_monster(mdef, dx, dy);
933         newsym(ax, ay);
934         newsym(dx, dy);
935     }
936
937     return status;
938 }
939
940 STATIC_OVL int
941 explmm(magr, mdef, mattk)
942 struct monst *magr, *mdef;
943 struct attack *mattk;
944 {
945     int result;
946
947     if (magr->mcan)
948         return MM_MISS;
949
950     if (cansee(magr->mx, magr->my))
951 /*JP
952         pline("%s explodes!", Monnam(magr));
953 */
954         pline("%s\82Í\94\9a\94­\82µ\82½\81I", Monnam(magr));
955     else
956         noises(magr, mattk);
957
958     result = mdamagem(magr, mdef, mattk);
959
960     /* Kill off aggressor if it didn't die. */
961     if (!(result & MM_AGR_DIED)) {
962         boolean was_leashed = (magr->mleashed != 0);
963
964         mondead(magr);
965         if (!DEADMONSTER(magr))
966             return result; /* life saved */
967         result |= MM_AGR_DIED;
968
969         /* mondead() -> m_detach() -> m_unleash() always suppresses
970            the m_unleash() slack message, so deliver it here instead */
971         if (was_leashed)
972             Your("leash falls slack.");
973     }
974     if (magr->mtame) /* give this one even if it was visible */
975 /*JP
976         You(brief_feeling, "melancholy");
977 */
978         You(brief_feeling, "\97J\82¤\82Â\82È");
979
980     return result;
981 }
982
983 /*
984  *  See comment at top of mattackm(), for return values.
985  */
986 STATIC_OVL int
987 mdamagem(magr, mdef, mattk)
988 register struct monst *magr, *mdef;
989 register struct attack *mattk;
990 {
991     struct obj *obj;
992     char buf[BUFSZ];
993     struct permonst *pa = magr->data, *pd = mdef->data;
994     int armpro, num,
995         tmp = d((int) mattk->damn, (int) mattk->damd),
996         res = MM_MISS;
997     boolean cancelled;
998
999     if ((touch_petrifies(pd) /* or flesh_petrifies() */
1000          || (mattk->adtyp == AD_DGST && pd == &mons[PM_MEDUSA]))
1001         && !resists_ston(magr)) {
1002         long protector = attk_protection((int) mattk->aatyp),
1003              wornitems = magr->misc_worn_check;
1004
1005         /* wielded weapon gives same protection as gloves here */
1006         if (otmp != 0)
1007             wornitems |= W_ARMG;
1008
1009         if (protector == 0L
1010             || (protector != ~0L && (wornitems & protector) != protector)) {
1011             if (poly_when_stoned(pa)) {
1012                 mon_to_stone(magr);
1013                 return MM_HIT; /* no damage during the polymorph */
1014             }
1015             if (vis && canspotmon(magr))
1016 /*JP
1017                 pline("%s turns to stone!", Monnam(magr));
1018 */
1019                 pline("%s\82Í\90Î\82É\82È\82Á\82½\81I", Monnam(magr));
1020             monstone(magr);
1021             if (!DEADMONSTER(magr))
1022                 return MM_HIT; /* lifesaved */
1023             else if (magr->mtame && !vis)
1024 /*JP
1025                 You(brief_feeling, "peculiarly sad");
1026 */
1027                 You(brief_feeling, "\82à\82Ì\94ß\82µ\82¢");
1028             return MM_AGR_DIED;
1029         }
1030     }
1031
1032     /* cancellation factor is the same as when attacking the hero */
1033     armpro = magic_negation(mdef);
1034     cancelled = magr->mcan || !(rn2(10) >= 3 * armpro);
1035
1036     switch (mattk->adtyp) {
1037     case AD_DGST:
1038         /* eating a Rider or its corpse is fatal */
1039         if (is_rider(pd)) {
1040             if (vis && canseemon(magr))
1041 #if 0 /*JP:T*/
1042                 pline("%s %s!", Monnam(magr),
1043                       (pd == &mons[PM_FAMINE])
1044                           ? "belches feebly, shrivels up and dies"
1045                           : (pd == &mons[PM_PESTILENCE])
1046                                 ? "coughs spasmodically and collapses"
1047                                 : "vomits violently and drops dead");
1048 #else
1049                 pline("%s%s\81I", Monnam(magr),
1050                       (pd == &mons[PM_FAMINE])
1051                           ? "\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½"
1052                           : (pd == &mons[PM_PESTILENCE])
1053                                 ? "áz\9d¹\82µ\82½\82æ\82¤\82É\82¹\82«\82±\82Ý\93|\82ê\82½"
1054                                 : "\8c\83\82µ\82­\9aq\93f\82µ\8e\80\82ñ\82¾");
1055 #endif
1056             mondied(magr);
1057             if (!DEADMONSTER(magr))
1058                 return 0; /* lifesaved */
1059             else if (magr->mtame && !vis)
1060 /*JP
1061                 You(brief_feeling, "queasy");
1062 */
1063                 You(brief_feeling, "\95s\88À\82È");
1064             return MM_AGR_DIED;
1065         }
1066         if (flags.verbose && !Deaf)
1067 /*JP
1068             verbalize("Burrrrp!");
1069 */
1070             verbalize("\82°\82Á\82Õ\81I");
1071         tmp = mdef->mhp;
1072         /* Use up amulet of life saving */
1073         if (!!(obj = mlifesaver(mdef)))
1074             m_useup(mdef, obj);
1075
1076         /* Is a corpse for nutrition possible?  It may kill magr */
1077         if (!corpse_chance(mdef, magr, TRUE) || DEADMONSTER(magr))
1078             break;
1079
1080         /* Pets get nutrition from swallowing monster whole.
1081          * No nutrition from G_NOCORPSE monster, eg, undead.
1082          * DGST monsters don't die from undead corpses
1083          */
1084         num = monsndx(pd);
1085         if (magr->mtame && !magr->isminion
1086             && !(mvitals[num].mvflags & G_NOCORPSE)) {
1087             struct obj *virtualcorpse = mksobj(CORPSE, FALSE, FALSE);
1088             int nutrit;
1089
1090             set_corpsenm(virtualcorpse, num);
1091             nutrit = dog_nutrition(magr, virtualcorpse);
1092             dealloc_obj(virtualcorpse);
1093
1094             /* only 50% nutrition, 25% of normal eating time */
1095             if (magr->meating > 1)
1096                 magr->meating = (magr->meating + 3) / 4;
1097             if (nutrit > 1)
1098                 nutrit /= 2;
1099             EDOG(magr)->hungrytime += nutrit;
1100         }
1101         break;
1102     case AD_STUN:
1103         if (magr->mcan)
1104             break;
1105         if (canseemon(mdef))
1106 #if 0 /*JP:T*/
1107             pline("%s %s for a moment.", Monnam(mdef),
1108                   makeplural(stagger(pd, "stagger")));
1109 #else
1110             pline("%s\82Í\82·\82±\82µ%s\81D", Monnam(mdef),
1111                   jpast(stagger(pd, "\82æ\82ë\82ß\82­")));
1112 #endif
1113         mdef->mstun = 1;
1114         goto physical;
1115     case AD_LEGS:
1116         if (magr->mcan) {
1117             tmp = 0;
1118             break;
1119         }
1120         goto physical;
1121     case AD_WERE:
1122     case AD_HEAL:
1123     case AD_PHYS:
1124  physical:
1125         obj = (mattk->aatyp == AT_WEAP || mattk->aatyp == AT_CLAW) ? otmp : 0;
1126         if (shade_miss(magr, mdef, obj, FALSE, TRUE)) {
1127             tmp = 0;
1128         } else if (mattk->aatyp == AT_KICK && thick_skinned(pd)) {
1129             tmp = 0;
1130         } else if (mattk->aatyp == AT_WEAP
1131                    || (mattk->aatyp == AT_CLAW && otmp)) {
1132             if (otmp) {
1133                 struct obj *marmg;
1134
1135                 if (otmp->otyp == CORPSE
1136                     && touch_petrifies(&mons[otmp->corpsenm]))
1137                     goto do_stone;
1138
1139                 tmp += dmgval(otmp, mdef);
1140                 if ((marmg = which_armor(magr, W_ARMG)) != 0
1141                     && marmg->otyp == GAUNTLETS_OF_POWER)
1142                     tmp += rn1(4, 3); /* 3..6 */
1143                 if (tmp < 1) /* is this necessary?  mhitu.c has it... */
1144                     tmp = 1;
1145                 if (otmp->oartifact) {
1146                     (void) artifact_hit(magr, mdef, otmp, &tmp, dieroll);
1147                     if (DEADMONSTER(mdef))
1148                         return (MM_DEF_DIED
1149                                 | (grow_up(magr, mdef) ? 0 : MM_AGR_DIED));
1150                 }
1151                 if (tmp)
1152                     rustm(mdef, otmp);
1153             }
1154         } else if (pa == &mons[PM_PURPLE_WORM] && pd == &mons[PM_SHRIEKER]) {
1155             /* hack to enhance mm_aggression(); we don't want purple
1156                worm's bite attack to kill a shrieker because then it
1157                won't swallow the corpse; but if the target survives,
1158                the subsequent engulf attack should accomplish that */
1159             if (tmp >= mdef->mhp && mdef->mhp > 1)
1160                 tmp = mdef->mhp - 1;
1161         }
1162         break;
1163     case AD_FIRE:
1164         if (cancelled) {
1165             tmp = 0;
1166             break;
1167         }
1168         if (vis && canseemon(mdef))
1169 /*JP
1170             pline("%s is %s!", Monnam(mdef), on_fire(pd, mattk));
1171 */
1172             pline("%s\82Í%s\81I", Monnam(mdef), on_fire(pd, mattk));
1173         if (completelyburns(pd)) { /* paper golem or straw golem */
1174             if (vis && canseemon(mdef))
1175 /*JP
1176                 pline("%s burns completely!", Monnam(mdef));
1177 */
1178                 pline("%s\82Í\8aD\82É\82È\82Á\82½\81I", Monnam(mdef));
1179             mondead(mdef); /* was mondied() but that dropped paper scrolls */
1180             if (!DEADMONSTER(mdef))
1181                 return 0;
1182             else if (mdef->mtame && !vis)
1183 /*JP
1184                 pline("May %s roast in peace.", mon_nam(mdef));
1185 */
1186                 pline("%s\82æ\81C\88À\82ç\82©\82É\94R\82¦\82ñ\8e\96\82ð\81D", mon_nam(mdef));
1187             return (MM_DEF_DIED | (grow_up(magr, mdef) ? 0 : MM_AGR_DIED));
1188         }
1189         tmp += destroy_mitem(mdef, SCROLL_CLASS, AD_FIRE);
1190         tmp += destroy_mitem(mdef, SPBOOK_CLASS, AD_FIRE);
1191         if (resists_fire(mdef)) {
1192             if (vis && canseemon(mdef))
1193 /*JP
1194                 pline_The("fire doesn't seem to burn %s!", mon_nam(mdef));
1195 */
1196                 pline("%s\82Í\89\8a\82Å\94R\82¦\82È\82¢\82æ\82¤\82¾\81I", mon_nam(mdef));
1197             shieldeff(mdef->mx, mdef->my);
1198             golemeffects(mdef, AD_FIRE, tmp);
1199             tmp = 0;
1200         }
1201         /* only potions damage resistant players in destroy_item */
1202         tmp += destroy_mitem(mdef, POTION_CLASS, AD_FIRE);
1203         break;
1204     case AD_COLD:
1205         if (cancelled) {
1206             tmp = 0;
1207             break;
1208         }
1209         if (vis && canseemon(mdef))
1210 /*JP
1211             pline("%s is covered in frost!", Monnam(mdef));
1212 */
1213             pline("%s\82Í\95X\82Å\95¢\82í\82ê\82½\81I", Monnam(mdef));
1214         if (resists_cold(mdef)) {
1215             if (vis && canseemon(mdef))
1216 /*JP
1217                 pline_The("frost doesn't seem to chill %s!", mon_nam(mdef));
1218 */
1219                 pline("\95X\82Í%s\82ð\93\80\82ç\82¹\82é\82±\82Æ\82ª\82Å\82«\82È\82¢\82æ\82¤\82¾\81I", mon_nam(mdef));
1220             shieldeff(mdef->mx, mdef->my);
1221             golemeffects(mdef, AD_COLD, tmp);
1222             tmp = 0;
1223         }
1224         tmp += destroy_mitem(mdef, POTION_CLASS, AD_COLD);
1225         break;
1226     case AD_ELEC:
1227         if (cancelled) {
1228             tmp = 0;
1229             break;
1230         }
1231         if (vis && canseemon(mdef))
1232 /*JP
1233             pline("%s gets zapped!", Monnam(mdef));
1234 */
1235             pline("%s\82Í\8fÕ\8c\82\82ð\82­\82ç\82Á\82½\81I", Monnam(mdef));
1236         tmp += destroy_mitem(mdef, WAND_CLASS, AD_ELEC);
1237         if (resists_elec(mdef)) {
1238             if (vis && canseemon(mdef))
1239 /*JP
1240                 pline_The("zap doesn't shock %s!", mon_nam(mdef));
1241 */
1242                 pline("\8fÕ\8c\82\82Í%s\82É\89e\8b¿\82ð\97^\82¦\82È\82¢\81I", mon_nam(mdef));
1243             shieldeff(mdef->mx, mdef->my);
1244             golemeffects(mdef, AD_ELEC, tmp);
1245             tmp = 0;
1246         }
1247         /* only rings damage resistant players in destroy_item */
1248         tmp += destroy_mitem(mdef, RING_CLASS, AD_ELEC);
1249         break;
1250     case AD_ACID:
1251         if (magr->mcan) {
1252             tmp = 0;
1253             break;
1254         }
1255         if (resists_acid(mdef)) {
1256             if (vis && canseemon(mdef))
1257 #if 0 /*JP:T*/
1258                 pline("%s is covered in %s, but it seems harmless.",
1259                       Monnam(mdef), hliquid("acid"));
1260 #else
1261                 pline("%s\82Í%s\82É\82Â\82Â\82Ü\82ê\82½\81D\82µ\82©\82µ\82È\82ñ\82Æ\82à\82È\82¢\82æ\82¤\82¾\81D",
1262                       Monnam(mdef), hliquid("\8e_"));
1263 #endif
1264             tmp = 0;
1265         } else if (vis && canseemon(mdef)) {
1266 /*JP
1267             pline("%s is covered in %s!", Monnam(mdef), hliquid("acid"));
1268 */
1269             pline("%s\82Í%s\82É\82Â\82Â\82Ü\82ê\82½\81I", Monnam(mdef), hliquid("\8e_"));
1270 /*JP
1271             pline("It burns %s!", mon_nam(mdef));
1272 */
1273             pline("%s\82Í\8fÄ\82©\82ê\82½\81I", mon_nam(mdef));
1274         }
1275         if (!rn2(30))
1276             erode_armor(mdef, ERODE_CORRODE);
1277         if (!rn2(6))
1278             acid_damage(MON_WEP(mdef));
1279         break;
1280     case AD_RUST:
1281         if (magr->mcan)
1282             break;
1283         if (pd == &mons[PM_IRON_GOLEM]) {
1284             if (vis && canseemon(mdef))
1285 /*JP
1286                 pline("%s falls to pieces!", Monnam(mdef));
1287 */
1288                 pline("%s\82Í\83o\83\89\83o\83\89\82É\82È\82Á\82½\81I", Monnam(mdef));
1289             mondied(mdef);
1290             if (!DEADMONSTER(mdef))
1291                 return 0;
1292             else if (mdef->mtame && !vis)
1293 /*JP
1294                 pline("May %s rust in peace.", mon_nam(mdef));
1295 */
1296                 pline("%s\82æ\81C\88À\82ç\82©\82É\8eK\82Ñ\82ñ\8e\96\82ð\81D", mon_nam(mdef));
1297             return (MM_DEF_DIED | (grow_up(magr, mdef) ? 0 : MM_AGR_DIED));
1298         }
1299         erode_armor(mdef, ERODE_RUST);
1300         mdef->mstrategy &= ~STRAT_WAITFORU;
1301         tmp = 0;
1302         break;
1303     case AD_CORR:
1304         if (magr->mcan)
1305             break;
1306         erode_armor(mdef, ERODE_CORRODE);
1307         mdef->mstrategy &= ~STRAT_WAITFORU;
1308         tmp = 0;
1309         break;
1310     case AD_DCAY:
1311         if (magr->mcan)
1312             break;
1313         if (pd == &mons[PM_WOOD_GOLEM] || pd == &mons[PM_LEATHER_GOLEM]) {
1314             if (vis && canseemon(mdef))
1315 /*JP
1316                 pline("%s falls to pieces!", Monnam(mdef));
1317 */
1318                 pline("%s\82Í\83o\83\89\83o\83\89\82É\82È\82Á\82½\81I", Monnam(mdef));
1319             mondied(mdef);
1320             if (!DEADMONSTER(mdef))
1321                 return 0;
1322             else if (mdef->mtame && !vis)
1323 /*JP
1324                 pline("May %s rot in peace.", mon_nam(mdef));
1325 */
1326                 pline("%s\82æ\81C\88À\82ç\82©\82É\95\85\82ç\82ñ\8e\96\82ð\81D", mon_nam(mdef));
1327             return (MM_DEF_DIED | (grow_up(magr, mdef) ? 0 : MM_AGR_DIED));
1328         }
1329         erode_armor(mdef, ERODE_CORRODE);
1330         mdef->mstrategy &= ~STRAT_WAITFORU;
1331         tmp = 0;
1332         break;
1333     case AD_STON:
1334         if (magr->mcan)
1335             break;
1336  do_stone:
1337         /* may die from the acid if it eats a stone-curing corpse */
1338         if (munstone(mdef, FALSE))
1339             goto post_stone;
1340         if (poly_when_stoned(pd)) {
1341             mon_to_stone(mdef);
1342             tmp = 0;
1343             break;
1344         }
1345         if (!resists_ston(mdef)) {
1346             if (vis && canseemon(mdef))
1347 /*JP
1348                 pline("%s turns to stone!", Monnam(mdef));
1349 */
1350                 pline("%s\82Í\90Î\82É\82È\82Á\82½\81I", Monnam(mdef));
1351             monstone(mdef);
1352  post_stone:
1353             if (!DEADMONSTER(mdef))
1354                 return 0;
1355             else if (mdef->mtame && !vis)
1356 /*JP
1357                 You(brief_feeling, "peculiarly sad");
1358 */
1359                 You(brief_feeling, "\82à\82Ì\94ß\82µ\82¢");
1360             return (MM_DEF_DIED | (grow_up(magr, mdef) ? 0 : MM_AGR_DIED));
1361         }
1362         tmp = (mattk->adtyp == AD_STON ? 0 : 1);
1363         break;
1364     case AD_TLPT:
1365         if (!cancelled && tmp < mdef->mhp && !tele_restrict(mdef)) {
1366             char mdef_Monnam[BUFSZ];
1367             boolean wasseen = canspotmon(mdef);
1368
1369             /* save the name before monster teleports, otherwise
1370                we'll get "it" in the suddenly disappears message */
1371             if (vis && wasseen)
1372                 Strcpy(mdef_Monnam, Monnam(mdef));
1373             mdef->mstrategy &= ~STRAT_WAITFORU;
1374             (void) rloc(mdef, TRUE);
1375             if (vis && wasseen && !canspotmon(mdef) && mdef != u.usteed)
1376 /*JP
1377                 pline("%s suddenly disappears!", mdef_Monnam);
1378 */
1379                 pline("%s\82Í\93Ë\91R\8fÁ\82¦\82½\81I", mdef_Monnam);
1380             if (tmp >= mdef->mhp) { /* see hitmu(mhitu.c) */
1381                 if (mdef->mhp == 1)
1382                     ++mdef->mhp;
1383                 tmp = mdef->mhp - 1;
1384             }
1385         }
1386         break;
1387     case AD_SLEE:
1388         if (!cancelled && !mdef->msleeping
1389             && sleep_monst(mdef, rnd(10), -1)) {
1390             if (vis && canspotmon(mdef)) {
1391                 Strcpy(buf, Monnam(mdef));
1392 /*JP
1393                 pline("%s is put to sleep by %s.", buf, mon_nam(magr));
1394 */
1395                 pline("%s\82Í%s\82É\82æ\82Á\82Ä\96°\82ç\82³\82ê\82½\81D", buf, mon_nam(magr));
1396             }
1397             mdef->mstrategy &= ~STRAT_WAITFORU;
1398             slept_monst(mdef);
1399         }
1400         break;
1401     case AD_PLYS:
1402         if (!cancelled && mdef->mcanmove) {
1403             if (vis && canspotmon(mdef)) {
1404                 Strcpy(buf, Monnam(mdef));
1405 /*JP
1406                 pline("%s is frozen by %s.", buf, mon_nam(magr));
1407 */
1408                 pline("%s\82Í%s\82É\82æ\82Á\82Ä\93®\82¯\82È\82­\82È\82Á\82½\81D", buf, mon_nam(magr));
1409             }
1410             paralyze_monst(mdef, rnd(10));
1411         }
1412         break;
1413     case AD_SLOW:
1414         if (!cancelled && mdef->mspeed != MSLOW) {
1415             unsigned int oldspeed = mdef->mspeed;
1416
1417             mon_adjust_speed(mdef, -1, (struct obj *) 0);
1418             mdef->mstrategy &= ~STRAT_WAITFORU;
1419             if (mdef->mspeed != oldspeed && vis && canspotmon(mdef))
1420 /*JP
1421                 pline("%s slows down.", Monnam(mdef));
1422 */
1423                 pline("%s\82Í\93®\8dì\82ª\82Ì\82ë\82­\82È\82Á\82½\81D", Monnam(mdef));
1424         }
1425         break;
1426     case AD_CONF:
1427         /* Since confusing another monster doesn't have a real time
1428          * limit, setting spec_used would not really be right (though
1429          * we still should check for it).
1430          */
1431         if (!magr->mcan && !mdef->mconf && !magr->mspec_used) {
1432             if (vis && canseemon(mdef))
1433 /*JP
1434                 pline("%s looks confused.", Monnam(mdef));
1435 */
1436                 pline("%s\82Í\8d¬\97\90\82µ\82Ä\82¢\82é\82æ\82¤\82É\8c©\82¦\82é\81D", Monnam(mdef));
1437             mdef->mconf = 1;
1438             mdef->mstrategy &= ~STRAT_WAITFORU;
1439         }
1440         break;
1441     case AD_BLND:
1442         if (can_blnd(magr, mdef, mattk->aatyp, (struct obj *) 0)) {
1443             register unsigned rnd_tmp;
1444
1445             if (vis && mdef->mcansee && canspotmon(mdef))
1446 /*JP
1447                 pline("%s is blinded.", Monnam(mdef));
1448 */
1449                 pline("%s\82Í\96Ú\82ª\8c©\82¦\82È\82­\82È\82Á\82½\81D", Monnam(mdef));
1450             rnd_tmp = d((int) mattk->damn, (int) mattk->damd);
1451             if ((rnd_tmp += mdef->mblinded) > 127)
1452                 rnd_tmp = 127;
1453             mdef->mblinded = rnd_tmp;
1454             mdef->mcansee = 0;
1455             mdef->mstrategy &= ~STRAT_WAITFORU;
1456         }
1457         tmp = 0;
1458         break;
1459     case AD_HALU:
1460         if (!magr->mcan && haseyes(pd) && mdef->mcansee) {
1461             if (vis && canseemon(mdef))
1462 #if 0 /*JP:T*/
1463                 pline("%s looks %sconfused.", Monnam(mdef),
1464                       mdef->mconf ? "more " : "");
1465 #else
1466                 pline("%s\82Í%s\8d¬\97\90\82µ\82Ä\82¢\82é\82æ\82¤\82É\8c©\82¦\82é\81D", Monnam(mdef),
1467                       mdef->mconf ? "\82Ü\82·\82Ü\82·" : "");
1468 #endif
1469             mdef->mconf = 1;
1470             mdef->mstrategy &= ~STRAT_WAITFORU;
1471         }
1472         tmp = 0;
1473         break;
1474     case AD_CURS:
1475         if (!night() && (pa == &mons[PM_GREMLIN]))
1476             break;
1477         if (!magr->mcan && !rn2(10)) {
1478             mdef->mcan = 1; /* cancelled regardless of lifesave */
1479             mdef->mstrategy &= ~STRAT_WAITFORU;
1480             if (is_were(pd) && pd->mlet != S_HUMAN)
1481                 were_change(mdef);
1482             if (pd == &mons[PM_CLAY_GOLEM]) {
1483                 if (vis && canseemon(mdef)) {
1484 #if 0 /*JP:T*/
1485                     pline("Some writing vanishes from %s head!",
1486                           s_suffix(mon_nam(mdef)));
1487 #else
1488                     pline("\82¢\82­\82Â\82©\82Ì\95\8e\9a\82ª%s\82Ì\93ª\82©\82ç\8fÁ\82¦\82½\81I",
1489                           mon_nam(mdef));
1490 #endif
1491 /*JP
1492                     pline("%s is destroyed!", Monnam(mdef));
1493 */
1494                     pline("%s\82Í\94j\89ó\82³\82ê\82½\81I", Monnam(mdef));
1495                 }
1496                 mondied(mdef);
1497                 if (!DEADMONSTER(mdef))
1498                     return 0;
1499                 else if (mdef->mtame && !vis)
1500 /*JP
1501                     You(brief_feeling, "strangely sad");
1502 */
1503                     You(brief_feeling, "\96­\82É\94ß\82µ\82¢");
1504                 return (MM_DEF_DIED
1505                         | (grow_up(magr, mdef) ? 0 : MM_AGR_DIED));
1506             }
1507             if (!Deaf) {
1508                 if (!vis)
1509 /*JP
1510                     You_hear("laughter.");
1511 */
1512                     You_hear("\8fÎ\82¢\90º\82ð\95·\82¢\82½\81D");
1513                 else if (canseemon(magr))
1514 /*JP
1515                     pline("%s chuckles.", Monnam(magr));
1516 */
1517                     pline("%s\82Í\82­\82·\82­\82·\8fÎ\82Á\82½\81D", Monnam(magr));
1518             }
1519         }
1520         break;
1521     case AD_SGLD:
1522         tmp = 0;
1523         if (magr->mcan)
1524             break;
1525         /* technically incorrect; no check for stealing gold from
1526          * between mdef's feet...
1527          */
1528         {
1529             struct obj *gold = findgold(mdef->minvent);
1530
1531             if (!gold)
1532                 break;
1533             obj_extract_self(gold);
1534             add_to_minv(magr, gold);
1535         }
1536         mdef->mstrategy &= ~STRAT_WAITFORU;
1537         if (vis && canseemon(mdef)) {
1538             Strcpy(buf, Monnam(magr));
1539 /*JP
1540             pline("%s steals some gold from %s.", buf, mon_nam(mdef));
1541 */
1542             pline("%s\82Í%s\82©\82ç\8bà\82ð\93\90\82ñ\82¾\81D", buf, mon_nam(mdef));
1543         }
1544         if (!tele_restrict(magr)) {
1545             boolean couldspot = canspotmon(magr);
1546             (void) rloc(magr, TRUE);
1547             if (vis && couldspot && !canspotmon(magr))
1548 /*JP
1549                 pline("%s suddenly disappears!", buf);
1550 */
1551                 pline("%s\82Í\93Ë\91R\8fÁ\82¦\82½\81I", buf);
1552         }
1553         break;
1554     case AD_DRLI:
1555         if (!cancelled && !rn2(3) && !resists_drli(mdef)) {
1556             tmp = d(2, 6);
1557             if (vis && canspotmon(mdef))
1558 /*JP
1559                 pline("%s suddenly seems weaker!", Monnam(mdef));
1560 */
1561                 pline("%s\82Í\93Ë\91R\8eã\82­\82È\82Á\82½\82æ\82¤\82É\8c©\82¦\82½\81I", Monnam(mdef));
1562             mdef->mhpmax -= tmp;
1563             if (mdef->m_lev == 0)
1564                 tmp = mdef->mhp;
1565             else
1566                 mdef->m_lev--;
1567             /* Automatic kill if drained past level 0 */
1568         }
1569         break;
1570     case AD_SSEX:
1571     case AD_SITM: /* for now these are the same */
1572     case AD_SEDU:
1573         if (magr->mcan)
1574             break;
1575         /* find an object to steal, non-cursed if magr is tame */
1576         for (obj = mdef->minvent; obj; obj = obj->nobj)
1577             if (!magr->mtame || !obj->cursed)
1578                 break;
1579
1580         if (obj) {
1581             char onambuf[BUFSZ], mdefnambuf[BUFSZ];
1582
1583             /* make a special x_monnam() call that never omits
1584                the saddle, and save it for later messages */
1585             Strcpy(mdefnambuf,
1586                    x_monnam(mdef, ARTICLE_THE, (char *) 0, 0, FALSE));
1587
1588             otmp = obj;
1589             if (u.usteed == mdef && otmp == which_armor(mdef, W_SADDLE))
1590                 /* "You can no longer ride <steed>." */
1591                 dismount_steed(DISMOUNT_POLY);
1592             obj_extract_self(otmp);
1593             if (otmp->owornmask) {
1594                 mdef->misc_worn_check &= ~otmp->owornmask;
1595                 if (otmp->owornmask & W_WEP)
1596                     mwepgone(mdef);
1597                 otmp->owornmask = 0L;
1598                 update_mon_intrinsics(mdef, otmp, FALSE, FALSE);
1599                 /* give monster a chance to wear other equipment on its next
1600                    move instead of waiting until it picks something up */
1601                 mdef->misc_worn_check |= I_SPECIAL;
1602             }
1603             /* add_to_minv() might free otmp [if it merges] */
1604             if (vis)
1605                 Strcpy(onambuf, doname(otmp));
1606             (void) add_to_minv(magr, otmp);
1607             if (vis && canseemon(mdef)) {
1608                 Strcpy(buf, Monnam(magr));
1609 /*JP
1610                 pline("%s steals %s from %s!", buf, onambuf, mdefnambuf);
1611 */
1612                 pline("%s\82Í%s\82©\82ç%s\82ð\93\90\82ñ\82¾\81I", buf, mdefnambuf, onambuf);
1613             }
1614             possibly_unwield(mdef, FALSE);
1615             mdef->mstrategy &= ~STRAT_WAITFORU;
1616             mselftouch(mdef, (const char *) 0, FALSE);
1617             if (DEADMONSTER(mdef))
1618                 return (MM_DEF_DIED
1619                         | (grow_up(magr, mdef) ? 0 : MM_AGR_DIED));
1620             if (pa->mlet == S_NYMPH && !tele_restrict(magr)) {
1621                 boolean couldspot = canspotmon(magr);
1622
1623                 (void) rloc(magr, TRUE);
1624                 if (vis && couldspot && !canspotmon(magr))
1625 /*JP
1626                     pline("%s suddenly disappears!", buf);
1627 */
1628                     pline("%s\82Í\93Ë\91R\8fÁ\82¦\82½\81I", buf);
1629             }
1630         }
1631         tmp = 0;
1632         break;
1633     case AD_DREN:
1634         if (!cancelled && !rn2(4))
1635             xdrainenergym(mdef, (boolean) (vis && canspotmon(mdef)
1636                                            && mattk->aatyp != AT_ENGL));
1637         tmp = 0;
1638         break;
1639     case AD_DRST:
1640     case AD_DRDX:
1641     case AD_DRCO:
1642         if (!cancelled && !rn2(8)) {
1643             if (vis && canspotmon(magr))
1644 #if 0 /*JP:T*/
1645                 pline("%s %s was poisoned!", s_suffix(Monnam(magr)),
1646                       mpoisons_subj(magr, mattk));
1647 #else
1648                 pline("%s\82Ì%s\82Í\93Å\82³\82ê\82Ä\82¢\82é\81I", Monnam(magr),
1649                       mpoisons_subj(magr, mattk));
1650 #endif
1651             if (resists_poison(mdef)) {
1652                 if (vis && canspotmon(mdef) && canspotmon(magr))
1653 /*JP
1654                     pline_The("poison doesn't seem to affect %s.",
1655 */
1656                     pline("%s\82Í\93Å\82Ì\89e\8b¿\82ð\8eó\82¯\82È\82¢\81D",
1657                               mon_nam(mdef));
1658             } else {
1659                 if (rn2(10))
1660                     tmp += rn1(10, 6);
1661                 else {
1662                     if (vis && canspotmon(mdef))
1663 /*JP
1664                         pline_The("poison was deadly...");
1665 */
1666                         pline("\93Å\82Í\92v\8e\80\97Ê\82¾\82Á\82½\81D\81D\81D");
1667                     tmp = mdef->mhp;
1668                 }
1669             }
1670         }
1671         break;
1672     case AD_DRIN:
1673         if (notonhead || !has_head(pd)) {
1674             if (vis && canspotmon(mdef))
1675 /*JP
1676                 pline("%s doesn't seem harmed.", Monnam(mdef));
1677 */
1678                 pline("%s\82Í\8f\9d\82Â\82¢\82½\82æ\82¤\82É\82Í\8c©\82¦\82È\82¢\81D", Monnam(mdef));
1679             /* Not clear what to do for green slimes */
1680             tmp = 0;
1681             break;
1682         }
1683         if ((mdef->misc_worn_check & W_ARMH) && rn2(8)) {
1684             if (vis && canspotmon(magr) && canseemon(mdef)) {
1685                 Strcpy(buf, s_suffix(Monnam(mdef)));
1686 #if 0 /*JP:T*/
1687                 pline("%s helmet blocks %s attack to %s head.", buf,
1688                       s_suffix(mon_nam(magr)), mhis(mdef));
1689 #else
1690                 pline("%s\82Ì\8a\95\82Í%s\82Ì\93ª\82Ö\82Ì\8dU\8c\82\82ð\96h\82¢\82¾\81D", buf,
1691                       mon_nam(magr));
1692 #endif
1693             }
1694             break;
1695         }
1696         res = eat_brains(magr, mdef, vis, &tmp);
1697         break;
1698     case AD_SLIM:
1699         if (cancelled)
1700             break; /* physical damage only */
1701         if (!rn2(4) && !slimeproof(pd)) {
1702             if (!munslime(mdef, FALSE) && !DEADMONSTER(mdef)) {
1703                 if (newcham(mdef, &mons[PM_GREEN_SLIME], FALSE,
1704                             (boolean) (vis && canseemon(mdef))))
1705                     pd = mdef->data;
1706                 mdef->mstrategy &= ~STRAT_WAITFORU;
1707                 res = MM_HIT;
1708             }
1709             /* munslime attempt could have been fatal,
1710                potentially to multiple monsters (SCR_FIRE) */
1711             if (DEADMONSTER(magr))
1712                 res |= MM_AGR_DIED;
1713             if (DEADMONSTER(mdef))
1714                 res |= MM_DEF_DIED;
1715             tmp = 0;
1716         }
1717         break;
1718     case AD_STCK:
1719         if (cancelled)
1720             tmp = 0;
1721         break;
1722     case AD_WRAP: /* monsters cannot grab one another, it's too hard */
1723         if (magr->mcan)
1724             tmp = 0;
1725         break;
1726     case AD_ENCH:
1727         /* there's no msomearmor() function, so just do damage */
1728         /* if (cancelled) break; */
1729         break;
1730     default:
1731         tmp = 0;
1732         break;
1733     }
1734     if (!tmp)
1735         return res;
1736
1737     if ((mdef->mhp -= tmp) < 1) {
1738         if (m_at(mdef->mx, mdef->my) == magr) { /* see gulpmm() */
1739             remove_monster(mdef->mx, mdef->my);
1740             mdef->mhp = 1; /* otherwise place_monster will complain */
1741             place_monster(mdef, mdef->mx, mdef->my);
1742             mdef->mhp = 0;
1743         }
1744         monkilled(mdef, "", (int) mattk->adtyp);
1745         if (!DEADMONSTER(mdef))
1746             return res; /* mdef lifesaved */
1747         else if (res == MM_AGR_DIED)
1748             return (MM_DEF_DIED | MM_AGR_DIED);
1749
1750         if (mattk->adtyp == AD_DGST) {
1751             /* various checks similar to dog_eat and meatobj.
1752              * after monkilled() to provide better message ordering */
1753             if (mdef->cham >= LOW_PM) {
1754                 (void) newcham(magr, (struct permonst *) 0, FALSE, TRUE);
1755             } else if (pd == &mons[PM_GREEN_SLIME] && !slimeproof(pa)) {
1756                 (void) newcham(magr, &mons[PM_GREEN_SLIME], FALSE, TRUE);
1757             } else if (pd == &mons[PM_WRAITH]) {
1758                 (void) grow_up(magr, (struct monst *) 0);
1759                 /* don't grow up twice */
1760                 return (MM_DEF_DIED | (!DEADMONSTER(magr) ? 0 : MM_AGR_DIED));
1761             } else if (pd == &mons[PM_NURSE]) {
1762                 magr->mhp = magr->mhpmax;
1763             }
1764         }
1765         /* caveat: above digestion handling doesn't keep `pa' up to date */
1766
1767         return (MM_DEF_DIED | (grow_up(magr, mdef) ? 0 : MM_AGR_DIED));
1768     }
1769     return (res == MM_AGR_DIED) ? MM_AGR_DIED : MM_HIT;
1770 }
1771
1772 void
1773 paralyze_monst(mon, amt)
1774 struct monst *mon;
1775 int amt;
1776 {
1777     if (amt > 127)
1778         amt = 127;
1779
1780     mon->mcanmove = 0;
1781     mon->mfrozen = amt;
1782     mon->meating = 0; /* terminate any meal-in-progress */
1783     mon->mstrategy &= ~STRAT_WAITFORU;
1784 }
1785
1786 /* `mon' is hit by a sleep attack; return 1 if it's affected, 0 otherwise */
1787 int
1788 sleep_monst(mon, amt, how)
1789 struct monst *mon;
1790 int amt, how;
1791 {
1792     if (resists_sleep(mon)
1793         || (how >= 0 && resist(mon, (char) how, 0, NOTELL))) {
1794         shieldeff(mon->mx, mon->my);
1795     } else if (mon->mcanmove) {
1796         finish_meating(mon); /* terminate any meal-in-progress */
1797         amt += (int) mon->mfrozen;
1798         if (amt > 0) { /* sleep for N turns */
1799             mon->mcanmove = 0;
1800             mon->mfrozen = min(amt, 127);
1801         } else { /* sleep until awakened */
1802             mon->msleeping = 1;
1803         }
1804         return 1;
1805     }
1806     return 0;
1807 }
1808
1809 /* sleeping grabber releases, engulfer doesn't; don't use for paralysis! */
1810 void
1811 slept_monst(mon)
1812 struct monst *mon;
1813 {
1814     if ((mon->msleeping || !mon->mcanmove) && mon == u.ustuck
1815         && !sticks(youmonst.data) && !u.uswallow) {
1816 /*JP
1817         pline("%s grip relaxes.", s_suffix(Monnam(mon)));
1818 */
1819         pline("%s\82Ì\88¬\82é\97Í\82ª\8eã\82­\82È\82Á\82½\81D", Monnam(mon));
1820         unstuck(mon);
1821     }
1822 }
1823
1824 void
1825 rustm(mdef, obj)
1826 struct monst *mdef;
1827 struct obj *obj;
1828 {
1829     int dmgtyp = -1, chance = 1;
1830
1831     if (!mdef || !obj)
1832         return; /* just in case */
1833     /* AD_ACID and AD_ENCH are handled in passivemm() and passiveum() */
1834     if (dmgtype(mdef->data, AD_CORR)) {
1835         dmgtyp = ERODE_CORRODE;
1836     } else if (dmgtype(mdef->data, AD_RUST)) {
1837         dmgtyp = ERODE_RUST;
1838     } else if (dmgtype(mdef->data, AD_FIRE)
1839                /* steam vortex: fire resist applies, fire damage doesn't */
1840                && mdef->data != &mons[PM_STEAM_VORTEX]) {
1841         dmgtyp = ERODE_BURN;
1842         chance = 6;
1843     }
1844
1845     if (dmgtyp >= 0 && !rn2(chance))
1846         (void) erode_obj(obj, (char *) 0, dmgtyp, EF_GREASE | EF_VERBOSE);
1847 }
1848
1849 STATIC_OVL void
1850 mswingsm(magr, mdef, otemp)
1851 struct monst *magr, *mdef;
1852 struct obj *otemp;
1853 {
1854     if (flags.verbose && !Blind && mon_visible(magr)) {
1855 #if 0 /*JP*/
1856         pline("%s %s %s%s %s at %s.", Monnam(magr),
1857               (objects[otemp->otyp].oc_dir & PIERCE) ? "thrusts" : "swings",
1858               (otemp->quan > 1L) ? "one of " : "", mhis(magr), xname(otemp),
1859               mon_nam(mdef));
1860 #else
1861         pline((objects[otemp->otyp].oc_dir & PIERCE) ?
1862               "%s\82Í%s\82Å%s\82ð\93Ë\82¢\82½\81D" :
1863               "%s\82Í%s\82ð\90U\82è\82Ü\82í\82µ%s\82ð\8dU\8c\82\82µ\82½\81D", Monnam(magr),
1864               xname(otemp), mon_nam(mdef));
1865 #endif
1866     }
1867 }
1868
1869 /*
1870  * Passive responses by defenders.  Does not replicate responses already
1871  * handled above.  Returns same values as mattackm.
1872  */
1873 STATIC_OVL int
1874 passivemm(magr, mdef, mhit, mdead)
1875 register struct monst *magr, *mdef;
1876 boolean mhit;
1877 int mdead;
1878 {
1879     register struct permonst *mddat = mdef->data;
1880     register struct permonst *madat = magr->data;
1881     char buf[BUFSZ];
1882     int i, tmp;
1883
1884     for (i = 0;; i++) {
1885         if (i >= NATTK)
1886             return (mdead | mhit); /* no passive attacks */
1887         if (mddat->mattk[i].aatyp == AT_NONE)
1888             break;
1889     }
1890     if (mddat->mattk[i].damn)
1891         tmp = d((int) mddat->mattk[i].damn, (int) mddat->mattk[i].damd);
1892     else if (mddat->mattk[i].damd)
1893         tmp = d((int) mddat->mlevel + 1, (int) mddat->mattk[i].damd);
1894     else
1895         tmp = 0;
1896
1897     /* These affect the enemy even if defender killed */
1898     switch (mddat->mattk[i].adtyp) {
1899     case AD_ACID:
1900         if (mhit && !rn2(2)) {
1901             Strcpy(buf, Monnam(magr));
1902             if (canseemon(magr))
1903 #if 0 /*JP:T*/
1904                 pline("%s is splashed by %s %s!", buf,
1905                       s_suffix(mon_nam(mdef)), hliquid("acid"));
1906 #else
1907                 pline("%s\82Í%s\82Ì%s\82ð\97\81\82Ñ\82½\81I", buf,
1908                       mon_nam(mdef), hliquid("\8e_"));
1909 #endif
1910             if (resists_acid(magr)) {
1911                 if (canseemon(magr))
1912 /*JP
1913                     pline("%s is not affected.", Monnam(magr));
1914 */
1915                     pline("%s\82Í\89e\8b¿\82ð\8eó\82¯\82È\82¢\81D", Monnam(magr));
1916                 tmp = 0;
1917             }
1918         } else
1919             tmp = 0;
1920         if (!rn2(30))
1921             erode_armor(magr, ERODE_CORRODE);
1922         if (!rn2(6))
1923             acid_damage(MON_WEP(magr));
1924         goto assess_dmg;
1925     case AD_ENCH: /* KMH -- remove enchantment (disenchanter) */
1926         if (mhit && !mdef->mcan && otmp) {
1927             (void) drain_item(otmp, FALSE);
1928             /* No message */
1929         }
1930         break;
1931     default:
1932         break;
1933     }
1934     if (mdead || mdef->mcan)
1935         return (mdead | mhit);
1936
1937     /* These affect the enemy only if defender is still alive */
1938     if (rn2(3))
1939         switch (mddat->mattk[i].adtyp) {
1940         case AD_PLYS: /* Floating eye */
1941             if (tmp > 127)
1942                 tmp = 127;
1943             if (mddat == &mons[PM_FLOATING_EYE]) {
1944                 if (!rn2(4))
1945                     tmp = 127;
1946                 if (magr->mcansee && haseyes(madat) && mdef->mcansee
1947                     && (perceives(madat) || !mdef->minvis)) {
1948                     /* construct format string; guard against '%' in Monnam */
1949 #if 0 /*JP*/
1950                     Strcpy(buf, s_suffix(Monnam(mdef)));
1951 #else
1952                     Strcpy(buf, Monnam(mdef));
1953 #endif
1954                     (void) strNsubst(buf, "%", "%%", 0);
1955 /*JP
1956                     Strcat(buf, " gaze is reflected by %s %s.");
1957 */
1958                     Strcat(buf, "\82Ì\82É\82ç\82Ý\82Í%s\82É\82æ\82Á\82Ä%s\81D");
1959                     if (mon_reflects(magr,
1960                                      canseemon(magr) ? buf : (char *) 0))
1961                         return (mdead | mhit);
1962                     Strcpy(buf, Monnam(magr));
1963                     if (canseemon(magr))
1964 #if 0 /*JP:T*/
1965                         pline("%s is frozen by %s gaze!", buf,
1966                               s_suffix(mon_nam(mdef)));
1967 #else
1968                         pline("%s\82Í%s\82Ì\82É\82ç\82Ý\82Å\93®\82¯\82È\82­\82È\82Á\82½\81I", buf,
1969                               mon_nam(mdef));
1970 #endif
1971                     paralyze_monst(magr, tmp);
1972                     return (mdead | mhit);
1973                 }
1974             } else { /* gelatinous cube */
1975                 Strcpy(buf, Monnam(magr));
1976                 if (canseemon(magr))
1977 /*JP
1978                     pline("%s is frozen by %s.", buf, mon_nam(mdef));
1979 */
1980                     pline("%s\82Í%s\82É\82æ\82Á\82Ä\93®\82¯\82È\82­\82È\82Á\82½\81D", buf, mon_nam(mdef));
1981                 paralyze_monst(magr, tmp);
1982                 return (mdead | mhit);
1983             }
1984             return 1;
1985         case AD_COLD:
1986             if (resists_cold(magr)) {
1987                 if (canseemon(magr)) {
1988 /*JP
1989                     pline("%s is mildly chilly.", Monnam(magr));
1990 */
1991                     pline("%s\82Í\97â\82¦\82½\81D", Monnam(magr));
1992                     golemeffects(magr, AD_COLD, tmp);
1993                 }
1994                 tmp = 0;
1995                 break;
1996             }
1997             if (canseemon(magr))
1998 /*JP
1999                 pline("%s is suddenly very cold!", Monnam(magr));
2000 */
2001                 pline("%s\82Í\93Ë\91R\93\80\82è\82Ã\82¯\82É\82È\82Á\82½\81I", Monnam(magr));
2002             mdef->mhp += tmp / 2;
2003             if (mdef->mhpmax < mdef->mhp)
2004                 mdef->mhpmax = mdef->mhp;
2005             if (mdef->mhpmax > ((int) (mdef->m_lev + 1) * 8))
2006                 (void) split_mon(mdef, magr);
2007             break;
2008         case AD_STUN:
2009             if (!magr->mstun) {
2010                 magr->mstun = 1;
2011                 if (canseemon(magr))
2012 #if 0 /*JP:T*/
2013                     pline("%s %s...", Monnam(magr),
2014                           makeplural(stagger(magr->data, "stagger")));
2015 #else
2016                     pline("%s\82Í%s\81D\81D\81D", Monnam(magr),
2017                           jpast(stagger(magr->data, "\82æ\82ë\82ß\82­")));
2018 #endif
2019             }
2020             tmp = 0;
2021             break;
2022         case AD_FIRE:
2023             if (resists_fire(magr)) {
2024                 if (canseemon(magr)) {
2025 /*JP
2026                     pline("%s is mildly warmed.", Monnam(magr));
2027 */
2028                     pline("%s\82Í\92g\82©\82­\82È\82Á\82½\81D", Monnam(magr));
2029                     golemeffects(magr, AD_FIRE, tmp);
2030                 }
2031                 tmp = 0;
2032                 break;
2033             }
2034             if (canseemon(magr))
2035 /*JP
2036                 pline("%s is suddenly very hot!", Monnam(magr));
2037 */
2038                 pline("%s\82Í\93Ë\91R\82Æ\82Ä\82à\94M\82­\82È\82Á\82½\81I", Monnam(magr));
2039             break;
2040         case AD_ELEC:
2041             if (resists_elec(magr)) {
2042                 if (canseemon(magr)) {
2043 /*JP
2044                     pline("%s is mildly tingled.", Monnam(magr));
2045 */
2046                     pline("%s\82Í\83s\83\8a\83s\83\8a\82µ\82Ä\82¢\82é\81D", Monnam(magr));
2047                     golemeffects(magr, AD_ELEC, tmp);
2048                 }
2049                 tmp = 0;
2050                 break;
2051             }
2052             if (canseemon(magr))
2053 /*JP
2054                 pline("%s is jolted with electricity!", Monnam(magr));
2055 */
2056                 pline("%s\82Í\93d\8bC\83V\83\87\83b\83N\82ð\82¤\82¯\82½\81I", Monnam(magr));
2057             break;
2058         default:
2059             tmp = 0;
2060             break;
2061         }
2062     else
2063         tmp = 0;
2064
2065  assess_dmg:
2066     if ((magr->mhp -= tmp) <= 0) {
2067         monkilled(magr, "", (int) mddat->mattk[i].adtyp);
2068         return (mdead | mhit | MM_AGR_DIED);
2069     }
2070     return (mdead | mhit);
2071 }
2072
2073 /* hero or monster has successfully hit target mon with drain energy attack */
2074 void
2075 xdrainenergym(mon, givemsg)
2076 struct monst *mon;
2077 boolean givemsg;
2078 {
2079     if (mon->mspec_used < 20 /* limit draining */
2080         && (attacktype(mon->data, AT_MAGC)
2081             || attacktype(mon->data, AT_BREA))) {
2082         mon->mspec_used += d(2, 2);
2083         if (givemsg)
2084 /*JP
2085             pline("%s seems lethargic.", Monnam(mon));
2086 */
2087             pline("%s\82Í\96³\8bC\97Í\82É\82È\82Á\82½\82æ\82¤\82¾\81D", Monnam(mon));
2088     }
2089 }
2090
2091 /* "aggressive defense"; what type of armor prevents specified attack
2092    from touching its target? */
2093 long
2094 attk_protection(aatyp)
2095 int aatyp;
2096 {
2097     long w_mask = 0L;
2098
2099     switch (aatyp) {
2100     case AT_NONE:
2101     case AT_SPIT:
2102     case AT_EXPL:
2103     case AT_BOOM:
2104     case AT_GAZE:
2105     case AT_BREA:
2106     case AT_MAGC:
2107         w_mask = ~0L; /* special case; no defense needed */
2108         break;
2109     case AT_CLAW:
2110     case AT_TUCH:
2111     case AT_WEAP:
2112         w_mask = W_ARMG; /* caller needs to check for weapon */
2113         break;
2114     case AT_KICK:
2115         w_mask = W_ARMF;
2116         break;
2117     case AT_BUTT:
2118         w_mask = W_ARMH;
2119         break;
2120     case AT_HUGS:
2121         w_mask = (W_ARMC | W_ARMG); /* attacker needs both to be protected */
2122         break;
2123     case AT_BITE:
2124     case AT_STNG:
2125     case AT_ENGL:
2126     case AT_TENT:
2127     default:
2128         w_mask = 0L; /* no defense available */
2129         break;
2130     }
2131     return w_mask;
2132 }
2133
2134 /*mhitm.c*/