OSDN Git Service

adjust for patch
[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µ%s\81D", Monnam(mdef),
973                   jpast(stagger(pd, "\82æ\82ë\82ß\82­")));
974 #endif
975         mdef->mstun = 1;
976         goto physical;
977     case AD_LEGS:
978         if (magr->mcan) {
979             tmp = 0;
980             break;
981         }
982         goto physical;
983     case AD_WERE:
984     case AD_HEAL:
985     case AD_PHYS:
986     physical:
987         if (mattk->aatyp == AT_KICK && thick_skinned(pd)) {
988             tmp = 0;
989         } else if (mattk->aatyp == AT_WEAP) {
990             if (otmp) {
991                 if (otmp->otyp == CORPSE
992                     && touch_petrifies(&mons[otmp->corpsenm]))
993                     goto do_stone;
994                 tmp += dmgval(otmp, mdef);
995                 if (otmp->oartifact) {
996                     (void) artifact_hit(magr, mdef, otmp, &tmp, dieroll);
997                     if (mdef->mhp <= 0)
998                         return (MM_DEF_DIED
999                                 | (grow_up(magr, mdef) ? 0 : MM_AGR_DIED));
1000                 }
1001                 if (tmp)
1002                     rustm(mdef, otmp);
1003             }
1004         } else if (pa == &mons[PM_PURPLE_WORM] && pd == &mons[PM_SHRIEKER]) {
1005             /* hack to enhance mm_aggression(); we don't want purple
1006                worm's bite attack to kill a shrieker because then it
1007                won't swallow the corpse; but if the target survives,
1008                the subsequent engulf attack should accomplish that */
1009             if (tmp >= mdef->mhp && mdef->mhp > 1)
1010                 tmp = mdef->mhp - 1;
1011         }
1012         break;
1013     case AD_FIRE:
1014         if (cancelled) {
1015             tmp = 0;
1016             break;
1017         }
1018         if (vis)
1019 /*JP
1020             pline("%s is %s!", Monnam(mdef), on_fire(pd, mattk));
1021 */
1022             pline("%s\82Í%s\81I", Monnam(mdef), on_fire(pd, mattk));
1023         if (pd == &mons[PM_STRAW_GOLEM] || pd == &mons[PM_PAPER_GOLEM]) {
1024             if (vis)
1025 /*JP
1026                 pline("%s burns completely!", Monnam(mdef));
1027 */
1028                 pline("%s\82Í\8aD\82É\82È\82Á\82½\81I", Monnam(mdef));
1029             mondied(mdef);
1030             if (mdef->mhp > 0)
1031                 return 0;
1032             else if (mdef->mtame && !vis)
1033 /*JP
1034                 pline("May %s roast in peace.", mon_nam(mdef));
1035 */
1036                 pline("%s\82æ\81C\88À\82ç\82©\82É\94R\82¦\82ñ\8e\96\82ð\81D", mon_nam(mdef));
1037             return (MM_DEF_DIED | (grow_up(magr, mdef) ? 0 : MM_AGR_DIED));
1038         }
1039         tmp += destroy_mitem(mdef, SCROLL_CLASS, AD_FIRE);
1040         tmp += destroy_mitem(mdef, SPBOOK_CLASS, AD_FIRE);
1041         if (resists_fire(mdef)) {
1042             if (vis)
1043 /*JP
1044                 pline_The("fire doesn't seem to burn %s!", mon_nam(mdef));
1045 */
1046                 pline("%s\82Í\89\8a\82Å\94R\82¦\82È\82¢\82æ\82¤\82¾\81I", mon_nam(mdef));
1047             shieldeff(mdef->mx, mdef->my);
1048             golemeffects(mdef, AD_FIRE, tmp);
1049             tmp = 0;
1050         }
1051         /* only potions damage resistant players in destroy_item */
1052         tmp += destroy_mitem(mdef, POTION_CLASS, AD_FIRE);
1053         break;
1054     case AD_COLD:
1055         if (cancelled) {
1056             tmp = 0;
1057             break;
1058         }
1059         if (vis)
1060 /*JP
1061             pline("%s is covered in frost!", Monnam(mdef));
1062 */
1063             pline("%s\82Í\95X\82Å\95¢\82í\82ê\82½\81I", Monnam(mdef));
1064         if (resists_cold(mdef)) {
1065             if (vis)
1066 /*JP
1067                 pline_The("frost doesn't seem to chill %s!", mon_nam(mdef));
1068 */
1069                 pline("\95X\82Í%s\82ð\93\80\82ç\82¹\82é\82±\82Æ\82ª\82Å\82«\82È\82¢\82æ\82¤\82¾\81I", mon_nam(mdef));
1070             shieldeff(mdef->mx, mdef->my);
1071             golemeffects(mdef, AD_COLD, tmp);
1072             tmp = 0;
1073         }
1074         tmp += destroy_mitem(mdef, POTION_CLASS, AD_COLD);
1075         break;
1076     case AD_ELEC:
1077         if (cancelled) {
1078             tmp = 0;
1079             break;
1080         }
1081         if (vis)
1082 /*JP
1083             pline("%s gets zapped!", Monnam(mdef));
1084 */
1085             pline("%s\82Í\8fÕ\8c\82\82ð\82­\82ç\82Á\82½\81I", Monnam(mdef));
1086         tmp += destroy_mitem(mdef, WAND_CLASS, AD_ELEC);
1087         if (resists_elec(mdef)) {
1088             if (vis)
1089 /*JP
1090                 pline_The("zap doesn't shock %s!", mon_nam(mdef));
1091 */
1092                 pline("\8fÕ\8c\82\82Í%s\82É\89e\8b¿\82ð\97^\82¦\82È\82¢\81I", mon_nam(mdef));
1093             shieldeff(mdef->mx, mdef->my);
1094             golemeffects(mdef, AD_ELEC, tmp);
1095             tmp = 0;
1096         }
1097         /* only rings damage resistant players in destroy_item */
1098         tmp += destroy_mitem(mdef, RING_CLASS, AD_ELEC);
1099         break;
1100     case AD_ACID:
1101         if (magr->mcan) {
1102             tmp = 0;
1103             break;
1104         }
1105         if (resists_acid(mdef)) {
1106             if (vis)
1107 /*JP
1108                 pline("%s is covered in acid, but it seems harmless.",
1109 */
1110                 pline("%s\82Í\8e_\82É\82Â\82Â\82Ü\82ê\82½\81D\82µ\82©\82µ\82È\82ñ\82Æ\82à\82È\82¢\82æ\82¤\82¾\81D",
1111                       Monnam(mdef));
1112             tmp = 0;
1113         } else if (vis) {
1114 /*JP
1115             pline("%s is covered in acid!", Monnam(mdef));
1116 */
1117             pline("%s\82Í\8e_\82É\82Â\82Â\82Ü\82ê\82½\81I", Monnam(mdef));
1118 /*JP
1119             pline("It burns %s!", mon_nam(mdef));
1120 */
1121             pline("%s\82Í\8fÄ\82©\82ê\82½\81I", mon_nam(mdef));
1122         }
1123         if (!rn2(30))
1124             erode_armor(mdef, ERODE_CORRODE);
1125         if (!rn2(6))
1126             acid_damage(MON_WEP(mdef));
1127         break;
1128     case AD_RUST:
1129         if (magr->mcan)
1130             break;
1131         if (pd == &mons[PM_IRON_GOLEM]) {
1132             if (vis)
1133 /*JP
1134                 pline("%s falls to pieces!", Monnam(mdef));
1135 */
1136                 pline("%s\82Í\83o\83\89\83o\83\89\82É\82È\82Á\82½\81I", Monnam(mdef));
1137             mondied(mdef);
1138             if (mdef->mhp > 0)
1139                 return 0;
1140             else if (mdef->mtame && !vis)
1141 /*JP
1142                 pline("May %s rust in peace.", mon_nam(mdef));
1143 */
1144                 pline("%s\82æ\81C\88À\82ç\82©\82É\8eK\82Ñ\82ñ\8e\96\82ð\81D", mon_nam(mdef));
1145             return (MM_DEF_DIED | (grow_up(magr, mdef) ? 0 : MM_AGR_DIED));
1146         }
1147         erode_armor(mdef, ERODE_RUST);
1148         mdef->mstrategy &= ~STRAT_WAITFORU;
1149         tmp = 0;
1150         break;
1151     case AD_CORR:
1152         if (magr->mcan)
1153             break;
1154         erode_armor(mdef, ERODE_CORRODE);
1155         mdef->mstrategy &= ~STRAT_WAITFORU;
1156         tmp = 0;
1157         break;
1158     case AD_DCAY:
1159         if (magr->mcan)
1160             break;
1161         if (pd == &mons[PM_WOOD_GOLEM] || pd == &mons[PM_LEATHER_GOLEM]) {
1162             if (vis)
1163 /*JP
1164                 pline("%s falls to pieces!", Monnam(mdef));
1165 */
1166                 pline("%s\82Í\83o\83\89\83o\83\89\82É\82È\82Á\82½\81I", Monnam(mdef));
1167             mondied(mdef);
1168             if (mdef->mhp > 0)
1169                 return 0;
1170             else if (mdef->mtame && !vis)
1171 /*JP
1172                 pline("May %s rot in peace.", mon_nam(mdef));
1173 */
1174                 pline("%s\82æ\81C\88À\82ç\82©\82É\95\85\82ç\82ñ\8e\96\82ð\81D", mon_nam(mdef));
1175             return (MM_DEF_DIED | (grow_up(magr, mdef) ? 0 : MM_AGR_DIED));
1176         }
1177         erode_armor(mdef, ERODE_CORRODE);
1178         mdef->mstrategy &= ~STRAT_WAITFORU;
1179         tmp = 0;
1180         break;
1181     case AD_STON:
1182         if (magr->mcan)
1183             break;
1184     do_stone:
1185         /* may die from the acid if it eats a stone-curing corpse */
1186         if (munstone(mdef, FALSE))
1187             goto post_stone;
1188         if (poly_when_stoned(pd)) {
1189             mon_to_stone(mdef);
1190             tmp = 0;
1191             break;
1192         }
1193         if (!resists_ston(mdef)) {
1194             if (vis)
1195 /*JP
1196                 pline("%s turns to stone!", Monnam(mdef));
1197 */
1198                 pline("%s\82Í\90Î\82É\82È\82Á\82½\81I", Monnam(mdef));
1199             monstone(mdef);
1200         post_stone:
1201             if (mdef->mhp > 0)
1202                 return 0;
1203             else if (mdef->mtame && !vis)
1204 /*JP
1205                 You(brief_feeling, "peculiarly sad");
1206 */
1207                 You(brief_feeling, "\82à\82Ì\94ß\82µ\82¢");
1208             return (MM_DEF_DIED | (grow_up(magr, mdef) ? 0 : MM_AGR_DIED));
1209         }
1210         tmp = (mattk->adtyp == AD_STON ? 0 : 1);
1211         break;
1212     case AD_TLPT:
1213         if (!cancelled && tmp < mdef->mhp && !tele_restrict(mdef)) {
1214             char mdef_Monnam[BUFSZ];
1215             /* save the name before monster teleports, otherwise
1216                we'll get "it" in the suddenly disappears message */
1217             if (vis)
1218                 Strcpy(mdef_Monnam, Monnam(mdef));
1219             mdef->mstrategy &= ~STRAT_WAITFORU;
1220             (void) rloc(mdef, TRUE);
1221             if (vis && !canspotmon(mdef) && mdef != u.usteed)
1222 /*JP
1223                 pline("%s suddenly disappears!", mdef_Monnam);
1224 */
1225                 pline("%s\82Í\93Ë\91R\8fÁ\82¦\82½\81I", mdef_Monnam);
1226         }
1227         break;
1228     case AD_SLEE:
1229         if (!cancelled && !mdef->msleeping
1230             && sleep_monst(mdef, rnd(10), -1)) {
1231             if (vis) {
1232                 Strcpy(buf, Monnam(mdef));
1233 /*JP
1234                 pline("%s is put to sleep by %s.", buf, mon_nam(magr));
1235 */
1236                 pline("%s\82Í%s\82É\82æ\82Á\82Ä\96°\82ç\82³\82ê\82½\81D", buf, mon_nam(magr));
1237             }
1238             mdef->mstrategy &= ~STRAT_WAITFORU;
1239             slept_monst(mdef);
1240         }
1241         break;
1242     case AD_PLYS:
1243         if (!cancelled && mdef->mcanmove) {
1244             if (vis) {
1245                 Strcpy(buf, Monnam(mdef));
1246 /*JP
1247                 pline("%s is frozen by %s.", buf, mon_nam(magr));
1248 */
1249                 pline("%s\82Í%s\82É\82æ\82Á\82Ä\93®\82¯\82È\82­\82È\82Á\82½\81D", buf, mon_nam(magr));
1250             }
1251             paralyze_monst(mdef, rnd(10));
1252         }
1253         break;
1254     case AD_SLOW:
1255         if (!cancelled && mdef->mspeed != MSLOW) {
1256             unsigned int oldspeed = mdef->mspeed;
1257
1258             mon_adjust_speed(mdef, -1, (struct obj *) 0);
1259             mdef->mstrategy &= ~STRAT_WAITFORU;
1260             if (mdef->mspeed != oldspeed && vis)
1261 /*JP
1262                 pline("%s slows down.", Monnam(mdef));
1263 */
1264                 pline("%s\82Í\93®\8dì\82ª\82Ì\82ë\82­\82È\82Á\82½\81D", Monnam(mdef));
1265         }
1266         break;
1267     case AD_CONF:
1268         /* Since confusing another monster doesn't have a real time
1269          * limit, setting spec_used would not really be right (though
1270          * we still should check for it).
1271          */
1272         if (!magr->mcan && !mdef->mconf && !magr->mspec_used) {
1273             if (vis)
1274 /*JP
1275                 pline("%s looks confused.", Monnam(mdef));
1276 */
1277                 pline("%s\82Í\8d¬\97\90\82µ\82Ä\82¢\82é\82æ\82¤\82É\8c©\82¦\82é\81D", Monnam(mdef));
1278             mdef->mconf = 1;
1279             mdef->mstrategy &= ~STRAT_WAITFORU;
1280         }
1281         break;
1282     case AD_BLND:
1283         if (can_blnd(magr, mdef, mattk->aatyp, (struct obj *) 0)) {
1284             register unsigned rnd_tmp;
1285
1286             if (vis && mdef->mcansee)
1287 /*JP
1288                 pline("%s is blinded.", Monnam(mdef));
1289 */
1290                 pline("%s\82Í\96Ú\82ª\8c©\82¦\82È\82­\82È\82Á\82½\81D", Monnam(mdef));
1291             rnd_tmp = d((int) mattk->damn, (int) mattk->damd);
1292             if ((rnd_tmp += mdef->mblinded) > 127)
1293                 rnd_tmp = 127;
1294             mdef->mblinded = rnd_tmp;
1295             mdef->mcansee = 0;
1296             mdef->mstrategy &= ~STRAT_WAITFORU;
1297         }
1298         tmp = 0;
1299         break;
1300     case AD_HALU:
1301         if (!magr->mcan && haseyes(pd) && mdef->mcansee) {
1302             if (vis)
1303 #if 0 /*JP*/
1304                 pline("%s looks %sconfused.", Monnam(mdef),
1305                       mdef->mconf ? "more " : "");
1306 #else
1307                 pline("%s\82Í%s\8d¬\97\90\82µ\82Ä\82¢\82é\82æ\82¤\82É\8c©\82¦\82é\81D", Monnam(mdef),
1308                       mdef->mconf ? "\82Ü\82·\82Ü\82·" : "");
1309 #endif
1310             mdef->mconf = 1;
1311             mdef->mstrategy &= ~STRAT_WAITFORU;
1312         }
1313         tmp = 0;
1314         break;
1315     case AD_CURS:
1316         if (!night() && (pa == &mons[PM_GREMLIN]))
1317             break;
1318         if (!magr->mcan && !rn2(10)) {
1319             mdef->mcan = 1; /* cancelled regardless of lifesave */
1320             mdef->mstrategy &= ~STRAT_WAITFORU;
1321             if (is_were(pd) && pd->mlet != S_HUMAN)
1322                 were_change(mdef);
1323             if (pd == &mons[PM_CLAY_GOLEM]) {
1324                 if (vis) {
1325 /*JP
1326                     pline("Some writing vanishes from %s head!",
1327 */
1328                     pline("\82¢\82­\82Â\82©\82Ì\95\8e\9a\82ª%s\82Ì\93ª\82©\82ç\8fÁ\82¦\82½\81I",
1329                           s_suffix(mon_nam(mdef)));
1330 /*JP
1331                     pline("%s is destroyed!", Monnam(mdef));
1332 */
1333                     pline("%s\82Í\94j\89ó\82³\82ê\82½\81I", Monnam(mdef));
1334                 }
1335                 mondied(mdef);
1336                 if (mdef->mhp > 0)
1337                     return 0;
1338                 else if (mdef->mtame && !vis)
1339 /*JP
1340                     You(brief_feeling, "strangely sad");
1341 */
1342                     You(brief_feeling, "\96­\82É\94ß\82µ\82¢");
1343                 return (MM_DEF_DIED
1344                         | (grow_up(magr, mdef) ? 0 : MM_AGR_DIED));
1345             }
1346             if (!Deaf) {
1347                 if (!vis)
1348 /*JP
1349                     You_hear("laughter.");
1350 */
1351                     You_hear("\8fÎ\82¢\90º\82ð\95·\82¢\82½\81D");
1352                 else
1353 /*JP
1354                     pline("%s chuckles.", Monnam(magr));
1355 */
1356                     pline("%s\82Í\82­\82·\82­\82·\8fÎ\82Á\82½\81D", Monnam(magr));
1357             }
1358         }
1359         break;
1360     case AD_SGLD:
1361         tmp = 0;
1362         if (magr->mcan)
1363             break;
1364         /* technically incorrect; no check for stealing gold from
1365          * between mdef's feet...
1366          */
1367         {
1368             struct obj *gold = findgold(mdef->minvent);
1369             if (!gold)
1370                 break;
1371             obj_extract_self(gold);
1372             add_to_minv(magr, gold);
1373         }
1374         mdef->mstrategy &= ~STRAT_WAITFORU;
1375         if (vis) {
1376             Strcpy(buf, Monnam(magr));
1377 /*JP
1378             pline("%s steals some gold from %s.", buf, mon_nam(mdef));
1379 */
1380             pline("%s\82Í%s\82©\82ç\8bà\82ð\93\90\82ñ\82¾\81D", buf, mon_nam(mdef));
1381         }
1382         if (!tele_restrict(magr)) {
1383             (void) rloc(magr, TRUE);
1384             if (vis && !canspotmon(magr))
1385 /*JP
1386                 pline("%s suddenly disappears!", buf);
1387 */
1388                 pline("%s\82Í\93Ë\91R\8fÁ\82¦\82½\81I", buf);
1389         }
1390         break;
1391     case AD_DRLI:
1392         if (!cancelled && !rn2(3) && !resists_drli(mdef)) {
1393             tmp = d(2, 6);
1394             if (vis)
1395 /*JP
1396                 pline("%s suddenly seems weaker!", Monnam(mdef));
1397 */
1398                 pline("%s\82Í\93Ë\91R\8eã\82­\82È\82Á\82½\82æ\82¤\82É\8c©\82¦\82½\81I", Monnam(mdef));
1399             mdef->mhpmax -= tmp;
1400             if (mdef->m_lev == 0)
1401                 tmp = mdef->mhp;
1402             else
1403                 mdef->m_lev--;
1404             /* Automatic kill if drained past level 0 */
1405         }
1406         break;
1407     case AD_SSEX:
1408     case AD_SITM: /* for now these are the same */
1409     case AD_SEDU:
1410         if (magr->mcan)
1411             break;
1412         /* find an object to steal, non-cursed if magr is tame */
1413         for (obj = mdef->minvent; obj; obj = obj->nobj)
1414             if (!magr->mtame || !obj->cursed)
1415                 break;
1416
1417         if (obj) {
1418             char onambuf[BUFSZ], mdefnambuf[BUFSZ];
1419
1420             /* make a special x_monnam() call that never omits
1421                the saddle, and save it for later messages */
1422             Strcpy(mdefnambuf,
1423                    x_monnam(mdef, ARTICLE_THE, (char *) 0, 0, FALSE));
1424
1425             otmp = obj;
1426             if (u.usteed == mdef && otmp == which_armor(mdef, W_SADDLE))
1427                 /* "You can no longer ride <steed>." */
1428                 dismount_steed(DISMOUNT_POLY);
1429             obj_extract_self(otmp);
1430             if (otmp->owornmask) {
1431                 mdef->misc_worn_check &= ~otmp->owornmask;
1432                 if (otmp->owornmask & W_WEP)
1433                     mwepgone(mdef);
1434                 otmp->owornmask = 0L;
1435                 update_mon_intrinsics(mdef, otmp, FALSE, FALSE);
1436             }
1437             /* add_to_minv() might free otmp [if it merges] */
1438             if (vis)
1439                 Strcpy(onambuf, doname(otmp));
1440             (void) add_to_minv(magr, otmp);
1441             if (vis) {
1442                 Strcpy(buf, Monnam(magr));
1443 /*JP
1444                 pline("%s steals %s from %s!", buf, onambuf, mdefnambuf);
1445 */
1446                 pline("%s\82Í%s\82©\82ç%s\82ð\93\90\82ñ\82¾\81I", buf, mdefnambuf, onambuf);
1447             }
1448             possibly_unwield(mdef, FALSE);
1449             mdef->mstrategy &= ~STRAT_WAITFORU;
1450             mselftouch(mdef, (const char *) 0, FALSE);
1451             if (mdef->mhp <= 0)
1452                 return (MM_DEF_DIED
1453                         | (grow_up(magr, mdef) ? 0 : MM_AGR_DIED));
1454             if (pa->mlet == S_NYMPH && !tele_restrict(magr)) {
1455                 (void) rloc(magr, TRUE);
1456                 if (vis && !canspotmon(magr))
1457 /*JP
1458                     pline("%s suddenly disappears!", buf);
1459 */
1460                     pline("%s\82Í\93Ë\91R\8fÁ\82¦\82½\81I", buf);
1461             }
1462         }
1463         tmp = 0;
1464         break;
1465     case AD_DREN:
1466         if (!cancelled && !rn2(4))
1467             xdrainenergym(mdef, vis && mattk->aatyp != AT_ENGL);
1468         tmp = 0;
1469         break;
1470     case AD_DRST:
1471     case AD_DRDX:
1472     case AD_DRCO:
1473         if (!cancelled && !rn2(8)) {
1474             if (vis)
1475 #if 0 /*JP*/
1476                 pline("%s %s was poisoned!", s_suffix(Monnam(magr)),
1477                       mpoisons_subj(magr, mattk));
1478 #else
1479                 pline("%s\82Ì%s\82Í\93Å\82³\82ê\82Ä\82¢\82é\81I", Monnam(magr),
1480                       mpoisons_subj(magr, mattk));
1481 #endif
1482             if (resists_poison(mdef)) {
1483                 if (vis)
1484 /*JP
1485                     pline_The("poison doesn't seem to affect %s.",
1486 */
1487                     pline("%s\82Í\93Å\82Ì\89e\8b¿\82ð\8eó\82¯\82È\82¢\81D",
1488                               mon_nam(mdef));
1489             } else {
1490                 if (rn2(10))
1491                     tmp += rn1(10, 6);
1492                 else {
1493                     if (vis)
1494 /*JP
1495                         pline_The("poison was deadly...");
1496 */
1497                         pline("\93Å\82Í\92v\8e\80\97Ê\82¾\82Á\82½\81D\81D\81D");
1498                     tmp = mdef->mhp;
1499                 }
1500             }
1501         }
1502         break;
1503     case AD_DRIN:
1504         if (notonhead || !has_head(pd)) {
1505             if (vis)
1506 /*JP
1507                 pline("%s doesn't seem harmed.", Monnam(mdef));
1508 */
1509                 pline("%s\82Í\8f\9d\82Â\82¢\82½\82æ\82¤\82É\82Í\8c©\82¦\82È\82¢\81D", Monnam(mdef));
1510             /* Not clear what to do for green slimes */
1511             tmp = 0;
1512             break;
1513         }
1514         if ((mdef->misc_worn_check & W_ARMH) && rn2(8)) {
1515             if (vis) {
1516                 Strcpy(buf, s_suffix(Monnam(mdef)));
1517 #if 0 /*JP*/
1518                 pline("%s helmet blocks %s attack to %s head.", buf,
1519                       s_suffix(mon_nam(magr)), mhis(mdef));
1520 #else
1521                 pline("%s\82Ì\8a\95\82Í%s\82Ì\93ª\82Ö\82Ì\8dU\8c\82\82ð\96h\82¢\82¾\81D", buf,
1522                       mon_nam(magr));
1523 #endif
1524             }
1525             break;
1526         }
1527         res = eat_brains(magr, mdef, vis, &tmp);
1528         break;
1529     case AD_SLIM:
1530         if (cancelled)
1531             break; /* physical damage only */
1532         if (!rn2(4) && !slimeproof(pd)) {
1533             if (!munslime(mdef, FALSE) && mdef->mhp > 0) {
1534                 if (newcham(mdef, &mons[PM_GREEN_SLIME], FALSE, vis))
1535                     pd = mdef->data;
1536                 mdef->mstrategy &= ~STRAT_WAITFORU;
1537                 res = MM_HIT;
1538             }
1539             /* munslime attempt could have been fatal,
1540                potentially to multiple monsters (SCR_FIRE) */
1541             if (magr->mhp < 1)
1542                 res |= MM_AGR_DIED;
1543             if (mdef->mhp < 1)
1544                 res |= MM_DEF_DIED;
1545             tmp = 0;
1546         }
1547         break;
1548     case AD_STCK:
1549         if (cancelled)
1550             tmp = 0;
1551         break;
1552     case AD_WRAP: /* monsters cannot grab one another, it's too hard */
1553         if (magr->mcan)
1554             tmp = 0;
1555         break;
1556     case AD_ENCH:
1557         /* there's no msomearmor() function, so just do damage */
1558         /* if (cancelled) break; */
1559         break;
1560     default:
1561         tmp = 0;
1562         break;
1563     }
1564     if (!tmp)
1565         return res;
1566
1567     if ((mdef->mhp -= tmp) < 1) {
1568         if (m_at(mdef->mx, mdef->my) == magr) { /* see gulpmm() */
1569             remove_monster(mdef->mx, mdef->my);
1570             mdef->mhp = 1; /* otherwise place_monster will complain */
1571             place_monster(mdef, mdef->mx, mdef->my);
1572             mdef->mhp = 0;
1573         }
1574         monkilled(mdef, "", (int) mattk->adtyp);
1575         if (mdef->mhp > 0)
1576             return res; /* mdef lifesaved */
1577         else if (res == MM_AGR_DIED)
1578             return (MM_DEF_DIED | MM_AGR_DIED);
1579
1580         if (mattk->adtyp == AD_DGST) {
1581             /* various checks similar to dog_eat and meatobj.
1582              * after monkilled() to provide better message ordering */
1583             if (mdef->cham >= LOW_PM) {
1584                 (void) newcham(magr, (struct permonst *) 0, FALSE, TRUE);
1585             } else if (pd == &mons[PM_GREEN_SLIME] && !slimeproof(pa)) {
1586                 (void) newcham(magr, &mons[PM_GREEN_SLIME], FALSE, TRUE);
1587             } else if (pd == &mons[PM_WRAITH]) {
1588                 (void) grow_up(magr, (struct monst *) 0);
1589                 /* don't grow up twice */
1590                 return (MM_DEF_DIED | (magr->mhp > 0 ? 0 : MM_AGR_DIED));
1591             } else if (pd == &mons[PM_NURSE]) {
1592                 magr->mhp = magr->mhpmax;
1593             }
1594         }
1595         /* caveat: above digestion handling doesn't keep `pa' up to date */
1596
1597         return (MM_DEF_DIED | (grow_up(magr, mdef) ? 0 : MM_AGR_DIED));
1598     }
1599     return (res == MM_AGR_DIED) ? MM_AGR_DIED : MM_HIT;
1600 }
1601
1602 void
1603 paralyze_monst(mon, amt)
1604 struct monst *mon;
1605 int amt;
1606 {
1607     if (amt > 127)
1608         amt = 127;
1609
1610     mon->mcanmove = 0;
1611     mon->mfrozen = amt;
1612     mon->meating = 0; /* terminate any meal-in-progress */
1613     mon->mstrategy &= ~STRAT_WAITFORU;
1614 }
1615
1616 /* `mon' is hit by a sleep attack; return 1 if it's affected, 0 otherwise */
1617 int
1618 sleep_monst(mon, amt, how)
1619 struct monst *mon;
1620 int amt, how;
1621 {
1622     if (resists_sleep(mon)
1623         || (how >= 0 && resist(mon, (char) how, 0, NOTELL))) {
1624         shieldeff(mon->mx, mon->my);
1625     } else if (mon->mcanmove) {
1626         finish_meating(mon); /* terminate any meal-in-progress */
1627         amt += (int) mon->mfrozen;
1628         if (amt > 0) { /* sleep for N turns */
1629             mon->mcanmove = 0;
1630             mon->mfrozen = min(amt, 127);
1631         } else { /* sleep until awakened */
1632             mon->msleeping = 1;
1633         }
1634         return 1;
1635     }
1636     return 0;
1637 }
1638
1639 /* sleeping grabber releases, engulfer doesn't; don't use for paralysis! */
1640 void
1641 slept_monst(mon)
1642 struct monst *mon;
1643 {
1644     if ((mon->msleeping || !mon->mcanmove) && mon == u.ustuck
1645         && !sticks(youmonst.data) && !u.uswallow) {
1646 /*JP
1647         pline("%s grip relaxes.", s_suffix(Monnam(mon)));
1648 */
1649         pline("%s\82Ì\88¬\82é\97Í\82ª\8eã\82­\82È\82Á\82½\81D", Monnam(mon));
1650         unstuck(mon);
1651     }
1652 }
1653
1654 void
1655 rustm(mdef, obj)
1656 struct monst *mdef;
1657 struct obj *obj;
1658 {
1659     int dmgtyp;
1660
1661     if (!mdef || !obj)
1662         return; /* just in case */
1663     /* AD_ACID is handled in passivemm */
1664     if (dmgtype(mdef->data, AD_CORR))
1665         dmgtyp = ERODE_CORRODE;
1666     else if (dmgtype(mdef->data, AD_RUST))
1667         dmgtyp = ERODE_RUST;
1668     else if (dmgtype(mdef->data, AD_FIRE))
1669         dmgtyp = ERODE_BURN;
1670     else
1671         return;
1672     (void) erode_obj(obj, NULL, dmgtyp, EF_GREASE | EF_VERBOSE);
1673 }
1674
1675 STATIC_OVL void
1676 mswingsm(magr, mdef, otemp)
1677 struct monst *magr, *mdef;
1678 struct obj *otemp;
1679 {
1680     if (flags.verbose && !Blind && mon_visible(magr)) {
1681 #if 0 /*JP*/
1682         pline("%s %s %s%s %s at %s.", Monnam(magr),
1683               (objects[otemp->otyp].oc_dir & PIERCE) ? "thrusts" : "swings",
1684               (otemp->quan > 1L) ? "one of " : "", mhis(magr), xname(otemp),
1685               mon_nam(mdef));
1686 #else
1687         pline((objects[otemp->otyp].oc_dir & PIERCE) ?
1688               "%s\82Í%s\82Å%s\82ð\93Ë\82¢\82½\81D" :
1689               "%s\82Í%s\82ð\90U\82è\82Ü\82í\82µ%s\82ð\8dU\8c\82\82µ\82½\81D", Monnam(magr),
1690               xname(otemp), mon_nam(mdef));
1691 #endif
1692     }
1693 }
1694
1695 /*
1696  * Passive responses by defenders.  Does not replicate responses already
1697  * handled above.  Returns same values as mattackm.
1698  */
1699 STATIC_OVL int
1700 passivemm(magr, mdef, mhit, mdead)
1701 register struct monst *magr, *mdef;
1702 boolean mhit;
1703 int mdead;
1704 {
1705     register struct permonst *mddat = mdef->data;
1706     register struct permonst *madat = magr->data;
1707     char buf[BUFSZ];
1708     int i, tmp;
1709
1710     for (i = 0;; i++) {
1711         if (i >= NATTK)
1712             return (mdead | mhit); /* no passive attacks */
1713         if (mddat->mattk[i].aatyp == AT_NONE)
1714             break;
1715     }
1716     if (mddat->mattk[i].damn)
1717         tmp = d((int) mddat->mattk[i].damn, (int) mddat->mattk[i].damd);
1718     else if (mddat->mattk[i].damd)
1719         tmp = d((int) mddat->mlevel + 1, (int) mddat->mattk[i].damd);
1720     else
1721         tmp = 0;
1722
1723     /* These affect the enemy even if defender killed */
1724     switch (mddat->mattk[i].adtyp) {
1725     case AD_ACID:
1726         if (mhit && !rn2(2)) {
1727             Strcpy(buf, Monnam(magr));
1728             if (canseemon(magr))
1729 #if 0 /*JP*/
1730                 pline("%s is splashed by %s acid!", buf,
1731                       s_suffix(mon_nam(mdef)));
1732 #else
1733                 pline("%s\82Í%s\82Ì\8e_\82ð\97\81\82Ñ\82½\81I", buf,
1734                       mon_nam(mdef));
1735 #endif
1736             if (resists_acid(magr)) {
1737                 if (canseemon(magr))
1738 /*JP
1739                     pline("%s is not affected.", Monnam(magr));
1740 */
1741                     pline("%s\82Í\89e\8b¿\82ð\8eó\82¯\82È\82¢\81D", Monnam(magr));
1742                 tmp = 0;
1743             }
1744         } else
1745             tmp = 0;
1746         if (!rn2(30))
1747             erode_armor(magr, ERODE_CORRODE);
1748         if (!rn2(6))
1749             acid_damage(MON_WEP(magr));
1750         goto assess_dmg;
1751     case AD_ENCH: /* KMH -- remove enchantment (disenchanter) */
1752         if (mhit && !mdef->mcan && otmp) {
1753             (void) drain_item(otmp);
1754             /* No message */
1755         }
1756         break;
1757     default:
1758         break;
1759     }
1760     if (mdead || mdef->mcan)
1761         return (mdead | mhit);
1762
1763     /* These affect the enemy only if defender is still alive */
1764     if (rn2(3))
1765         switch (mddat->mattk[i].adtyp) {
1766         case AD_PLYS: /* Floating eye */
1767             if (tmp > 127)
1768                 tmp = 127;
1769             if (mddat == &mons[PM_FLOATING_EYE]) {
1770                 if (!rn2(4))
1771                     tmp = 127;
1772                 if (magr->mcansee && haseyes(madat) && mdef->mcansee
1773                     && (perceives(madat) || !mdef->minvis)) {
1774 /*JP
1775                     Sprintf(buf, "%s gaze is reflected by %%s %%s.",
1776 */
1777                     Sprintf(buf, "%s\82Ì\82É\82ç\82Ý\82Í%%s\82É\82æ\82Á\82Ä%%s\81D",
1778                             s_suffix(Monnam(mdef)));
1779                     if (mon_reflects(magr,
1780                                      canseemon(magr) ? buf : (char *) 0))
1781                         return (mdead | mhit);
1782                     Strcpy(buf, Monnam(magr));
1783                     if (canseemon(magr))
1784 #if 0 /*JP*/
1785                         pline("%s is frozen by %s gaze!", buf,
1786                               s_suffix(mon_nam(mdef)));
1787 #else
1788                         pline("%s\82Í%s\82Ì\82É\82ç\82Ý\82Å\93®\82¯\82È\82­\82È\82Á\82½\81I", buf,
1789                               mon_nam(mdef));
1790 #endif
1791                     paralyze_monst(magr, tmp);
1792                     return (mdead | mhit);
1793                 }
1794             } else { /* gelatinous cube */
1795                 Strcpy(buf, Monnam(magr));
1796                 if (canseemon(magr))
1797 /*JP
1798                     pline("%s is frozen by %s.", buf, mon_nam(mdef));
1799 */
1800                     pline("%s\82Í%s\82É\82æ\82Á\82Ä\93®\82¯\82È\82­\82È\82Á\82½\81D", buf, mon_nam(mdef));
1801                 paralyze_monst(magr, tmp);
1802                 return (mdead | mhit);
1803             }
1804             return 1;
1805         case AD_COLD:
1806             if (resists_cold(magr)) {
1807                 if (canseemon(magr)) {
1808 /*JP
1809                     pline("%s is mildly chilly.", Monnam(magr));
1810 */
1811                     pline("%s\82Í\97â\82¦\82½\81D", Monnam(magr));
1812                     golemeffects(magr, AD_COLD, tmp);
1813                 }
1814                 tmp = 0;
1815                 break;
1816             }
1817             if (canseemon(magr))
1818 /*JP
1819                 pline("%s is suddenly very cold!", Monnam(magr));
1820 */
1821                 pline("%s\82Í\93Ë\91R\93\80\82è\82Ã\82¯\82É\82È\82Á\82½\81I", Monnam(magr));
1822             mdef->mhp += tmp / 2;
1823             if (mdef->mhpmax < mdef->mhp)
1824                 mdef->mhpmax = mdef->mhp;
1825             if (mdef->mhpmax > ((int) (mdef->m_lev + 1) * 8))
1826                 (void) split_mon(mdef, magr);
1827             break;
1828         case AD_STUN:
1829             if (!magr->mstun) {
1830                 magr->mstun = 1;
1831                 if (canseemon(magr))
1832 #if 0 /*JP*/
1833                     pline("%s %s...", Monnam(magr),
1834                           makeplural(stagger(magr->data, "stagger")));
1835 #else
1836                     pline("%s\82Í%s\81D\81D\81D", Monnam(magr),
1837                           jpast(stagger(magr->data, "\82æ\82ë\82ß\82­")));
1838 #endif
1839             }
1840             tmp = 0;
1841             break;
1842         case AD_FIRE:
1843             if (resists_fire(magr)) {
1844                 if (canseemon(magr)) {
1845 /*JP
1846                     pline("%s is mildly warmed.", Monnam(magr));
1847 */
1848                     pline("%s\82Í\92g\82©\82­\82È\82Á\82½\81D", Monnam(magr));
1849                     golemeffects(magr, AD_FIRE, tmp);
1850                 }
1851                 tmp = 0;
1852                 break;
1853             }
1854             if (canseemon(magr))
1855 /*JP
1856                 pline("%s is suddenly very hot!", Monnam(magr));
1857 */
1858                 pline("%s\82Í\93Ë\91R\82Æ\82Ä\82à\94M\82­\82È\82Á\82½\81I", Monnam(magr));
1859             break;
1860         case AD_ELEC:
1861             if (resists_elec(magr)) {
1862                 if (canseemon(magr)) {
1863 /*JP
1864                     pline("%s is mildly tingled.", Monnam(magr));
1865 */
1866                     pline("%s\82Í\83s\83\8a\83s\83\8a\82µ\82Ä\82¢\82é\81D", Monnam(magr));
1867                     golemeffects(magr, AD_ELEC, tmp);
1868                 }
1869                 tmp = 0;
1870                 break;
1871             }
1872             if (canseemon(magr))
1873 /*JP
1874                 pline("%s is jolted with electricity!", Monnam(magr));
1875 */
1876                 pline("%s\82Í\93d\8bC\83V\83\87\83b\83N\82ð\82¤\82¯\82½\81I", Monnam(magr));
1877             break;
1878         default:
1879             tmp = 0;
1880             break;
1881         }
1882     else
1883         tmp = 0;
1884
1885 assess_dmg:
1886     if ((magr->mhp -= tmp) <= 0) {
1887         monkilled(magr, "", (int) mddat->mattk[i].adtyp);
1888         return (mdead | mhit | MM_AGR_DIED);
1889     }
1890     return (mdead | mhit);
1891 }
1892
1893 /* hero or monster has successfully hit target mon with drain energy attack */
1894 void
1895 xdrainenergym(mon, givemsg)
1896 struct monst *mon;
1897 boolean givemsg;
1898 {
1899     if (mon->mspec_used < 20 /* limit draining */
1900         && (attacktype(mon->data, AT_MAGC)
1901             || attacktype(mon->data, AT_BREA))) {
1902         mon->mspec_used += d(2, 2);
1903         if (givemsg)
1904 /*JP
1905             pline("%s seems lethargic.", Monnam(mon));
1906 */
1907             pline("%s\82Í\96³\8bC\97Í\82É\82È\82Á\82½\82æ\82¤\82¾\81D", Monnam(mon));
1908     }
1909 }
1910
1911 /* "aggressive defense"; what type of armor prevents specified attack
1912    from touching its target? */
1913 long
1914 attk_protection(aatyp)
1915 int aatyp;
1916 {
1917     long w_mask = 0L;
1918
1919     switch (aatyp) {
1920     case AT_NONE:
1921     case AT_SPIT:
1922     case AT_EXPL:
1923     case AT_BOOM:
1924     case AT_GAZE:
1925     case AT_BREA:
1926     case AT_MAGC:
1927         w_mask = ~0L; /* special case; no defense needed */
1928         break;
1929     case AT_CLAW:
1930     case AT_TUCH:
1931     case AT_WEAP:
1932         w_mask = W_ARMG; /* caller needs to check for weapon */
1933         break;
1934     case AT_KICK:
1935         w_mask = W_ARMF;
1936         break;
1937     case AT_BUTT:
1938         w_mask = W_ARMH;
1939         break;
1940     case AT_HUGS:
1941         w_mask = (W_ARMC | W_ARMG); /* attacker needs both to be protected */
1942         break;
1943     case AT_BITE:
1944     case AT_STNG:
1945     case AT_ENGL:
1946     case AT_TENT:
1947     default:
1948         w_mask = 0L; /* no defense available */
1949         break;
1950     }
1951     return w_mask;
1952 }
1953
1954 /*mhitm.c*/