OSDN Git Service

update year to 2020
[jnethack/source.git] / src / uhitm.c
1 /* NetHack 3.6  uhitm.c $NHDT-Date: 1573764936 2019/11/14 20:55:36 $  $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.215 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /*-Copyright (c) Robert Patrick Rankin, 2012. */
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-2020            */
9 /* JNetHack may be freely redistributed.  See license for details. */
10
11 #include "hack.h"
12
13 STATIC_DCL boolean FDECL(known_hitum, (struct monst *, struct obj *, int *,
14                                        int, int, struct attack *, int));
15 STATIC_DCL boolean FDECL(theft_petrifies, (struct obj *));
16 STATIC_DCL void FDECL(steal_it, (struct monst *, struct attack *));
17 STATIC_DCL boolean FDECL(hitum_cleave, (struct monst *, struct attack *));
18 STATIC_DCL boolean FDECL(hitum, (struct monst *, struct attack *));
19 STATIC_DCL boolean FDECL(hmon_hitmon, (struct monst *, struct obj *, int,
20                                        int));
21 STATIC_DCL int FDECL(joust, (struct monst *, struct obj *));
22 STATIC_DCL void NDECL(demonpet);
23 STATIC_DCL boolean FDECL(m_slips_free, (struct monst *, struct attack *));
24 STATIC_DCL int FDECL(explum, (struct monst *, struct attack *));
25 STATIC_DCL void FDECL(start_engulf, (struct monst *));
26 STATIC_DCL void NDECL(end_engulf);
27 STATIC_DCL int FDECL(gulpum, (struct monst *, struct attack *));
28 STATIC_DCL boolean FDECL(hmonas, (struct monst *));
29 STATIC_DCL void FDECL(nohandglow, (struct monst *));
30 STATIC_DCL boolean FDECL(shade_aware, (struct obj *));
31
32 extern boolean notonhead; /* for long worms */
33
34 /* Used to flag attacks caused by Stormbringer's maliciousness. */
35 static boolean override_confirmation = FALSE;
36
37 #define PROJECTILE(obj) ((obj) && is_ammo(obj))
38
39 void
40 erode_armor(mdef, hurt)
41 struct monst *mdef;
42 int hurt;
43 {
44     struct obj *target;
45
46     /* What the following code does: it keeps looping until it
47      * finds a target for the rust monster.
48      * Head, feet, etc... not covered by metal, or covered by
49      * rusty metal, are not targets.  However, your body always
50      * is, no matter what covers it.
51      */
52     while (1) {
53         switch (rn2(5)) {
54         case 0:
55             target = which_armor(mdef, W_ARMH);
56             if (!target
57                 || erode_obj(target, xname(target), hurt, EF_GREASE)
58                        == ER_NOTHING)
59                 continue;
60             break;
61         case 1:
62             target = which_armor(mdef, W_ARMC);
63             if (target) {
64                 (void) erode_obj(target, xname(target), hurt,
65                                  EF_GREASE | EF_VERBOSE);
66                 break;
67             }
68             if ((target = which_armor(mdef, W_ARM)) != (struct obj *) 0) {
69                 (void) erode_obj(target, xname(target), hurt,
70                                  EF_GREASE | EF_VERBOSE);
71             } else if ((target = which_armor(mdef, W_ARMU))
72                        != (struct obj *) 0) {
73                 (void) erode_obj(target, xname(target), hurt,
74                                  EF_GREASE | EF_VERBOSE);
75             }
76             break;
77         case 2:
78             target = which_armor(mdef, W_ARMS);
79             if (!target
80                 || erode_obj(target, xname(target), hurt, EF_GREASE)
81                        == ER_NOTHING)
82                 continue;
83             break;
84         case 3:
85             target = which_armor(mdef, W_ARMG);
86             if (!target
87                 || erode_obj(target, xname(target), hurt, EF_GREASE)
88                        == ER_NOTHING)
89                 continue;
90             break;
91         case 4:
92             target = which_armor(mdef, W_ARMF);
93             if (!target
94                 || erode_obj(target, xname(target), hurt, EF_GREASE)
95                        == ER_NOTHING)
96                 continue;
97             break;
98         }
99         break; /* Out of while loop */
100     }
101 }
102
103 /* FALSE means it's OK to attack */
104 boolean
105 attack_checks(mtmp, wep)
106 register struct monst *mtmp;
107 struct obj *wep; /* uwep for attack(), null for kick_monster() */
108 {
109     int glyph;
110
111     /* if you're close enough to attack, alert any waiting monster */
112     mtmp->mstrategy &= ~STRAT_WAITMASK;
113
114     if (u.uswallow && mtmp == u.ustuck)
115         return FALSE;
116
117     if (context.forcefight) {
118         /* Do this in the caller, after we checked that the monster
119          * didn't die from the blow.  Reason: putting the 'I' there
120          * causes the hero to forget the square's contents since
121          * both 'I' and remembered contents are stored in .glyph.
122          * If the monster dies immediately from the blow, the 'I' will
123          * not stay there, so the player will have suddenly forgotten
124          * the square's contents for no apparent reason.
125         if (!canspotmon(mtmp)
126             && !glyph_is_invisible(levl[bhitpos.x][bhitpos.y].glyph))
127             map_invisible(bhitpos.x, bhitpos.y);
128          */
129         return FALSE;
130     }
131
132     /* cache the shown glyph;
133        cases which might change it (by placing or removing
134        'rembered, unseen monster' glyph or revealing a mimic)
135        always return without further reference to this */
136     glyph = glyph_at(bhitpos.x, bhitpos.y);
137
138     /* Put up an invisible monster marker, but with exceptions for
139      * monsters that hide and monsters you've been warned about.
140      * The former already prints a warning message and
141      * prevents you from hitting the monster just via the hidden monster
142      * code below; if we also did that here, similar behavior would be
143      * happening two turns in a row.  The latter shows a glyph on
144      * the screen, so you know something is there.
145      */
146     if (!canspotmon(mtmp)
147         && !glyph_is_warning(glyph) && !glyph_is_invisible(glyph)
148         && !(!Blind && mtmp->mundetected && hides_under(mtmp->data))) {
149 /*JP
150         pline("Wait!  There's %s there you can't see!", something);
151 */
152         pline("\82¿\82å\82Á\82Æ\91Ò\82Á\82½\81I\8ep\82Ì\8c©\82¦\82È\82¢%s\82ª\82¢\82é\81I", something);
153         map_invisible(bhitpos.x, bhitpos.y);
154         /* if it was an invisible mimic, treat it as if we stumbled
155          * onto a visible mimic
156          */
157         if (M_AP_TYPE(mtmp) && !Protection_from_shape_changers
158             /* applied pole-arm attack is too far to get stuck */
159             && distu(mtmp->mx, mtmp->my) <= 2) {
160             if (!u.ustuck && !mtmp->mflee && dmgtype(mtmp->data, AD_STCK))
161                 u.ustuck = mtmp;
162         }
163         /* #H7329 - if hero is on engraved "Elbereth", this will end up
164          * assessing an alignment penalty and removing the engraving
165          * even though no attack actually occurs.  Since it also angers
166          * peacefuls, we're operating as if an attack attempt did occur
167          * and the Elbereth behavior is consistent.
168          */
169         wakeup(mtmp, TRUE); /* always necessary; also un-mimics mimics */
170         return TRUE;
171     }
172
173     if (M_AP_TYPE(mtmp) && !Protection_from_shape_changers && !sensemon(mtmp)
174         && !glyph_is_warning(glyph)) {
175         /* If a hidden mimic was in a square where a player remembers
176          * some (probably different) unseen monster, the player is in
177          * luck--he attacks it even though it's hidden.
178          */
179         if (glyph_is_invisible(glyph)) {
180             seemimic(mtmp);
181             return FALSE;
182         }
183         stumble_onto_mimic(mtmp);
184         return TRUE;
185     }
186
187     if (mtmp->mundetected && !canseemon(mtmp)
188         && !glyph_is_warning(glyph)
189         && (hides_under(mtmp->data) || mtmp->data->mlet == S_EEL)) {
190         mtmp->mundetected = mtmp->msleeping = 0;
191         newsym(mtmp->mx, mtmp->my);
192         if (glyph_is_invisible(glyph)) {
193             seemimic(mtmp);
194             return FALSE;
195         }
196         if (!((Blind ? Blind_telepat : Unblind_telepat) || Detect_monsters)) {
197             struct obj *obj;
198
199             if (!Blind && Hallucination)
200 #if 0 /*JP:T*/
201                 pline("A %s %s appeared!",
202                       mtmp->mtame ? "tame" : "wild", l_monnam(mtmp));
203 #else
204                 pline("%s%s\82ª\8c»\82ê\82½\81I",
205                       mtmp->mtame ? "\8eè\82È\82Ã\82¯\82ç\82ê\82½" : "\96ì\90\82Ì", l_monnam(mtmp));
206 #endif
207             else if (Blind || (is_pool(mtmp->mx, mtmp->my) && !Underwater))
208 /*JP
209                 pline("Wait!  There's a hidden monster there!");
210 */
211                 pline("\91Ò\82Ä\81I\89ö\95¨\82ª\89B\82ê\82Ä\82¢\82é\81I");
212             else if ((obj = level.objects[mtmp->mx][mtmp->my]) != 0)
213 #if 0 /*JP:T*/
214                 pline("Wait!  There's %s hiding under %s!",
215                       an(l_monnam(mtmp)), doname(obj));
216 #else
217                 pline("\91Ò\82Ä\81I%s\82Ì\89º\82É%s\82ª\89B\82ê\82Ä\82¢\82é\81I",
218                       doname(obj), l_monnam(mtmp));
219 #endif
220             return TRUE;
221         }
222     }
223
224     /*
225      * make sure to wake up a monster from the above cases if the
226      * hero can sense that the monster is there.
227      */
228     if ((mtmp->mundetected || M_AP_TYPE(mtmp)) && sensemon(mtmp)) {
229         mtmp->mundetected = 0;
230         wakeup(mtmp, TRUE);
231     }
232
233     if (flags.confirm && mtmp->mpeaceful
234         && !Confusion && !Hallucination && !Stunned) {
235         /* Intelligent chaotic weapons (Stormbringer) want blood */
236         if (wep && wep->oartifact == ART_STORMBRINGER) {
237             override_confirmation = TRUE;
238             return FALSE;
239         }
240         if (canspotmon(mtmp)) {
241             char qbuf[QBUFSZ];
242
243 /*JP
244             Sprintf(qbuf, "Really attack %s?", mon_nam(mtmp));
245 */
246             Sprintf(qbuf, "\96{\93\96\82É%s\82ð\8dU\8c\82\82·\82é\82Ì\81H", mon_nam(mtmp));
247             if (!paranoid_query(ParanoidHit, qbuf)) {
248                 context.move = 0;
249                 return TRUE;
250             }
251         }
252     }
253
254     return FALSE;
255 }
256
257 /*
258  * It is unchivalrous for a knight to attack the defenseless or from behind.
259  */
260 void
261 check_caitiff(mtmp)
262 struct monst *mtmp;
263 {
264     if (u.ualign.record <= -10)
265         return;
266
267     if (Role_if(PM_KNIGHT) && u.ualign.type == A_LAWFUL
268         && (!mtmp->mcanmove || mtmp->msleeping
269             || (mtmp->mflee && !mtmp->mavenge))) {
270 /*JP
271         You("caitiff!");
272 */
273         pline("\82±\82ê\82Í\94Ú\8b¯\82È\8ds\82¢\82¾\81I");
274         adjalign(-1);
275     } else if (Role_if(PM_SAMURAI) && mtmp->mpeaceful) {
276         /* attacking peaceful creatures is bad for the samurai's giri */
277 /*JP
278         You("dishonorably attack the innocent!");
279 */
280         pline("\96³\8eÀ\82Ì\8eÒ\82ð\8dU\8c\82\82·\82é\82Ì\82Í\95s\96¼\97_\82¾\81I");
281         adjalign(-1);
282     }
283 }
284
285 int
286 find_roll_to_hit(mtmp, aatyp, weapon, attk_count, role_roll_penalty)
287 register struct monst *mtmp;
288 uchar aatyp;        /* usually AT_WEAP or AT_KICK */
289 struct obj *weapon; /* uwep or uswapwep or NULL */
290 int *attk_count, *role_roll_penalty;
291 {
292     int tmp, tmp2;
293
294     *role_roll_penalty = 0; /* default is `none' */
295
296     tmp = 1 + Luck + abon() + find_mac(mtmp) + u.uhitinc
297           + maybe_polyd(youmonst.data->mlevel, u.ulevel);
298
299     /* some actions should occur only once during multiple attacks */
300     if (!(*attk_count)++) {
301         /* knight's chivalry or samurai's giri */
302         check_caitiff(mtmp);
303     }
304
305     /* adjust vs. (and possibly modify) monster state */
306     if (mtmp->mstun)
307         tmp += 2;
308     if (mtmp->mflee)
309         tmp += 2;
310
311     if (mtmp->msleeping) {
312         mtmp->msleeping = 0;
313         tmp += 2;
314     }
315     if (!mtmp->mcanmove) {
316         tmp += 4;
317         if (!rn2(10)) {
318             mtmp->mcanmove = 1;
319             mtmp->mfrozen = 0;
320         }
321     }
322
323     /* role/race adjustments */
324     if (Role_if(PM_MONK) && !Upolyd) {
325         if (uarm)
326             tmp -= (*role_roll_penalty = urole.spelarmr);
327         else if (!uwep && !uarms)
328             tmp += (u.ulevel / 3) + 2;
329     }
330     if (is_orc(mtmp->data)
331         && maybe_polyd(is_elf(youmonst.data), Race_if(PM_ELF)))
332         tmp++;
333
334     /* encumbrance: with a lot of luggage, your agility diminishes */
335     if ((tmp2 = near_capacity()) != 0)
336         tmp -= (tmp2 * 2) - 1;
337     if (u.utrap)
338         tmp -= 3;
339
340     /*
341      * hitval applies if making a weapon attack while wielding a weapon;
342      * weapon_hit_bonus applies if doing a weapon attack even bare-handed
343      * or if kicking as martial artist
344      */
345     if (aatyp == AT_WEAP || aatyp == AT_CLAW) {
346         if (weapon)
347             tmp += hitval(weapon, mtmp);
348         tmp += weapon_hit_bonus(weapon);
349     } else if (aatyp == AT_KICK && martial_bonus()) {
350         tmp += weapon_hit_bonus((struct obj *) 0);
351     }
352
353     return tmp;
354 }
355
356 /* try to attack; return False if monster evaded;
357    u.dx and u.dy must be set */
358 boolean
359 attack(mtmp)
360 register struct monst *mtmp;
361 {
362     register struct permonst *mdat = mtmp->data;
363
364     /* This section of code provides protection against accidentally
365      * hitting peaceful (like '@') and tame (like 'd') monsters.
366      * Protection is provided as long as player is not: blind, confused,
367      * hallucinating or stunned.
368      * changes by wwp 5/16/85
369      * More changes 12/90, -dkh-. if its tame and safepet, (and protected
370      * 07/92) then we assume that you're not trying to attack. Instead,
371      * you'll usually just swap places if this is a movement command
372      */
373     /* Intelligent chaotic weapons (Stormbringer) want blood */
374     if (is_safepet(mtmp) && !context.forcefight) {
375         if (!uwep || uwep->oartifact != ART_STORMBRINGER) {
376             /* There are some additional considerations: this won't work
377              * if in a shop or Punished or you miss a random roll or
378              * if you can walk thru walls and your pet cannot (KAA) or
379              * if your pet is a long worm with a tail.
380              * There's also a chance of displacing a "frozen" monster:
381              * sleeping monsters might magically walk in their sleep.
382              */
383             boolean foo = (Punished || !rn2(7)
384                            || (is_longworm(mtmp->data) && mtmp->wormno)),
385                     inshop = FALSE;
386             char *p;
387
388             /* only check for in-shop if don't already have reason to stop */
389             if (!foo) {
390                 for (p = in_rooms(mtmp->mx, mtmp->my, SHOPBASE); *p; p++)
391                     if (tended_shop(&rooms[*p - ROOMOFFSET])) {
392                         inshop = TRUE;
393                         break;
394                     }
395             }
396             if (inshop || foo || (IS_ROCK(levl[u.ux][u.uy].typ)
397                                   && !passes_walls(mtmp->data))) {
398                 char buf[BUFSZ];
399
400                 monflee(mtmp, rnd(6), FALSE, FALSE);
401                 Strcpy(buf, y_monnam(mtmp));
402                 buf[0] = highc(buf[0]);
403 /*JP
404                 You("stop.  %s is in the way!", buf);
405 */
406                 You("\8e~\82Ü\82Á\82½\81D%s\82ª\93¹\82É\82¢\82é\81I", buf);
407                 context.travel = context.travel1 = context.mv = context.run
408                     = 0;
409                 return TRUE;
410             } else if ((mtmp->mfrozen || (!mtmp->mcanmove)
411                         || (mtmp->data->mmove == 0)) && rn2(6)) {
412 /*JP
413                 pline("%s doesn't seem to move!", Monnam(mtmp));
414 */
415                 pline("%s\82Í\93®\82¯\82È\82¢\82æ\82¤\82¾\81I", Monnam(mtmp));
416                 context.travel = context.travel1 = context.mv = context.run
417                     = 0;
418                 return TRUE;
419             } else
420                 return FALSE;
421         }
422     }
423
424     /* possibly set in attack_checks;
425        examined in known_hitum, called via hitum or hmonas below */
426     override_confirmation = FALSE;
427     /* attack_checks() used to use <u.ux+u.dx,u.uy+u.dy> directly, now
428        it uses bhitpos instead; it might map an invisible monster there */
429     bhitpos.x = u.ux + u.dx;
430     bhitpos.y = u.uy + u.dy;
431     notonhead = (bhitpos.x != mtmp->mx || bhitpos.y != mtmp->my);
432     if (attack_checks(mtmp, uwep))
433         return TRUE;
434
435     if (Upolyd && noattacks(youmonst.data)) {
436         /* certain "pacifist" monsters don't attack */
437 /*JP
438         You("have no way to attack monsters physically.");
439 */
440         You("\95¨\97\9d\93I\82É\89ö\95¨\82ð\8dU\8c\82\82·\82é\82·\82×\82ª\82È\82¢\81D");
441         mtmp->mstrategy &= ~STRAT_WAITMASK;
442         goto atk_done;
443     }
444
445 /*JP
446     if (check_capacity("You cannot fight while so heavily loaded.")
447 */
448     if (check_capacity("\82 \82È\82½\82Í\95¨\82ð\82½\82­\82³\82ñ\8e\9d\82¿\82·\82¬\82Ä\90í\82¦\82È\82¢\81D")
449         /* consume extra nutrition during combat; maybe pass out */
450         || overexertion())
451         goto atk_done;
452
453     if (u.twoweap && !can_twoweapon())
454         untwoweapon();
455
456     if (unweapon) {
457         unweapon = FALSE;
458         if (flags.verbose) {
459             if (uwep)
460 /*JP
461                 You("begin bashing monsters with %s.", yname(uwep));
462 */
463                 You("%s\82Å\89ö\95¨\82ð\82È\82®\82è\82Â\82¯\82½\81D", yname(uwep));
464             else if (!cantwield(youmonst.data))
465 #if 0 /*JP:T*/
466                 You("begin %s monsters with your %s %s.",
467                     ing_suffix(Role_if(PM_MONK) ? "strike" : "bash"),
468                     uarmg ? "gloved" : "bare", /* Del Lamb */
469                     makeplural(body_part(HAND)));
470 #else
471                 You("%s%s\82Å\89ö\95¨\82ð%s\82Â\82¯\82½\81D",
472                     uarmg ? "\83O\83\8d\81[\83u\82ð\95t\82¯\82½" : "\91f",
473                     body_part(HAND),
474                     Role_if(PM_MONK) ? "\91Å\82¿" : "\82È\82®\82è");
475 #endif
476         }
477     }
478     exercise(A_STR, TRUE); /* you're exercising muscles */
479     /* andrew@orca: prevent unlimited pick-axe attacks */
480     u_wipe_engr(3);
481
482     /* Is the "it died" check actually correct? */
483     if (mdat->mlet == S_LEPRECHAUN && !mtmp->mfrozen && !mtmp->msleeping
484         && !mtmp->mconf && mtmp->mcansee && !rn2(7)
485         && (m_move(mtmp, 0) == 2 /* it died */
486             || mtmp->mx != u.ux + u.dx
487             || mtmp->my != u.uy + u.dy)) { /* it moved */
488 /*JP
489         You("miss wildly and stumble forwards.");
490 */
491         You("\91å\82«\82­\8aO\82µ\82Ä\91O\82É\82Â\82Ü\82Ã\82¢\82½\81D");
492         return FALSE;
493     }
494
495     if (Upolyd)
496         (void) hmonas(mtmp);
497     else
498         (void) hitum(mtmp, youmonst.data->mattk);
499     mtmp->mstrategy &= ~STRAT_WAITMASK;
500
501  atk_done:
502     /* see comment in attack_checks() */
503     /* we only need to check for this if we did an attack_checks()
504      * and it returned 0 (it's okay to attack), and the monster didn't
505      * evade.
506      */
507     if (context.forcefight && !DEADMONSTER(mtmp) && !canspotmon(mtmp)
508         && !glyph_is_invisible(levl[u.ux + u.dx][u.uy + u.dy].glyph)
509         && !(u.uswallow && mtmp == u.ustuck))
510         map_invisible(u.ux + u.dx, u.uy + u.dy);
511
512     return TRUE;
513 }
514
515 /* really hit target monster; returns TRUE if it still lives */
516 STATIC_OVL boolean
517 known_hitum(mon, weapon, mhit, rollneeded, armorpenalty, uattk, dieroll)
518 register struct monst *mon;
519 struct obj *weapon;
520 int *mhit;
521 int rollneeded, armorpenalty; /* for monks */
522 struct attack *uattk;
523 int dieroll;
524 {
525     boolean malive = TRUE,
526             /* hmon() might destroy weapon; remember aspect for cutworm */
527             slice_or_chop = (weapon && (is_blade(weapon) || is_axe(weapon)));
528
529     if (override_confirmation) {
530         /* this may need to be generalized if weapons other than
531            Stormbringer acquire similar anti-social behavior... */
532         if (flags.verbose)
533 /*JP
534             Your("bloodthirsty blade attacks!");
535 */
536             Your("\95\90\8aí\82Í\8c\8c\82É\8bQ\82¦\82Ä\82¢\82é\81I");
537     }
538
539     if (!*mhit) {
540         missum(mon, uattk, (rollneeded + armorpenalty > dieroll));
541     } else {
542         int oldhp = mon->mhp;
543         long oldweaphit = u.uconduct.weaphit;
544
545         /* KMH, conduct */
546         if (weapon && (weapon->oclass == WEAPON_CLASS || is_weptool(weapon)))
547             u.uconduct.weaphit++;
548
549         /* we hit the monster; be careful: it might die or
550            be knocked into a different location */
551         notonhead = (mon->mx != bhitpos.x || mon->my != bhitpos.y);
552         malive = hmon(mon, weapon, HMON_MELEE, dieroll);
553         if (malive) {
554             /* monster still alive */
555             if (!rn2(25) && mon->mhp < mon->mhpmax / 2
556                 && !(u.uswallow && mon == u.ustuck)) {
557                 /* maybe should regurgitate if swallowed? */
558                 monflee(mon, !rn2(3) ? rnd(100) : 0, FALSE, TRUE);
559
560                 if (u.ustuck == mon && !u.uswallow && !sticks(youmonst.data))
561                     u.ustuck = 0;
562             }
563             /* Vorpal Blade hit converted to miss */
564             /* could be headless monster or worm tail */
565             if (mon->mhp == oldhp) {
566                 *mhit = 0;
567                 /* a miss does not break conduct */
568                 u.uconduct.weaphit = oldweaphit;
569             }
570             if (mon->wormno && *mhit)
571                 cutworm(mon, bhitpos.x, bhitpos.y, slice_or_chop);
572         }
573     }
574     return malive;
575 }
576
577 /* hit the monster next to you and the monsters to the left and right of it;
578    return False if the primary target is killed, True otherwise */
579 STATIC_OVL boolean
580 hitum_cleave(target, uattk)
581 struct monst *target; /* non-Null; forcefight at nothing doesn't cleave... */
582 struct attack *uattk; /* ... but we don't enforce that here; Null works ok */
583 {
584     /* swings will be delivered in alternate directions; with consecutive
585        attacks it will simulate normal swing and backswing; when swings
586        are non-consecutive, hero will sometimes start a series of attacks
587        with a backswing--that doesn't impact actual play, just spoils the
588        simulation attempt a bit */
589     static boolean clockwise = FALSE;
590     unsigned i;
591     coord save_bhitpos;
592     int count, umort, x = u.ux, y = u.uy;
593
594     /* find the direction toward primary target */
595     for (i = 0; i < 8; ++i)
596         if (xdir[i] == u.dx && ydir[i] == u.dy)
597             break;
598     if (i == 8) {
599         impossible("hitum_cleave: unknown target direction [%d,%d,%d]?",
600                    u.dx, u.dy, u.dz);
601         return TRUE; /* target hasn't been killed */
602     }
603     /* adjust direction by two so that loop's increment (for clockwise)
604        or decrement (for counter-clockwise) will point at the spot next
605        to primary target */
606     i = (i + (clockwise ? 6 : 2)) % 8;
607     umort = u.umortality; /* used to detect life-saving */
608     save_bhitpos = bhitpos;
609
610     /*
611      * Three attacks:  adjacent to primary, primary, adjacent on other
612      * side.  Primary target must be present or we wouldn't have gotten
613      * here (forcefight at thin air won't 'cleave').  However, the
614      * first attack might kill it (gas spore explosion, weak long worm
615      * occupying both spots) so we don't assume that it's still present
616      * on the second attack.
617      */
618     for (count = 3; count > 0; --count) {
619         struct monst *mtmp;
620         int tx, ty, tmp, dieroll, mhit, attknum, armorpenalty;
621
622         /* ++i, wrap 8 to i=0 /or/ --i, wrap -1 to i=7 */
623         i = (i + (clockwise ? 1 : 7)) % 8;
624
625         tx = x + xdir[i], ty = y + ydir[i]; /* current target location */
626         if (!isok(tx, ty))
627             continue;
628         mtmp = m_at(tx, ty);
629         if (!mtmp) {
630             if (glyph_is_invisible(levl[tx][ty].glyph))
631                 (void) unmap_invisible(tx, ty);
632             continue;
633         }
634
635         tmp = find_roll_to_hit(mtmp, uattk->aatyp, uwep,
636                                &attknum, &armorpenalty);
637         dieroll = rnd(20);
638         mhit = (tmp > dieroll);
639         bhitpos.x = tx, bhitpos.y = ty; /* normally set up by attack() */
640         (void) known_hitum(mtmp, uwep, &mhit, tmp, armorpenalty,
641                            uattk, dieroll);
642         (void) passive(mtmp, uwep, mhit, !DEADMONSTER(mtmp), AT_WEAP, !uwep);
643
644         /* stop attacking if weapon is gone or hero got killed and
645            life-saved after passive counter-attack */
646         if (!uwep || u.umortality > umort)
647             break;
648     }
649     /* set up for next time */
650     clockwise = !clockwise; /* alternate */
651     bhitpos = save_bhitpos; /* in case somebody relies on bhitpos
652                              * designating the primary target */
653
654     /* return False if primary target died, True otherwise; note: if 'target'
655        was nonNull upon entry then it's still nonNull even if *target died */
656     return (target && DEADMONSTER(target)) ? FALSE : TRUE;
657 }
658
659 /* hit target monster; returns TRUE if it still lives */
660 STATIC_OVL boolean
661 hitum(mon, uattk)
662 struct monst *mon;
663 struct attack *uattk;
664 {
665     boolean malive, wep_was_destroyed = FALSE;
666     struct obj *wepbefore = uwep;
667     int armorpenalty, attknum = 0, x = u.ux + u.dx, y = u.uy + u.dy,
668                       tmp = find_roll_to_hit(mon, uattk->aatyp, uwep,
669                                              &attknum, &armorpenalty);
670     int dieroll = rnd(20);
671     int mhit = (tmp > dieroll || u.uswallow);
672
673     /* Cleaver attacks three spots, 'mon' and one on either side of 'mon';
674        it can't be part of dual-wielding but we guard against that anyway;
675        cleave return value reflects status of primary target ('mon') */
676     if (uwep && uwep->oartifact == ART_CLEAVER && !u.twoweap
677         && !u.uswallow && !u.ustuck && !NODIAG(u.umonnum))
678         return hitum_cleave(mon, uattk);
679
680     if (tmp > dieroll)
681         exercise(A_DEX, TRUE);
682     /* bhitpos is set up by caller */
683     malive = known_hitum(mon, uwep, &mhit, tmp, armorpenalty, uattk, dieroll);
684     if (wepbefore && !uwep)
685         wep_was_destroyed = TRUE;
686     (void) passive(mon, uwep, mhit, malive, AT_WEAP, wep_was_destroyed);
687
688     /* second attack for two-weapon combat; won't occur if Stormbringer
689        overrode confirmation (assumes Stormbringer is primary weapon)
690        or if the monster was killed or knocked to different location */
691     if (u.twoweap && !override_confirmation && malive && m_at(x, y) == mon) {
692         tmp = find_roll_to_hit(mon, uattk->aatyp, uswapwep, &attknum,
693                                &armorpenalty);
694         dieroll = rnd(20);
695         mhit = (tmp > dieroll || u.uswallow);
696         malive = known_hitum(mon, uswapwep, &mhit, tmp, armorpenalty, uattk,
697                              dieroll);
698         /* second passive counter-attack only occurs if second attack hits */
699         if (mhit)
700             (void) passive(mon, uswapwep, mhit, malive, AT_WEAP, !uswapwep);
701     }
702     return malive;
703 }
704
705 /* general "damage monster" routine; return True if mon still alive */
706 boolean
707 hmon(mon, obj, thrown, dieroll)
708 struct monst *mon;
709 struct obj *obj;
710 int thrown; /* HMON_xxx (0 => hand-to-hand, other => ranged) */
711 int dieroll;
712 {
713     boolean result, anger_guards;
714
715     anger_guards = (mon->mpeaceful
716                     && (mon->ispriest || mon->isshk || is_watch(mon->data)));
717     result = hmon_hitmon(mon, obj, thrown, dieroll);
718     if (mon->ispriest && !rn2(2))
719         ghod_hitsu(mon);
720     if (anger_guards)
721         (void) angry_guards(!!Deaf);
722     return result;
723 }
724
725 /* guts of hmon() */
726 STATIC_OVL boolean
727 hmon_hitmon(mon, obj, thrown, dieroll)
728 struct monst *mon;
729 struct obj *obj;
730 int thrown; /* HMON_xxx (0 => hand-to-hand, other => ranged) */
731 int dieroll;
732 {
733     int tmp;
734     struct permonst *mdat = mon->data;
735     int barehand_silver_rings = 0;
736     /* The basic reason we need all these booleans is that we don't want
737      * a "hit" message when a monster dies, so we have to know how much
738      * damage it did _before_ outputting a hit message, but any messages
739      * associated with the damage don't come out until _after_ outputting
740      * a hit message.
741      */
742     boolean hittxt = FALSE, destroyed = FALSE, already_killed = FALSE;
743     boolean get_dmg_bonus = TRUE;
744     boolean ispoisoned = FALSE, needpoismsg = FALSE, poiskilled = FALSE,
745             unpoisonmsg = FALSE;
746     boolean silvermsg = FALSE, silverobj = FALSE;
747     boolean lightobj = FALSE;
748     boolean valid_weapon_attack = FALSE;
749     boolean unarmed = !uwep && !uarm && !uarms;
750     boolean hand_to_hand = (thrown == HMON_MELEE
751                             /* not grapnels; applied implies uwep */
752                             || (thrown == HMON_APPLIED && is_pole(uwep)));
753     int jousting = 0;
754     long silverhit = 0L;
755     int wtype;
756     struct obj *monwep;
757     char saved_oname[BUFSZ];
758
759     saved_oname[0] = '\0';
760
761     wakeup(mon, TRUE);
762     if (!obj) { /* attack with bare hands */
763         if (mdat == &mons[PM_SHADE])
764             tmp = 0;
765         else if (martial_bonus())
766             tmp = rnd(4); /* bonus for martial arts */
767         else
768             tmp = rnd(2);
769         valid_weapon_attack = (tmp > 1);
770         /* Blessed gloves give bonuses when fighting 'bare-handed'.  So do
771            silver rings.  Note:  rings are worn under gloves, so you don't
772            get both bonuses, and two silver rings don't give double bonus. */
773         tmp += special_dmgval(&youmonst, mon, (W_ARMG | W_RINGL | W_RINGR),
774                               &silverhit);
775         barehand_silver_rings += (((silverhit & W_RINGL) ? 1 : 0)
776                                   + ((silverhit & W_RINGR) ? 1 : 0));
777         if (barehand_silver_rings > 0)
778             silvermsg = TRUE;
779     } else {
780         if (!(artifact_light(obj) && obj->lamplit))
781             Strcpy(saved_oname, cxname(obj));
782         else
783             Strcpy(saved_oname, bare_artifactname(obj));
784         if (obj->oclass == WEAPON_CLASS || is_weptool(obj)
785             || obj->oclass == GEM_CLASS) {
786             /* is it not a melee weapon? */
787             if (/* if you strike with a bow... */
788                 is_launcher(obj)
789                 /* or strike with a missile in your hand... */
790                 || (!thrown && (is_missile(obj) || is_ammo(obj)))
791                 /* or use a pole at short range and not mounted... */
792                 || (!thrown && !u.usteed && is_pole(obj))
793                 /* or throw a missile without the proper bow... */
794                 || (is_ammo(obj) && (thrown != HMON_THROWN
795                                      || !ammo_and_launcher(obj, uwep)))) {
796                 /* then do only 1-2 points of damage */
797                 if (mdat == &mons[PM_SHADE] && !shade_glare(obj))
798                     tmp = 0;
799                 else
800                     tmp = rnd(2);
801                 if (objects[obj->otyp].oc_material == SILVER
802                     && mon_hates_silver(mon)) {
803                     silvermsg = TRUE;
804                     silverobj = TRUE;
805                     /* if it will already inflict dmg, make it worse */
806                     tmp += rnd((tmp) ? 20 : 10);
807                 }
808                 if (!thrown && obj == uwep && obj->otyp == BOOMERANG
809                     && rnl(4) == 4 - 1) {
810                     boolean more_than_1 = (obj->quan > 1L);
811
812 #if 0 /*JP:T*/
813                     pline("As you hit %s, %s%s breaks into splinters.",
814                           mon_nam(mon), more_than_1 ? "one of " : "",
815                           yname(obj));
816 #else
817                     pline("%s\82ð\8dU\8c\82\82·\82é\82Æ\81C%s%s\82Í\82±\82Á\82Ï\82Ý\82\82ñ\82É\82È\82Á\82½\81D",
818                           mon_nam(mon), yname(obj),
819                           more_than_1 ? "\82Ì\82Ð\82Æ\82Â" : "");
820 #endif
821                     if (!more_than_1)
822                         uwepgone(); /* set unweapon */
823                     useup(obj);
824                     if (!more_than_1)
825                         obj = (struct obj *) 0;
826                     hittxt = TRUE;
827                     if (mdat != &mons[PM_SHADE])
828                         tmp++;
829                 }
830             } else {
831                 tmp = dmgval(obj, mon);
832                 /* a minimal hit doesn't exercise proficiency */
833                 valid_weapon_attack = (tmp > 1);
834                 if (!valid_weapon_attack || mon == u.ustuck || u.twoweap
835                     /* Cleaver can hit up to three targets at once so don't
836                        let it also hit from behind or shatter foes' weapons */
837                     || (hand_to_hand && obj->oartifact == ART_CLEAVER)) {
838                     ; /* no special bonuses */
839                 } else if (mon->mflee && Role_if(PM_ROGUE) && !Upolyd
840                            /* multi-shot throwing is too powerful here */
841                            && hand_to_hand) {
842 /*JP
843                     You("strike %s from behind!", mon_nam(mon));
844 */
845                     You("%s\82ð\94w\8cã\82©\82ç\8dU\8c\82\82µ\82½\81I", mon_nam(mon));
846                     tmp += rnd(u.ulevel);
847                     hittxt = TRUE;
848                 } else if (dieroll == 2 && obj == uwep
849                            && obj->oclass == WEAPON_CLASS
850                            && (bimanual(obj)
851                                || (Role_if(PM_SAMURAI) && obj->otyp == KATANA
852                                    && !uarms))
853                            && ((wtype = uwep_skill_type()) != P_NONE
854                                && P_SKILL(wtype) >= P_SKILLED)
855                            && ((monwep = MON_WEP(mon)) != 0
856                                && !is_flimsy(monwep)
857                                && !obj_resists(monwep,
858                                        50 + 15 * (greatest_erosion(obj)
859                                                   - greatest_erosion(monwep)),
860                                                100))) {
861                     /*
862                      * 2.5% chance of shattering defender's weapon when
863                      * using a two-handed weapon; less if uwep is rusted.
864                      * [dieroll == 2 is most successful non-beheading or
865                      * -bisecting hit, in case of special artifact damage;
866                      * the percentage chance is (1/20)*(50/100).]
867                      * If attacker's weapon is rustier than defender's,
868                      * the obj_resists chance is increased so the shatter
869                      * chance is decreased; if less rusty, then vice versa.
870                      */
871                     setmnotwielded(mon, monwep);
872                     mon->weapon_check = NEED_WEAPON;
873 #if 0 /*JP:T*/
874                     pline("%s from the force of your blow!",
875                           Yobjnam2(monwep, "shatter"));
876 #else
877                     pline("%s\82Ì%s\82Í\82 \82È\82½\82Ì\88ê\8c\82\82Å\95²\81X\82É\82È\82Á\82½\81I",
878                           Monnam(mon), xname(monwep));
879 #endif
880                     m_useupall(mon, monwep);
881                     /* If someone just shattered MY weapon, I'd flee! */
882                     if (rn2(4)) {
883                         monflee(mon, d(2, 3), TRUE, TRUE);
884                     }
885                     hittxt = TRUE;
886                 }
887
888                 if (obj->oartifact
889                     && artifact_hit(&youmonst, mon, obj, &tmp, dieroll)) {
890                     if (DEADMONSTER(mon)) /* artifact killed monster */
891                         return FALSE;
892                     if (tmp == 0)
893                         return TRUE;
894                     hittxt = TRUE;
895                 }
896                 if (objects[obj->otyp].oc_material == SILVER
897                     && mon_hates_silver(mon)) {
898                     silvermsg = TRUE;
899                     silverobj = TRUE;
900                 }
901                 if (artifact_light(obj) && obj->lamplit
902                     && mon_hates_light(mon))
903                     lightobj = TRUE;
904                 if (u.usteed && !thrown && tmp > 0
905                     && weapon_type(obj) == P_LANCE && mon != u.ustuck) {
906                     jousting = joust(mon, obj);
907                     /* exercise skill even for minimal damage hits */
908                     if (jousting)
909                         valid_weapon_attack = TRUE;
910                 }
911                 if (thrown == HMON_THROWN
912                     && (is_ammo(obj) || is_missile(obj))) {
913                     if (ammo_and_launcher(obj, uwep)) {
914                         /* Elves and Samurai do extra damage using
915                          * their bows&arrows; they're highly trained.
916                          */
917                         if (Role_if(PM_SAMURAI) && obj->otyp == YA
918                             && uwep->otyp == YUMI)
919                             tmp++;
920                         else if (Race_if(PM_ELF) && obj->otyp == ELVEN_ARROW
921                                  && uwep->otyp == ELVEN_BOW)
922                             tmp++;
923                     }
924                     if (obj->opoisoned && is_poisonable(obj))
925                         ispoisoned = TRUE;
926                 }
927             }
928         } else if (obj->oclass == POTION_CLASS) {
929             if (obj->quan > 1L)
930                 obj = splitobj(obj, 1L);
931             else
932                 setuwep((struct obj *) 0);
933             freeinv(obj);
934             potionhit(mon, obj,
935                       hand_to_hand ? POTHIT_HERO_BASH : POTHIT_HERO_THROW);
936             if (DEADMONSTER(mon))
937                 return FALSE; /* killed */
938             hittxt = TRUE;
939             /* in case potion effect causes transformation */
940             mdat = mon->data;
941             tmp = (mdat == &mons[PM_SHADE]) ? 0 : 1;
942         } else {
943             if (mdat == &mons[PM_SHADE] && !shade_aware(obj)) {
944                 tmp = 0;
945             } else {
946                 switch (obj->otyp) {
947                 case BOULDER:         /* 1d20 */
948                 case HEAVY_IRON_BALL: /* 1d25 */
949                 case IRON_CHAIN:      /* 1d4+1 */
950                     tmp = dmgval(obj, mon);
951                     break;
952                 case MIRROR:
953                     if (breaktest(obj)) {
954 /*JP
955                         You("break %s.  That's bad luck!", ysimple_name(obj));
956 */
957                         You("%s\8b¾\82ð\89ó\82µ\82Ä\82µ\82Ü\82Á\82½\81D\82±\82è\82á\82Ü\82¢\82Á\82½\81I", ysimple_name(obj));
958                         change_luck(-2);
959                         useup(obj);
960                         obj = (struct obj *) 0;
961                         unarmed = FALSE; /* avoid obj==0 confusion */
962                         get_dmg_bonus = FALSE;
963                         hittxt = TRUE;
964                     }
965                     tmp = 1;
966                     break;
967                 case EXPENSIVE_CAMERA:
968 /*JP
969                     You("succeed in destroying %s.  Congratulations!",
970 */
971                     You("%s\83J\83\81\83\89\82ð\89ó\82·\82±\82Æ\82ª\82Å\82«\82½\81D\82¨\82ß\82Å\82Æ\82¤\81I",
972                         ysimple_name(obj));
973                     release_camera_demon(obj, u.ux, u.uy);
974                     useup(obj);
975                     return TRUE;
976                 case CORPSE: /* fixed by polder@cs.vu.nl */
977                     if (touch_petrifies(&mons[obj->corpsenm])) {
978                         tmp = 1;
979                         hittxt = TRUE;
980 #if 0 /*JP:T*/
981                         You("hit %s with %s.", mon_nam(mon),
982                             corpse_xname(obj, (const char *) 0,
983                                          obj->dknown ? CXN_PFX_THE
984                                                      : CXN_ARTICLE));
985 #else
986                         You("%s\82ð%s\82Å\8dU\8c\82\82µ\82½\81D", mon_nam(mon),
987                             corpse_xname(obj, (const char *) 0,
988                                          obj->dknown ? CXN_PFX_THE
989                                                      : CXN_ARTICLE));
990 #endif
991                         obj->dknown = 1;
992                         if (!munstone(mon, TRUE))
993                             minstapetrify(mon, TRUE);
994                         if (resists_ston(mon))
995                             break;
996                         /* note: hp may be <= 0 even if munstoned==TRUE */
997                         return (boolean) !DEADMONSTER(mon);
998 #if 0
999                     } else if (touch_petrifies(mdat)) {
1000                         ; /* maybe turn the corpse into a statue? */
1001 #endif
1002                     }
1003                     tmp = (obj->corpsenm >= LOW_PM ? mons[obj->corpsenm].msize
1004                                                    : 0) + 1;
1005                     break;
1006
1007 #define useup_eggs(o)                    \
1008     do {                                 \
1009         if (thrown)                      \
1010             obfree(o, (struct obj *) 0); \
1011         else                             \
1012             useupall(o);                 \
1013         o = (struct obj *) 0;            \
1014     } while (0) /* now gone */
1015                 case EGG: {
1016                     long cnt = obj->quan;
1017
1018                     tmp = 1; /* nominal physical damage */
1019                     get_dmg_bonus = FALSE;
1020                     hittxt = TRUE; /* message always given */
1021                     /* egg is always either used up or transformed, so next
1022                        hand-to-hand attack should yield a "bashing" mesg */
1023                     if (obj == uwep)
1024                         unweapon = TRUE;
1025                     if (obj->spe && obj->corpsenm >= LOW_PM) {
1026                         if (obj->quan < 5L)
1027                             change_luck((schar) - (obj->quan));
1028                         else
1029                             change_luck(-5);
1030                     }
1031
1032                     if (touch_petrifies(&mons[obj->corpsenm])) {
1033                         /*learn_egg_type(obj->corpsenm);*/
1034 #if 0 /*JP:T*/
1035                         pline("Splat!  You hit %s with %s %s egg%s!",
1036                               mon_nam(mon),
1037                               obj->known ? "the" : cnt > 1L ? "some" : "a",
1038                               obj->known ? mons[obj->corpsenm].mname
1039                                          : "petrifying",
1040                               plur(cnt));
1041 #else
1042                         pline("\83r\83`\83\83\83b\81I\82 \82È\82½\82Í%s\82É%s%s\82Ì\97\91\82ð\93\8a\82°\82Â\82¯\82½\81I",
1043                               mon_nam(mon),
1044                               cnt > 1L ? "\82¢\82­\82Â\82©\82Ì" : "",
1045                               obj->known ? mons[obj->corpsenm].mname
1046                                          : "\90Î\89»");
1047 #endif
1048                         obj->known = 1; /* (not much point...) */
1049                         useup_eggs(obj);
1050                         if (!munstone(mon, TRUE))
1051                             minstapetrify(mon, TRUE);
1052                         if (resists_ston(mon))
1053                             break;
1054                         return (boolean) (!DEADMONSTER(mon));
1055                     } else { /* ordinary egg(s) */
1056 #if 0 /*JP:T*/
1057                         const char *eggp = (obj->corpsenm != NON_PM
1058                                             && obj->known)
1059                                            ? the(mons[obj->corpsenm].mname)
1060                                            : (cnt > 1L) ? "some" : "an";
1061
1062                         You("hit %s with %s egg%s.", mon_nam(mon), eggp,
1063                             plur(cnt));
1064 #else
1065                         const char *eggp = (obj->corpsenm != NON_PM
1066                                             && obj->known)
1067                                            ? mons[obj->corpsenm].mname
1068                                            : "";
1069                         You("%s\82É%s%s\97\91\82ð\93\8a\82°\82Â\82¯\82½\81D",
1070                                 mon_nam(mon), eggp, *eggp ? "\82Ì" : "");
1071 #endif
1072                         if (touch_petrifies(mdat) && !stale_egg(obj)) {
1073 #if 0 /*JP:T*/
1074                             pline_The("egg%s %s alive any more...", plur(cnt),
1075                                       (cnt == 1L) ? "isn't" : "aren't");
1076 #else
1077                             pline("\82à\82¤\97\91\82ª\9bz\89»\82·\82é\82±\82Æ\82Í\82È\82¢\82¾\82ë\82¤\81D\81D\81D");
1078 #endif
1079                             if (obj->timed)
1080                                 obj_stop_timers(obj);
1081                             obj->otyp = ROCK;
1082                             obj->oclass = GEM_CLASS;
1083                             obj->oartifact = 0;
1084                             obj->spe = 0;
1085                             obj->known = obj->dknown = obj->bknown = 0;
1086                             obj->owt = weight(obj);
1087                             if (thrown)
1088                                 place_object(obj, mon->mx, mon->my);
1089                         } else {
1090 /*JP
1091                             pline("Splat!");
1092 */
1093                             pline("\83r\83`\83\83\83b\81I");
1094                             useup_eggs(obj);
1095                             exercise(A_WIS, FALSE);
1096                         }
1097                     }
1098                     break;
1099 #undef useup_eggs
1100                 }
1101                 case CLOVE_OF_GARLIC: /* no effect against demons */
1102                     if (is_undead(mdat) || is_vampshifter(mon)) {
1103                         monflee(mon, d(2, 4), FALSE, TRUE);
1104                     }
1105                     tmp = 1;
1106                     break;
1107                 case CREAM_PIE:
1108                 case BLINDING_VENOM:
1109                     mon->msleeping = 0;
1110                     if (can_blnd(&youmonst, mon,
1111                                  (uchar) ((obj->otyp == BLINDING_VENOM)
1112                                              ? AT_SPIT
1113                                              : AT_WEAP),
1114                                  obj)) {
1115                         if (Blind) {
1116 #if 0 /*JP:T*/
1117                             pline(obj->otyp == CREAM_PIE ? "Splat!"
1118                                                          : "Splash!");
1119 #else
1120                             pline(obj->otyp == CREAM_PIE ? "\83r\83V\83\83\83b\81I"
1121                                                          : "\83s\83`\83\83\83b\81I");
1122 #endif
1123                         } else if (obj->otyp == BLINDING_VENOM) {
1124 #if 0 /*JP:T*/
1125                             pline_The("venom blinds %s%s!", mon_nam(mon),
1126                                       mon->mcansee ? "" : " further");
1127 #else
1128                             pline("\93Å\89t\82Å%s\82Í%s\96Ú\82ª\8c©\82¦\82È\82­\82È\82Á\82½\81I", mon_nam(mon),
1129                                   mon->mcansee ? "" : "\82³\82ç\82É");
1130 #endif
1131                         } else {
1132                             char *whom = mon_nam(mon);
1133                             char *what = The(xname(obj));
1134
1135                             if (!thrown && obj->quan > 1L)
1136                                 what = An(singular(obj, xname));
1137                             /* note: s_suffix returns a modifiable buffer */
1138                             if (haseyes(mdat)
1139                                 && mdat != &mons[PM_FLOATING_EYE])
1140 #if 0 /*JP*/
1141                                 whom = strcat(strcat(s_suffix(whom), " "),
1142                                               mbodypart(mon, FACE));
1143 #else
1144                                 whom = strcat(s_suffix(whom),
1145                                               mbodypart(mon, FACE));
1146 #endif
1147 #if 0 /*JP:T*/
1148                             pline("%s %s over %s!", what,
1149                                   vtense(what, "splash"), whom);
1150 #else
1151                             pline("%s\82Í%s\82É\82Ô\82¿\82Ü\82¯\82ç\82ê\82½\81I",
1152                                   what, whom);
1153 #endif
1154                         }
1155                         setmangry(mon, TRUE);
1156                         mon->mcansee = 0;
1157                         tmp = rn1(25, 21);
1158                         if (((int) mon->mblinded + tmp) > 127)
1159                             mon->mblinded = 127;
1160                         else
1161                             mon->mblinded += tmp;
1162                     } else {
1163 /*JP
1164                         pline(obj->otyp == CREAM_PIE ? "Splat!" : "Splash!");
1165 */
1166                         pline(obj->otyp==CREAM_PIE ? "\83r\83V\83\83\83b\81I" : "\83s\83`\83\83\83b\81I");
1167                         setmangry(mon, TRUE);
1168                     }
1169                     if (thrown)
1170                         obfree(obj, (struct obj *) 0);
1171                     else
1172                         useup(obj);
1173                     hittxt = TRUE;
1174                     get_dmg_bonus = FALSE;
1175                     tmp = 0;
1176                     break;
1177                 case ACID_VENOM: /* thrown (or spit) */
1178                     if (resists_acid(mon)) {
1179 /*JP
1180                         Your("venom hits %s harmlessly.", mon_nam(mon));
1181 */
1182                         pline("\93Å\89t\82Í%s\82É\82Í\8cø\89Ê\82ª\82È\82©\82Á\82½\81D", mon_nam(mon));
1183                         tmp = 0;
1184                     } else {
1185 /*JP
1186                         Your("venom burns %s!", mon_nam(mon));
1187 */
1188                         Your("\93Å\89t\82Í%s\82ð\8fÄ\82¢\82½\81I", mon_nam(mon));
1189                         tmp = dmgval(obj, mon);
1190                     }
1191                     if (thrown)
1192                         obfree(obj, (struct obj *) 0);
1193                     else
1194                         useup(obj);
1195                     hittxt = TRUE;
1196                     get_dmg_bonus = FALSE;
1197                     break;
1198                 default:
1199                     /* non-weapons can damage because of their weight */
1200                     /* (but not too much) */
1201                     tmp = obj->owt / 100;
1202                     if (is_wet_towel(obj)) {
1203                         /* wielded wet towel should probably use whip skill
1204                            (but not by setting objects[TOWEL].oc_skill==P_WHIP
1205                            because that would turn towel into a weptool) */
1206                         tmp += obj->spe;
1207                         if (rn2(obj->spe + 1)) /* usually lose some wetness */
1208                             dry_a_towel(obj, -1, TRUE);
1209                     }
1210                     if (tmp < 1)
1211                         tmp = 1;
1212                     else
1213                         tmp = rnd(tmp);
1214                     if (tmp > 6)
1215                         tmp = 6;
1216                     /*
1217                      * Things like silver wands can arrive here so
1218                      * so we need another silver check.
1219                      */
1220                     if (objects[obj->otyp].oc_material == SILVER
1221                         && mon_hates_silver(mon)) {
1222                         tmp += rnd(20);
1223                         silvermsg = TRUE;
1224                         silverobj = TRUE;
1225                     }
1226                 }
1227             }
1228         }
1229     }
1230
1231     /****** NOTE: perhaps obj is undefined!! (if !thrown && BOOMERANG)
1232      *      *OR* if attacking bare-handed!! */
1233
1234     if (get_dmg_bonus && tmp > 0) {
1235         tmp += u.udaminc;
1236         /* If you throw using a propellor, you don't get a strength
1237          * bonus but you do get an increase-damage bonus.
1238          */
1239         if (thrown != HMON_THROWN || !obj || !uwep
1240             || !ammo_and_launcher(obj, uwep))
1241             tmp += dbon();
1242     }
1243
1244     if (valid_weapon_attack) {
1245         struct obj *wep;
1246
1247         /* to be valid a projectile must have had the correct projector */
1248         wep = PROJECTILE(obj) ? uwep : obj;
1249         tmp += weapon_dam_bonus(wep);
1250         /* [this assumes that `!thrown' implies wielded...] */
1251         wtype = thrown ? weapon_type(wep) : uwep_skill_type();
1252         use_skill(wtype, 1);
1253     }
1254
1255     if (ispoisoned) {
1256         int nopoison = (10 - (obj->owt / 10));
1257
1258         if (nopoison < 2)
1259             nopoison = 2;
1260         if (Role_if(PM_SAMURAI)) {
1261 /*JP
1262             You("dishonorably use a poisoned weapon!");
1263 */
1264             You("\95s\96¼\97_\82É\82à\93Å\82Ì\95\90\8aí\82ð\8eg\97p\82µ\82½\81I");
1265             adjalign(-sgn(u.ualign.type));
1266         } else if (u.ualign.type == A_LAWFUL && u.ualign.record > -10) {
1267 /*JP
1268             You_feel("like an evil coward for using a poisoned weapon.");
1269 */
1270             You("\93Å\82Ì\95\90\8aí\82ð\8eg\97p\82·\82é\82Ì\82Í\94Ú\8b¯\82¾\82Æ\8a´\82\82½\81D");
1271             adjalign(-1);
1272         }
1273         if (obj && !rn2(nopoison)) {
1274             /* remove poison now in case obj ends up in a bones file */
1275             obj->opoisoned = FALSE;
1276             /* defer "obj is no longer poisoned" until after hit message */
1277             unpoisonmsg = TRUE;
1278         }
1279         if (resists_poison(mon))
1280             needpoismsg = TRUE;
1281         else if (rn2(10))
1282             tmp += rnd(6);
1283         else
1284             poiskilled = TRUE;
1285     }
1286     if (tmp < 1) {
1287         boolean mon_is_shade = (mon->data == &mons[PM_SHADE]);
1288
1289         /* make sure that negative damage adjustment can't result
1290            in inadvertently boosting the victim's hit points */
1291         tmp = (get_dmg_bonus && !mon_is_shade) ? 1 : 0;
1292         if (mon_is_shade && !hittxt
1293             && thrown != HMON_THROWN && thrown != HMON_KICKED)
1294             hittxt = shade_miss(&youmonst, mon, obj, FALSE, TRUE);
1295     }
1296
1297     if (jousting) {
1298         tmp += d(2, (obj == uwep) ? 10 : 2); /* [was in dmgval()] */
1299 /*JP
1300         You("joust %s%s", mon_nam(mon), canseemon(mon) ? exclam(tmp) : ".");
1301 */
1302         You("%s\82É\93Ë\8c\82\82µ\82½%s", mon_nam(mon), canseemon(mon) ? exclam(tmp) : "\81D");
1303         if (jousting < 0) {
1304 /*JP
1305             pline("%s shatters on impact!", Yname2(obj));
1306 */
1307             Your("%s\82Í\8fÕ\8c\82\82Å\89ó\82ê\82½\81I", xname(obj));
1308             /* (must be either primary or secondary weapon to get here) */
1309             u.twoweap = FALSE; /* untwoweapon() is too verbose here */
1310             if (obj == uwep)
1311                 uwepgone(); /* set unweapon */
1312             /* minor side-effect: broken lance won't split puddings */
1313             useup(obj);
1314             obj = 0;
1315         }
1316         /* avoid migrating a dead monster */
1317         if (mon->mhp > tmp) {
1318             mhurtle(mon, u.dx, u.dy, 1);
1319             mdat = mon->data; /* in case of a polymorph trap */
1320             if (DEADMONSTER(mon))
1321                 already_killed = TRUE;
1322         }
1323         hittxt = TRUE;
1324     } else if (unarmed && tmp > 1 && !thrown && !obj && !Upolyd) {
1325         /* VERY small chance of stunning opponent if unarmed. */
1326         if (rnd(100) < P_SKILL(P_BARE_HANDED_COMBAT) && !bigmonst(mdat)
1327             && !thick_skinned(mdat)) {
1328             if (canspotmon(mon))
1329 #if 0 /*JP:T*/
1330                 pline("%s %s from your powerful strike!", Monnam(mon),
1331                       makeplural(stagger(mon->data, "stagger")));
1332 #else
1333                 pline("%s\82Í\82 \82È\82½\82Ì\89ï\90S\82Ì\88ê\8c\82\82Å%s\81I", Monnam(mon),
1334                       jpast(stagger(mon->data, "\82æ\82ë\82ß\82­")));
1335 #endif
1336             /* avoid migrating a dead monster */
1337             if (mon->mhp > tmp) {
1338                 mhurtle(mon, u.dx, u.dy, 1);
1339                 mdat = mon->data; /* in case of a polymorph trap */
1340                 if (DEADMONSTER(mon))
1341                     already_killed = TRUE;
1342             }
1343             hittxt = TRUE;
1344         }
1345     }
1346
1347     if (!already_killed)
1348         mon->mhp -= tmp;
1349     /* adjustments might have made tmp become less than what
1350        a level draining artifact has already done to max HP */
1351     if (mon->mhp > mon->mhpmax)
1352         mon->mhp = mon->mhpmax;
1353     if (DEADMONSTER(mon))
1354         destroyed = TRUE;
1355     if (mon->mtame && tmp > 0) {
1356         /* do this even if the pet is being killed (affects revival) */
1357         abuse_dog(mon); /* reduces tameness */
1358         /* flee if still alive and still tame; if already suffering from
1359            untimed fleeing, no effect, otherwise increases timed fleeing */
1360         if (mon->mtame && !destroyed)
1361             monflee(mon, 10 * rnd(tmp), FALSE, FALSE);
1362     }
1363     if ((mdat == &mons[PM_BLACK_PUDDING] || mdat == &mons[PM_BROWN_PUDDING])
1364         /* pudding is alive and healthy enough to split */
1365         && mon->mhp > 1 && !mon->mcan
1366         /* iron weapon using melee or polearm hit [3.6.1: metal weapon too;
1367            also allow either or both weapons to cause split when twoweap] */
1368         && obj && (obj == uwep || (u.twoweap && obj == uswapwep))
1369         && ((objects[obj->otyp].oc_material == IRON
1370              /* allow scalpel and tsurugi to split puddings */
1371              || objects[obj->otyp].oc_material == METAL)
1372             /* but not bashing with darts, arrows or ya */
1373             && !(is_ammo(obj) || is_missile(obj)))
1374         && hand_to_hand) {
1375         struct monst *mclone;
1376         if ((mclone = clone_mon(mon, 0, 0)) != 0) {
1377             char withwhat[BUFSZ];
1378
1379             withwhat[0] = '\0';
1380 #if 0 /*JP:T*/
1381             if (u.twoweap && flags.verbose)
1382                 Sprintf(withwhat, " with %s", yname(obj));
1383             pline("%s divides as you hit it%s!", Monnam(mon), withwhat);
1384 #else
1385             if (u.twoweap && flags.verbose)
1386                 Sprintf(withwhat, "%s\82Å\82Ì", yname(obj));
1387             pline("\82 \82È\82½\82Ì%s\8dU\8c\82\82Å%s\82Í\95ª\97ô\82µ\82½\81I", withwhat, Monnam(mon));
1388 #endif
1389             hittxt = TRUE;
1390             mintrap(mclone);
1391         }
1392     }
1393
1394     if (!hittxt /*( thrown => obj exists )*/
1395         && (!destroyed
1396             || (thrown && m_shot.n > 1 && m_shot.o == obj->otyp))) {
1397         if (thrown)
1398             hit(mshot_xname(obj), mon, exclam(tmp));
1399         else if (!flags.verbose)
1400 /*JP
1401             You("hit it.");
1402 */
1403             pline("\8dU\8c\82\82Í\96½\92\86\82µ\82½\81D");
1404         else
1405 #if 0 /*JP*//*\89£\82è\95û\82ð\95ª\82¯\82é\82Ü\82Å\82Í\82â\82ç\82È\82¢*/
1406             You("%s %s%s",
1407                 (obj && (is_shield(obj) || obj->otyp == HEAVY_IRON_BALL))
1408                   ? "bash" : Role_if(PM_BARBARIAN) ? "smite" : "hit",
1409                 mon_nam(mon), canseemon(mon) ? exclam(tmp) : ".");
1410 #else
1411             Your("%s\82Ö\82Ì\8dU\8c\82\82Í\96½\92\86\82µ\82½%s",
1412                  mon_nam(mon), canseemon(mon) ? exclam(tmp) : "\81D");
1413 #endif
1414     }
1415
1416     if (silvermsg) {
1417         const char *fmt;
1418         char *whom = mon_nam(mon);
1419         char silverobjbuf[BUFSZ];
1420
1421         if (canspotmon(mon)) {
1422             if (barehand_silver_rings == 1)
1423 /*JP
1424                 fmt = "Your silver ring sears %s!";
1425 */
1426                 fmt = "%s\82Í\8bâ\82Ì\8ew\97Ö\82Å\8fÄ\82©\82ê\82½\81I";
1427             else if (barehand_silver_rings == 2)
1428 /*JP
1429                 fmt = "Your silver rings sear %s!";
1430 */
1431                 fmt = "%s\82Í\8bâ\82Ì\8ew\97Ö\82Å\8fÄ\82©\82ê\82½\81I";
1432             else if (silverobj && saved_oname[0]) {
1433                 /* guard constructed format string against '%' in
1434                    saved_oname[] from xname(via cxname()) */
1435 #if 0 /*JP*/
1436                 Sprintf(silverobjbuf, "Your %s%s %s",
1437                         strstri(saved_oname, "silver") ? "" : "silver ",
1438                         saved_oname, vtense(saved_oname, "sear"));
1439                 (void) strNsubst(silverobjbuf, "%", "%%", 0);
1440                 Strcat(silverobjbuf, " %s!");
1441 #else
1442                 Sprintf(silverobjbuf, "%%s\82Í%s%s\82Å\8fÄ\82©\82ê\82½\81I",
1443                         strstri(saved_oname, "\8bâ") ?
1444                         "" : "\8bâ\82Ì",
1445                         saved_oname);
1446                 (void) strNsubst(silverobjbuf, "%%", "%", 0);
1447 #endif
1448                 fmt = silverobjbuf;
1449             } else
1450 /*JP
1451                 fmt = "The silver sears %s!";
1452 */
1453                 fmt = "%s\82Í\8bâ\82Å\8fÄ\82©\82ê\82½\81I";
1454         } else {
1455             *whom = highc(*whom); /* "it" -> "It" */
1456 /*JP
1457             fmt = "%s is seared!";
1458 */
1459             fmt = "%s\82Í\8fÄ\82©\82ê\82½\81I";
1460         }
1461         /* note: s_suffix returns a modifiable buffer */
1462         if (!noncorporeal(mdat) && !amorphous(mdat))
1463 /*JP
1464             whom = strcat(s_suffix(whom), " flesh");
1465 */
1466             whom = strcat(s_suffix(whom), "\93÷");
1467         pline(fmt, whom);
1468     }
1469     if (lightobj) {
1470         const char *fmt;
1471         char *whom = mon_nam(mon);
1472         char emitlightobjbuf[BUFSZ];
1473
1474         if (canspotmon(mon)) {
1475             if (saved_oname[0]) {
1476 #if 0 /*JP*/
1477                 Sprintf(emitlightobjbuf,
1478                         "%s radiance penetrates deep into",
1479                         s_suffix(saved_oname));
1480                 Strcat(emitlightobjbuf, " %s!");
1481 #else
1482                 Sprintf(emitlightobjbuf,
1483                         "%s\8cõ\82ª%%s\82É\90[\82­\8aÑ\92Ê\82µ\82½\81I",
1484                         s_suffix(saved_oname));
1485 #endif
1486                 fmt = emitlightobjbuf;
1487             } else
1488 /*JP
1489                 fmt = "The light sears %s!";
1490 */
1491                 fmt = "\8cõ\82Í%s\82ð\8fÄ\82¢\82½\81I";
1492         } else {
1493 #if 0 /*JP*/
1494             *whom = highc(*whom); /* "it" -> "It" */
1495 #endif
1496 /*JP
1497             fmt = "%s is seared!";
1498 */
1499             fmt = "%s\82Í\8fÄ\82©\82ê\82½\81I";
1500         }
1501         /* note: s_suffix returns a modifiable buffer */
1502         if (!noncorporeal(mdat) && !amorphous(mdat))
1503 /*JP
1504             whom = strcat(s_suffix(whom), " flesh");
1505 */
1506             whom = strcat(s_suffix(whom), "\93÷");
1507         pline(fmt, whom);
1508     }
1509     /* if a "no longer poisoned" message is coming, it will be last;
1510        obj->opoisoned was cleared above and any message referring to
1511        "poisoned <obj>" has now been given; we want just "<obj>" for
1512        last message, so reformat while obj is still accessible */
1513     if (unpoisonmsg)
1514         Strcpy(saved_oname, cxname(obj));
1515
1516     /* [note: thrown obj might go away during killed()/xkilled() call
1517        (via 'thrownobj'; if swallowed, it gets added to engulfer's
1518        minvent and might merge with a stack that's already there)] */
1519
1520     if (needpoismsg)
1521 /*JP
1522         pline_The("poison doesn't seem to affect %s.", mon_nam(mon));
1523 */
1524         pline("\93Å\82Í%s\82É\8cø\82©\82È\82©\82Á\82½\82æ\82¤\82¾\81D", mon_nam(mon));
1525     if (poiskilled) {
1526 /*JP
1527         pline_The("poison was deadly...");
1528 */
1529         pline("\93Å\82Í\92v\8e\80\97Ê\82¾\82Á\82½\81D\81D\81D");
1530         if (!already_killed)
1531             xkilled(mon, XKILL_NOMSG);
1532         destroyed = TRUE; /* return FALSE; */
1533     } else if (destroyed) {
1534         if (!already_killed)
1535             killed(mon); /* takes care of most messages */
1536     } else if (u.umconf && hand_to_hand) {
1537         nohandglow(mon);
1538         if (!mon->mconf && !resist(mon, SPBOOK_CLASS, 0, NOTELL)) {
1539             mon->mconf = 1;
1540             if (!mon->mstun && mon->mcanmove && !mon->msleeping
1541                 && canseemon(mon))
1542 /*JP
1543                 pline("%s appears confused.", Monnam(mon));
1544 */
1545                 pline("%s\82Í\8d¬\97\90\82µ\82Ä\82¢\82é\82æ\82¤\82¾\81D", Monnam(mon));
1546         }
1547     }
1548     if (unpoisonmsg)
1549 #if 0 /*JP:T*/
1550         Your("%s %s no longer poisoned.", saved_oname,
1551              vtense(saved_oname, "are"));
1552 #else
1553         Your("%s\82Í\82à\82¤\93Å\82ª\93h\82ç\82ê\82Ä\82¢\82È\82¢\81D", xname(obj));
1554 #endif
1555
1556     return destroyed ? FALSE : TRUE;
1557 }
1558
1559 STATIC_OVL boolean
1560 shade_aware(obj)
1561 struct obj *obj;
1562 {
1563     if (!obj)
1564         return FALSE;
1565     /*
1566      * The things in this list either
1567      * 1) affect shades.
1568      *  OR
1569      * 2) are dealt with properly by other routines
1570      *    when it comes to shades.
1571      */
1572     if (obj->otyp == BOULDER
1573         || obj->otyp == HEAVY_IRON_BALL
1574         || obj->otyp == IRON_CHAIN      /* dmgval handles those first three */
1575         || obj->otyp == MIRROR          /* silver in the reflective surface */
1576         || obj->otyp == CLOVE_OF_GARLIC /* causes shades to flee */
1577         || objects[obj->otyp].oc_material == SILVER)
1578         return TRUE;
1579     return FALSE;
1580 }
1581
1582 /* used for hero vs monster and monster vs monster; also handles
1583    monster vs hero but that won't happen because hero can't be a shade */
1584 boolean
1585 shade_miss(magr, mdef, obj, thrown, verbose)
1586 struct monst *magr, *mdef;
1587 struct obj *obj;
1588 boolean thrown, verbose;
1589 {
1590     const char *what, *whose, *target;
1591     boolean youagr = (magr == &youmonst), youdef = (mdef == &youmonst);
1592
1593     /* we're using dmgval() for zero/not-zero, not for actual damage amount */
1594     if (mdef->data != &mons[PM_SHADE] || (obj && dmgval(obj, mdef)))
1595         return FALSE;
1596
1597     if (verbose
1598         && ((youdef || cansee(mdef->mx, mdef->my) || sensemon(mdef))
1599             || (magr == &youmonst && distu(mdef->mx, mdef->my) <= 2))) {
1600 #if 0 /*JP*/
1601         static const char harmlessly_thru[] = " harmlessly through ";
1602 #endif
1603
1604 /*JP
1605         what = (!obj || shade_aware(obj)) ? "attack" : cxname(obj);
1606 */
1607         what = (!obj || shade_aware(obj)) ? "\8dU\8c\82" : cxname(obj);
1608 /*JP
1609         target = youdef ? "you" : mon_nam(mdef);
1610 */
1611         target = youdef ? "\82 \82È\82½" : mon_nam(mdef);
1612         if (!thrown) {
1613 /*JP
1614             whose = youagr ? "Your" : s_suffix(Monnam(magr));
1615 */
1616             whose = youagr ? "\82 \82È\82½\82Ì" : s_suffix(Monnam(magr));
1617 #if 0 /*JP:T*/
1618             pline("%s %s %s%s%s.", whose, what,
1619                   vtense(what, "pass"), harmlessly_thru, target);
1620 #else
1621             pline("%s%s\82Í%s\82ð\92Ê\82è\82Ê\82¯\82½\81D", whose, what,
1622                   target);
1623 #endif
1624         } else {
1625 #if 0 /*JP:T*/
1626             pline("%s %s%s%s.", The(what), /* note: not pline_The() */
1627                   vtense(what, "pass"), harmlessly_thru, target);
1628 #else
1629             pline("%s\82Í%s\82ð\92Ê\82è\82Ê\82¯\82½\81D", what, target);
1630 #endif
1631         }
1632         if (!youdef && !canspotmon(mdef))
1633             map_invisible(mdef->mx, mdef->my);
1634     }
1635     if (!youdef)
1636         mdef->msleeping = 0;
1637     return TRUE;
1638 }
1639
1640 /* check whether slippery clothing protects from hug or wrap attack */
1641 /* [currently assumes that you are the attacker] */
1642 STATIC_OVL boolean
1643 m_slips_free(mdef, mattk)
1644 struct monst *mdef;
1645 struct attack *mattk;
1646 {
1647     struct obj *obj;
1648
1649     if (mattk->adtyp == AD_DRIN) {
1650         /* intelligence drain attacks the head */
1651         obj = which_armor(mdef, W_ARMH);
1652     } else {
1653         /* grabbing attacks the body */
1654         obj = which_armor(mdef, W_ARMC); /* cloak */
1655         if (!obj)
1656             obj = which_armor(mdef, W_ARM); /* suit */
1657         if (!obj)
1658             obj = which_armor(mdef, W_ARMU); /* shirt */
1659     }
1660
1661     /* if monster's cloak/armor is greased, your grab slips off; this
1662        protection might fail (33% chance) when the armor is cursed */
1663     if (obj && (obj->greased || obj->otyp == OILSKIN_CLOAK)
1664         && (!obj->cursed || rn2(3))) {
1665 #if 0 /*JP:T*/
1666         You("%s %s %s %s!",
1667             mattk->adtyp == AD_WRAP ? "slip off of"
1668                                     : "grab, but cannot hold onto",
1669             s_suffix(mon_nam(mdef)), obj->greased ? "greased" : "slippery",
1670             /* avoid "slippery slippery cloak"
1671                for undiscovered oilskin cloak */
1672             (obj->greased || objects[obj->otyp].oc_name_known)
1673                 ? xname(obj)
1674                 : cloak_simple_name(obj));
1675 #else
1676         You("%s\82Ì%s%s%s\81I",
1677             mon_nam(mdef), obj->greased ? "\96û\82Ì\93h\82ç\82ê\82½" : "\8a\8a\82è\82â\82·\82¢",
1678             (obj->greased || objects[obj->otyp].oc_name_known)
1679                 ? xname(obj)
1680                 : cloak_simple_name(obj),
1681             mattk->adtyp == AD_WRAP ? "\82Å\8a\8a\82Á\82½"
1682                                     : "\82ð\82Â\82©\82Ü\82æ\82¤\82Æ\82µ\82½\82ª\81C\82Å\82«\82È\82©\82Á\82½");
1683 #endif
1684
1685         if (obj->greased && !rn2(2)) {
1686 /*JP
1687             pline_The("grease wears off.");
1688 */
1689             pline("\96û\82Í\97\8e\82¿\82Ä\82µ\82Ü\82Á\82½\81D");
1690             obj->greased = 0;
1691         }
1692         return TRUE;
1693     }
1694     return FALSE;
1695 }
1696
1697 /* used when hitting a monster with a lance while mounted;
1698    1: joust hit; 0: ordinary hit; -1: joust but break lance */
1699 STATIC_OVL int
1700 joust(mon, obj)
1701 struct monst *mon; /* target */
1702 struct obj *obj;   /* weapon */
1703 {
1704     int skill_rating, joust_dieroll;
1705
1706     if (Fumbling || Stunned)
1707         return 0;
1708     /* sanity check; lance must be wielded in order to joust */
1709     if (obj != uwep && (obj != uswapwep || !u.twoweap))
1710         return 0;
1711
1712     /* if using two weapons, use worse of lance and two-weapon skills */
1713     skill_rating = P_SKILL(weapon_type(obj)); /* lance skill */
1714     if (u.twoweap && P_SKILL(P_TWO_WEAPON_COMBAT) < skill_rating)
1715         skill_rating = P_SKILL(P_TWO_WEAPON_COMBAT);
1716     if (skill_rating == P_ISRESTRICTED)
1717         skill_rating = P_UNSKILLED; /* 0=>1 */
1718
1719     /* odds to joust are expert:80%, skilled:60%, basic:40%, unskilled:20% */
1720     if ((joust_dieroll = rn2(5)) < skill_rating) {
1721         if (joust_dieroll == 0 && rnl(50) == (50 - 1) && !unsolid(mon->data)
1722             && !obj_resists(obj, 0, 100))
1723             return -1; /* hit that breaks lance */
1724         return 1;      /* successful joust */
1725     }
1726     return 0; /* no joust bonus; revert to ordinary attack */
1727 }
1728
1729 /*
1730  * Send in a demon pet for the hero.  Exercise wisdom.
1731  *
1732  * This function used to be inline to damageum(), but the Metrowerks compiler
1733  * (DR4 and DR4.5) screws up with an internal error 5 "Expression Too
1734  * Complex."
1735  * Pulling it out makes it work.
1736  */
1737 STATIC_OVL void
1738 demonpet()
1739 {
1740     int i;
1741     struct permonst *pm;
1742     struct monst *dtmp;
1743
1744 /*JP
1745     pline("Some hell-p has arrived!");
1746 */
1747     pline("\92n\8d\96\82Ì\92\87\8aÔ\82ª\8c»\82í\82ê\82½\81I");
1748     i = !rn2(6) ? ndemon(u.ualign.type) : NON_PM;
1749     pm = i != NON_PM ? &mons[i] : youmonst.data;
1750     if ((dtmp = makemon(pm, u.ux, u.uy, NO_MM_FLAGS)) != 0)
1751         (void) tamedog(dtmp, (struct obj *) 0);
1752     exercise(A_WIS, TRUE);
1753 }
1754
1755 STATIC_OVL boolean
1756 theft_petrifies(otmp)
1757 struct obj *otmp;
1758 {
1759     if (uarmg || otmp->otyp != CORPSE
1760         || !touch_petrifies(&mons[otmp->corpsenm]) || Stone_resistance)
1761         return FALSE;
1762
1763 #if 0   /* no poly_when_stoned() critter has theft capability */
1764     if (poly_when_stoned(youmonst.data) && polymon(PM_STONE_GOLEM)) {
1765         display_nhwindow(WIN_MESSAGE, FALSE);   /* --More-- */
1766         return TRUE;
1767     }
1768 #endif
1769
1770     /* stealing this corpse is fatal... */
1771 /*JP
1772     instapetrify(corpse_xname(otmp, "stolen", CXN_ARTICLE));
1773 */
1774     instapetrify(corpse_xname(otmp, "\93\90\82Ü\82ê\82½", CXN_ARTICLE));
1775     /* apparently wasn't fatal after all... */
1776     return TRUE;
1777 }
1778
1779 /*
1780  * Player uses theft attack against monster.
1781  *
1782  * If the target is wearing body armor, take all of its possessions;
1783  * otherwise, take one object.  [Is this really the behavior we want?]
1784  */
1785 STATIC_OVL void
1786 steal_it(mdef, mattk)
1787 struct monst *mdef;
1788 struct attack *mattk;
1789 {
1790     struct obj *otmp, *gold = 0, *stealoid, **minvent_ptr;
1791     long unwornmask;
1792
1793     otmp = mdef->minvent;
1794     if (!otmp || (otmp->oclass == COIN_CLASS && !otmp->nobj))
1795         return; /* nothing to take */
1796
1797     /* look for worn body armor */
1798     stealoid = (struct obj *) 0;
1799     if (could_seduce(&youmonst, mdef, mattk)) {
1800         /* find armor, and move it to end of inventory in the process */
1801         minvent_ptr = &mdef->minvent;
1802         while ((otmp = *minvent_ptr) != 0)
1803             if (otmp->owornmask & W_ARM) {
1804                 if (stealoid)
1805                     panic("steal_it: multiple worn suits");
1806                 *minvent_ptr = otmp->nobj; /* take armor out of minvent */
1807                 stealoid = otmp;
1808                 stealoid->nobj = (struct obj *) 0;
1809             } else {
1810                 minvent_ptr = &otmp->nobj;
1811             }
1812         *minvent_ptr = stealoid; /* put armor back into minvent */
1813     }
1814     gold = findgold(mdef->minvent);
1815
1816     if (stealoid) { /* we will be taking everything */
1817         if (gender(mdef) == (int) u.mfemale && youmonst.data->mlet == S_NYMPH)
1818 #if 0 /*JP:T*/
1819             You("charm %s.  She gladly hands over %sher possessions.",
1820                 mon_nam(mdef), !gold ? "" : "most of ");
1821 #else
1822             You("%s\82ð\82¤\82Á\82Æ\82è\82³\82¹\82½\81D\94Þ\8f\97\82Í\82æ\82ë\82±\82ñ\82Å\8e\9d\82¿\95¨%s\82ð\82³\82µ\82¾\82µ\82½\81D",
1823                 mon_nam(mdef), !gold ? "" : "\82Ì\82Ù\82Æ\82ñ\82Ç");
1824 #endif
1825         else
1826 #if 0 /*JP:T*/
1827             You("seduce %s and %s starts to take off %s clothes.",
1828                 mon_nam(mdef), mhe(mdef), mhis(mdef));
1829 #else
1830             You("%s\82ð\97U\98f\82µ\82½\81D%s\82Í\95\9e\82ð\92E\82¬\82Í\82\82ß\82½\81D",
1831                 mon_nam(mdef), mhe(mdef));
1832 #endif
1833     }
1834
1835     /* prevent gold from being stolen so that steal-item isn't a superset
1836        of steal-gold; shuffling it out of minvent before selecting next
1837        item, and then back in case hero or monster dies (hero touching
1838        stolen c'trice corpse or monster wielding one and having gloves
1839        stolen) is less bookkeeping than skipping it within the loop or
1840        taking it out once and then trying to figure out how to put it back */
1841     if (gold)
1842         obj_extract_self(gold);
1843
1844     while ((otmp = mdef->minvent) != 0) {
1845         if (gold) /* put 'mdef's gold back after remembering mdef->minvent */
1846             mpickobj(mdef, gold), gold = 0;
1847         if (!Upolyd)
1848             break; /* no longer have ability to steal */
1849         /* take the object away from the monster */
1850         obj_extract_self(otmp);
1851         if ((unwornmask = otmp->owornmask) != 0L) {
1852             mdef->misc_worn_check &= ~unwornmask;
1853             if (otmp->owornmask & W_WEP)
1854                 setmnotwielded(mdef, otmp);
1855             otmp->owornmask = 0L;
1856             update_mon_intrinsics(mdef, otmp, FALSE, FALSE);
1857             /* give monster a chance to wear other equipment on its next
1858                move instead of waiting until it picks something up */
1859             mdef->misc_worn_check |= I_SPECIAL;
1860
1861             if (otmp == stealoid) /* special message for final item */
1862 #if 0 /*JP:T*/
1863                 pline("%s finishes taking off %s suit.", Monnam(mdef),
1864                       mhis(mdef));
1865 #else
1866                 pline("%s\82Í\92E\82¬\8fI\82¦\82½\81D", Monnam(mdef));
1867 #endif
1868         }
1869         /* give the object to the character */
1870 #if 0 /*JP:T*/
1871         otmp = hold_another_object(otmp, "You snatched but dropped %s.",
1872                                    doname(otmp), "You steal: ");
1873 #else
1874         otmp = hold_another_object(otmp, "\82 \82È\82½\82Í%s\82ð\93\90\82ñ\82¾\82ª\97\8e\82Æ\82µ\82½\81D",
1875                                    doname(otmp), "\82ð\93\90\82ñ\82¾\81D");
1876 #endif
1877         /* might have dropped otmp, and it might have broken or left level */
1878         if (!otmp || otmp->where != OBJ_INVENT)
1879             continue;
1880         if (theft_petrifies(otmp))
1881             break; /* stop thieving even though hero survived */
1882         /* more take-away handling, after theft message */
1883         if (unwornmask & W_WEP) { /* stole wielded weapon */
1884             possibly_unwield(mdef, FALSE);
1885         } else if (unwornmask & W_ARMG) { /* stole worn gloves */
1886             mselftouch(mdef, (const char *) 0, TRUE);
1887             if (DEADMONSTER(mdef)) /* it's now a statue */
1888                 break; /* can't continue stealing */
1889         }
1890
1891         if (!stealoid)
1892             break; /* only taking one item */
1893
1894         /* take gold out of minvent before making next selection; if it
1895            is the only thing left, the loop will terminate and it will be
1896            put back below */
1897         if ((gold = findgold(mdef->minvent)) != 0)
1898             obj_extract_self(gold);
1899     }
1900
1901     /* put gold back; won't happen if either hero or 'mdef' dies because
1902        gold will be back in monster's inventory at either of those times
1903        (so will be present in mdef's minvent for bones, or in its statue
1904        now if it has just been turned into one) */
1905     if (gold)
1906         mpickobj(mdef, gold);
1907 }
1908
1909 int
1910 damageum(mdef, mattk, specialdmg)
1911 register struct monst *mdef;
1912 register struct attack *mattk;
1913 int specialdmg; /* blessed and/or silver bonus against various things */
1914 {
1915     register struct permonst *pd = mdef->data;
1916     int armpro, tmp = d((int) mattk->damn, (int) mattk->damd);
1917     boolean negated;
1918     struct obj *mongold;
1919
1920     armpro = magic_negation(mdef);
1921     /* since hero can't be cancelled, only defender's armor applies */
1922     negated = !(rn2(10) >= 3 * armpro);
1923
1924     if (is_demon(youmonst.data) && !rn2(13) && !uwep
1925         && u.umonnum != PM_SUCCUBUS && u.umonnum != PM_INCUBUS
1926         && u.umonnum != PM_BALROG) {
1927         demonpet();
1928         return 0;
1929     }
1930     switch (mattk->adtyp) {
1931     case AD_STUN:
1932         if (!Blind)
1933 #if 0 /*JP:T*/
1934             pline("%s %s for a moment.", Monnam(mdef),
1935                   makeplural(stagger(pd, "stagger")));
1936 #else
1937             pline("%s\82Í\88ê\8fu%s\81D", Monnam(mdef),
1938                   jpast(stagger(pd, "\82æ\82ë\82ß\82­")));
1939 #endif
1940         mdef->mstun = 1;
1941         goto physical;
1942     case AD_LEGS:
1943 #if 0
1944         if (u.ucancelled) {
1945             tmp = 0;
1946             break;
1947         }
1948 #endif
1949         goto physical;
1950     case AD_WERE: /* no special effect on monsters */
1951     case AD_HEAL: /* likewise */
1952     case AD_PHYS:
1953  physical:
1954         if (pd == &mons[PM_SHADE]) {
1955             tmp = 0;
1956             if (!specialdmg)
1957                 impossible("bad shade attack function flow?");
1958         }
1959         tmp += specialdmg;
1960
1961         if (mattk->aatyp == AT_WEAP) {
1962             /* hmonas() uses known_hitum() to deal physical damage,
1963                then also damageum() for non-AD_PHYS; don't inflict
1964                extra physical damage for unusual damage types */
1965             tmp = 0;
1966         } else if (mattk->aatyp == AT_KICK
1967                    || mattk->aatyp == AT_CLAW
1968                    || mattk->aatyp == AT_TUCH
1969                    || mattk->aatyp == AT_HUGS) {
1970             if (thick_skinned(pd))
1971                 tmp = (mattk->aatyp == AT_KICK) ? 0 : (tmp + 1) / 2;
1972             /* add ring(s) of increase damage */
1973             if (u.udaminc > 0) {
1974                 /* applies even if damage was 0 */
1975                 tmp += u.udaminc;
1976             } else if (tmp > 0) {
1977                 /* ring(s) might be negative; avoid converting
1978                    0 to non-0 or positive to non-positive */
1979                 tmp += u.udaminc;
1980                 if (tmp < 1)
1981                     tmp = 1;
1982             }
1983         }
1984         break;
1985     case AD_FIRE:
1986         if (negated) {
1987             tmp = 0;
1988             break;
1989         }
1990         if (!Blind)
1991 /*JP
1992             pline("%s is %s!", Monnam(mdef), on_fire(pd, mattk));
1993 */
1994             pline("%s\82Í%s\81I", Monnam(mdef), on_fire(mdef->data, mattk));
1995         if (completelyburns(pd)) { /* paper golem or straw golem */
1996             if (!Blind)
1997 /*JP
1998                 pline("%s burns completely!", Monnam(mdef));
1999 */
2000                 pline("%s\82Í\8a®\91S\82É\94R\82¦\90s\82«\82½\81I", Monnam(mdef));
2001             else
2002 #if 0 /*JP:T*/
2003                 You("smell burning%s.",
2004                     (pd == &mons[PM_PAPER_GOLEM]) ? " paper"
2005                       : (pd == &mons[PM_STRAW_GOLEM]) ? " straw" : "");
2006 #else
2007                 You("%s\82ª\94R\82¦\82é\82É\82¨\82¢\82ª\82µ\82½\81D",
2008                     (pd == &mons[PM_PAPER_GOLEM]) ? "\8e\86"
2009                       : (pd == &mons[PM_STRAW_GOLEM]) ? "\82í\82ç" : "\89½\82©");
2010 #endif
2011             xkilled(mdef, XKILL_NOMSG | XKILL_NOCORPSE);
2012             tmp = 0;
2013             break;
2014             /* Don't return yet; keep hp<1 and tmp=0 for pet msg */
2015         }
2016         tmp += destroy_mitem(mdef, SCROLL_CLASS, AD_FIRE);
2017         tmp += destroy_mitem(mdef, SPBOOK_CLASS, AD_FIRE);
2018         if (resists_fire(mdef)) {
2019             if (!Blind)
2020 /*JP
2021                 pline_The("fire doesn't heat %s!", mon_nam(mdef));
2022 */
2023                 pline("\89\8a\82Í%s\82É\89e\8b¿\82ª\82È\82¢\81I", mon_nam(mdef));
2024             golemeffects(mdef, AD_FIRE, tmp);
2025             shieldeff(mdef->mx, mdef->my);
2026             tmp = 0;
2027         }
2028         /* only potions damage resistant players in destroy_item */
2029         tmp += destroy_mitem(mdef, POTION_CLASS, AD_FIRE);
2030         break;
2031     case AD_COLD:
2032         if (negated) {
2033             tmp = 0;
2034             break;
2035         }
2036         if (!Blind)
2037 /*JP
2038             pline("%s is covered in frost!", Monnam(mdef));
2039 */
2040             pline("%s\82Í\95X\82Å\95¢\82í\82ê\82½\81I", Monnam(mdef));
2041         if (resists_cold(mdef)) {
2042             shieldeff(mdef->mx, mdef->my);
2043             if (!Blind)
2044 /*JP
2045                 pline_The("frost doesn't chill %s!", mon_nam(mdef));
2046 */
2047                 pline("\95X\82Í%s\82ð\93\80\82ç\82·\82±\82Æ\82ª\82Å\82«\82È\82¢\81I", mon_nam(mdef));
2048             golemeffects(mdef, AD_COLD, tmp);
2049             tmp = 0;
2050         }
2051         tmp += destroy_mitem(mdef, POTION_CLASS, AD_COLD);
2052         break;
2053     case AD_ELEC:
2054         if (negated) {
2055             tmp = 0;
2056             break;
2057         }
2058         if (!Blind)
2059 /*JP
2060             pline("%s is zapped!", Monnam(mdef));
2061 */
2062             pline("%s\82Í\93d\8c\82\82ð\82­\82ç\82Á\82½\81I", Monnam(mdef));
2063         tmp += destroy_mitem(mdef, WAND_CLASS, AD_ELEC);
2064         if (resists_elec(mdef)) {
2065             if (!Blind)
2066 /*JP
2067                 pline_The("zap doesn't shock %s!", mon_nam(mdef));
2068 */
2069                 pline("\93d\8c\82\82Í%s\82É\89e\8b¿\82ð\97^\82¦\82È\82¢\81I", mon_nam(mdef));
2070             golemeffects(mdef, AD_ELEC, tmp);
2071             shieldeff(mdef->mx, mdef->my);
2072             tmp = 0;
2073         }
2074         /* only rings damage resistant players in destroy_item */
2075         tmp += destroy_mitem(mdef, RING_CLASS, AD_ELEC);
2076         break;
2077     case AD_ACID:
2078         if (resists_acid(mdef))
2079             tmp = 0;
2080         break;
2081     case AD_STON:
2082         if (!munstone(mdef, TRUE))
2083             minstapetrify(mdef, TRUE);
2084         tmp = 0;
2085         break;
2086     case AD_SSEX:
2087     case AD_SEDU:
2088     case AD_SITM:
2089         steal_it(mdef, mattk);
2090         tmp = 0;
2091         break;
2092     case AD_SGLD:
2093         /* This you as a leprechaun, so steal
2094            real gold only, no lesser coins */
2095         mongold = findgold(mdef->minvent);
2096         if (mongold) {
2097             obj_extract_self(mongold);
2098             if (merge_choice(invent, mongold) || inv_cnt(FALSE) < 52) {
2099                 addinv(mongold);
2100 /*JP
2101                 Your("purse feels heavier.");
2102 */
2103                 You("\8dà\95z\82ª\8fd\82­\82È\82Á\82½\82æ\82¤\82È\8bC\82ª\82µ\82½\81D");
2104             } else {
2105 /*JP
2106                 You("grab %s's gold, but find no room in your knapsack.",
2107 */
2108                 You("%s\82Ì\82¨\8bà\82ð\82Â\82©\82ñ\82¾\82ª\81C\8e\9d\82¿\95¨\91Ü\82É\93ü\82ç\82È\82©\82Á\82½\81D",
2109                     mon_nam(mdef));
2110                 dropy(mongold);
2111             }
2112         }
2113         exercise(A_DEX, TRUE);
2114         tmp = 0;
2115         break;
2116     case AD_TLPT:
2117         if (tmp <= 0)
2118             tmp = 1;
2119         if (!negated) {
2120             char nambuf[BUFSZ];
2121             boolean u_saw_mon = (canseemon(mdef)
2122                                  || (u.uswallow && u.ustuck == mdef));
2123
2124             /* record the name before losing sight of monster */
2125             Strcpy(nambuf, Monnam(mdef));
2126             if (u_teleport_mon(mdef, FALSE) && u_saw_mon
2127                 && !(canseemon(mdef) || (u.uswallow && u.ustuck == mdef)))
2128 /*JP
2129                 pline("%s suddenly disappears!", nambuf);
2130 */
2131                 pline("%s\82Í\93Ë\91R\8fÁ\82¦\82½\81I", nambuf);
2132             if (tmp >= mdef->mhp) { /* see hitmu(mhitu.c) */
2133                 if (mdef->mhp == 1)
2134                     ++mdef->mhp;
2135                 tmp = mdef->mhp - 1;
2136             }
2137         }
2138         break;
2139     case AD_BLND:
2140         if (can_blnd(&youmonst, mdef, mattk->aatyp, (struct obj *) 0)) {
2141             if (!Blind && mdef->mcansee)
2142 /*JP
2143                 pline("%s is blinded.", Monnam(mdef));
2144 */
2145                 pline("%s\82Í\96Ú\82ª\8c©\82¦\82È\82­\82È\82Á\82½\81D", Monnam(mdef));
2146             mdef->mcansee = 0;
2147             tmp += mdef->mblinded;
2148             if (tmp > 127)
2149                 tmp = 127;
2150             mdef->mblinded = tmp;
2151         }
2152         tmp = 0;
2153         break;
2154     case AD_CURS:
2155         if (night() && !rn2(10) && !mdef->mcan) {
2156             if (pd == &mons[PM_CLAY_GOLEM]) {
2157                 if (!Blind)
2158 #if 0 /*JP:T*/
2159                     pline("Some writing vanishes from %s head!",
2160                           s_suffix(mon_nam(mdef)));
2161 #else
2162                     pline("%s\82Ì\93ª\82É\8f\91\82¢\82Ä\82 \82é\95\8e\9a\82Ì\82¢\82­\82Â\82©\82ª\8fÁ\82¦\82½\81I",
2163                           mon_nam(mdef));
2164 #endif
2165                 xkilled(mdef, XKILL_NOMSG);
2166                 /* Don't return yet; keep hp<1 and tmp=0 for pet msg */
2167             } else {
2168                 mdef->mcan = 1;
2169 /*JP
2170                 You("chuckle.");
2171 */
2172                 You("\82­\82·\82­\82·\8fÎ\82Á\82½\81D");
2173             }
2174         }
2175         tmp = 0;
2176         break;
2177     case AD_DRLI:
2178         if (!negated && !rn2(3) && !resists_drli(mdef)) {
2179             int xtmp = d(2, 6);
2180
2181 /*JP
2182             pline("%s suddenly seems weaker!", Monnam(mdef));
2183 */
2184             pline("%s\82Í\93Ë\91R\8eã\82­\82È\82Á\82½\82æ\82¤\82É\8c©\82¦\82½\81I", Monnam(mdef));
2185             mdef->mhpmax -= xtmp;
2186             mdef->mhp -= xtmp;
2187             /* !m_lev: level 0 monster is killed regardless of hit points
2188                rather than drop to level -1 */
2189             if (DEADMONSTER(mdef) || !mdef->m_lev) {
2190 /*JP
2191                 pline("%s dies!", Monnam(mdef));
2192 */
2193                 pline("%s\82Í\8e\80\82ñ\82¾\81I", Monnam(mdef));
2194                 xkilled(mdef, XKILL_NOMSG);
2195             } else
2196                 mdef->m_lev--;
2197             tmp = 0;
2198         }
2199         break;
2200     case AD_RUST:
2201         if (pd == &mons[PM_IRON_GOLEM]) {
2202 /*JP
2203             pline("%s falls to pieces!", Monnam(mdef));
2204 */
2205             pline("%s\82Í\83o\83\89\83o\83\89\82É\82È\82Á\82½\81I", Monnam(mdef));
2206             xkilled(mdef, XKILL_NOMSG);
2207         }
2208         erode_armor(mdef, ERODE_RUST);
2209         tmp = 0;
2210         break;
2211     case AD_CORR:
2212         erode_armor(mdef, ERODE_CORRODE);
2213         tmp = 0;
2214         break;
2215     case AD_DCAY:
2216         if (pd == &mons[PM_WOOD_GOLEM] || pd == &mons[PM_LEATHER_GOLEM]) {
2217 /*JP
2218             pline("%s falls to pieces!", Monnam(mdef));
2219 */
2220             pline("%s\82Í\83o\83\89\83o\83\89\82É\82È\82Á\82½\81I", Monnam(mdef));
2221             xkilled(mdef, XKILL_NOMSG);
2222         }
2223         erode_armor(mdef, ERODE_ROT);
2224         tmp = 0;
2225         break;
2226     case AD_DREN:
2227         if (!negated && !rn2(4))
2228             xdrainenergym(mdef, TRUE);
2229         tmp = 0;
2230         break;
2231     case AD_DRST:
2232     case AD_DRDX:
2233     case AD_DRCO:
2234         if (!negated && !rn2(8)) {
2235 /*JP
2236             Your("%s was poisoned!", mpoisons_subj(&youmonst, mattk));
2237 */
2238             Your("%s\82Í\93Å\82³\82ê\82Ä\82¢\82é\81I", mpoisons_subj(&youmonst, mattk));
2239             if (resists_poison(mdef)) {
2240 /*JP
2241                 pline_The("poison doesn't seem to affect %s.", mon_nam(mdef));
2242 */
2243                 pline("\93Å\82Í%s\82É\89e\8b¿\82ð\97^\82¦\82È\82¢\81D", mon_nam(mdef));
2244             } else {
2245                 if (!rn2(10)) {
2246 /*JP
2247                     Your("poison was deadly...");
2248 */
2249                     Your("\97^\82¦\82½\93Å\82Í\92v\8e\80\97Ê\82¾\82Á\82½\81D\81D\81D");
2250                     tmp = mdef->mhp;
2251                 } else
2252                     tmp += rn1(10, 6);
2253             }
2254         }
2255         break;
2256     case AD_DRIN: {
2257         struct obj *helmet;
2258
2259         if (notonhead || !has_head(pd)) {
2260 /*JP
2261             pline("%s doesn't seem harmed.", Monnam(mdef));
2262 */
2263             pline("%s\82Í\8f\9d\82Â\82¢\82½\82æ\82¤\82É\82Í\8c©\82¦\82È\82¢\81D", Monnam(mdef));
2264             tmp = 0;
2265             if (!Unchanging && pd == &mons[PM_GREEN_SLIME]) {
2266                 if (!Slimed) {
2267 /*JP
2268                     You("suck in some slime and don't feel very well.");
2269 */
2270                     You("\83X\83\89\83C\83\80\82ð\8bz\82¢\8eæ\82Á\82Ä\81C\8bï\8d\87\82ª\88«\82­\82È\82Á\82½\81D");
2271                     make_slimed(10L, (char *) 0);
2272                 }
2273             }
2274             break;
2275         }
2276         if (m_slips_free(mdef, mattk))
2277             break;
2278
2279         if ((helmet = which_armor(mdef, W_ARMH)) != 0 && rn2(8)) {
2280 #if 0 /*JP:T*/
2281             pline("%s %s blocks your attack to %s head.",
2282                   s_suffix(Monnam(mdef)), helm_simple_name(helmet),
2283                   mhis(mdef));
2284 #else
2285             pline("%s\82Ì%s\82ª\93ª\82Ö\82Ì\8dU\8c\82\82ð\96h\82¢\82¾\81D",
2286                   Monnam(mdef), helm_simple_name(helmet));
2287 #endif
2288             break;
2289         }
2290
2291         (void) eat_brains(&youmonst, mdef, TRUE, &tmp);
2292         break;
2293     }
2294     case AD_STCK:
2295         if (!negated && !sticks(pd))
2296             u.ustuck = mdef; /* it's now stuck to you */
2297         break;
2298     case AD_WRAP:
2299         if (!sticks(pd)) {
2300             if (!u.ustuck && !rn2(10)) {
2301                 if (m_slips_free(mdef, mattk)) {
2302                     tmp = 0;
2303                 } else {
2304 /*JP
2305                     You("swing yourself around %s!", mon_nam(mdef));
2306 */
2307                     You("%s\82É\90g\91Ì\82ð\97\8d\82Ý\82Â\82©\82¹\82½\81I", mon_nam(mdef));
2308                     u.ustuck = mdef;
2309                 }
2310             } else if (u.ustuck == mdef) {
2311                 /* Monsters don't wear amulets of magical breathing */
2312                 if (is_pool(u.ux, u.uy) && !is_swimmer(pd)
2313                     && !amphibious(pd)) {
2314 /*JP
2315                     You("drown %s...", mon_nam(mdef));
2316 */
2317                     You("%s\82ð\93M\82ê\82³\82¹\82½\81D\81D\81D", mon_nam(mdef));
2318                     tmp = mdef->mhp;
2319                 } else if (mattk->aatyp == AT_HUGS)
2320 /*JP
2321                     pline("%s is being crushed.", Monnam(mdef));
2322 */
2323                     pline("%s\82Í\89\9f\82µ\82Â\82Ô\82³\82ê\82Ä\82¢\82é\81D", Monnam(mdef));
2324             } else {
2325                 tmp = 0;
2326                 if (flags.verbose)
2327 #if 0 /*JP:T*/
2328                     You("brush against %s %s.", s_suffix(mon_nam(mdef)),
2329                         mbodypart(mdef, LEG));
2330 #else
2331                     You("%s\82Ì%s\82É\90G\82ê\82½\81D", mon_nam(mdef),
2332                         mbodypart(mdef, LEG));
2333 #endif
2334             }
2335         } else
2336             tmp = 0;
2337         break;
2338     case AD_PLYS:
2339         if (!negated && mdef->mcanmove && !rn2(3) && tmp < mdef->mhp) {
2340             if (!Blind)
2341 /*JP
2342                 pline("%s is frozen by you!", Monnam(mdef));
2343 */
2344                 pline("%s\82Í\82 \82È\82½\82Ì\82É\82ç\82Ý\82Å\93®\82¯\82È\82­\82È\82Á\82½\81I", Monnam(mdef));
2345             paralyze_monst(mdef, rnd(10));
2346         }
2347         break;
2348     case AD_SLEE:
2349         if (!negated && !mdef->msleeping && sleep_monst(mdef, rnd(10), -1)) {
2350             if (!Blind)
2351 /*JP
2352                 pline("%s is put to sleep by you!", Monnam(mdef));
2353 */
2354                 pline("%s\82Í\93Ë\91R\96°\82è\82É\82¨\82¿\82½\81I", Monnam(mdef));
2355             slept_monst(mdef);
2356         }
2357         break;
2358     case AD_SLIM:
2359         if (negated)
2360             break; /* physical damage only */
2361         if (!rn2(4) && !slimeproof(pd)) {
2362             if (!munslime(mdef, TRUE) && !DEADMONSTER(mdef)) {
2363                 /* this assumes newcham() won't fail; since hero has
2364                    a slime attack, green slimes haven't been geno'd */
2365 /*JP
2366                 You("turn %s into slime.", mon_nam(mdef));
2367 */
2368                 pline("%s\82Í\83X\83\89\83C\83\80\82É\82È\82Á\82½\81D", mon_nam(mdef));
2369                 if (newcham(mdef, &mons[PM_GREEN_SLIME], FALSE, FALSE))
2370                     pd = mdef->data;
2371             }
2372             /* munslime attempt could have been fatal */
2373             if (DEADMONSTER(mdef))
2374                 return 2; /* skip death message */
2375             tmp = 0;
2376         }
2377         break;
2378     case AD_ENCH: /* KMH -- remove enchantment (disenchanter) */
2379         /* there's no msomearmor() function, so just do damage */
2380         /* if (negated) break; */
2381         break;
2382     case AD_SLOW:
2383         if (!negated && mdef->mspeed != MSLOW) {
2384             unsigned int oldspeed = mdef->mspeed;
2385
2386             mon_adjust_speed(mdef, -1, (struct obj *) 0);
2387             if (mdef->mspeed != oldspeed && canseemon(mdef))
2388 /*JP
2389                 pline("%s slows down.", Monnam(mdef));
2390 */
2391                 pline("%s\82Í\82Ì\82ë\82­\82È\82Á\82½\81D", Monnam(mdef));
2392         }
2393         break;
2394     case AD_CONF:
2395         if (!mdef->mconf) {
2396             if (canseemon(mdef))
2397 /*JP
2398                 pline("%s looks confused.", Monnam(mdef));
2399 */
2400                 pline("%s\82Í\8d¬\97\90\82µ\82½\82æ\82¤\82¾\81D", Monnam(mdef));
2401             mdef->mconf = 1;
2402         }
2403         break;
2404     default:
2405         tmp = 0;
2406         break;
2407     }
2408
2409     mdef->mstrategy &= ~STRAT_WAITFORU; /* in case player is very fast */
2410     mdef->mhp -= tmp;
2411     if (DEADMONSTER(mdef)) {
2412         if (mdef->mtame && !cansee(mdef->mx, mdef->my)) {
2413 /*JP
2414             You_feel("embarrassed for a moment.");
2415 */
2416             You("\82µ\82Î\82ç\82­\8d¢\98f\82µ\82½\81D");
2417             if (tmp)
2418                 xkilled(mdef, XKILL_NOMSG); /* !tmp but hp<1: already killed */
2419         } else if (!flags.verbose) {
2420 /*JP
2421             You("destroy it!");
2422 */
2423             You("\93|\82µ\82½\81I");
2424             if (tmp)
2425                 xkilled(mdef, XKILL_NOMSG);
2426         } else if (tmp)
2427             killed(mdef);
2428         return 2;
2429     }
2430     return 1;
2431 }
2432
2433 STATIC_OVL int
2434 explum(mdef, mattk)
2435 register struct monst *mdef;
2436 register struct attack *mattk;
2437 {
2438     boolean resistance; /* only for cold/fire/elec */
2439     register int tmp = d((int) mattk->damn, (int) mattk->damd);
2440
2441 /*JP
2442     You("explode!");
2443 */
2444     You("\94\9a\94­\82µ\82½\81I");
2445     switch (mattk->adtyp) {
2446     case AD_BLND:
2447         if (!resists_blnd(mdef)) {
2448 /*JP
2449             pline("%s is blinded by your flash of light!", Monnam(mdef));
2450 */
2451             pline("%s\82Í\82Ü\82Î\82ä\82¢\8cõ\82Å\96Ú\82ª\82­\82ç\82ñ\82¾\81I", Monnam(mdef));
2452             mdef->mblinded = min((int) mdef->mblinded + tmp, 127);
2453             mdef->mcansee = 0;
2454         }
2455         break;
2456     case AD_HALU:
2457         if (haseyes(mdef->data) && mdef->mcansee) {
2458 /*JP
2459             pline("%s is affected by your flash of light!", Monnam(mdef));
2460 */
2461             pline("%s\82Í\82Ü\82Î\82ä\82¢\8cõ\82Å\89e\8b¿\82ð\8eó\82¯\82½\81I", Monnam(mdef));
2462             mdef->mconf = 1;
2463         }
2464         break;
2465     case AD_COLD:
2466         resistance = resists_cold(mdef);
2467         goto common;
2468     case AD_FIRE:
2469         resistance = resists_fire(mdef);
2470         goto common;
2471     case AD_ELEC:
2472         resistance = resists_elec(mdef);
2473  common:
2474         if (!resistance) {
2475 /*JP
2476             pline("%s gets blasted!", Monnam(mdef));
2477 */
2478             pline("%s\82Í\94\9a\94­\82ð\97\81\82Ñ\82½\81I", Monnam(mdef));
2479             mdef->mhp -= tmp;
2480             if (DEADMONSTER(mdef)) {
2481                 killed(mdef);
2482                 return 2;
2483             }
2484         } else {
2485             shieldeff(mdef->mx, mdef->my);
2486             if (is_golem(mdef->data))
2487                 golemeffects(mdef, (int) mattk->adtyp, tmp);
2488             else
2489 /*JP
2490                 pline_The("blast doesn't seem to affect %s.", mon_nam(mdef));
2491 */
2492                 pline("\94\9a\94­\82Í%s\82É\89e\8b¿\82ð\97^\82¦\82È\82©\82Á\82½\82æ\82¤\82¾\81D", mon_nam(mdef));
2493         }
2494         break;
2495     default:
2496         break;
2497     }
2498     return 1;
2499 }
2500
2501 STATIC_OVL void
2502 start_engulf(mdef)
2503 struct monst *mdef;
2504 {
2505     if (!Invisible) {
2506         map_location(u.ux, u.uy, TRUE);
2507         tmp_at(DISP_ALWAYS, mon_to_glyph(&youmonst, rn2_on_display_rng));
2508         tmp_at(mdef->mx, mdef->my);
2509     }
2510 /*JP
2511     You("engulf %s!", mon_nam(mdef));
2512 */
2513     You("%s\82ð\88ù\82Ý\8d\9e\82ñ\82¾\81I", mon_nam(mdef));
2514     delay_output();
2515     delay_output();
2516 }
2517
2518 STATIC_OVL void
2519 end_engulf()
2520 {
2521     if (!Invisible) {
2522         tmp_at(DISP_END, 0);
2523         newsym(u.ux, u.uy);
2524     }
2525 }
2526
2527 STATIC_OVL int
2528 gulpum(mdef, mattk)
2529 register struct monst *mdef;
2530 register struct attack *mattk;
2531 {
2532 #ifdef LINT /* static char msgbuf[BUFSZ]; */
2533     char msgbuf[BUFSZ];
2534 #else
2535     static char msgbuf[BUFSZ]; /* for nomovemsg */
2536 #endif
2537     register int tmp;
2538     register int dam = d((int) mattk->damn, (int) mattk->damd);
2539     boolean fatal_gulp;
2540     struct obj *otmp;
2541     struct permonst *pd = mdef->data;
2542
2543     /* Not totally the same as for real monsters.  Specifically, these
2544      * don't take multiple moves.  (It's just too hard, for too little
2545      * result, to program monsters which attack from inside you, which
2546      * would be necessary if done accurately.)  Instead, we arbitrarily
2547      * kill the monster immediately for AD_DGST and we regurgitate them
2548      * after exactly 1 round of attack otherwise.  -KAA
2549      */
2550
2551     if (!engulf_target(&youmonst, mdef))
2552         return 0;
2553
2554     if (u.uhunger < 1500 && !u.uswallow) {
2555         for (otmp = mdef->minvent; otmp; otmp = otmp->nobj)
2556             (void) snuff_lit(otmp);
2557
2558         /* force vampire in bat, cloud, or wolf form to revert back to
2559            vampire form now instead of dealing with that when it dies */
2560         if (is_vampshifter(mdef)
2561             && newcham(mdef, &mons[mdef->cham], FALSE, FALSE)) {
2562 /*JP
2563             You("engulf it, then expel it.");
2564 */
2565             You("\88ù\82Ý\8d\9e\82ñ\82Å\81C\93f\82«\8fo\82µ\82½\81D");
2566             if (canspotmon(mdef))
2567 /*JP
2568                 pline("It turns into %s.", a_monnam(mdef));
2569 */
2570                 pline("\82»\82ê\82Í%s\82É\82È\82Á\82½\81D", a_monnam(mdef));
2571             else
2572                 map_invisible(mdef->mx, mdef->my);
2573             return 1;
2574         }
2575
2576         /* engulfing a cockatrice or digesting a Rider or Medusa */
2577         fatal_gulp = (touch_petrifies(pd) && !Stone_resistance)
2578                      || (mattk->adtyp == AD_DGST
2579                          && (is_rider(pd) || (pd == &mons[PM_MEDUSA]
2580                                               && !Stone_resistance)));
2581
2582         if ((mattk->adtyp == AD_DGST && !Slow_digestion) || fatal_gulp)
2583             eating_conducts(pd);
2584
2585         if (fatal_gulp && !is_rider(pd)) { /* petrification */
2586             char kbuf[BUFSZ];
2587             const char *mname = pd->mname;
2588
2589             if (!type_is_pname(pd))
2590                 mname = an(mname);
2591 /*JP
2592             You("englut %s.", mon_nam(mdef));
2593 */
2594             You("%s\82ð\88ù\82Ý\8d\9e\82ñ\82¾\81D", mon_nam(mdef));
2595 /*JP
2596             Sprintf(kbuf, "swallowing %s whole", mname);
2597 */
2598             Sprintf(kbuf, "%s\82ð\88ù\82Ý\8d\9e\82ñ\82Å", mname);
2599             instapetrify(kbuf);
2600         } else {
2601             start_engulf(mdef);
2602             switch (mattk->adtyp) {
2603             case AD_DGST:
2604                 /* eating a Rider or its corpse is fatal */
2605                 if (is_rider(pd)) {
2606 /*JP
2607                     pline("Unfortunately, digesting any of it is fatal.");
2608 */
2609                     pline("\8ec\94O\82È\82ª\82ç\81C\82»\82ê\82ð\90H\82×\82é\82Ì\82Í\92v\96½\93I\82È\8aÔ\88á\82¢\82¾\81D");
2610                     end_engulf();
2611 #if 0 /*JP*/
2612                     Sprintf(killer.name, "unwisely tried to eat %s",
2613                             pd->mname);
2614                     killer.format = NO_KILLER_PREFIX;
2615 #else
2616                     Sprintf(killer.name, "\8bð\82©\82É\82à%s\82ð\90H\82×\82æ\82¤\82Æ\82µ\82Ä",
2617                             pd->mname);
2618                     killer.format = KILLED_BY;
2619 #endif
2620                     done(DIED);
2621                     return 0; /* lifesaved */
2622                 }
2623
2624                 if (Slow_digestion) {
2625                     dam = 0;
2626                     break;
2627                 }
2628
2629                 /* Use up amulet of life saving */
2630                 if ((otmp = mlifesaver(mdef)) != 0)
2631                     m_useup(mdef, otmp);
2632
2633                 newuhs(FALSE);
2634                 /* start_engulf() issues "you engulf <mdef>" above; this
2635                    used to specify XKILL_NOMSG but we need "you kill <mdef>"
2636                    in case we're also going to get "welcome to level N+1";
2637                    "you totally digest <mdef>" will be coming soon (after
2638                    several turns) but the level-gain message seems out of
2639                    order if the kill message is left implicit */
2640                 xkilled(mdef, XKILL_GIVEMSG | XKILL_NOCORPSE);
2641                 if (!DEADMONSTER(mdef)) { /* monster lifesaved */
2642 /*JP
2643                     You("hurriedly regurgitate the sizzling in your %s.",
2644 */
2645                     You("%s\82Ì\92\86\82Å\83V\83\85\81[\83V\83\85\81[\82Æ\82¢\82¤\89¹\82ð\97§\82Ä\82Ä\82¢\82é\82à\82Ì\82ð\91å\8b}\82¬\82Å\93f\82«\96ß\82µ\82½\81D",
2646                         body_part(STOMACH));
2647                 } else {
2648                     tmp = 1 + (pd->cwt >> 8);
2649                     if (corpse_chance(mdef, &youmonst, TRUE)
2650                         && !(mvitals[monsndx(pd)].mvflags & G_NOCORPSE)) {
2651                         /* nutrition only if there can be a corpse */
2652                         u.uhunger += (pd->cnutrit + 1) / 2;
2653                     } else
2654                         tmp = 0;
2655 /*JP
2656                     Sprintf(msgbuf, "You totally digest %s.", mon_nam(mdef));
2657 */
2658                     Sprintf(msgbuf, "\82 \82È\82½\82Í%s\82ð\8a®\91S\82É\8fÁ\89»\82µ\82½\81D", mon_nam(mdef));
2659                     if (tmp != 0) {
2660                         /* setting afternmv = end_engulf is tempting,
2661                          * but will cause problems if the player is
2662                          * attacked (which uses his real location) or
2663                          * if his See_invisible wears off
2664                          */
2665 /*JP
2666                         You("digest %s.", mon_nam(mdef));
2667 */
2668                         You("%s\82ð\8fÁ\89»\82µ\82Ä\82¢\82é\81D", mon_nam(mdef));
2669                         if (Slow_digestion)
2670                             tmp *= 2;
2671                         nomul(-tmp);
2672 /*JP
2673                         multi_reason = "digesting something";
2674 */
2675                         multi_reason = "\8fÁ\89»\92\86\82É";
2676                         nomovemsg = msgbuf;
2677                     } else
2678                         pline1(msgbuf);
2679                     if (pd == &mons[PM_GREEN_SLIME]) {
2680 /*JP
2681                         Sprintf(msgbuf, "%s isn't sitting well with you.",
2682 */
2683                         Sprintf(msgbuf, "%s\82Í\82 \82È\82½\82Æ\82¤\82Ü\82­\90Ü\82è\8d\87\82¢\82ð\82Â\82¯\82ç\82ê\82È\82¢\82æ\82¤\82¾\81D",
2684                                 The(pd->mname));
2685                         if (!Unchanging) {
2686                             make_slimed(5L, (char *) 0);
2687                         }
2688                     } else
2689                         exercise(A_CON, TRUE);
2690                 }
2691                 end_engulf();
2692                 return 2;
2693             case AD_PHYS:
2694                 if (youmonst.data == &mons[PM_FOG_CLOUD]) {
2695 /*JP
2696                     pline("%s is laden with your moisture.", Monnam(mdef));
2697 */
2698                     pline("%s\82Í\82 \82È\82½\82Ì\8e¼\8bC\82É\8bê\82µ\82ß\82ç\82ê\82Ä\82¢\82é\81D", Monnam(mdef));
2699                     if (amphibious(pd) && !flaming(pd)) {
2700                         dam = 0;
2701 /*JP
2702                         pline("%s seems unharmed.", Monnam(mdef));
2703 */
2704                         pline("%s\82Í\8f\9d\82Â\82¢\82Ä\82¢\82È\82¢\82æ\82¤\82¾\81D", Monnam(mdef));
2705                     }
2706                 } else
2707 /*JP
2708                     pline("%s is pummeled with your debris!", Monnam(mdef));
2709 */
2710                     pline("%s\82Í\8a¢âI\82Å\92É\82ß\82Â\82¯\82ç\82ê\82½\81I", Monnam(mdef));
2711                 break;
2712             case AD_ACID:
2713 /*JP
2714                 pline("%s is covered with your goo!", Monnam(mdef));
2715 */
2716                 pline("%s\82Í\82Ë\82Î\82Â\82­\82à\82Ì\82Å\95¢\82í\82ê\82½\81I", Monnam(mdef));
2717                 if (resists_acid(mdef)) {
2718 /*JP
2719                     pline("It seems harmless to %s.", mon_nam(mdef));
2720 */
2721                     pline("\82µ\82©\82µ\81C%s\82Í\82È\82ñ\82Æ\82à\82È\82¢\81D", mon_nam(mdef));
2722                     dam = 0;
2723                 }
2724                 break;
2725             case AD_BLND:
2726                 if (can_blnd(&youmonst, mdef, mattk->aatyp,
2727                              (struct obj *) 0)) {
2728                     if (mdef->mcansee)
2729 /*JP
2730                         pline("%s can't see in there!", Monnam(mdef));
2731 */
2732                         pline("%s\82Í\96Ú\82ª\8c©\82¦\82È\82­\82È\82Á\82½\81I", mon_nam(mdef));
2733                     mdef->mcansee = 0;
2734                     dam += mdef->mblinded;
2735                     if (dam > 127)
2736                         dam = 127;
2737                     mdef->mblinded = dam;
2738                 }
2739                 dam = 0;
2740                 break;
2741             case AD_ELEC:
2742                 if (rn2(2)) {
2743 /*JP
2744                     pline_The("air around %s crackles with electricity.",
2745 */
2746                     pline("%s\82Ì\89ñ\82è\82Ì\8bó\8bC\82Í\93d\8bC\82Å\83s\83\8a\83s\83\8a\82µ\82Ä\82¢\82é\81D",
2747                               mon_nam(mdef));
2748                     if (resists_elec(mdef)) {
2749 /*JP
2750                         pline("%s seems unhurt.", Monnam(mdef));
2751 */
2752                         pline("\82µ\82©\82µ\81C%s\82Í\95½\8bC\82È\82æ\82¤\82¾\81D", Monnam(mdef));
2753                         dam = 0;
2754                     }
2755                     golemeffects(mdef, (int) mattk->adtyp, dam);
2756                 } else
2757                     dam = 0;
2758                 break;
2759             case AD_COLD:
2760                 if (rn2(2)) {
2761                     if (resists_cold(mdef)) {
2762 /*JP
2763                         pline("%s seems mildly chilly.", Monnam(mdef));
2764 */
2765                         pline("%s\82Í\97â\82¦\82½\82æ\82¤\82¾\81D", Monnam(mdef));
2766                         dam = 0;
2767                     } else
2768 /*JP
2769                         pline("%s is freezing to death!", Monnam(mdef));
2770 */
2771                         pline("%s\82Í\93\80\8e\80\82µ\82»\82¤\82¾\81I", Monnam(mdef));
2772                     golemeffects(mdef, (int) mattk->adtyp, dam);
2773                 } else
2774                     dam = 0;
2775                 break;
2776             case AD_FIRE:
2777                 if (rn2(2)) {
2778                     if (resists_fire(mdef)) {
2779 /*JP
2780                         pline("%s seems mildly hot.", Monnam(mdef));
2781 */
2782                         pline("%s\82Í\92g\82©\82­\82È\82Á\82½\82æ\82¤\82¾\81D", Monnam(mdef));
2783                         dam = 0;
2784                     } else
2785 /*JP
2786                         pline("%s is burning to a crisp!", Monnam(mdef));
2787 */
2788                         pline("%s\82Í\94R\82¦\82Ä\83J\83\89\83J\83\89\82É\82È\82Á\82½\81I", Monnam(mdef));
2789                     golemeffects(mdef, (int) mattk->adtyp, dam);
2790                 } else
2791                     dam = 0;
2792                 break;
2793             case AD_DREN:
2794                 if (!rn2(4))
2795                     xdrainenergym(mdef, TRUE);
2796                 dam = 0;
2797                 break;
2798             }
2799             end_engulf();
2800             mdef->mhp -= dam;
2801             if (DEADMONSTER(mdef)) {
2802                 killed(mdef);
2803                 if (DEADMONSTER(mdef)) /* not lifesaved */
2804                     return 2;
2805             }
2806 #if 0 /*JP:T*/
2807             You("%s %s!", is_animal(youmonst.data) ? "regurgitate" : "expel",
2808                 mon_nam(mdef));
2809 #else
2810             You("%s\82ð%s\82µ\82½\81I", mon_nam(mdef),
2811                 is_animal(youmonst.data) ? "\93f\82«\96ß" : "\94r\8fo");
2812 #endif
2813             if (Slow_digestion || is_animal(youmonst.data)) {
2814 #if 0 /*JP:T*/
2815                 pline("Obviously, you didn't like %s taste.",
2816                       s_suffix(mon_nam(mdef)));
2817 #else
2818                 pline("\82Ç\82¤\82à%s\82Ì\96¡\82Í\8dD\82«\82É\82È\82ê\82È\82¢\81D",
2819                       mon_nam(mdef));
2820 #endif
2821             }
2822         }
2823     }
2824     return 0;
2825 }
2826
2827 void
2828 missum(mdef, mattk, wouldhavehit)
2829 register struct monst *mdef;
2830 register struct attack *mattk;
2831 boolean wouldhavehit;
2832 {
2833     if (wouldhavehit) /* monk is missing due to penalty for wearing suit */
2834 /*JP
2835         Your("armor is rather cumbersome...");
2836 */
2837         Your("\96h\8bï\82Í\8f­\82µ\8e×\96\82\82¾\81D\81D\81D");
2838
2839     if (could_seduce(&youmonst, mdef, mattk))
2840 /*JP
2841         You("pretend to be friendly to %s.", mon_nam(mdef));
2842 */
2843         You("%s\82É\97F\8dD\93I\82È\82Ó\82è\82ð\82µ\82½\81D", mon_nam(mdef));
2844     else if (canspotmon(mdef) && flags.verbose)
2845 /*JP
2846         You("miss %s.", mon_nam(mdef));
2847 */
2848         Your("%s\82Ö\82Ì\8dU\8c\82\82Í\8aO\82ê\82½\81D", mon_nam(mdef));
2849     else
2850 /*JP
2851         You("miss it.");
2852 */
2853         Your("\89½\8eÒ\82©\82Ö\82Ì\8dU\8c\82\82Í\8aO\82ê\82½\81D");
2854     if (!mdef->msleeping && mdef->mcanmove)
2855         wakeup(mdef, TRUE);
2856 }
2857
2858 /* attack monster as a monster; returns True if mon survives */
2859 STATIC_OVL boolean
2860 hmonas(mon)
2861 register struct monst *mon;
2862 {
2863     struct attack *mattk, alt_attk;
2864     struct obj *weapon, **originalweapon;
2865     boolean altwep = FALSE, weapon_used = FALSE, odd_claw = TRUE;
2866     int i, tmp, armorpenalty, sum[NATTK], nsum = 0, dhit = 0, attknum = 0;
2867     int dieroll, multi_claw = 0;
2868
2869     /* with just one touch/claw/weapon attack, both rings matter;
2870        with more than one, alternate right and left when checking
2871        whether silver ring causes successful hit */
2872     for (i = 0; i < NATTK; i++) {
2873         sum[i] = 0;
2874         mattk = getmattk(&youmonst, mon, i, sum, &alt_attk);
2875         if (mattk->aatyp == AT_WEAP
2876             || mattk->aatyp == AT_CLAW || mattk->aatyp == AT_TUCH)
2877             ++multi_claw;
2878     }
2879     multi_claw = (multi_claw > 1); /* switch from count to yes/no */
2880
2881     for (i = 0; i < NATTK; i++) {
2882         /* sum[i] = 0; -- now done above */
2883         mattk = getmattk(&youmonst, mon, i, sum, &alt_attk);
2884         weapon = 0;
2885         switch (mattk->aatyp) {
2886         case AT_WEAP:
2887             /* if (!uwep) goto weaponless; */
2888  use_weapon:
2889             odd_claw = !odd_claw; /* see case AT_CLAW,AT_TUCH below */
2890             /* if we've already hit with a two-handed weapon, we don't
2891                get to make another weapon attack (note:  monsters who
2892                use weapons do not have this restriction, but they also
2893                never have the opportunity to use two weapons) */
2894             if (weapon_used && sum[i - 1] && uwep && bimanual(uwep))
2895                 continue;
2896             /* Certain monsters don't use weapons when encountered as enemies,
2897              * but players who polymorph into them have hands or claws and
2898              * thus should be able to use weapons.  This shouldn't prohibit
2899              * the use of most special abilities, either.
2900              * If monster has multiple claw attacks, only one can use weapon.
2901              */
2902             weapon_used = TRUE;
2903             /* Potential problem: if the monster gets multiple weapon attacks,
2904              * we currently allow the player to get each of these as a weapon
2905              * attack.  Is this really desirable?
2906              */
2907             /* approximate two-weapon mode; known_hitum() -> hmon() -> &c
2908                might destroy the weapon argument, but it might also already
2909                be Null, and we want to track that for passive() */
2910             originalweapon = (altwep && uswapwep) ? &uswapwep : &uwep;
2911             if (uswapwep /* set up 'altwep' flag for next iteration */
2912                 /* only consider seconary when wielding one-handed primary */
2913                 && uwep && (uwep->oclass == WEAPON_CLASS || is_weptool(uwep))
2914                 && !bimanual(uwep)
2915                 /* only switch if not wearing shield and not at artifact;
2916                    shield limitation is iffy since still get extra swings
2917                    if polyform has them, but it matches twoweap behavior;
2918                    twoweap also only allows primary to be an artifact, so
2919                    if alternate weapon is one, don't use it */
2920                 && !uarms && !uswapwep->oartifact
2921                 /* only switch to uswapwep if it's a weapon */
2922                 && (uswapwep->oclass == WEAPON_CLASS || is_weptool(uswapwep))
2923                 /* only switch if uswapwep is not bow, arrows, or darts */
2924                 && !(is_launcher(uswapwep) || is_ammo(uswapwep)
2925                      || is_missile(uswapwep)) /* dart, shuriken, boomerang */
2926                 /* and not two-handed and not incapable of being wielded */
2927                 && !bimanual(uswapwep)
2928                 && !(objects[uswapwep->otyp].oc_material == SILVER
2929                      && Hate_silver))
2930                 altwep = !altwep; /* toggle for next attack */
2931             weapon = *originalweapon;
2932             if (!weapon) /* no need to go beyond no-gloves to rings; not ...*/
2933                 originalweapon = &uarmg; /*... subject to erosion damage */
2934
2935             tmp = find_roll_to_hit(mon, AT_WEAP, weapon, &attknum,
2936                                    &armorpenalty);
2937             dieroll = rnd(20);
2938             dhit = (tmp > dieroll || u.uswallow);
2939             /* caller must set bhitpos */
2940             if (!known_hitum(mon, weapon, &dhit, tmp,
2941                              armorpenalty, mattk, dieroll)) {
2942                 /* enemy dead, before any special abilities used */
2943                 sum[i] = 2;
2944                 break;
2945             } else
2946                 sum[i] = dhit;
2947             /* originalweapon points to an equipment slot which might
2948                now be empty if the weapon was destroyed during the hit;
2949                passive(,weapon,...) won't call passive_obj() in that case */
2950             weapon = *originalweapon; /* might receive passive erosion */
2951             /* might be a worm that gets cut in half; if so, early return */
2952             if (m_at(u.ux + u.dx, u.uy + u.dy) != mon) {
2953                 i = NATTK; /* skip additional attacks */
2954                 /* proceed with uswapwep->cursed check, then exit loop */
2955                 goto passivedone;
2956             }
2957             /* Do not print "You hit" message; known_hitum already did it. */
2958             if (dhit && mattk->adtyp != AD_SPEL && mattk->adtyp != AD_PHYS)
2959                 sum[i] = damageum(mon, mattk, 0);
2960             break;
2961         case AT_CLAW:
2962             if (uwep && !cantwield(youmonst.data) && !weapon_used)
2963                 goto use_weapon;
2964             /*FALLTHRU*/
2965         case AT_TUCH:
2966             if (uwep && youmonst.data->mlet == S_LICH && !weapon_used)
2967                 goto use_weapon;
2968             /*FALLTHRU*/
2969         case AT_KICK:
2970         case AT_BITE:
2971         case AT_STNG:
2972         case AT_BUTT:
2973         case AT_TENT:
2974         /*weaponless:*/
2975             tmp = find_roll_to_hit(mon, mattk->aatyp, (struct obj *) 0,
2976                                    &attknum, &armorpenalty);
2977             dieroll = rnd(20);
2978             dhit = (tmp > dieroll || u.uswallow);
2979             if (dhit) {
2980                 int compat, specialdmg;
2981                 long silverhit = 0L;
2982 #if 0 /*JP*//* \82·\82×\82Ä\81u\8dU\8c\82\82µ\82½\81v\82É\82·\82é */
2983                 const char *verb = 0; /* verb or body part */
2984 #endif
2985
2986                 if (!u.uswallow
2987                     && (compat = could_seduce(&youmonst, mon, mattk)) != 0) {
2988 #if 0 /*JP:T*/
2989                     You("%s %s %s.",
2990                         (mon->mcansee && haseyes(mon->data)) ? "smile at"
2991                                                              : "talk to",
2992                         mon_nam(mon),
2993                         (compat == 2) ? "engagingly" : "seductively");
2994 #else
2995                     You("%s\82Ö%s%s\81D",
2996                         mon_nam(mon),
2997                         compat == 2 ? "\96£\97Í\93I\82É" : "\97U\98f\93I\82É",
2998                         mon->mcansee && haseyes(mon->data) ? "\94÷\8fÎ\82Ý\82©\82¯\82½"
2999                                                            : "\98b\82µ\82©\82¯\82½");
3000 #endif
3001                     /* doesn't anger it; no wakeup() */
3002                     sum[i] = damageum(mon, mattk, 0);
3003                     break;
3004                 }
3005                 wakeup(mon, TRUE);
3006
3007                 specialdmg = 0; /* blessed and/or silver bonus */
3008                 switch (mattk->aatyp) {
3009                 case AT_CLAW:
3010                 case AT_TUCH:
3011                     /* verb=="claws" may be overridden below */
3012 #if 0 /*JP*/
3013                     verb = (mattk->aatyp == AT_TUCH) ? "touch" : "claws";
3014 #endif
3015                     /* decide if silver-hater will be hit by silver ring(s);
3016                        for 'multi_claw' where attacks alternate right/left,
3017                        assume 'even' claw or touch attacks use right hand
3018                        or paw, 'odd' ones use left for ring interaction;
3019                        even vs odd is based on actual attacks rather
3020                        than on index into mon->dat->mattk[] so that {bite,
3021                        claw,claw} instead of {claw,claw,bite} doesn't
3022                        make poly'd hero mysteriously become left-handed */
3023                     odd_claw = !odd_claw;
3024                     specialdmg = special_dmgval(&youmonst, mon,
3025                                                 W_ARMG
3026                                                 | ((odd_claw || !multi_claw)
3027                                                    ? W_RINGL : 0L)
3028                                                 | ((!odd_claw || !multi_claw)
3029                                                    ? W_RINGR : 0L),
3030                                                 &silverhit);
3031                     break;
3032                 case AT_TENT:
3033                     /* assumes mind flayer's tentacles-on-head rather
3034                        than sea monster's tentacle-as-arm */
3035 #if 0 /*JP*/
3036                     verb = "tentacles";
3037 #endif
3038                     break;
3039                 case AT_KICK:
3040 #if 0 /*JP*/
3041                     verb = "kick";
3042 #endif
3043                     specialdmg = special_dmgval(&youmonst, mon, W_ARMF,
3044                                                 &silverhit);
3045                     break;
3046                 case AT_BUTT:
3047 #if 0 /*JP*/
3048                     verb = "head butt"; /* mbodypart(mon,HEAD)=="head" */
3049                     /* hypothetical; if any form with a head-butt attack
3050                        could wear a helmet, it would hit shades when
3051                        wearing a blessed (or silver) one */
3052 #endif
3053                     specialdmg = special_dmgval(&youmonst, mon, W_ARMH,
3054                                                 &silverhit);
3055                     break;
3056                 case AT_BITE:
3057 #if 0 /*JP*/
3058                     verb = "bite";
3059 #endif
3060                     break;
3061                 case AT_STNG:
3062 #if 0 /*JP*/
3063                     verb = "sting";
3064 #endif
3065                     break;
3066                 default:
3067 #if 0 /*JP*/
3068                     verb = "hit";
3069 #endif
3070                     break;
3071                 }
3072                 if (mon->data == &mons[PM_SHADE] && !specialdmg) {
3073 #if 0 /*JP*/
3074                     if (!strcmp(verb, "hit")
3075                         || (mattk->aatyp == AT_CLAW && humanoid(mon->data)))
3076                         verb = "attack";
3077 #endif
3078 #if 0 /*JP*/
3079                     Your("%s %s harmlessly through %s.",
3080                          verb, vtense(verb, "pass"), mon_nam(mon));
3081 #else
3082                     Your("\8dU\8c\82\82Í%s\82ð\92Ê\82è\82Ê\82¯\82½\81D",
3083                          mon_nam(mon));
3084 #endif
3085                 } else {
3086                     if (mattk->aatyp == AT_TENT) {
3087 /*JP
3088                         Your("tentacles suck %s.", mon_nam(mon));
3089 */
3090                         Your("\90G\8eè\82ª%s\82Ì\91Ì\89t\82ð\8bz\82¢\82Æ\82Á\82½\81D", mon_nam(mon));
3091                     } else {
3092 #if 0 /*JP*/
3093                         if (mattk->aatyp == AT_CLAW)
3094                             verb = "hit"; /* not "claws" */
3095 #endif
3096 #if 0 /*JP*/
3097                         You("%s %s.", verb, mon_nam(mon));
3098 #else
3099                         You("%s\82ð\8dU\8c\82\82µ\82½\81D", mon_nam(mon));
3100 #endif
3101                         if (silverhit && flags.verbose)
3102                             silver_sears(&youmonst, mon, silverhit);
3103                     }
3104                     sum[i] = damageum(mon, mattk, specialdmg);
3105                 }
3106             } else { /* !dhit */
3107                 missum(mon, mattk, (tmp + armorpenalty > dieroll));
3108             }
3109             break;
3110
3111         case AT_HUGS: {
3112             int specialdmg;
3113             long silverhit = 0L;
3114             boolean byhand = hug_throttles(&mons[u.umonnum]), /* rope golem */
3115                     unconcerned = (byhand && !can_be_strangled(mon));
3116
3117             if (sticks(mon->data) || u.uswallow || notonhead
3118                 || (byhand && (uwep || !has_head(mon->data)))) {
3119                 /* can't hold a holder due to subsequent ambiguity over
3120                    who is holding whom; can't hug engulfer from inside;
3121                    can't hug a worm tail (would immobilize entire worm!);
3122                    byhand: can't choke something that lacks a head;
3123                    not allowed to make a choking hug if wielding a weapon
3124                    (but might have grabbed w/o weapon, then wielded one,
3125                    and may even be attacking a different monster now) */
3126                 if (byhand && uwep && u.ustuck
3127                     && !(sticks(u.ustuck->data) || u.uswallow))
3128                     uunstick();
3129                 continue; /* not 'break'; bypass passive counter-attack */
3130             }
3131             /* automatic if prev two attacks succeed, or if
3132                already grabbed in a previous attack */
3133             dhit = 1;
3134             wakeup(mon, TRUE);
3135             /* choking hug/throttling grab uses hands (gloves or rings);
3136                normal hug uses outermost of cloak/suit/shirt */
3137             specialdmg = special_dmgval(&youmonst, mon,
3138                                         byhand ? (W_ARMG | W_RINGL | W_RINGR)
3139                                                : (W_ARMC | W_ARM | W_ARMU),
3140                                         &silverhit);
3141             if (unconcerned) {
3142                 /* strangling something which can't be strangled */
3143                 if (mattk != &alt_attk) {
3144                     alt_attk = *mattk;
3145                     mattk = &alt_attk;
3146                 }
3147                 /* change damage to 1d1; not strangling but still
3148                    doing [minimal] physical damage to victim's body */
3149                 mattk->damn = mattk->damd = 1;
3150                 /* don't give 'unconcerned' feedback if there is extra damage
3151                    or if it is nearly destroyed or if creature doesn't have
3152                    the mental ability to be concerned in the first place */
3153                 if (specialdmg || mindless(mon->data)
3154                     || mon->mhp <= 1 + max(u.udaminc, 1))
3155                     unconcerned = FALSE;
3156             }
3157             if (mon->data == &mons[PM_SHADE]) {
3158 #if 0 /*JP*/
3159                 const char *verb = byhand ? "grasp" : "hug";
3160 #endif
3161
3162                 /* hugging a shade; successful if blessed outermost armor
3163                    for normal hug, or blessed gloves or silver ring(s) for
3164                    choking hug; deals damage but never grabs hold */
3165                 if (specialdmg) {
3166 #if 0 /*JP:T*/
3167                     You("%s %s%s", verb, mon_nam(mon), exclam(specialdmg));
3168 #else
3169                     You("%s\82ð\82Â\82©\82ñ\82¾%s", mon_nam(mon), exclam(specialdmg));
3170 #endif
3171                     if (silverhit && flags.verbose)
3172                         silver_sears(&youmonst, mon, silverhit);
3173                     sum[i] = damageum(mon, mattk, specialdmg);
3174                 } else {
3175 #if 0 /*JP:T*/
3176                     Your("%s passes harmlessly through %s.",
3177                          verb, mon_nam(mon));
3178 #else
3179                     You("%s\82ð\82Â\82©\82Ü\82¦\82æ\82¤\82Æ\82µ\82½\82ª\92Ê\82è\82Ê\82¯\82½\81D",
3180                         mon_nam(mon));
3181 #endif
3182                 }
3183                 break;
3184             }
3185             /* hug attack against ordinary foe */
3186             if (mon == u.ustuck) {
3187 #if 0 /*JP:T*/
3188                 pline("%s is being %s%s.", Monnam(mon),
3189                       byhand ? "throttled" : "crushed",
3190                       /* extra feedback for non-breather being choked */
3191                       unconcerned ? " but doesn't seem concerned" : "");
3192 #else
3193                 pline("%s\82Í%s%s\81D", Monnam(mon),
3194                       byhand ? "\8eñ\82ð\8di\82ß\82ç\82ê\82Ä\82¢\82é" : "\89\9f\82µ\82Â\82Ô\82³\82ê\82Ä\82¢\82é",
3195                       /* extra feedback for non-breather being choked */
3196                       unconcerned ? "\82ª\81C\8bC\82É\82µ\82Ä\82¢\82È\82¢\82æ\82¤\82¾" : "");
3197 #endif
3198                 if (silverhit && flags.verbose)
3199                     silver_sears(&youmonst, mon, silverhit);
3200                 sum[i] = damageum(mon, mattk, specialdmg);
3201             } else if (i >= 2 && sum[i - 1] && sum[i - 2]) {
3202                 /* in case we're hugging a new target while already
3203                    holding something else; yields feedback
3204                    "<u.ustuck> is no longer in your clutches" */
3205                 if (u.ustuck && u.ustuck != mon)
3206                     uunstick();
3207 /*JP
3208                 You("grab %s!", mon_nam(mon));
3209 */
3210                 You("%s\82ð\82Â\82©\82Ü\82¦\82½\81I", mon_nam(mon));
3211                 u.ustuck = mon;
3212                 if (silverhit && flags.verbose)
3213                     silver_sears(&youmonst, mon, silverhit);
3214                 sum[i] = damageum(mon, mattk, specialdmg);
3215             }
3216             break; /* AT_HUGS */
3217         }
3218
3219         case AT_EXPL: /* automatic hit if next to */
3220             dhit = -1;
3221             wakeup(mon, TRUE);
3222             sum[i] = explum(mon, mattk);
3223             break;
3224
3225         case AT_ENGL:
3226             tmp = find_roll_to_hit(mon, mattk->aatyp, (struct obj *) 0,
3227                                    &attknum, &armorpenalty);
3228             if ((dhit = (tmp > rnd(20 + i)))) {
3229                 wakeup(mon, TRUE);
3230                 if (mon->data == &mons[PM_SHADE])
3231 /*JP
3232                     Your("attempt to surround %s is harmless.", mon_nam(mon));
3233 */
3234                     You("%s\82ð\88ù\82Ý\82±\82à\82¤\82Æ\82µ\82½\82ª\8e¸\94s\82µ\82½\81D", mon_nam(mon));
3235                 else {
3236                     sum[i] = gulpum(mon, mattk);
3237                     if (sum[i] == 2 && (mon->data->mlet == S_ZOMBIE
3238                                         || mon->data->mlet == S_MUMMY)
3239                         && rn2(5) && !Sick_resistance) {
3240 /*JP
3241                         You_feel("%ssick.", (Sick) ? "very " : "");
3242 */
3243                         You_feel("%s\8bC\95ª\82ª\88«\82¢\81D", (Sick) ? "\82Æ\82Ä\82à" : "");
3244                         mdamageu(mon, rnd(8));
3245                     }
3246                 }
3247             } else {
3248                 missum(mon, mattk, FALSE);
3249             }
3250             break;
3251
3252         case AT_MAGC:
3253             /* No check for uwep; if wielding nothing we want to
3254              * do the normal 1-2 points bare hand damage...
3255              */
3256             if ((youmonst.data->mlet == S_KOBOLD
3257                  || youmonst.data->mlet == S_ORC
3258                  || youmonst.data->mlet == S_GNOME) && !weapon_used)
3259                 goto use_weapon;
3260             /*FALLTHRU*/
3261
3262         case AT_NONE:
3263         case AT_BOOM:
3264             continue;
3265         /* Not break--avoid passive attacks from enemy */
3266
3267         case AT_BREA:
3268         case AT_SPIT:
3269         case AT_GAZE: /* all done using #monster command */
3270             dhit = 0;
3271             break;
3272
3273         default: /* Strange... */
3274             impossible("strange attack of yours (%d)", mattk->aatyp);
3275         }
3276         if (dhit == -1) {
3277             u.mh = -1; /* dead in the current form */
3278             rehumanize();
3279         }
3280         if (sum[i] == 2) {
3281             /* defender dead */
3282             (void) passive(mon, weapon, 1, 0, mattk->aatyp, FALSE);
3283             nsum = 0; /* return value below used to be 'nsum > 0' */
3284         } else {
3285             (void) passive(mon, weapon, sum[i], 1, mattk->aatyp, FALSE);
3286             nsum |= sum[i];
3287         }
3288
3289         /* don't use sum[i] beyond this point;
3290            'i' will be out of bounds if we get here via 'goto' */
3291  passivedone:
3292         /* when using dual weapons, cursed secondary weapon doesn't weld,
3293            it gets dropped; do the same when multiple AT_WEAP attacks
3294            simulate twoweap */
3295         if (uswapwep && weapon == uswapwep && weapon->cursed) {
3296             drop_uswapwep();
3297             break; /* don't proceed with additional attacks */
3298         }
3299         /* stop attacking if defender has died;
3300            needed to defer this until after uswapwep->cursed check */
3301         if (DEADMONSTER(mon))
3302             break;
3303         if (!Upolyd)
3304             break; /* No extra attacks if no longer a monster */
3305         if (multi < 0)
3306             break; /* If paralyzed while attacking, i.e. floating eye */
3307     }
3308     /* return value isn't used, but make it match hitum()'s */
3309     return !DEADMONSTER(mon);
3310 }
3311
3312 /*      Special (passive) attacks on you by monsters done here.
3313  */
3314 int
3315 passive(mon, weapon, mhit, malive, aatyp, wep_was_destroyed)
3316 struct monst *mon;
3317 struct obj *weapon; /* uwep or uswapwep or uarmg or uarmf or Null */
3318 boolean mhit;
3319 int malive;
3320 uchar aatyp;
3321 boolean wep_was_destroyed;
3322 {
3323     register struct permonst *ptr = mon->data;
3324     register int i, tmp;
3325
3326     for (i = 0;; i++) {
3327         if (i >= NATTK)
3328             return (malive | mhit); /* no passive attacks */
3329         if (ptr->mattk[i].aatyp == AT_NONE)
3330             break; /* try this one */
3331     }
3332     /* Note: tmp not always used */
3333     if (ptr->mattk[i].damn)
3334         tmp = d((int) ptr->mattk[i].damn, (int) ptr->mattk[i].damd);
3335     else if (ptr->mattk[i].damd)
3336         tmp = d((int) mon->m_lev + 1, (int) ptr->mattk[i].damd);
3337     else
3338         tmp = 0;
3339
3340     /*  These affect you even if they just died.
3341      */
3342     switch (ptr->mattk[i].adtyp) {
3343     case AD_FIRE:
3344         if (mhit && !mon->mcan && weapon) {
3345             if (aatyp == AT_KICK) {
3346                 if (uarmf && !rn2(6))
3347                     (void) erode_obj(uarmf, xname(uarmf), ERODE_BURN,
3348                                      EF_GREASE | EF_VERBOSE);
3349             } else if (aatyp == AT_WEAP || aatyp == AT_CLAW
3350                        || aatyp == AT_MAGC || aatyp == AT_TUCH)
3351                 passive_obj(mon, weapon, &(ptr->mattk[i]));
3352         }
3353         break;
3354     case AD_ACID:
3355         if (mhit && rn2(2)) {
3356             if (Blind || !flags.verbose)
3357 /*JP
3358                 You("are splashed!");
3359 */
3360                 You("\89½\82©\82ð\97\81\82Ñ\82¹\82ç\82ê\82½\81I");
3361             else
3362 #if 0 /*JP:T*/
3363                 You("are splashed by %s %s!", s_suffix(mon_nam(mon)),
3364                     hliquid("acid"));
3365 #else
3366                 You("%s\82Ì%s\82ð\97\81\82Ñ\82¹\82ç\82ê\82½\81I", mon_nam(mon),
3367                     hliquid("\8e_"));
3368 #endif
3369
3370             if (!Acid_resistance)
3371                 mdamageu(mon, tmp);
3372             if (!rn2(30))
3373                 erode_armor(&youmonst, ERODE_CORRODE);
3374         }
3375         if (mhit && weapon) {
3376             if (aatyp == AT_KICK) {
3377                 if (uarmf && !rn2(6))
3378                     (void) erode_obj(uarmf, xname(uarmf), ERODE_CORRODE,
3379                                      EF_GREASE | EF_VERBOSE);
3380             } else if (aatyp == AT_WEAP || aatyp == AT_CLAW
3381                        || aatyp == AT_MAGC || aatyp == AT_TUCH)
3382                 passive_obj(mon, weapon, &(ptr->mattk[i]));
3383         }
3384         exercise(A_STR, FALSE);
3385         break;
3386     case AD_STON:
3387         if (mhit) { /* successful attack */
3388             long protector = attk_protection((int) aatyp);
3389
3390             /* hero using monsters' AT_MAGC attack is hitting hand to
3391                hand rather than casting a spell */
3392             if (aatyp == AT_MAGC)
3393                 protector = W_ARMG;
3394
3395             if (protector == 0L /* no protection */
3396                 || (protector == W_ARMG && !uarmg
3397                     && !uwep && !wep_was_destroyed)
3398                 || (protector == W_ARMF && !uarmf)
3399                 || (protector == W_ARMH && !uarmh)
3400                 || (protector == (W_ARMC | W_ARMG) && (!uarmc || !uarmg))) {
3401                 if (!Stone_resistance
3402                     && !(poly_when_stoned(youmonst.data)
3403                          && polymon(PM_STONE_GOLEM))) {
3404                     done_in_by(mon, STONING); /* "You turn to stone..." */
3405                     return 2;
3406                 }
3407             }
3408         }
3409         break;
3410     case AD_RUST:
3411         if (mhit && !mon->mcan && weapon) {
3412             if (aatyp == AT_KICK) {
3413                 if (uarmf)
3414                     (void) erode_obj(uarmf, xname(uarmf), ERODE_RUST,
3415                                      EF_GREASE | EF_VERBOSE);
3416             } else if (aatyp == AT_WEAP || aatyp == AT_CLAW
3417                        || aatyp == AT_MAGC || aatyp == AT_TUCH)
3418                 passive_obj(mon, weapon, &(ptr->mattk[i]));
3419         }
3420         break;
3421     case AD_CORR:
3422         if (mhit && !mon->mcan && weapon) {
3423             if (aatyp == AT_KICK) {
3424                 if (uarmf)
3425                     (void) erode_obj(uarmf, xname(uarmf), ERODE_CORRODE,
3426                                      EF_GREASE | EF_VERBOSE);
3427             } else if (aatyp == AT_WEAP || aatyp == AT_CLAW
3428                        || aatyp == AT_MAGC || aatyp == AT_TUCH)
3429                 passive_obj(mon, weapon, &(ptr->mattk[i]));
3430         }
3431         break;
3432     case AD_MAGM:
3433         /* wrath of gods for attacking Oracle */
3434         if (Antimagic) {
3435             shieldeff(u.ux, u.uy);
3436 /*JP
3437             pline("A hail of magic missiles narrowly misses you!");
3438 */
3439             pline("\96\82\96@\82Ì\96î\82Ì\89J\82ª\82©\82·\82ß\82Ä\82¢\82Á\82½\81I");
3440         } else {
3441 /*JP
3442             You("are hit by magic missiles appearing from thin air!");
3443 */
3444             pline("\93Ë\94@\8bó\92\86\82É\8c»\82í\82ê\82½\96\82\96@\82Ì\96î\82ª\96½\92\86\82µ\82½\81I");
3445             mdamageu(mon, tmp);
3446         }
3447         break;
3448     case AD_ENCH: /* KMH -- remove enchantment (disenchanter) */
3449         if (mhit) {
3450             if (aatyp == AT_KICK) {
3451                 if (!weapon)
3452                     break;
3453             } else if (aatyp == AT_BITE || aatyp == AT_BUTT
3454                        || (aatyp >= AT_STNG && aatyp < AT_WEAP)) {
3455                 break; /* no object involved */
3456             }
3457             passive_obj(mon, weapon, &(ptr->mattk[i]));
3458         }
3459         break;
3460     default:
3461         break;
3462     }
3463
3464     /*  These only affect you if they still live.
3465      */
3466     if (malive && !mon->mcan && rn2(3)) {
3467         switch (ptr->mattk[i].adtyp) {
3468         case AD_PLYS:
3469             if (ptr == &mons[PM_FLOATING_EYE]) {
3470                 if (!canseemon(mon)) {
3471                     break;
3472                 }
3473                 if (mon->mcansee) {
3474 #if 0 /*JP:T*/
3475                     if (ureflects("%s gaze is reflected by your %s.",
3476                                   s_suffix(Monnam(mon)))) {
3477 #else
3478                     if (ureflects("%s\82Ì\82É\82ç\82Ý\82Í%s\82É\82æ\82Á\82Ä\94½\8eË\82³\82ê\82½\81D",
3479                                   Monnam(mon))) {
3480 #endif
3481                         ;
3482                     } else if (Hallucination && rn2(4)) {
3483                         /* [it's the hero who should be getting paralyzed
3484                            and isn't; this message describes the monster's
3485                            reaction rather than the hero's escape] */
3486 #if 0 /*JP:T*/
3487                         pline("%s looks %s%s.", Monnam(mon),
3488                               !rn2(2) ? "" : "rather ",
3489                               !rn2(2) ? "numb" : "stupefied");
3490 #else
3491                         pline("%s\82Í%s\82Î\82©\82É\82È\82Á\82½\82æ\82¤\82¾\81D", Monnam(mon),
3492                               !rn2(2) ? "" : "\8f­\82µ");
3493 #endif
3494                     } else if (Free_action) {
3495 #if 0 /*JP:T*/
3496                         You("momentarily stiffen under %s gaze!",
3497                             s_suffix(mon_nam(mon)));
3498 #else
3499                         You("%s\82Ì\82É\82ç\82Ý\82Å\88ê\8fu\8dd\92¼\82µ\82½\81I",
3500                             mon_nam(mon));
3501 #endif
3502                     } else {
3503 /*JP
3504                         You("are frozen by %s gaze!", s_suffix(mon_nam(mon)));
3505 */
3506                         You("%s\82Ì\82É\82ç\82Ý\82Å\93®\82¯\82È\82­\82È\82Á\82½\81I", mon_nam(mon));
3507                         nomul((ACURR(A_WIS) > 12 || rn2(4)) ? -tmp : -127);
3508 /*JP
3509                         multi_reason = "frozen by a monster's gaze";
3510 */
3511                         multi_reason = "\89ö\95¨\82Ì\82É\82ç\82Ý\82Å\8dd\92¼\82µ\82Ä\82¢\82é\8e\9e\82É";
3512                         nomovemsg = 0;
3513                     }
3514                 } else {
3515 #if 0 /*JP:T*/
3516                     pline("%s cannot defend itself.",
3517                           Adjmonnam(mon, "blind"));
3518 #else
3519                     pline("%s\82Í\96h\8cä\82Å\82«\82È\82¢\81D",
3520                           Adjmonnam(mon,"\96Ú\82Ì\8c©\82¦\82È\82¢"));
3521 #endif
3522                     if (!rn2(500))
3523                         change_luck(-1);
3524                 }
3525             } else if (Free_action) {
3526 /*JP
3527                 You("momentarily stiffen.");
3528 */
3529                 You("\88ê\8fu\8dd\92¼\82µ\82½\81D");
3530             } else { /* gelatinous cube */
3531 /*JP
3532                 You("are frozen by %s!", mon_nam(mon));
3533 */
3534                 You("%s\82É\82æ\82Á\82Ä\93®\82¯\82È\82­\82È\82Á\82½\81I", mon_nam(mon));
3535                 nomovemsg = You_can_move_again;
3536                 nomul(-tmp);
3537 /*JP
3538                 multi_reason = "frozen by a monster";
3539 */
3540                 multi_reason = "\89ö\95¨\82É\82æ\82Á\82Ä\8dd\92¼\82µ\82Ä\82¢\82é\8e\9e\82É";
3541                 exercise(A_DEX, FALSE);
3542             }
3543             break;
3544         case AD_COLD: /* brown mold or blue jelly */
3545             if (monnear(mon, u.ux, u.uy)) {
3546                 if (Cold_resistance) {
3547                     shieldeff(u.ux, u.uy);
3548 /*JP
3549                     You_feel("a mild chill.");
3550 */
3551                     You("\8a¦\82³\82ð\8a´\82\82½\81D");
3552                     ugolemeffects(AD_COLD, tmp);
3553                     break;
3554                 }
3555 /*JP
3556                 You("are suddenly very cold!");
3557 */
3558                 You("\93Ë\91R\81C\96Ò\97ó\82É\8a¦\82­\82È\82Á\82½\81I");
3559                 mdamageu(mon, tmp);
3560                 /* monster gets stronger with your heat! */
3561                 mon->mhp += tmp / 2;
3562                 if (mon->mhpmax < mon->mhp)
3563                     mon->mhpmax = mon->mhp;
3564                 /* at a certain point, the monster will reproduce! */
3565                 if (mon->mhpmax > ((int) (mon->m_lev + 1) * 8))
3566                     (void) split_mon(mon, &youmonst);
3567             }
3568             break;
3569         case AD_STUN: /* specifically yellow mold */
3570             if (!Stunned)
3571                 make_stunned((long) tmp, TRUE);
3572             break;
3573         case AD_FIRE:
3574             if (monnear(mon, u.ux, u.uy)) {
3575                 if (Fire_resistance) {
3576                     shieldeff(u.ux, u.uy);
3577 /*JP
3578                     You_feel("mildly warm.");
3579 */
3580                     You("\92g\82©\82³\82ð\8a´\82\82½\81D");
3581                     ugolemeffects(AD_FIRE, tmp);
3582                     break;
3583                 }
3584 /*JP
3585                 You("are suddenly very hot!");
3586 */
3587                 You("\93Ë\91R\81C\96Ò\97ó\82É\94M\82­\82È\82Á\82½\81I");
3588                 mdamageu(mon, tmp); /* fire damage */
3589             }
3590             break;
3591         case AD_ELEC:
3592             if (Shock_resistance) {
3593                 shieldeff(u.ux, u.uy);
3594 /*JP
3595                 You_feel("a mild tingle.");
3596 */
3597                 You("\83s\83\8a\83s\83\8a\82Æá\83\82ê\82ð\8a´\82\82½\81D");
3598                 ugolemeffects(AD_ELEC, tmp);
3599                 break;
3600             }
3601 /*JP
3602             You("are jolted with electricity!");
3603 */
3604             You("\93d\8bC\83V\83\87\83b\83N\82ð\82¤\82¯\82½\81I");
3605             mdamageu(mon, tmp);
3606             break;
3607         default:
3608             break;
3609         }
3610     }
3611     return (malive | mhit);
3612 }
3613
3614 /*
3615  * Special (passive) attacks on an attacking object by monsters done here.
3616  * Assumes the attack was successful.
3617  */
3618 void
3619 passive_obj(mon, obj, mattk)
3620 struct monst *mon;
3621 struct obj *obj;          /* null means pick uwep, uswapwep or uarmg */
3622 struct attack *mattk;     /* null means we find one internally */
3623 {
3624     struct permonst *ptr = mon->data;
3625     int i;
3626
3627     /* [this first bit is obsolete; we're not called with Null anymore] */
3628     /* if caller hasn't specified an object, use uwep, uswapwep or uarmg */
3629     if (!obj) {
3630         obj = (u.twoweap && uswapwep && !rn2(2)) ? uswapwep : uwep;
3631         if (!obj && mattk->adtyp == AD_ENCH)
3632             obj = uarmg; /* no weapon? then must be gloves */
3633         if (!obj)
3634             return; /* no object to affect */
3635     }
3636
3637     /* if caller hasn't specified an attack, find one */
3638     if (!mattk) {
3639         for (i = 0;; i++) {
3640             if (i >= NATTK)
3641                 return; /* no passive attacks */
3642             if (ptr->mattk[i].aatyp == AT_NONE)
3643                 break; /* try this one */
3644         }
3645         mattk = &(ptr->mattk[i]);
3646     }
3647
3648     switch (mattk->adtyp) {
3649     case AD_FIRE:
3650         if (!rn2(6) && !mon->mcan
3651             /* steam vortex: fire resist applies, fire damage doesn't */
3652             && mon->data != &mons[PM_STEAM_VORTEX]) {
3653             (void) erode_obj(obj, NULL, ERODE_BURN, EF_NONE);
3654         }
3655         break;
3656     case AD_ACID:
3657         if (!rn2(6)) {
3658             (void) erode_obj(obj, NULL, ERODE_CORRODE, EF_GREASE);
3659         }
3660         break;
3661     case AD_RUST:
3662         if (!mon->mcan) {
3663             (void) erode_obj(obj, (char *) 0, ERODE_RUST, EF_GREASE);
3664         }
3665         break;
3666     case AD_CORR:
3667         if (!mon->mcan) {
3668             (void) erode_obj(obj, (char *) 0, ERODE_CORRODE, EF_GREASE);
3669         }
3670         break;
3671     case AD_ENCH:
3672         if (!mon->mcan) {
3673             if (drain_item(obj, TRUE) && carried(obj)
3674                 && (obj->known || obj->oclass == ARMOR_CLASS)) {
3675 /*JP
3676                 pline("%s less effective.", Yobjnam2(obj, "seem"));
3677 */
3678                 Your("%s\82©\82ç\96\82\97Í\82ª\8fÁ\82¦\82½\82æ\82¤\82¾\81D", xname(obj));
3679             }
3680             break;
3681         }
3682     default:
3683         break;
3684     }
3685
3686     if (carried(obj))
3687         update_inventory();
3688 }
3689
3690 /* Note: caller must ascertain mtmp is mimicking... */
3691 void
3692 stumble_onto_mimic(mtmp)
3693 struct monst *mtmp;
3694 {
3695 /*JP
3696     const char *fmt = "Wait!  That's %s!", *generic = "a monster", *what = 0;
3697 */
3698     const char *fmt = "\82¿\82å\82Á\82Æ\82Ü\82Á\82½\81I%s\82¾\81I", *generic = "\89ö\95¨", *what = 0;
3699
3700     if (!u.ustuck && !mtmp->mflee && dmgtype(mtmp->data, AD_STCK))
3701         u.ustuck = mtmp;
3702
3703     if (Blind) {
3704         if (!Blind_telepat)
3705             what = generic; /* with default fmt */
3706         else if (M_AP_TYPE(mtmp) == M_AP_MONSTER)
3707             what = a_monnam(mtmp); /* differs from what was sensed */
3708     } else {
3709         int glyph = levl[u.ux + u.dx][u.uy + u.dy].glyph;
3710
3711         if (glyph_is_cmap(glyph) && (glyph_to_cmap(glyph) == S_hcdoor
3712                                      || glyph_to_cmap(glyph) == S_vcdoor))
3713 /*JP
3714             fmt = "The door actually was %s!";
3715 */
3716             fmt = "\94à\82Í\8eÀ\8dÛ\82É\82Í%s\82¾\82Á\82½\81I";
3717         else if (glyph_is_object(glyph) && glyph_to_obj(glyph) == GOLD_PIECE)
3718 /*JP
3719             fmt = "That gold was %s!";
3720 */
3721             fmt = "\8bà\89Ý\82Í%s\82¾\82Á\82½\81I";
3722
3723         /* cloned Wiz starts out mimicking some other monster and
3724            might make himself invisible before being revealed */
3725         if (mtmp->minvis && !See_invisible)
3726             what = generic;
3727         else
3728             what = a_monnam(mtmp);
3729     }
3730     if (what)
3731         pline(fmt, what);
3732
3733     wakeup(mtmp, FALSE); /* clears mimicking */
3734     /* if hero is blind, wakeup() won't display the monster even though
3735        it's no longer concealed */
3736     if (!canspotmon(mtmp)
3737         && !glyph_is_invisible(levl[mtmp->mx][mtmp->my].glyph))
3738         map_invisible(mtmp->mx, mtmp->my);
3739 }
3740
3741 STATIC_OVL void
3742 nohandglow(mon)
3743 struct monst *mon;
3744 {
3745     char *hands = makeplural(body_part(HAND));
3746
3747     if (!u.umconf || mon->mconf)
3748         return;
3749     if (u.umconf == 1) {
3750         if (Blind)
3751 /*JP
3752             Your("%s stop tingling.", hands);
3753 */
3754             Your("%s\82Ìá\83\82ê\82ª\82Æ\82ê\82½\81D", hands);
3755         else
3756 /*JP
3757             Your("%s stop glowing %s.", hands, hcolor(NH_RED));
3758 */
3759             Your("%s\82Ì%s\8bP\82«\82Í\82È\82­\82È\82Á\82½\81D", hands, hcolor(NH_RED));
3760     } else {
3761         if (Blind)
3762 /*JP
3763             pline_The("tingling in your %s lessens.", hands);
3764 */
3765             pline("%s\82Ìá\83\82ê\82ª\82Æ\82ê\82Ä\82«\82½\81D",hands);
3766         else
3767 /*JP
3768             Your("%s no longer glow so brightly %s.", hands, hcolor(NH_RED));
3769 */
3770             Your("%s\82Ì%s\8bP\82«\82ª\82È\82­\82È\82Á\82Ä\82«\82½\81D",hands, hcolor(NH_RED));
3771     }
3772     u.umconf--;
3773 }
3774
3775 int
3776 flash_hits_mon(mtmp, otmp)
3777 struct monst *mtmp;
3778 struct obj *otmp; /* source of flash */
3779 {
3780     int tmp, amt, res = 0, useeit = canseemon(mtmp);
3781
3782     if (mtmp->msleeping) {
3783         mtmp->msleeping = 0;
3784         if (useeit) {
3785 /*JP
3786             pline_The("flash awakens %s.", mon_nam(mtmp));
3787 */
3788             pline("\91M\8cõ\82Å%s\82ª\96Ú\82ð\8ao\82Ü\82µ\82½\81D", mon_nam(mtmp));
3789             res = 1;
3790         }
3791     } else if (mtmp->data->mlet != S_LIGHT) {
3792         if (!resists_blnd(mtmp)) {
3793             tmp = dist2(otmp->ox, otmp->oy, mtmp->mx, mtmp->my);
3794             if (useeit) {
3795 /*JP
3796                 pline("%s is blinded by the flash!", Monnam(mtmp));
3797 */
3798                 pline("%s\82Í\91M\8cõ\82Å\96Ú\82ª\8c©\82¦\82È\82­\82È\82Á\82½\81I", Monnam(mtmp));
3799                 res = 1;
3800             }
3801             if (mtmp->data == &mons[PM_GREMLIN]) {
3802                 /* Rule #1: Keep them out of the light. */
3803                 amt = otmp->otyp == WAN_LIGHT ? d(1 + otmp->spe, 4)
3804                                               : rn2(min(mtmp->mhp, 4));
3805                 light_hits_gremlin(mtmp, amt);
3806             }
3807             if (!DEADMONSTER(mtmp)) {
3808                 if (!context.mon_moving)
3809                     setmangry(mtmp, TRUE);
3810                 if (tmp < 9 && !mtmp->isshk && rn2(4))
3811                     monflee(mtmp, rn2(4) ? rnd(100) : 0, FALSE, TRUE);
3812                 mtmp->mcansee = 0;
3813                 mtmp->mblinded = (tmp < 3) ? 0 : rnd(1 + 50 / tmp);
3814             }
3815         }
3816     }
3817     return res;
3818 }
3819
3820 void
3821 light_hits_gremlin(mon, dmg)
3822 struct monst *mon;
3823 int dmg;
3824 {
3825 #if 0 /*JP:T*/
3826     pline("%s %s!", Monnam(mon),
3827           (dmg > mon->mhp / 2) ? "wails in agony" : "cries out in pain");
3828 #else
3829     pline("%s\82Í%s\81I", Monnam(mon),
3830           (dmg > mon->mhp / 2) ? "\8bê\92É\82Ì\90º\82ð\82 \82°\82½" : "\8c\83\92É\82Å\8b©\82ñ\82¾");
3831 #endif
3832     mon->mhp -= dmg;
3833     wake_nearto(mon->mx, mon->my, 30);
3834     if (DEADMONSTER(mon)) {
3835         if (context.mon_moving)
3836             monkilled(mon, (char *) 0, AD_BLND);
3837         else
3838             killed(mon);
3839     } else if (cansee(mon->mx, mon->my) && !canspotmon(mon)) {
3840         map_invisible(mon->mx, mon->my);
3841     }
3842 }
3843
3844 /*uhitm.c*/