OSDN Git Service

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