OSDN Git Service

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