OSDN Git Service

add translation
[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 #if 0 /*JP*/
822             pline("%s expels %s.", Monnam(magr),
823                   canspotmon(mdef) ? "it" : something);
824 #else
825             pline("%s\82Í%s\82ð\93f\82«\8fo\82µ\82½\81D", Monnam(magr),
826                   canspotmon(mdef) ? "\89½\82©" : something);
827 #endif
828             if (canspotmon(mdef))
829 /*JP
830                 pline("It turns into %s.", a_monnam(mdef));
831 */
832                 pline("\82»\82ê\82Í%s\82É\82È\82Á\82½\81D", a_monnam(mdef));
833         }
834         return MM_HIT; /* bypass mdamagem() */
835     }
836
837     /*
838      *  All of this manipulation is needed to keep the display correct.
839      *  There is a flush at the next pline().
840      */
841     ax = magr->mx;
842     ay = magr->my;
843     dx = mdef->mx;
844     dy = mdef->my;
845     /*
846      *  Leave the defender in the monster chain at it's current position,
847      *  but don't leave it on the screen.  Move the aggressor to the
848      *  defender's position.
849      */
850     remove_monster(ax, ay);
851     place_monster(magr, dx, dy);
852     newsym(ax, ay); /* erase old position */
853     newsym(dx, dy); /* update new position */
854
855     status = mdamagem(magr, mdef, mattk);
856
857     if ((status & (MM_AGR_DIED | MM_DEF_DIED))
858         == (MM_AGR_DIED | MM_DEF_DIED)) {
859         ;                              /* both died -- do nothing  */
860     } else if (status & MM_DEF_DIED) { /* defender died */
861         /*
862          *  Note:  remove_monster() was called in relmon(), wiping out
863          *  magr from level.monsters[mdef->mx][mdef->my].  We need to
864          *  put it back and display it.  -kd
865          */
866         place_monster(magr, dx, dy);
867         newsym(dx, dy);
868         /* aggressor moves to <dx,dy> and might encounter trouble there */
869         if (minliquid(magr) || (t_at(dx, dy) && mintrap(magr) == 2))
870             status |= MM_AGR_DIED;
871     } else if (status & MM_AGR_DIED) { /* aggressor died */
872         place_monster(mdef, dx, dy);
873         newsym(dx, dy);
874     } else {                           /* both alive, put them back */
875         if (cansee(dx, dy))
876 /*JP
877             pline("%s is regurgitated!", Monnam(mdef));
878 */
879             pline("%s\82Í\93f\82«\96ß\82³\82ê\82½\81I", Monnam(mdef));
880
881         remove_monster(dx,dy);
882         place_monster(magr, ax, ay);
883         place_monster(mdef, dx, dy);
884         newsym(ax, ay);
885         newsym(dx, dy);
886     }
887
888     return status;
889 }
890
891 STATIC_OVL int
892 explmm(magr, mdef, mattk)
893 struct monst *magr, *mdef;
894 struct attack *mattk;
895 {
896     int result;
897
898     if (magr->mcan)
899         return MM_MISS;
900
901     if (cansee(magr->mx, magr->my))
902 /*JP
903         pline("%s explodes!", Monnam(magr));
904 */
905         pline("%s\82Í\94\9a\94­\82µ\82½\81I", Monnam(magr));
906     else
907         noises(magr, mattk);
908
909     result = mdamagem(magr, mdef, mattk);
910
911     /* Kill off aggressor if it didn't die. */
912     if (!(result & MM_AGR_DIED)) {
913         mondead(magr);
914         if (magr->mhp > 0)
915             return result; /* life saved */
916         result |= MM_AGR_DIED;
917     }
918     if (magr->mtame) /* give this one even if it was visible */
919 /*JP
920         You(brief_feeling, "melancholy");
921 */
922         You(brief_feeling, "\97J\82¤\82Â\82È");
923
924     return result;
925 }
926
927 /*
928  *  See comment at top of mattackm(), for return values.
929  */
930 STATIC_OVL int
931 mdamagem(magr, mdef, mattk)
932 register struct monst *magr, *mdef;
933 register struct attack *mattk;
934 {
935     struct obj *obj;
936     char buf[BUFSZ];
937     struct permonst *pa = magr->data, *pd = mdef->data;
938     int armpro, num, tmp = d((int) mattk->damn, (int) mattk->damd),
939                      res = MM_MISS;
940     boolean cancelled;
941
942     if ((touch_petrifies(pd) /* or flesh_petrifies() */
943          || (mattk->adtyp == AD_DGST && pd == &mons[PM_MEDUSA]))
944         && !resists_ston(magr)) {
945         long protector = attk_protection((int) mattk->aatyp),
946              wornitems = magr->misc_worn_check;
947
948         /* wielded weapon gives same protection as gloves here */
949         if (otmp != 0)
950             wornitems |= W_ARMG;
951
952         if (protector == 0L
953             || (protector != ~0L && (wornitems & protector) != protector)) {
954             if (poly_when_stoned(pa)) {
955                 mon_to_stone(magr);
956                 return MM_HIT; /* no damage during the polymorph */
957             }
958             if (vis && canspotmon(magr))
959 /*JP
960                 pline("%s turns to stone!", Monnam(magr));
961 */
962                 pline("%s\82Í\90Î\82É\82È\82Á\82½\81I", Monnam(magr));
963             monstone(magr);
964             if (magr->mhp > 0)
965                 return MM_HIT; /* lifesaved */
966             else if (magr->mtame && !vis)
967 /*JP
968                 You(brief_feeling, "peculiarly sad");
969 */
970                 You(brief_feeling, "\82à\82Ì\94ß\82µ\82¢");
971             return MM_AGR_DIED;
972         }
973     }
974
975     /* cancellation factor is the same as when attacking the hero */
976     armpro = magic_negation(mdef);
977     cancelled = magr->mcan || !(rn2(10) >= 3 * armpro);
978
979     switch (mattk->adtyp) {
980     case AD_DGST:
981         /* eating a Rider or its corpse is fatal */
982         if (is_rider(pd)) {
983             if (vis && canseemon(magr))
984 #if 0 /*JP:T*/
985                 pline("%s %s!", Monnam(magr),
986                       (pd == &mons[PM_FAMINE])
987                           ? "belches feebly, shrivels up and dies"
988                           : (pd == &mons[PM_PESTILENCE])
989                                 ? "coughs spasmodically and collapses"
990                                 : "vomits violently and drops dead");
991 #else
992                 pline("%s%s\81I", Monnam(magr),
993                       (pd == &mons[PM_FAMINE])
994                           ? "\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½"
995                           : (pd == &mons[PM_PESTILENCE])
996                                 ? "áz\9d¹\82µ\82½\82æ\82¤\82É\82¹\82«\82±\82Ý\93|\82ê\82½"
997                                 : "\8c\83\82µ\82­\9aq\93f\82µ\8e\80\82ñ\82¾");
998 #endif
999             mondied(magr);
1000             if (magr->mhp > 0)
1001                 return 0; /* lifesaved */
1002             else if (magr->mtame && !vis)
1003 /*JP
1004                 You(brief_feeling, "queasy");
1005 */
1006                 You(brief_feeling, "\95s\88À\82È");
1007             return MM_AGR_DIED;
1008         }
1009         if (flags.verbose && !Deaf)
1010 /*JP
1011             verbalize("Burrrrp!");
1012 */
1013             verbalize("\82°\82Á\82Õ\81I");
1014         tmp = mdef->mhp;
1015         /* Use up amulet of life saving */
1016         if (!!(obj = mlifesaver(mdef)))
1017             m_useup(mdef, obj);
1018
1019         /* Is a corpse for nutrition possible?  It may kill magr */
1020         if (!corpse_chance(mdef, magr, TRUE) || magr->mhp < 1)
1021             break;
1022
1023         /* Pets get nutrition from swallowing monster whole.
1024          * No nutrition from G_NOCORPSE monster, eg, undead.
1025          * DGST monsters don't die from undead corpses
1026          */
1027         num = monsndx(pd);
1028         if (magr->mtame && !magr->isminion
1029             && !(mvitals[num].mvflags & G_NOCORPSE)) {
1030             struct obj *virtualcorpse = mksobj(CORPSE, FALSE, FALSE);
1031             int nutrit;
1032
1033             set_corpsenm(virtualcorpse, num);
1034             nutrit = dog_nutrition(magr, virtualcorpse);
1035             dealloc_obj(virtualcorpse);
1036
1037             /* only 50% nutrition, 25% of normal eating time */
1038             if (magr->meating > 1)
1039                 magr->meating = (magr->meating + 3) / 4;
1040             if (nutrit > 1)
1041                 nutrit /= 2;
1042             EDOG(magr)->hungrytime += nutrit;
1043         }
1044         break;
1045     case AD_STUN:
1046         if (magr->mcan)
1047             break;
1048         if (canseemon(mdef))
1049 #if 0 /*JP*/
1050             pline("%s %s for a moment.", Monnam(mdef),
1051                   makeplural(stagger(pd, "stagger")));
1052 #else
1053             pline("%s\82Í\82·\82±\82µ%s\81D", Monnam(mdef),
1054                   jpast(stagger(pd, "\82æ\82ë\82ß\82­")));
1055 #endif
1056         mdef->mstun = 1;
1057         goto physical;
1058     case AD_LEGS:
1059         if (magr->mcan) {
1060             tmp = 0;
1061             break;
1062         }
1063         goto physical;
1064     case AD_WERE:
1065     case AD_HEAL:
1066     case AD_PHYS:
1067     physical:
1068         if (mattk->aatyp == AT_KICK && thick_skinned(pd)) {
1069             tmp = 0;
1070         } else if (mattk->aatyp == AT_WEAP) {
1071             if (otmp) {
1072                 struct obj *marmg;
1073
1074                 if (otmp->otyp == CORPSE
1075                     && touch_petrifies(&mons[otmp->corpsenm]))
1076                     goto do_stone;
1077                 tmp += dmgval(otmp, mdef);
1078                 if ((marmg = which_armor(magr, W_ARMG)) != 0
1079                     && marmg->otyp == GAUNTLETS_OF_POWER)
1080                     tmp += rn1(4, 3); /* 3..6 */
1081                 if (tmp < 1) /* is this necessary?  mhitu.c has it... */
1082                     tmp = 1;
1083                 if (otmp->oartifact) {
1084                     (void) artifact_hit(magr, mdef, otmp, &tmp, dieroll);
1085                     if (mdef->mhp <= 0)
1086                         return (MM_DEF_DIED
1087                                 | (grow_up(magr, mdef) ? 0 : MM_AGR_DIED));
1088                 }
1089                 if (tmp)
1090                     rustm(mdef, otmp);
1091             }
1092         } else if (pa == &mons[PM_PURPLE_WORM] && pd == &mons[PM_SHRIEKER]) {
1093             /* hack to enhance mm_aggression(); we don't want purple
1094                worm's bite attack to kill a shrieker because then it
1095                won't swallow the corpse; but if the target survives,
1096                the subsequent engulf attack should accomplish that */
1097             if (tmp >= mdef->mhp && mdef->mhp > 1)
1098                 tmp = mdef->mhp - 1;
1099         }
1100         break;
1101     case AD_FIRE:
1102         if (cancelled) {
1103             tmp = 0;
1104             break;
1105         }
1106         if (vis && canseemon(mdef))
1107 /*JP
1108             pline("%s is %s!", Monnam(mdef), on_fire(pd, mattk));
1109 */
1110             pline("%s\82Í%s\81I", Monnam(mdef), on_fire(pd, mattk));
1111         if (completelyburns(pd)) { /* paper golem or straw golem */
1112             if (vis && canseemon(mdef))
1113 /*JP
1114                 pline("%s burns completely!", Monnam(mdef));
1115 */
1116                 pline("%s\82Í\8aD\82É\82È\82Á\82½\81I", Monnam(mdef));
1117             mondead(mdef); /* was mondied() but that dropped paper scrolls */
1118             if (mdef->mhp > 0)
1119                 return 0;
1120             else if (mdef->mtame && !vis)
1121 /*JP
1122                 pline("May %s roast in peace.", mon_nam(mdef));
1123 */
1124                 pline("%s\82æ\81C\88À\82ç\82©\82É\94R\82¦\82ñ\8e\96\82ð\81D", mon_nam(mdef));
1125             return (MM_DEF_DIED | (grow_up(magr, mdef) ? 0 : MM_AGR_DIED));
1126         }
1127         tmp += destroy_mitem(mdef, SCROLL_CLASS, AD_FIRE);
1128         tmp += destroy_mitem(mdef, SPBOOK_CLASS, AD_FIRE);
1129         if (resists_fire(mdef)) {
1130             if (vis && canseemon(mdef))
1131 /*JP
1132                 pline_The("fire doesn't seem to burn %s!", mon_nam(mdef));
1133 */
1134                 pline("%s\82Í\89\8a\82Å\94R\82¦\82È\82¢\82æ\82¤\82¾\81I", mon_nam(mdef));
1135             shieldeff(mdef->mx, mdef->my);
1136             golemeffects(mdef, AD_FIRE, tmp);
1137             tmp = 0;
1138         }
1139         /* only potions damage resistant players in destroy_item */
1140         tmp += destroy_mitem(mdef, POTION_CLASS, AD_FIRE);
1141         break;
1142     case AD_COLD:
1143         if (cancelled) {
1144             tmp = 0;
1145             break;
1146         }
1147         if (vis && canseemon(mdef))
1148 /*JP
1149             pline("%s is covered in frost!", Monnam(mdef));
1150 */
1151             pline("%s\82Í\95X\82Å\95¢\82í\82ê\82½\81I", Monnam(mdef));
1152         if (resists_cold(mdef)) {
1153             if (vis && canseemon(mdef))
1154 /*JP
1155                 pline_The("frost doesn't seem to chill %s!", mon_nam(mdef));
1156 */
1157                 pline("\95X\82Í%s\82ð\93\80\82ç\82¹\82é\82±\82Æ\82ª\82Å\82«\82È\82¢\82æ\82¤\82¾\81I", mon_nam(mdef));
1158             shieldeff(mdef->mx, mdef->my);
1159             golemeffects(mdef, AD_COLD, tmp);
1160             tmp = 0;
1161         }
1162         tmp += destroy_mitem(mdef, POTION_CLASS, AD_COLD);
1163         break;
1164     case AD_ELEC:
1165         if (cancelled) {
1166             tmp = 0;
1167             break;
1168         }
1169         if (vis && canseemon(mdef))
1170 /*JP
1171             pline("%s gets zapped!", Monnam(mdef));
1172 */
1173             pline("%s\82Í\8fÕ\8c\82\82ð\82­\82ç\82Á\82½\81I", Monnam(mdef));
1174         tmp += destroy_mitem(mdef, WAND_CLASS, AD_ELEC);
1175         if (resists_elec(mdef)) {
1176             if (vis && canseemon(mdef))
1177 /*JP
1178                 pline_The("zap doesn't shock %s!", mon_nam(mdef));
1179 */
1180                 pline("\8fÕ\8c\82\82Í%s\82É\89e\8b¿\82ð\97^\82¦\82È\82¢\81I", mon_nam(mdef));
1181             shieldeff(mdef->mx, mdef->my);
1182             golemeffects(mdef, AD_ELEC, tmp);
1183             tmp = 0;
1184         }
1185         /* only rings damage resistant players in destroy_item */
1186         tmp += destroy_mitem(mdef, RING_CLASS, AD_ELEC);
1187         break;
1188     case AD_ACID:
1189         if (magr->mcan) {
1190             tmp = 0;
1191             break;
1192         }
1193         if (resists_acid(mdef)) {
1194             if (vis && canseemon(mdef))
1195 #if 0 /*JP*/
1196                 pline("%s is covered in %s, but it seems harmless.",
1197                       Monnam(mdef), hliquid("acid"));
1198 #else
1199                 pline("%s\82Í%s\82É\82Â\82Â\82Ü\82ê\82½\81D\82µ\82©\82µ\82È\82ñ\82Æ\82à\82È\82¢\82æ\82¤\82¾\81D",
1200                       Monnam(mdef), hliquid("\8e_"));
1201 #endif
1202             tmp = 0;
1203         } else if (vis && canseemon(mdef)) {
1204 /*JP
1205             pline("%s is covered in %s!", Monnam(mdef), hliquid("acid"));
1206 */
1207             pline("%s\82Í%s\82É\82Â\82Â\82Ü\82ê\82½\81I", Monnam(mdef), hliquid("\8e_"));
1208 /*JP
1209             pline("It burns %s!", mon_nam(mdef));
1210 */
1211             pline("%s\82Í\8fÄ\82©\82ê\82½\81I", mon_nam(mdef));
1212         }
1213         if (!rn2(30))
1214             erode_armor(mdef, ERODE_CORRODE);
1215         if (!rn2(6))
1216             acid_damage(MON_WEP(mdef));
1217         break;
1218     case AD_RUST:
1219         if (magr->mcan)
1220             break;
1221         if (pd == &mons[PM_IRON_GOLEM]) {
1222             if (vis && canseemon(mdef))
1223 /*JP
1224                 pline("%s falls to pieces!", Monnam(mdef));
1225 */
1226                 pline("%s\82Í\83o\83\89\83o\83\89\82É\82È\82Á\82½\81I", Monnam(mdef));
1227             mondied(mdef);
1228             if (mdef->mhp > 0)
1229                 return 0;
1230             else if (mdef->mtame && !vis)
1231 /*JP
1232                 pline("May %s rust in peace.", mon_nam(mdef));
1233 */
1234                 pline("%s\82æ\81C\88À\82ç\82©\82É\8eK\82Ñ\82ñ\8e\96\82ð\81D", mon_nam(mdef));
1235             return (MM_DEF_DIED | (grow_up(magr, mdef) ? 0 : MM_AGR_DIED));
1236         }
1237         erode_armor(mdef, ERODE_RUST);
1238         mdef->mstrategy &= ~STRAT_WAITFORU;
1239         tmp = 0;
1240         break;
1241     case AD_CORR:
1242         if (magr->mcan)
1243             break;
1244         erode_armor(mdef, ERODE_CORRODE);
1245         mdef->mstrategy &= ~STRAT_WAITFORU;
1246         tmp = 0;
1247         break;
1248     case AD_DCAY:
1249         if (magr->mcan)
1250             break;
1251         if (pd == &mons[PM_WOOD_GOLEM] || pd == &mons[PM_LEATHER_GOLEM]) {
1252             if (vis && canseemon(mdef))
1253 /*JP
1254                 pline("%s falls to pieces!", Monnam(mdef));
1255 */
1256                 pline("%s\82Í\83o\83\89\83o\83\89\82É\82È\82Á\82½\81I", Monnam(mdef));
1257             mondied(mdef);
1258             if (mdef->mhp > 0)
1259                 return 0;
1260             else if (mdef->mtame && !vis)
1261 /*JP
1262                 pline("May %s rot in peace.", mon_nam(mdef));
1263 */
1264                 pline("%s\82æ\81C\88À\82ç\82©\82É\95\85\82ç\82ñ\8e\96\82ð\81D", mon_nam(mdef));
1265             return (MM_DEF_DIED | (grow_up(magr, mdef) ? 0 : MM_AGR_DIED));
1266         }
1267         erode_armor(mdef, ERODE_CORRODE);
1268         mdef->mstrategy &= ~STRAT_WAITFORU;
1269         tmp = 0;
1270         break;
1271     case AD_STON:
1272         if (magr->mcan)
1273             break;
1274     do_stone:
1275         /* may die from the acid if it eats a stone-curing corpse */
1276         if (munstone(mdef, FALSE))
1277             goto post_stone;
1278         if (poly_when_stoned(pd)) {
1279             mon_to_stone(mdef);
1280             tmp = 0;
1281             break;
1282         }
1283         if (!resists_ston(mdef)) {
1284             if (vis && canseemon(mdef))
1285 /*JP
1286                 pline("%s turns to stone!", Monnam(mdef));
1287 */
1288                 pline("%s\82Í\90Î\82É\82È\82Á\82½\81I", Monnam(mdef));
1289             monstone(mdef);
1290         post_stone:
1291             if (mdef->mhp > 0)
1292                 return 0;
1293             else if (mdef->mtame && !vis)
1294 /*JP
1295                 You(brief_feeling, "peculiarly sad");
1296 */
1297                 You(brief_feeling, "\82à\82Ì\94ß\82µ\82¢");
1298             return (MM_DEF_DIED | (grow_up(magr, mdef) ? 0 : MM_AGR_DIED));
1299         }
1300         tmp = (mattk->adtyp == AD_STON ? 0 : 1);
1301         break;
1302     case AD_TLPT:
1303         if (!cancelled && tmp < mdef->mhp && !tele_restrict(mdef)) {
1304             char mdef_Monnam[BUFSZ];
1305             boolean wasseen = canspotmon(mdef);
1306             /* save the name before monster teleports, otherwise
1307                we'll get "it" in the suddenly disappears message */
1308             if (vis && wasseen)
1309                 Strcpy(mdef_Monnam, Monnam(mdef));
1310             mdef->mstrategy &= ~STRAT_WAITFORU;
1311             (void) rloc(mdef, TRUE);
1312             if (vis && wasseen && !canspotmon(mdef) && mdef != u.usteed)
1313 /*JP
1314                 pline("%s suddenly disappears!", mdef_Monnam);
1315 */
1316                 pline("%s\82Í\93Ë\91R\8fÁ\82¦\82½\81I", mdef_Monnam);
1317         }
1318         break;
1319     case AD_SLEE:
1320         if (!cancelled && !mdef->msleeping
1321             && sleep_monst(mdef, rnd(10), -1)) {
1322             if (vis && canspotmon(mdef)) {
1323                 Strcpy(buf, Monnam(mdef));
1324 /*JP
1325                 pline("%s is put to sleep by %s.", buf, mon_nam(magr));
1326 */
1327                 pline("%s\82Í%s\82É\82æ\82Á\82Ä\96°\82ç\82³\82ê\82½\81D", buf, mon_nam(magr));
1328             }
1329             mdef->mstrategy &= ~STRAT_WAITFORU;
1330             slept_monst(mdef);
1331         }
1332         break;
1333     case AD_PLYS:
1334         if (!cancelled && mdef->mcanmove) {
1335             if (vis && canspotmon(mdef)) {
1336                 Strcpy(buf, Monnam(mdef));
1337 /*JP
1338                 pline("%s is frozen by %s.", buf, mon_nam(magr));
1339 */
1340                 pline("%s\82Í%s\82É\82æ\82Á\82Ä\93®\82¯\82È\82­\82È\82Á\82½\81D", buf, mon_nam(magr));
1341             }
1342             paralyze_monst(mdef, rnd(10));
1343         }
1344         break;
1345     case AD_SLOW:
1346         if (!cancelled && mdef->mspeed != MSLOW) {
1347             unsigned int oldspeed = mdef->mspeed;
1348
1349             mon_adjust_speed(mdef, -1, (struct obj *) 0);
1350             mdef->mstrategy &= ~STRAT_WAITFORU;
1351             if (mdef->mspeed != oldspeed && vis && canspotmon(mdef))
1352 /*JP
1353                 pline("%s slows down.", Monnam(mdef));
1354 */
1355                 pline("%s\82Í\93®\8dì\82ª\82Ì\82ë\82­\82È\82Á\82½\81D", Monnam(mdef));
1356         }
1357         break;
1358     case AD_CONF:
1359         /* Since confusing another monster doesn't have a real time
1360          * limit, setting spec_used would not really be right (though
1361          * we still should check for it).
1362          */
1363         if (!magr->mcan && !mdef->mconf && !magr->mspec_used) {
1364             if (vis && canseemon(mdef))
1365 /*JP
1366                 pline("%s looks confused.", Monnam(mdef));
1367 */
1368                 pline("%s\82Í\8d¬\97\90\82µ\82Ä\82¢\82é\82æ\82¤\82É\8c©\82¦\82é\81D", Monnam(mdef));
1369             mdef->mconf = 1;
1370             mdef->mstrategy &= ~STRAT_WAITFORU;
1371         }
1372         break;
1373     case AD_BLND:
1374         if (can_blnd(magr, mdef, mattk->aatyp, (struct obj *) 0)) {
1375             register unsigned rnd_tmp;
1376
1377             if (vis && mdef->mcansee && canspotmon(mdef))
1378 /*JP
1379                 pline("%s is blinded.", Monnam(mdef));
1380 */
1381                 pline("%s\82Í\96Ú\82ª\8c©\82¦\82È\82­\82È\82Á\82½\81D", Monnam(mdef));
1382             rnd_tmp = d((int) mattk->damn, (int) mattk->damd);
1383             if ((rnd_tmp += mdef->mblinded) > 127)
1384                 rnd_tmp = 127;
1385             mdef->mblinded = rnd_tmp;
1386             mdef->mcansee = 0;
1387             mdef->mstrategy &= ~STRAT_WAITFORU;
1388         }
1389         tmp = 0;
1390         break;
1391     case AD_HALU:
1392         if (!magr->mcan && haseyes(pd) && mdef->mcansee) {
1393             if (vis && canseemon(mdef))
1394 #if 0 /*JP:T*/
1395                 pline("%s looks %sconfused.", Monnam(mdef),
1396                       mdef->mconf ? "more " : "");
1397 #else
1398                 pline("%s\82Í%s\8d¬\97\90\82µ\82Ä\82¢\82é\82æ\82¤\82É\8c©\82¦\82é\81D", Monnam(mdef),
1399                       mdef->mconf ? "\82Ü\82·\82Ü\82·" : "");
1400 #endif
1401             mdef->mconf = 1;
1402             mdef->mstrategy &= ~STRAT_WAITFORU;
1403         }
1404         tmp = 0;
1405         break;
1406     case AD_CURS:
1407         if (!night() && (pa == &mons[PM_GREMLIN]))
1408             break;
1409         if (!magr->mcan && !rn2(10)) {
1410             mdef->mcan = 1; /* cancelled regardless of lifesave */
1411             mdef->mstrategy &= ~STRAT_WAITFORU;
1412             if (is_were(pd) && pd->mlet != S_HUMAN)
1413                 were_change(mdef);
1414             if (pd == &mons[PM_CLAY_GOLEM]) {
1415                 if (vis && canseemon(mdef)) {
1416 #if 0 /*JP*/
1417                     pline("Some writing vanishes from %s head!",
1418                           s_suffix(mon_nam(mdef)));
1419 #else
1420                     pline("\82¢\82­\82Â\82©\82Ì\95\8e\9a\82ª%s\82Ì\93ª\82©\82ç\8fÁ\82¦\82½\81I",
1421                           mon_nam(mdef));
1422 #endif
1423 /*JP
1424                     pline("%s is destroyed!", Monnam(mdef));
1425 */
1426                     pline("%s\82Í\94j\89ó\82³\82ê\82½\81I", Monnam(mdef));
1427                 }
1428                 mondied(mdef);
1429                 if (mdef->mhp > 0)
1430                     return 0;
1431                 else if (mdef->mtame && !vis)
1432 /*JP
1433                     You(brief_feeling, "strangely sad");
1434 */
1435                     You(brief_feeling, "\96­\82É\94ß\82µ\82¢");
1436                 return (MM_DEF_DIED
1437                         | (grow_up(magr, mdef) ? 0 : MM_AGR_DIED));
1438             }
1439             if (!Deaf) {
1440                 if (!vis)
1441 /*JP
1442                     You_hear("laughter.");
1443 */
1444                     You_hear("\8fÎ\82¢\90º\82ð\95·\82¢\82½\81D");
1445                 else if (canseemon(magr))
1446 /*JP
1447                     pline("%s chuckles.", Monnam(magr));
1448 */
1449                     pline("%s\82Í\82­\82·\82­\82·\8fÎ\82Á\82½\81D", Monnam(magr));
1450             }
1451         }
1452         break;
1453     case AD_SGLD:
1454         tmp = 0;
1455         if (magr->mcan)
1456             break;
1457         /* technically incorrect; no check for stealing gold from
1458          * between mdef's feet...
1459          */
1460         {
1461             struct obj *gold = findgold(mdef->minvent);
1462
1463             if (!gold)
1464                 break;
1465             obj_extract_self(gold);
1466             add_to_minv(magr, gold);
1467         }
1468         mdef->mstrategy &= ~STRAT_WAITFORU;
1469         if (vis && canseemon(mdef)) {
1470             Strcpy(buf, Monnam(magr));
1471 /*JP
1472             pline("%s steals some gold from %s.", buf, mon_nam(mdef));
1473 */
1474             pline("%s\82Í%s\82©\82ç\8bà\82ð\93\90\82ñ\82¾\81D", buf, mon_nam(mdef));
1475         }
1476         if (!tele_restrict(magr)) {
1477             boolean couldspot = canspotmon(magr);
1478             (void) rloc(magr, TRUE);
1479             if (vis && couldspot && !canspotmon(magr))
1480 /*JP
1481                 pline("%s suddenly disappears!", buf);
1482 */
1483                 pline("%s\82Í\93Ë\91R\8fÁ\82¦\82½\81I", buf);
1484         }
1485         break;
1486     case AD_DRLI:
1487         if (!cancelled && !rn2(3) && !resists_drli(mdef)) {
1488             tmp = d(2, 6);
1489             if (vis && canspotmon(mdef))
1490 /*JP
1491                 pline("%s suddenly seems weaker!", Monnam(mdef));
1492 */
1493                 pline("%s\82Í\93Ë\91R\8eã\82­\82È\82Á\82½\82æ\82¤\82É\8c©\82¦\82½\81I", Monnam(mdef));
1494             mdef->mhpmax -= tmp;
1495             if (mdef->m_lev == 0)
1496                 tmp = mdef->mhp;
1497             else
1498                 mdef->m_lev--;
1499             /* Automatic kill if drained past level 0 */
1500         }
1501         break;
1502     case AD_SSEX:
1503     case AD_SITM: /* for now these are the same */
1504     case AD_SEDU:
1505         if (magr->mcan)
1506             break;
1507         /* find an object to steal, non-cursed if magr is tame */
1508         for (obj = mdef->minvent; obj; obj = obj->nobj)
1509             if (!magr->mtame || !obj->cursed)
1510                 break;
1511
1512         if (obj) {
1513             char onambuf[BUFSZ], mdefnambuf[BUFSZ];
1514
1515             /* make a special x_monnam() call that never omits
1516                the saddle, and save it for later messages */
1517             Strcpy(mdefnambuf,
1518                    x_monnam(mdef, ARTICLE_THE, (char *) 0, 0, FALSE));
1519
1520             otmp = obj;
1521             if (u.usteed == mdef && otmp == which_armor(mdef, W_SADDLE))
1522                 /* "You can no longer ride <steed>." */
1523                 dismount_steed(DISMOUNT_POLY);
1524             obj_extract_self(otmp);
1525             if (otmp->owornmask) {
1526                 mdef->misc_worn_check &= ~otmp->owornmask;
1527                 if (otmp->owornmask & W_WEP)
1528                     mwepgone(mdef);
1529                 otmp->owornmask = 0L;
1530                 update_mon_intrinsics(mdef, otmp, FALSE, FALSE);
1531             }
1532             /* add_to_minv() might free otmp [if it merges] */
1533             if (vis)
1534                 Strcpy(onambuf, doname(otmp));
1535             (void) add_to_minv(magr, otmp);
1536             if (vis && canseemon(mdef)) {
1537                 Strcpy(buf, Monnam(magr));
1538 /*JP
1539                 pline("%s steals %s from %s!", buf, onambuf, mdefnambuf);
1540 */
1541                 pline("%s\82Í%s\82©\82ç%s\82ð\93\90\82ñ\82¾\81I", buf, mdefnambuf, onambuf);
1542             }
1543             possibly_unwield(mdef, FALSE);
1544             mdef->mstrategy &= ~STRAT_WAITFORU;
1545             mselftouch(mdef, (const char *) 0, FALSE);
1546             if (mdef->mhp <= 0)
1547                 return (MM_DEF_DIED
1548                         | (grow_up(magr, mdef) ? 0 : MM_AGR_DIED));
1549             if (pa->mlet == S_NYMPH && !tele_restrict(magr)) {
1550                 boolean couldspot = canspotmon(magr);
1551
1552                 (void) rloc(magr, TRUE);
1553                 if (vis && couldspot && !canspotmon(magr))
1554 /*JP
1555                     pline("%s suddenly disappears!", buf);
1556 */
1557                     pline("%s\82Í\93Ë\91R\8fÁ\82¦\82½\81I", buf);
1558             }
1559         }
1560         tmp = 0;
1561         break;
1562     case AD_DREN:
1563         if (!cancelled && !rn2(4))
1564             xdrainenergym(mdef, (boolean) (vis && canspotmon(mdef)
1565                                            && mattk->aatyp != AT_ENGL));
1566         tmp = 0;
1567         break;
1568     case AD_DRST:
1569     case AD_DRDX:
1570     case AD_DRCO:
1571         if (!cancelled && !rn2(8)) {
1572             if (vis && canspotmon(magr))
1573 #if 0 /*JP:T*/
1574                 pline("%s %s was poisoned!", s_suffix(Monnam(magr)),
1575                       mpoisons_subj(magr, mattk));
1576 #else
1577                 pline("%s\82Ì%s\82Í\93Å\82³\82ê\82Ä\82¢\82é\81I", Monnam(magr),
1578                       mpoisons_subj(magr, mattk));
1579 #endif
1580             if (resists_poison(mdef)) {
1581                 if (vis && canspotmon(mdef) && canspotmon(magr))
1582 /*JP
1583                     pline_The("poison doesn't seem to affect %s.",
1584 */
1585                     pline("%s\82Í\93Å\82Ì\89e\8b¿\82ð\8eó\82¯\82È\82¢\81D",
1586                               mon_nam(mdef));
1587             } else {
1588                 if (rn2(10))
1589                     tmp += rn1(10, 6);
1590                 else {
1591                     if (vis && canspotmon(mdef))
1592 /*JP
1593                         pline_The("poison was deadly...");
1594 */
1595                         pline("\93Å\82Í\92v\8e\80\97Ê\82¾\82Á\82½\81D\81D\81D");
1596                     tmp = mdef->mhp;
1597                 }
1598             }
1599         }
1600         break;
1601     case AD_DRIN:
1602         if (notonhead || !has_head(pd)) {
1603             if (vis && canspotmon(mdef))
1604 /*JP
1605                 pline("%s doesn't seem harmed.", Monnam(mdef));
1606 */
1607                 pline("%s\82Í\8f\9d\82Â\82¢\82½\82æ\82¤\82É\82Í\8c©\82¦\82È\82¢\81D", Monnam(mdef));
1608             /* Not clear what to do for green slimes */
1609             tmp = 0;
1610             break;
1611         }
1612         if ((mdef->misc_worn_check & W_ARMH) && rn2(8)) {
1613             if (vis && canspotmon(magr) && canseemon(mdef)) {
1614                 Strcpy(buf, s_suffix(Monnam(mdef)));
1615 #if 0 /*JP*/
1616                 pline("%s helmet blocks %s attack to %s head.", buf,
1617                       s_suffix(mon_nam(magr)), mhis(mdef));
1618 #else
1619                 pline("%s\82Ì\8a\95\82Í%s\82Ì\93ª\82Ö\82Ì\8dU\8c\82\82ð\96h\82¢\82¾\81D", buf,
1620                       mon_nam(magr));
1621 #endif
1622             }
1623             break;
1624         }
1625         res = eat_brains(magr, mdef, vis, &tmp);
1626         break;
1627     case AD_SLIM:
1628         if (cancelled)
1629             break; /* physical damage only */
1630         if (!rn2(4) && !slimeproof(pd)) {
1631             if (!munslime(mdef, FALSE) && mdef->mhp > 0) {
1632                 if (newcham(mdef, &mons[PM_GREEN_SLIME], FALSE, vis && canseemon(mdef)))
1633                     pd = mdef->data;
1634                 mdef->mstrategy &= ~STRAT_WAITFORU;
1635                 res = MM_HIT;
1636             }
1637             /* munslime attempt could have been fatal,
1638                potentially to multiple monsters (SCR_FIRE) */
1639             if (magr->mhp < 1)
1640                 res |= MM_AGR_DIED;
1641             if (mdef->mhp < 1)
1642                 res |= MM_DEF_DIED;
1643             tmp = 0;
1644         }
1645         break;
1646     case AD_STCK:
1647         if (cancelled)
1648             tmp = 0;
1649         break;
1650     case AD_WRAP: /* monsters cannot grab one another, it's too hard */
1651         if (magr->mcan)
1652             tmp = 0;
1653         break;
1654     case AD_ENCH:
1655         /* there's no msomearmor() function, so just do damage */
1656         /* if (cancelled) break; */
1657         break;
1658     default:
1659         tmp = 0;
1660         break;
1661     }
1662     if (!tmp)
1663         return res;
1664
1665     if ((mdef->mhp -= tmp) < 1) {
1666         if (m_at(mdef->mx, mdef->my) == magr) { /* see gulpmm() */
1667             remove_monster(mdef->mx, mdef->my);
1668             mdef->mhp = 1; /* otherwise place_monster will complain */
1669             place_monster(mdef, mdef->mx, mdef->my);
1670             mdef->mhp = 0;
1671         }
1672         monkilled(mdef, "", (int) mattk->adtyp);
1673         if (mdef->mhp > 0)
1674             return res; /* mdef lifesaved */
1675         else if (res == MM_AGR_DIED)
1676             return (MM_DEF_DIED | MM_AGR_DIED);
1677
1678         if (mattk->adtyp == AD_DGST) {
1679             /* various checks similar to dog_eat and meatobj.
1680              * after monkilled() to provide better message ordering */
1681             if (mdef->cham >= LOW_PM) {
1682                 (void) newcham(magr, (struct permonst *) 0, FALSE, TRUE);
1683             } else if (pd == &mons[PM_GREEN_SLIME] && !slimeproof(pa)) {
1684                 (void) newcham(magr, &mons[PM_GREEN_SLIME], FALSE, TRUE);
1685             } else if (pd == &mons[PM_WRAITH]) {
1686                 (void) grow_up(magr, (struct monst *) 0);
1687                 /* don't grow up twice */
1688                 return (MM_DEF_DIED | (magr->mhp > 0 ? 0 : MM_AGR_DIED));
1689             } else if (pd == &mons[PM_NURSE]) {
1690                 magr->mhp = magr->mhpmax;
1691             }
1692         }
1693         /* caveat: above digestion handling doesn't keep `pa' up to date */
1694
1695         return (MM_DEF_DIED | (grow_up(magr, mdef) ? 0 : MM_AGR_DIED));
1696     }
1697     return (res == MM_AGR_DIED) ? MM_AGR_DIED : MM_HIT;
1698 }
1699
1700 void
1701 paralyze_monst(mon, amt)
1702 struct monst *mon;
1703 int amt;
1704 {
1705     if (amt > 127)
1706         amt = 127;
1707
1708     mon->mcanmove = 0;
1709     mon->mfrozen = amt;
1710     mon->meating = 0; /* terminate any meal-in-progress */
1711     mon->mstrategy &= ~STRAT_WAITFORU;
1712 }
1713
1714 /* `mon' is hit by a sleep attack; return 1 if it's affected, 0 otherwise */
1715 int
1716 sleep_monst(mon, amt, how)
1717 struct monst *mon;
1718 int amt, how;
1719 {
1720     if (resists_sleep(mon)
1721         || (how >= 0 && resist(mon, (char) how, 0, NOTELL))) {
1722         shieldeff(mon->mx, mon->my);
1723     } else if (mon->mcanmove) {
1724         finish_meating(mon); /* terminate any meal-in-progress */
1725         amt += (int) mon->mfrozen;
1726         if (amt > 0) { /* sleep for N turns */
1727             mon->mcanmove = 0;
1728             mon->mfrozen = min(amt, 127);
1729         } else { /* sleep until awakened */
1730             mon->msleeping = 1;
1731         }
1732         return 1;
1733     }
1734     return 0;
1735 }
1736
1737 /* sleeping grabber releases, engulfer doesn't; don't use for paralysis! */
1738 void
1739 slept_monst(mon)
1740 struct monst *mon;
1741 {
1742     if ((mon->msleeping || !mon->mcanmove) && mon == u.ustuck
1743         && !sticks(youmonst.data) && !u.uswallow) {
1744 /*JP
1745         pline("%s grip relaxes.", s_suffix(Monnam(mon)));
1746 */
1747         pline("%s\82Ì\88¬\82é\97Í\82ª\8eã\82­\82È\82Á\82½\81D", Monnam(mon));
1748         unstuck(mon);
1749     }
1750 }
1751
1752 void
1753 rustm(mdef, obj)
1754 struct monst *mdef;
1755 struct obj *obj;
1756 {
1757     int dmgtyp = -1, chance = 1;
1758
1759     if (!mdef || !obj)
1760         return; /* just in case */
1761     /* AD_ACID and AD_ENCH are handled in passivemm() and passiveum() */
1762     if (dmgtype(mdef->data, AD_CORR)) {
1763         dmgtyp = ERODE_CORRODE;
1764     } else if (dmgtype(mdef->data, AD_RUST)) {
1765         dmgtyp = ERODE_RUST;
1766     } else if (dmgtype(mdef->data, AD_FIRE)
1767                /* steam vortex: fire resist applies, fire damage doesn't */
1768                && mdef->data != &mons[PM_STEAM_VORTEX]) {
1769         dmgtyp = ERODE_BURN;
1770         chance = 6;
1771     }
1772
1773     if (dmgtyp >= 0 && !rn2(chance))
1774         (void) erode_obj(obj, (char *) 0, dmgtyp, EF_GREASE | EF_VERBOSE);
1775 }
1776
1777 STATIC_OVL void
1778 mswingsm(magr, mdef, otemp)
1779 struct monst *magr, *mdef;
1780 struct obj *otemp;
1781 {
1782     if (flags.verbose && !Blind && mon_visible(magr)) {
1783 #if 0 /*JP*/
1784         pline("%s %s %s%s %s at %s.", Monnam(magr),
1785               (objects[otemp->otyp].oc_dir & PIERCE) ? "thrusts" : "swings",
1786               (otemp->quan > 1L) ? "one of " : "", mhis(magr), xname(otemp),
1787               mon_nam(mdef));
1788 #else
1789         pline((objects[otemp->otyp].oc_dir & PIERCE) ?
1790               "%s\82Í%s\82Å%s\82ð\93Ë\82¢\82½\81D" :
1791               "%s\82Í%s\82ð\90U\82è\82Ü\82í\82µ%s\82ð\8dU\8c\82\82µ\82½\81D", Monnam(magr),
1792               xname(otemp), mon_nam(mdef));
1793 #endif
1794     }
1795 }
1796
1797 /*
1798  * Passive responses by defenders.  Does not replicate responses already
1799  * handled above.  Returns same values as mattackm.
1800  */
1801 STATIC_OVL int
1802 passivemm(magr, mdef, mhit, mdead)
1803 register struct monst *magr, *mdef;
1804 boolean mhit;
1805 int mdead;
1806 {
1807     register struct permonst *mddat = mdef->data;
1808     register struct permonst *madat = magr->data;
1809     char buf[BUFSZ];
1810     int i, tmp;
1811
1812     for (i = 0;; i++) {
1813         if (i >= NATTK)
1814             return (mdead | mhit); /* no passive attacks */
1815         if (mddat->mattk[i].aatyp == AT_NONE)
1816             break;
1817     }
1818     if (mddat->mattk[i].damn)
1819         tmp = d((int) mddat->mattk[i].damn, (int) mddat->mattk[i].damd);
1820     else if (mddat->mattk[i].damd)
1821         tmp = d((int) mddat->mlevel + 1, (int) mddat->mattk[i].damd);
1822     else
1823         tmp = 0;
1824
1825     /* These affect the enemy even if defender killed */
1826     switch (mddat->mattk[i].adtyp) {
1827     case AD_ACID:
1828         if (mhit && !rn2(2)) {
1829             Strcpy(buf, Monnam(magr));
1830             if (canseemon(magr))
1831 #if 0 /*JP:T*/
1832                 pline("%s is splashed by %s %s!", buf,
1833                       s_suffix(mon_nam(mdef)), hliquid("acid"));
1834 #else
1835                 pline("%s\82Í%s\82Ì%s\82ð\97\81\82Ñ\82½\81I", buf,
1836                       mon_nam(mdef), hliquid("\8e_"));
1837 #endif
1838             if (resists_acid(magr)) {
1839                 if (canseemon(magr))
1840 /*JP
1841                     pline("%s is not affected.", Monnam(magr));
1842 */
1843                     pline("%s\82Í\89e\8b¿\82ð\8eó\82¯\82È\82¢\81D", Monnam(magr));
1844                 tmp = 0;
1845             }
1846         } else
1847             tmp = 0;
1848         if (!rn2(30))
1849             erode_armor(magr, ERODE_CORRODE);
1850         if (!rn2(6))
1851             acid_damage(MON_WEP(magr));
1852         goto assess_dmg;
1853     case AD_ENCH: /* KMH -- remove enchantment (disenchanter) */
1854         if (mhit && !mdef->mcan && otmp) {
1855             (void) drain_item(otmp, FALSE);
1856             /* No message */
1857         }
1858         break;
1859     default:
1860         break;
1861     }
1862     if (mdead || mdef->mcan)
1863         return (mdead | mhit);
1864
1865     /* These affect the enemy only if defender is still alive */
1866     if (rn2(3))
1867         switch (mddat->mattk[i].adtyp) {
1868         case AD_PLYS: /* Floating eye */
1869             if (tmp > 127)
1870                 tmp = 127;
1871             if (mddat == &mons[PM_FLOATING_EYE]) {
1872                 if (!rn2(4))
1873                     tmp = 127;
1874                 if (magr->mcansee && haseyes(madat) && mdef->mcansee
1875                     && (perceives(madat) || !mdef->minvis)) {
1876                     /* construct format string; guard against '%' in Monnam */
1877 #if 0 /*JP*/
1878                     Strcpy(buf, s_suffix(Monnam(mdef)));
1879 #else
1880                     Strcpy(buf, Monnam(mdef));
1881 #endif
1882                     (void) strNsubst(buf, "%", "%%", 0);
1883 /*JP
1884                     Strcat(buf, " gaze is reflected by %s %s.");
1885 */
1886                     Strcat(buf, "\82Ì\82É\82ç\82Ý\82Í%s\82É\82æ\82Á\82Ä%s\81D");
1887                     if (mon_reflects(magr,
1888                                      canseemon(magr) ? buf : (char *) 0))
1889                         return (mdead | mhit);
1890                     Strcpy(buf, Monnam(magr));
1891                     if (canseemon(magr))
1892 #if 0 /*JP*/
1893                         pline("%s is frozen by %s gaze!", buf,
1894                               s_suffix(mon_nam(mdef)));
1895 #else
1896                         pline("%s\82Í%s\82Ì\82É\82ç\82Ý\82Å\93®\82¯\82È\82­\82È\82Á\82½\81I", buf,
1897                               mon_nam(mdef));
1898 #endif
1899                     paralyze_monst(magr, tmp);
1900                     return (mdead | mhit);
1901                 }
1902             } else { /* gelatinous cube */
1903                 Strcpy(buf, Monnam(magr));
1904                 if (canseemon(magr))
1905 /*JP
1906                     pline("%s is frozen by %s.", buf, mon_nam(mdef));
1907 */
1908                     pline("%s\82Í%s\82É\82æ\82Á\82Ä\93®\82¯\82È\82­\82È\82Á\82½\81D", buf, mon_nam(mdef));
1909                 paralyze_monst(magr, tmp);
1910                 return (mdead | mhit);
1911             }
1912             return 1;
1913         case AD_COLD:
1914             if (resists_cold(magr)) {
1915                 if (canseemon(magr)) {
1916 /*JP
1917                     pline("%s is mildly chilly.", Monnam(magr));
1918 */
1919                     pline("%s\82Í\97â\82¦\82½\81D", Monnam(magr));
1920                     golemeffects(magr, AD_COLD, tmp);
1921                 }
1922                 tmp = 0;
1923                 break;
1924             }
1925             if (canseemon(magr))
1926 /*JP
1927                 pline("%s is suddenly very cold!", Monnam(magr));
1928 */
1929                 pline("%s\82Í\93Ë\91R\93\80\82è\82Ã\82¯\82É\82È\82Á\82½\81I", Monnam(magr));
1930             mdef->mhp += tmp / 2;
1931             if (mdef->mhpmax < mdef->mhp)
1932                 mdef->mhpmax = mdef->mhp;
1933             if (mdef->mhpmax > ((int) (mdef->m_lev + 1) * 8))
1934                 (void) split_mon(mdef, magr);
1935             break;
1936         case AD_STUN:
1937             if (!magr->mstun) {
1938                 magr->mstun = 1;
1939                 if (canseemon(magr))
1940 #if 0 /*JP*/
1941                     pline("%s %s...", Monnam(magr),
1942                           makeplural(stagger(magr->data, "stagger")));
1943 #else
1944                     pline("%s\82Í%s\81D\81D\81D", Monnam(magr),
1945                           jpast(stagger(magr->data, "\82æ\82ë\82ß\82­")));
1946 #endif
1947             }
1948             tmp = 0;
1949             break;
1950         case AD_FIRE:
1951             if (resists_fire(magr)) {
1952                 if (canseemon(magr)) {
1953 /*JP
1954                     pline("%s is mildly warmed.", Monnam(magr));
1955 */
1956                     pline("%s\82Í\92g\82©\82­\82È\82Á\82½\81D", Monnam(magr));
1957                     golemeffects(magr, AD_FIRE, tmp);
1958                 }
1959                 tmp = 0;
1960                 break;
1961             }
1962             if (canseemon(magr))
1963 /*JP
1964                 pline("%s is suddenly very hot!", Monnam(magr));
1965 */
1966                 pline("%s\82Í\93Ë\91R\82Æ\82Ä\82à\94M\82­\82È\82Á\82½\81I", Monnam(magr));
1967             break;
1968         case AD_ELEC:
1969             if (resists_elec(magr)) {
1970                 if (canseemon(magr)) {
1971 /*JP
1972                     pline("%s is mildly tingled.", Monnam(magr));
1973 */
1974                     pline("%s\82Í\83s\83\8a\83s\83\8a\82µ\82Ä\82¢\82é\81D", Monnam(magr));
1975                     golemeffects(magr, AD_ELEC, tmp);
1976                 }
1977                 tmp = 0;
1978                 break;
1979             }
1980             if (canseemon(magr))
1981 /*JP
1982                 pline("%s is jolted with electricity!", Monnam(magr));
1983 */
1984                 pline("%s\82Í\93d\8bC\83V\83\87\83b\83N\82ð\82¤\82¯\82½\81I", Monnam(magr));
1985             break;
1986         default:
1987             tmp = 0;
1988             break;
1989         }
1990     else
1991         tmp = 0;
1992
1993 assess_dmg:
1994     if ((magr->mhp -= tmp) <= 0) {
1995         monkilled(magr, "", (int) mddat->mattk[i].adtyp);
1996         return (mdead | mhit | MM_AGR_DIED);
1997     }
1998     return (mdead | mhit);
1999 }
2000
2001 /* hero or monster has successfully hit target mon with drain energy attack */
2002 void
2003 xdrainenergym(mon, givemsg)
2004 struct monst *mon;
2005 boolean givemsg;
2006 {
2007     if (mon->mspec_used < 20 /* limit draining */
2008         && (attacktype(mon->data, AT_MAGC)
2009             || attacktype(mon->data, AT_BREA))) {
2010         mon->mspec_used += d(2, 2);
2011         if (givemsg)
2012 /*JP
2013             pline("%s seems lethargic.", Monnam(mon));
2014 */
2015             pline("%s\82Í\96³\8bC\97Í\82É\82È\82Á\82½\82æ\82¤\82¾\81D", Monnam(mon));
2016     }
2017 }
2018
2019 /* "aggressive defense"; what type of armor prevents specified attack
2020    from touching its target? */
2021 long
2022 attk_protection(aatyp)
2023 int aatyp;
2024 {
2025     long w_mask = 0L;
2026
2027     switch (aatyp) {
2028     case AT_NONE:
2029     case AT_SPIT:
2030     case AT_EXPL:
2031     case AT_BOOM:
2032     case AT_GAZE:
2033     case AT_BREA:
2034     case AT_MAGC:
2035         w_mask = ~0L; /* special case; no defense needed */
2036         break;
2037     case AT_CLAW:
2038     case AT_TUCH:
2039     case AT_WEAP:
2040         w_mask = W_ARMG; /* caller needs to check for weapon */
2041         break;
2042     case AT_KICK:
2043         w_mask = W_ARMF;
2044         break;
2045     case AT_BUTT:
2046         w_mask = W_ARMH;
2047         break;
2048     case AT_HUGS:
2049         w_mask = (W_ARMC | W_ARMG); /* attacker needs both to be protected */
2050         break;
2051     case AT_BITE:
2052     case AT_STNG:
2053     case AT_ENGL:
2054     case AT_TENT:
2055     default:
2056         w_mask = 0L; /* no defense available */
2057         break;
2058     }
2059     return w_mask;
2060 }
2061
2062 /*mhitm.c*/