OSDN Git Service

set trivial flags
[jnethack/source.git] / src / uhitm.c
1 /* NetHack 3.6  uhitm.c $NHDT-Date: 1555720104 2019/04/20 00:28:24 $  $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.207 $ */
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-2019            */
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 #if 0 /*JP*/
758     char unconventional[BUFSZ]; /* substituted for word "attack" in msg */
759 #endif
760     char saved_oname[BUFSZ];
761
762 #if 0 /*JP*/
763     unconventional[0] = '\0';
764 #endif
765     saved_oname[0] = '\0';
766
767     wakeup(mon, TRUE);
768     if (!obj) { /* attack with bare hands */
769         if (mdat == &mons[PM_SHADE])
770             tmp = 0;
771         else if (martial_bonus())
772             tmp = rnd(4); /* bonus for martial arts */
773         else
774             tmp = rnd(2);
775         valid_weapon_attack = (tmp > 1);
776         /* Blessed gloves give bonuses when fighting 'bare-handed'.  So do
777            silver rings.  Note:  rings are worn under gloves, so you don't
778            get both bonuses, and two silver rings don't give double bonus. */
779         tmp += special_dmgval(&youmonst, mon, (W_ARMG | W_RINGL | W_RINGR),
780                               &silverhit);
781         barehand_silver_rings += (((silverhit & W_RINGL) ? 1 : 0)
782                                   + ((silverhit & W_RINGR) ? 1 : 0));
783         if (barehand_silver_rings > 0)
784             silvermsg = TRUE;
785     } else {
786         if (!(artifact_light(obj) && obj->lamplit))
787             Strcpy(saved_oname, cxname(obj));
788         else
789             Strcpy(saved_oname, bare_artifactname(obj));
790         if (obj->oclass == WEAPON_CLASS || is_weptool(obj)
791             || obj->oclass == GEM_CLASS) {
792             /* is it not a melee weapon? */
793             if (/* if you strike with a bow... */
794                 is_launcher(obj)
795                 /* or strike with a missile in your hand... */
796                 || (!thrown && (is_missile(obj) || is_ammo(obj)))
797                 /* or use a pole at short range and not mounted... */
798                 || (!thrown && !u.usteed && is_pole(obj))
799                 /* or throw a missile without the proper bow... */
800                 || (is_ammo(obj) && (thrown != HMON_THROWN
801                                      || !ammo_and_launcher(obj, uwep)))) {
802                 /* then do only 1-2 points of damage */
803                 if (mdat == &mons[PM_SHADE] && !shade_glare(obj))
804                     tmp = 0;
805                 else
806                     tmp = rnd(2);
807                 if (objects[obj->otyp].oc_material == SILVER
808                     && mon_hates_silver(mon)) {
809                     silvermsg = TRUE;
810                     silverobj = TRUE;
811                     /* if it will already inflict dmg, make it worse */
812                     tmp += rnd((tmp) ? 20 : 10);
813                 }
814                 if (!thrown && obj == uwep && obj->otyp == BOOMERANG
815                     && rnl(4) == 4 - 1) {
816                     boolean more_than_1 = (obj->quan > 1L);
817
818 #if 0 /*JP:T*/
819                     pline("As you hit %s, %s%s breaks into splinters.",
820                           mon_nam(mon), more_than_1 ? "one of " : "",
821                           yname(obj));
822 #else
823                     pline("%s\82ð\8dU\8c\82\82·\82é\82Æ\81C%s%s\82Í\82±\82Á\82Ï\82Ý\82\82ñ\82É\82È\82Á\82½\81D",
824                           mon_nam(mon), yname(obj),
825                           more_than_1 ? "\82Ì\82Ð\82Æ\82Â" : "");
826 #endif
827                     if (!more_than_1)
828                         uwepgone(); /* set unweapon */
829                     useup(obj);
830                     if (!more_than_1)
831                         obj = (struct obj *) 0;
832                     hittxt = TRUE;
833                     if (mdat != &mons[PM_SHADE])
834                         tmp++;
835                 }
836             } else {
837                 tmp = dmgval(obj, mon);
838                 /* a minimal hit doesn't exercise proficiency */
839                 valid_weapon_attack = (tmp > 1);
840                 if (!valid_weapon_attack || mon == u.ustuck || u.twoweap
841                     /* Cleaver can hit up to three targets at once so don't
842                        let it also hit from behind or shatter foes' weapons */
843                     || (hand_to_hand && obj->oartifact == ART_CLEAVER)) {
844                     ; /* no special bonuses */
845                 } else if (mon->mflee && Role_if(PM_ROGUE) && !Upolyd
846                            /* multi-shot throwing is too powerful here */
847                            && hand_to_hand) {
848 /*JP
849                     You("strike %s from behind!", mon_nam(mon));
850 */
851                     You("%s\82ð\94w\8cã\82©\82ç\8dU\8c\82\82µ\82½\81I", mon_nam(mon));
852                     tmp += rnd(u.ulevel);
853                     hittxt = TRUE;
854                 } else if (dieroll == 2 && obj == uwep
855                            && obj->oclass == WEAPON_CLASS
856                            && (bimanual(obj)
857                                || (Role_if(PM_SAMURAI) && obj->otyp == KATANA
858                                    && !uarms))
859                            && ((wtype = uwep_skill_type()) != P_NONE
860                                && P_SKILL(wtype) >= P_SKILLED)
861                            && ((monwep = MON_WEP(mon)) != 0
862                                && !is_flimsy(monwep)
863                                && !obj_resists(monwep,
864                                        50 + 15 * (greatest_erosion(obj)
865                                                   - greatest_erosion(monwep)),
866                                                100))) {
867                     /*
868                      * 2.5% chance of shattering defender's weapon when
869                      * using a two-handed weapon; less if uwep is rusted.
870                      * [dieroll == 2 is most successful non-beheading or
871                      * -bisecting hit, in case of special artifact damage;
872                      * the percentage chance is (1/20)*(50/100).]
873                      * If attacker's weapon is rustier than defender's,
874                      * the obj_resists chance is increased so the shatter
875                      * chance is decreased; if less rusty, then vice versa.
876                      */
877                     setmnotwielded(mon, monwep);
878                     mon->weapon_check = NEED_WEAPON;
879 #if 0 /*JP:T*/
880                     pline("%s from the force of your blow!",
881                           Yobjnam2(monwep, "shatter"));
882 #else
883                     pline("%s\82Ì%s\82Í\82 \82È\82½\82Ì\88ê\8c\82\82Å\95²\81X\82É\82È\82Á\82½\81I",
884                           Monnam(mon), xname(monwep));
885 #endif
886                     m_useupall(mon, monwep);
887                     /* If someone just shattered MY weapon, I'd flee! */
888                     if (rn2(4)) {
889                         monflee(mon, d(2, 3), TRUE, TRUE);
890                     }
891                     hittxt = TRUE;
892                 }
893
894                 if (obj->oartifact
895                     && artifact_hit(&youmonst, mon, obj, &tmp, dieroll)) {
896                     if (DEADMONSTER(mon)) /* artifact killed monster */
897                         return FALSE;
898                     if (tmp == 0)
899                         return TRUE;
900                     hittxt = TRUE;
901                 }
902                 if (objects[obj->otyp].oc_material == SILVER
903                     && mon_hates_silver(mon)) {
904                     silvermsg = TRUE;
905                     silverobj = TRUE;
906                 }
907                 if (artifact_light(obj) && obj->lamplit
908                     && mon_hates_light(mon))
909                     lightobj = TRUE;
910                 if (u.usteed && !thrown && tmp > 0
911                     && weapon_type(obj) == P_LANCE && mon != u.ustuck) {
912                     jousting = joust(mon, obj);
913                     /* exercise skill even for minimal damage hits */
914                     if (jousting)
915                         valid_weapon_attack = TRUE;
916                 }
917                 if (thrown == HMON_THROWN
918                     && (is_ammo(obj) || is_missile(obj))) {
919                     if (ammo_and_launcher(obj, uwep)) {
920                         /* Elves and Samurai do extra damage using
921                          * their bows&arrows; they're highly trained.
922                          */
923                         if (Role_if(PM_SAMURAI) && obj->otyp == YA
924                             && uwep->otyp == YUMI)
925                             tmp++;
926                         else if (Race_if(PM_ELF) && obj->otyp == ELVEN_ARROW
927                                  && uwep->otyp == ELVEN_BOW)
928                             tmp++;
929                     }
930                     if (obj->opoisoned && is_poisonable(obj))
931                         ispoisoned = TRUE;
932                 }
933             }
934         } else if (obj->oclass == POTION_CLASS) {
935             if (obj->quan > 1L)
936                 obj = splitobj(obj, 1L);
937             else
938                 setuwep((struct obj *) 0);
939             freeinv(obj);
940             potionhit(mon, obj,
941                       hand_to_hand ? POTHIT_HERO_BASH : POTHIT_HERO_THROW);
942             if (DEADMONSTER(mon))
943                 return FALSE; /* killed */
944             hittxt = TRUE;
945             /* in case potion effect causes transformation */
946             mdat = mon->data;
947             tmp = (mdat == &mons[PM_SHADE]) ? 0 : 1;
948         } else {
949             if (mdat == &mons[PM_SHADE] && !shade_aware(obj)) {
950                 tmp = 0;
951 #if 0 /*JP*/
952                 Strcpy(unconventional, cxname(obj));
953 #endif
954             } else {
955                 switch (obj->otyp) {
956                 case BOULDER:         /* 1d20 */
957                 case HEAVY_IRON_BALL: /* 1d25 */
958                 case IRON_CHAIN:      /* 1d4+1 */
959                     tmp = dmgval(obj, mon);
960                     break;
961                 case MIRROR:
962                     if (breaktest(obj)) {
963 /*JP
964                         You("break %s.  That's bad luck!", ysimple_name(obj));
965 */
966                         You("%s\8b¾\82ð\89ó\82µ\82Ä\82µ\82Ü\82Á\82½\81D\82±\82è\82á\82Ü\82¢\82Á\82½\81I", ysimple_name(obj));
967                         change_luck(-2);
968                         useup(obj);
969                         obj = (struct obj *) 0;
970                         unarmed = FALSE; /* avoid obj==0 confusion */
971                         get_dmg_bonus = FALSE;
972                         hittxt = TRUE;
973                     }
974                     tmp = 1;
975                     break;
976                 case EXPENSIVE_CAMERA:
977 /*JP
978                     You("succeed in destroying %s.  Congratulations!",
979 */
980                     You("%s\83J\83\81\83\89\82ð\89ó\82·\82±\82Æ\82ª\82Å\82«\82½\81D\82¨\82ß\82Å\82Æ\82¤\81I",
981                         ysimple_name(obj));
982                     release_camera_demon(obj, u.ux, u.uy);
983                     useup(obj);
984                     return TRUE;
985                 case CORPSE: /* fixed by polder@cs.vu.nl */
986                     if (touch_petrifies(&mons[obj->corpsenm])) {
987                         tmp = 1;
988                         hittxt = TRUE;
989 #if 0 /*JP:T*/
990                         You("hit %s with %s.", mon_nam(mon),
991                             corpse_xname(obj, (const char *) 0,
992                                          obj->dknown ? CXN_PFX_THE
993                                                      : CXN_ARTICLE));
994 #else
995                         You("%s\82ð%s\82Å\8dU\8c\82\82µ\82½\81D", mon_nam(mon),
996                             corpse_xname(obj, (const char *) 0,
997                                          obj->dknown ? CXN_PFX_THE
998                                                      : CXN_ARTICLE));
999 #endif
1000                         obj->dknown = 1;
1001                         if (!munstone(mon, TRUE))
1002                             minstapetrify(mon, TRUE);
1003                         if (resists_ston(mon))
1004                             break;
1005                         /* note: hp may be <= 0 even if munstoned==TRUE */
1006                         return (boolean) !DEADMONSTER(mon);
1007 #if 0
1008                     } else if (touch_petrifies(mdat)) {
1009                         ; /* maybe turn the corpse into a statue? */
1010 #endif
1011                     }
1012                     tmp = (obj->corpsenm >= LOW_PM ? mons[obj->corpsenm].msize
1013                                                    : 0) + 1;
1014                     break;
1015
1016 #define useup_eggs(o)                    \
1017     do {                                 \
1018         if (thrown)                      \
1019             obfree(o, (struct obj *) 0); \
1020         else                             \
1021             useupall(o);                 \
1022         o = (struct obj *) 0;            \
1023     } while (0) /* now gone */
1024                 case EGG: {
1025                     long cnt = obj->quan;
1026
1027                     tmp = 1; /* nominal physical damage */
1028                     get_dmg_bonus = FALSE;
1029                     hittxt = TRUE; /* message always given */
1030                     /* egg is always either used up or transformed, so next
1031                        hand-to-hand attack should yield a "bashing" mesg */
1032                     if (obj == uwep)
1033                         unweapon = TRUE;
1034                     if (obj->spe && obj->corpsenm >= LOW_PM) {
1035                         if (obj->quan < 5L)
1036                             change_luck((schar) - (obj->quan));
1037                         else
1038                             change_luck(-5);
1039                     }
1040
1041                     if (touch_petrifies(&mons[obj->corpsenm])) {
1042                         /*learn_egg_type(obj->corpsenm);*/
1043 #if 0 /*JP:T*/
1044                         pline("Splat!  You hit %s with %s %s egg%s!",
1045                               mon_nam(mon),
1046                               obj->known ? "the" : cnt > 1L ? "some" : "a",
1047                               obj->known ? mons[obj->corpsenm].mname
1048                                          : "petrifying",
1049                               plur(cnt));
1050 #else
1051                         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",
1052                               mon_nam(mon),
1053                               cnt > 1L ? "\82¢\82­\82Â\82©\82Ì" : "",
1054                               obj->known ? mons[obj->corpsenm].mname
1055                                          : "\90Î\89»");
1056 #endif
1057                         obj->known = 1; /* (not much point...) */
1058                         useup_eggs(obj);
1059                         if (!munstone(mon, TRUE))
1060                             minstapetrify(mon, TRUE);
1061                         if (resists_ston(mon))
1062                             break;
1063                         return (boolean) (!DEADMONSTER(mon));
1064                     } else { /* ordinary egg(s) */
1065 #if 0 /*JP:T*/
1066                         const char *eggp = (obj->corpsenm != NON_PM
1067                                             && obj->known)
1068                                            ? the(mons[obj->corpsenm].mname)
1069                                            : (cnt > 1L) ? "some" : "an";
1070
1071                         You("hit %s with %s egg%s.", mon_nam(mon), eggp,
1072                             plur(cnt));
1073 #else
1074                         const char *eggp = (obj->corpsenm != NON_PM
1075                                             && obj->known)
1076                                            ? mons[obj->corpsenm].mname
1077                                            : "";
1078                         You("%s\82É%s%s\97\91\82ð\93\8a\82°\82Â\82¯\82½\81D",
1079                                 mon_nam(mon), eggp, *eggp ? "\82Ì" : "");
1080 #endif
1081                         if (touch_petrifies(mdat) && !stale_egg(obj)) {
1082 #if 0 /*JP:T*/
1083                             pline_The("egg%s %s alive any more...", plur(cnt),
1084                                       (cnt == 1L) ? "isn't" : "aren't");
1085 #else
1086                             pline("\82à\82¤\97\91\82ª\9bz\89»\82·\82é\82±\82Æ\82Í\82È\82¢\82¾\82ë\82¤\81D\81D\81D");
1087 #endif
1088                             if (obj->timed)
1089                                 obj_stop_timers(obj);
1090                             obj->otyp = ROCK;
1091                             obj->oclass = GEM_CLASS;
1092                             obj->oartifact = 0;
1093                             obj->spe = 0;
1094                             obj->known = obj->dknown = obj->bknown = 0;
1095                             obj->owt = weight(obj);
1096                             if (thrown)
1097                                 place_object(obj, mon->mx, mon->my);
1098                         } else {
1099 /*JP
1100                             pline("Splat!");
1101 */
1102                             pline("\83r\83`\83\83\83b\81I");
1103                             useup_eggs(obj);
1104                             exercise(A_WIS, FALSE);
1105                         }
1106                     }
1107                     break;
1108 #undef useup_eggs
1109                 }
1110                 case CLOVE_OF_GARLIC: /* no effect against demons */
1111                     if (is_undead(mdat) || is_vampshifter(mon)) {
1112                         monflee(mon, d(2, 4), FALSE, TRUE);
1113                     }
1114                     tmp = 1;
1115                     break;
1116                 case CREAM_PIE:
1117                 case BLINDING_VENOM:
1118                     mon->msleeping = 0;
1119                     if (can_blnd(&youmonst, mon,
1120                                  (uchar) ((obj->otyp == BLINDING_VENOM)
1121                                              ? AT_SPIT
1122                                              : AT_WEAP),
1123                                  obj)) {
1124                         if (Blind) {
1125 #if 0 /*JP:T*/
1126                             pline(obj->otyp == CREAM_PIE ? "Splat!"
1127                                                          : "Splash!");
1128 #else
1129                             pline(obj->otyp == CREAM_PIE ? "\83r\83V\83\83\83b\81I"
1130                                                          : "\83s\83`\83\83\83b\81I");
1131 #endif
1132                         } else if (obj->otyp == BLINDING_VENOM) {
1133 #if 0 /*JP:T*/
1134                             pline_The("venom blinds %s%s!", mon_nam(mon),
1135                                       mon->mcansee ? "" : " further");
1136 #else
1137                             pline("\93Å\89t\82Å%s\82Í%s\96Ú\82ª\8c©\82¦\82È\82­\82È\82Á\82½\81I", mon_nam(mon),
1138                                   mon->mcansee ? "" : "\82³\82ç\82É");
1139 #endif
1140                         } else {
1141                             char *whom = mon_nam(mon);
1142                             char *what = The(xname(obj));
1143
1144                             if (!thrown && obj->quan > 1L)
1145                                 what = An(singular(obj, xname));
1146                             /* note: s_suffix returns a modifiable buffer */
1147                             if (haseyes(mdat)
1148                                 && mdat != &mons[PM_FLOATING_EYE])
1149 #if 0 /*JP*/
1150                                 whom = strcat(strcat(s_suffix(whom), " "),
1151                                               mbodypart(mon, FACE));
1152 #else
1153                                 whom = strcat(s_suffix(whom),
1154                                               mbodypart(mon, FACE));
1155 #endif
1156 #if 0 /*JP:T*/
1157                             pline("%s %s over %s!", what,
1158                                   vtense(what, "splash"), whom);
1159 #else
1160                             pline("%s\82Í%s\82É\82Ô\82¿\82Ü\82¯\82ç\82ê\82½\81I",
1161                                   what, whom);
1162 #endif
1163                         }
1164                         setmangry(mon, TRUE);
1165                         mon->mcansee = 0;
1166                         tmp = rn1(25, 21);
1167                         if (((int) mon->mblinded + tmp) > 127)
1168                             mon->mblinded = 127;
1169                         else
1170                             mon->mblinded += tmp;
1171                     } else {
1172 /*JP
1173                         pline(obj->otyp == CREAM_PIE ? "Splat!" : "Splash!");
1174 */
1175                         pline(obj->otyp==CREAM_PIE ? "\83r\83V\83\83\83b\81I" : "\83s\83`\83\83\83b\81I");
1176                         setmangry(mon, TRUE);
1177                     }
1178                     if (thrown)
1179                         obfree(obj, (struct obj *) 0);
1180                     else
1181                         useup(obj);
1182                     hittxt = TRUE;
1183                     get_dmg_bonus = FALSE;
1184                     tmp = 0;
1185                     break;
1186                 case ACID_VENOM: /* thrown (or spit) */
1187                     if (resists_acid(mon)) {
1188 /*JP
1189                         Your("venom hits %s harmlessly.", mon_nam(mon));
1190 */
1191                         pline("\93Å\89t\82Í%s\82É\82Í\8cø\89Ê\82ª\82È\82©\82Á\82½\81D", mon_nam(mon));
1192                         tmp = 0;
1193                     } else {
1194 /*JP
1195                         Your("venom burns %s!", mon_nam(mon));
1196 */
1197                         Your("\93Å\89t\82Í%s\82ð\8fÄ\82¢\82½\81I", mon_nam(mon));
1198                         tmp = dmgval(obj, mon);
1199                     }
1200                     if (thrown)
1201                         obfree(obj, (struct obj *) 0);
1202                     else
1203                         useup(obj);
1204                     hittxt = TRUE;
1205                     get_dmg_bonus = FALSE;
1206                     break;
1207                 default:
1208                     /* non-weapons can damage because of their weight */
1209                     /* (but not too much) */
1210                     tmp = obj->owt / 100;
1211                     if (is_wet_towel(obj)) {
1212                         /* wielded wet towel should probably use whip skill
1213                            (but not by setting objects[TOWEL].oc_skill==P_WHIP
1214                            because that would turn towel into a weptool) */
1215                         tmp += obj->spe;
1216                         if (rn2(obj->spe + 1)) /* usually lose some wetness */
1217                             dry_a_towel(obj, -1, TRUE);
1218                     }
1219                     if (tmp < 1)
1220                         tmp = 1;
1221                     else
1222                         tmp = rnd(tmp);
1223                     if (tmp > 6)
1224                         tmp = 6;
1225                     /*
1226                      * Things like silver wands can arrive here so
1227                      * so we need another silver check.
1228                      */
1229                     if (objects[obj->otyp].oc_material == SILVER
1230                         && mon_hates_silver(mon)) {
1231                         tmp += rnd(20);
1232                         silvermsg = TRUE;
1233                         silverobj = TRUE;
1234                     }
1235                 }
1236             }
1237         }
1238     }
1239
1240     /****** NOTE: perhaps obj is undefined!! (if !thrown && BOOMERANG)
1241      *      *OR* if attacking bare-handed!! */
1242
1243     if (get_dmg_bonus && tmp > 0) {
1244         tmp += u.udaminc;
1245         /* If you throw using a propellor, you don't get a strength
1246          * bonus but you do get an increase-damage bonus.
1247          */
1248         if (thrown != HMON_THROWN || !obj || !uwep
1249             || !ammo_and_launcher(obj, uwep))
1250             tmp += dbon();
1251     }
1252
1253     if (valid_weapon_attack) {
1254         struct obj *wep;
1255
1256         /* to be valid a projectile must have had the correct projector */
1257         wep = PROJECTILE(obj) ? uwep : obj;
1258         tmp += weapon_dam_bonus(wep);
1259         /* [this assumes that `!thrown' implies wielded...] */
1260         wtype = thrown ? weapon_type(wep) : uwep_skill_type();
1261         use_skill(wtype, 1);
1262     }
1263
1264     if (ispoisoned) {
1265         int nopoison = (10 - (obj->owt / 10));
1266
1267         if (nopoison < 2)
1268             nopoison = 2;
1269         if (Role_if(PM_SAMURAI)) {
1270 /*JP
1271             You("dishonorably use a poisoned weapon!");
1272 */
1273             You("\95s\96¼\97_\82É\82à\93Å\82Ì\95\90\8aí\82ð\8eg\97p\82µ\82½\81I");
1274             adjalign(-sgn(u.ualign.type));
1275         } else if (u.ualign.type == A_LAWFUL && u.ualign.record > -10) {
1276 /*JP
1277             You_feel("like an evil coward for using a poisoned weapon.");
1278 */
1279             You("\93Å\82Ì\95\90\8aí\82ð\8eg\97p\82·\82é\82Ì\82Í\94Ú\8b¯\82¾\82Æ\8a´\82\82½\81D");
1280             adjalign(-1);
1281         }
1282         if (obj && !rn2(nopoison)) {
1283             /* remove poison now in case obj ends up in a bones file */
1284             obj->opoisoned = FALSE;
1285             /* defer "obj is no longer poisoned" until after hit message */
1286             unpoisonmsg = TRUE;
1287         }
1288         if (resists_poison(mon))
1289             needpoismsg = TRUE;
1290         else if (rn2(10))
1291             tmp += rnd(6);
1292         else
1293             poiskilled = TRUE;
1294     }
1295     if (tmp < 1) {
1296         /* make sure that negative damage adjustment can't result
1297            in inadvertently boosting the victim's hit points */
1298         tmp = 0;
1299         if (mdat == &mons[PM_SHADE]) {
1300             if (!hittxt) {
1301 #if 0 /*JP*/
1302                 const char *what = *unconventional ? unconventional : "attack";
1303
1304                 Your("%s %s harmlessly through %s.", what,
1305                      vtense(what, "pass"), mon_nam(mon));
1306 #else
1307                 Your("\8dU\8c\82\82Í%s\82ð\92Ê\82è\82Ê\82¯\82½\81D", mon_nam(mon));
1308 #endif
1309                 hittxt = TRUE;
1310             }
1311         } else {
1312             if (get_dmg_bonus)
1313                 tmp = 1;
1314         }
1315     }
1316
1317     if (jousting) {
1318         tmp += d(2, (obj == uwep) ? 10 : 2); /* [was in dmgval()] */
1319 /*JP
1320         You("joust %s%s", mon_nam(mon), canseemon(mon) ? exclam(tmp) : ".");
1321 */
1322         You("%s\82É\93Ë\8c\82\82µ\82½%s", mon_nam(mon), canseemon(mon) ? exclam(tmp) : "\81D");
1323         if (jousting < 0) {
1324 /*JP
1325             pline("%s shatters on impact!", Yname2(obj));
1326 */
1327             Your("%s\82Í\8fÕ\8c\82\82Å\89ó\82ê\82½\81I", xname(obj));
1328             /* (must be either primary or secondary weapon to get here) */
1329             u.twoweap = FALSE; /* untwoweapon() is too verbose here */
1330             if (obj == uwep)
1331                 uwepgone(); /* set unweapon */
1332             /* minor side-effect: broken lance won't split puddings */
1333             useup(obj);
1334             obj = 0;
1335         }
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     } else if (unarmed && tmp > 1 && !thrown && !obj && !Upolyd) {
1345         /* VERY small chance of stunning opponent if unarmed. */
1346         if (rnd(100) < P_SKILL(P_BARE_HANDED_COMBAT) && !bigmonst(mdat)
1347             && !thick_skinned(mdat)) {
1348             if (canspotmon(mon))
1349 #if 0 /*JP:T*/
1350                 pline("%s %s from your powerful strike!", Monnam(mon),
1351                       makeplural(stagger(mon->data, "stagger")));
1352 #else
1353                 pline("%s\82Í\82 \82È\82½\82Ì\89ï\90S\82Ì\88ê\8c\82\82Å%s\81I", Monnam(mon),
1354                       jpast(stagger(mon->data, "\82æ\82ë\82ß\82­")));
1355 #endif
1356             /* avoid migrating a dead monster */
1357             if (mon->mhp > tmp) {
1358                 mhurtle(mon, u.dx, u.dy, 1);
1359                 mdat = mon->data; /* in case of a polymorph trap */
1360                 if (DEADMONSTER(mon))
1361                     already_killed = TRUE;
1362             }
1363             hittxt = TRUE;
1364         }
1365     }
1366
1367     if (!already_killed)
1368         mon->mhp -= tmp;
1369     /* adjustments might have made tmp become less than what
1370        a level draining artifact has already done to max HP */
1371     if (mon->mhp > mon->mhpmax)
1372         mon->mhp = mon->mhpmax;
1373     if (DEADMONSTER(mon))
1374         destroyed = TRUE;
1375     if (mon->mtame && tmp > 0) {
1376         /* do this even if the pet is being killed (affects revival) */
1377         abuse_dog(mon); /* reduces tameness */
1378         /* flee if still alive and still tame; if already suffering from
1379            untimed fleeing, no effect, otherwise increases timed fleeing */
1380         if (mon->mtame && !destroyed)
1381             monflee(mon, 10 * rnd(tmp), FALSE, FALSE);
1382     }
1383     if ((mdat == &mons[PM_BLACK_PUDDING] || mdat == &mons[PM_BROWN_PUDDING])
1384         /* pudding is alive and healthy enough to split */
1385         && mon->mhp > 1 && !mon->mcan
1386         /* iron weapon using melee or polearm hit [3.6.1: metal weapon too;
1387            also allow either or both weapons to cause split when twoweap] */
1388         && obj && (obj == uwep || (u.twoweap && obj == uswapwep))
1389         && ((objects[obj->otyp].oc_material == IRON
1390              /* allow scalpel and tsurugi to split puddings */
1391              || objects[obj->otyp].oc_material == METAL)
1392             /* but not bashing with darts, arrows or ya */
1393             && !(is_ammo(obj) || is_missile(obj)))
1394         && hand_to_hand) {
1395         struct monst *mclone;
1396         if ((mclone = clone_mon(mon, 0, 0)) != 0) {
1397             char withwhat[BUFSZ];
1398
1399             withwhat[0] = '\0';
1400 #if 0 /*JP:T*/
1401             if (u.twoweap && flags.verbose)
1402                 Sprintf(withwhat, " with %s", yname(obj));
1403             pline("%s divides as you hit it%s!", Monnam(mon), withwhat);
1404 #else
1405             if (u.twoweap && flags.verbose)
1406                 Sprintf(withwhat, "%s\82Å\82Ì", yname(obj));
1407             pline("\82 \82È\82½\82Ì%s\8dU\8c\82\82Å%s\82Í\95ª\97ô\82µ\82½\81I", withwhat, Monnam(mon));
1408 #endif
1409             hittxt = TRUE;
1410             mintrap(mclone);
1411         }
1412     }
1413
1414     if (!hittxt /*( thrown => obj exists )*/
1415         && (!destroyed
1416             || (thrown && m_shot.n > 1 && m_shot.o == obj->otyp))) {
1417         if (thrown)
1418             hit(mshot_xname(obj), mon, exclam(tmp));
1419         else if (!flags.verbose)
1420 /*JP
1421             You("hit it.");
1422 */
1423             pline("\8dU\8c\82\82Í\96½\92\86\82µ\82½\81D");
1424         else
1425 #if 0 /*JP*//*\89£\82è\95û\82ð\95ª\82¯\82é\82Ü\82Å\82Í\82â\82ç\82È\82¢*/
1426             You("%s %s%s",
1427                 (obj && (is_shield(obj) || obj->otyp == HEAVY_IRON_BALL))
1428                   ? "bash" : Role_if(PM_BARBARIAN) ? "smite" : "hit",
1429                 mon_nam(mon), canseemon(mon) ? exclam(tmp) : ".");
1430 #else
1431             Your("%s\82Ö\82Ì\8dU\8c\82\82Í\96½\92\86\82µ\82½%s",
1432                  mon_nam(mon), canseemon(mon) ? exclam(tmp) : "\81D");
1433 #endif
1434     }
1435
1436     if (silvermsg) {
1437         const char *fmt;
1438         char *whom = mon_nam(mon);
1439         char silverobjbuf[BUFSZ];
1440
1441         if (canspotmon(mon)) {
1442             if (barehand_silver_rings == 1)
1443 /*JP
1444                 fmt = "Your silver ring sears %s!";
1445 */
1446                 fmt = "%s\82Í\8bâ\82Ì\8ew\97Ö\82Å\8fÄ\82©\82ê\82½\81I";
1447             else if (barehand_silver_rings == 2)
1448 /*JP
1449                 fmt = "Your silver rings sear %s!";
1450 */
1451                 fmt = "%s\82Í\8bâ\82Ì\8ew\97Ö\82Å\8fÄ\82©\82ê\82½\81I";
1452             else if (silverobj && saved_oname[0]) {
1453                 /* guard constructed format string against '%' in
1454                    saved_oname[] from xname(via cxname()) */
1455 #if 0 /*JP*/
1456                 Sprintf(silverobjbuf, "Your %s%s %s",
1457                         strstri(saved_oname, "silver") ? "" : "silver ",
1458                         saved_oname, vtense(saved_oname, "sear"));
1459                 (void) strNsubst(silverobjbuf, "%", "%%", 0);
1460                 Strcat(silverobjbuf, " %s!");
1461 #else
1462                 Sprintf(silverobjbuf, "%%s\82Í%s%s\82Å\8fÄ\82©\82ê\82½\81I",
1463                         strstri(saved_oname, "\8bâ") ?
1464                         "" : "\8bâ\82Ì",
1465                         saved_oname);
1466                 (void) strNsubst(silverobjbuf, "%%", "%", 0);
1467 #endif
1468                 fmt = silverobjbuf;
1469             } else
1470 /*JP
1471                 fmt = "The silver sears %s!";
1472 */
1473                 fmt = "%s\82Í\8bâ\82Å\8fÄ\82©\82ê\82½\81I";
1474         } else {
1475             *whom = highc(*whom); /* "it" -> "It" */
1476 /*JP
1477             fmt = "%s is seared!";
1478 */
1479             fmt = "%s\82Í\8fÄ\82©\82ê\82½\81I";
1480         }
1481         /* note: s_suffix returns a modifiable buffer */
1482         if (!noncorporeal(mdat) && !amorphous(mdat))
1483 /*JP
1484             whom = strcat(s_suffix(whom), " flesh");
1485 */
1486             whom = strcat(s_suffix(whom), "\93÷");
1487         pline(fmt, whom);
1488     }
1489     if (lightobj) {
1490         const char *fmt;
1491         char *whom = mon_nam(mon);
1492         char emitlightobjbuf[BUFSZ];
1493
1494         if (canspotmon(mon)) {
1495             if (saved_oname[0]) {
1496 #if 0 /*JP*/
1497                 Sprintf(emitlightobjbuf,
1498                         "%s radiance penetrates deep into",
1499                         s_suffix(saved_oname));
1500                 Strcat(emitlightobjbuf, " %s!");
1501 #else
1502                 Sprintf(emitlightobjbuf,
1503                         "%s\8cõ\82ª%%s\82É\90[\82­\8aÑ\92Ê\82µ\82½\81I",
1504                         s_suffix(saved_oname));
1505 #endif
1506                 fmt = emitlightobjbuf;
1507             } else
1508 /*JP
1509                 fmt = "The light sears %s!";
1510 */
1511                 fmt = "\8cõ\82Í%s\82ð\8fÄ\82¢\82½\81I";
1512         } else {
1513 #if 0 /*JP*/
1514             *whom = highc(*whom); /* "it" -> "It" */
1515 #endif
1516 /*JP
1517             fmt = "%s is seared!";
1518 */
1519             fmt = "%s\82Í\8fÄ\82©\82ê\82½\81I";
1520         }
1521         /* note: s_suffix returns a modifiable buffer */
1522         if (!noncorporeal(mdat) && !amorphous(mdat))
1523 /*JP
1524             whom = strcat(s_suffix(whom), " flesh");
1525 */
1526             whom = strcat(s_suffix(whom), "\93÷");
1527         pline(fmt, whom);
1528     }
1529     /* if a "no longer poisoned" message is coming, it will be last;
1530        obj->opoisoned was cleared above and any message referring to
1531        "poisoned <obj>" has now been given; we want just "<obj>" for
1532        last message, so reformat while obj is still accessible */
1533     if (unpoisonmsg)
1534         Strcpy(saved_oname, cxname(obj));
1535
1536     /* [note: thrown obj might go away during killed()/xkilled() call
1537        (via 'thrownobj'; if swallowed, it gets added to engulfer's
1538        minvent and might merge with a stack that's already there)] */
1539
1540     if (needpoismsg)
1541 /*JP
1542         pline_The("poison doesn't seem to affect %s.", mon_nam(mon));
1543 */
1544         pline("\93Å\82Í%s\82É\8cø\82©\82È\82©\82Á\82½\82æ\82¤\82¾\81D", mon_nam(mon));
1545     if (poiskilled) {
1546 /*JP
1547         pline_The("poison was deadly...");
1548 */
1549         pline("\93Å\82Í\92v\8e\80\97Ê\82¾\82Á\82½\81D\81D\81D");
1550         if (!already_killed)
1551             xkilled(mon, XKILL_NOMSG);
1552         destroyed = TRUE; /* return FALSE; */
1553     } else if (destroyed) {
1554         if (!already_killed)
1555             killed(mon); /* takes care of most messages */
1556     } else if (u.umconf && hand_to_hand) {
1557         nohandglow(mon);
1558         if (!mon->mconf && !resist(mon, SPBOOK_CLASS, 0, NOTELL)) {
1559             mon->mconf = 1;
1560             if (!mon->mstun && mon->mcanmove && !mon->msleeping
1561                 && canseemon(mon))
1562 /*JP
1563                 pline("%s appears confused.", Monnam(mon));
1564 */
1565                 pline("%s\82Í\8d¬\97\90\82µ\82Ä\82¢\82é\82æ\82¤\82¾\81D", Monnam(mon));
1566         }
1567     }
1568     if (unpoisonmsg)
1569 #if 0 /*JP:T*/
1570         Your("%s %s no longer poisoned.", saved_oname,
1571              vtense(saved_oname, "are"));
1572 #else
1573         Your("%s\82Í\82à\82¤\93Å\82ª\93h\82ç\82ê\82Ä\82¢\82È\82¢\81D", xname(obj));
1574 #endif
1575
1576     return destroyed ? FALSE : TRUE;
1577 }
1578
1579 STATIC_OVL boolean
1580 shade_aware(obj)
1581 struct obj *obj;
1582 {
1583     if (!obj)
1584         return FALSE;
1585     /*
1586      * The things in this list either
1587      * 1) affect shades.
1588      *  OR
1589      * 2) are dealt with properly by other routines
1590      *    when it comes to shades.
1591      */
1592     if (obj->otyp == BOULDER
1593         || obj->otyp == HEAVY_IRON_BALL
1594         || obj->otyp == IRON_CHAIN      /* dmgval handles those first three */
1595         || obj->otyp == MIRROR          /* silver in the reflective surface */
1596         || obj->otyp == CLOVE_OF_GARLIC /* causes shades to flee */
1597         || objects[obj->otyp].oc_material == SILVER)
1598         return TRUE;
1599     return FALSE;
1600 }
1601
1602 /* check whether slippery clothing protects from hug or wrap attack */
1603 /* [currently assumes that you are the attacker] */
1604 STATIC_OVL boolean
1605 m_slips_free(mdef, mattk)
1606 struct monst *mdef;
1607 struct attack *mattk;
1608 {
1609     struct obj *obj;
1610
1611     if (mattk->adtyp == AD_DRIN) {
1612         /* intelligence drain attacks the head */
1613         obj = which_armor(mdef, W_ARMH);
1614     } else {
1615         /* grabbing attacks the body */
1616         obj = which_armor(mdef, W_ARMC); /* cloak */
1617         if (!obj)
1618             obj = which_armor(mdef, W_ARM); /* suit */
1619         if (!obj)
1620             obj = which_armor(mdef, W_ARMU); /* shirt */
1621     }
1622
1623     /* if monster's cloak/armor is greased, your grab slips off; this
1624        protection might fail (33% chance) when the armor is cursed */
1625     if (obj && (obj->greased || obj->otyp == OILSKIN_CLOAK)
1626         && (!obj->cursed || rn2(3))) {
1627 #if 0 /*JP:T*/
1628         You("%s %s %s %s!",
1629             mattk->adtyp == AD_WRAP ? "slip off of"
1630                                     : "grab, but cannot hold onto",
1631             s_suffix(mon_nam(mdef)), obj->greased ? "greased" : "slippery",
1632             /* avoid "slippery slippery cloak"
1633                for undiscovered oilskin cloak */
1634             (obj->greased || objects[obj->otyp].oc_name_known)
1635                 ? xname(obj)
1636                 : cloak_simple_name(obj));
1637 #else
1638         You("%s\82Ì%s%s%s\81I",
1639             mon_nam(mdef), obj->greased ? "\96û\82Ì\93h\82ç\82ê\82½" : "\8a\8a\82è\82â\82·\82¢",
1640             (obj->greased || objects[obj->otyp].oc_name_known)
1641                 ? xname(obj)
1642                 : cloak_simple_name(obj),
1643             mattk->adtyp == AD_WRAP ? "\82Å\8a\8a\82Á\82½"
1644                                     : "\82ð\82Â\82©\82Ü\82æ\82¤\82Æ\82µ\82½\82ª\81C\82Å\82«\82È\82©\82Á\82½");
1645 #endif
1646
1647         if (obj->greased && !rn2(2)) {
1648 /*JP
1649             pline_The("grease wears off.");
1650 */
1651             pline("\96û\82Í\97\8e\82¿\82Ä\82µ\82Ü\82Á\82½\81D");
1652             obj->greased = 0;
1653         }
1654         return TRUE;
1655     }
1656     return FALSE;
1657 }
1658
1659 /* used when hitting a monster with a lance while mounted;
1660    1: joust hit; 0: ordinary hit; -1: joust but break lance */
1661 STATIC_OVL int
1662 joust(mon, obj)
1663 struct monst *mon; /* target */
1664 struct obj *obj;   /* weapon */
1665 {
1666     int skill_rating, joust_dieroll;
1667
1668     if (Fumbling || Stunned)
1669         return 0;
1670     /* sanity check; lance must be wielded in order to joust */
1671     if (obj != uwep && (obj != uswapwep || !u.twoweap))
1672         return 0;
1673
1674     /* if using two weapons, use worse of lance and two-weapon skills */
1675     skill_rating = P_SKILL(weapon_type(obj)); /* lance skill */
1676     if (u.twoweap && P_SKILL(P_TWO_WEAPON_COMBAT) < skill_rating)
1677         skill_rating = P_SKILL(P_TWO_WEAPON_COMBAT);
1678     if (skill_rating == P_ISRESTRICTED)
1679         skill_rating = P_UNSKILLED; /* 0=>1 */
1680
1681     /* odds to joust are expert:80%, skilled:60%, basic:40%, unskilled:20% */
1682     if ((joust_dieroll = rn2(5)) < skill_rating) {
1683         if (joust_dieroll == 0 && rnl(50) == (50 - 1) && !unsolid(mon->data)
1684             && !obj_resists(obj, 0, 100))
1685             return -1; /* hit that breaks lance */
1686         return 1;      /* successful joust */
1687     }
1688     return 0; /* no joust bonus; revert to ordinary attack */
1689 }
1690
1691 /*
1692  * Send in a demon pet for the hero.  Exercise wisdom.
1693  *
1694  * This function used to be inline to damageum(), but the Metrowerks compiler
1695  * (DR4 and DR4.5) screws up with an internal error 5 "Expression Too
1696  * Complex."
1697  * Pulling it out makes it work.
1698  */
1699 STATIC_OVL void
1700 demonpet()
1701 {
1702     int i;
1703     struct permonst *pm;
1704     struct monst *dtmp;
1705
1706 /*JP
1707     pline("Some hell-p has arrived!");
1708 */
1709     pline("\92n\8d\96\82Ì\92\87\8aÔ\82ª\8c»\82í\82ê\82½\81I");
1710     i = !rn2(6) ? ndemon(u.ualign.type) : NON_PM;
1711     pm = i != NON_PM ? &mons[i] : youmonst.data;
1712     if ((dtmp = makemon(pm, u.ux, u.uy, NO_MM_FLAGS)) != 0)
1713         (void) tamedog(dtmp, (struct obj *) 0);
1714     exercise(A_WIS, TRUE);
1715 }
1716
1717 STATIC_OVL boolean
1718 theft_petrifies(otmp)
1719 struct obj *otmp;
1720 {
1721     if (uarmg || otmp->otyp != CORPSE
1722         || !touch_petrifies(&mons[otmp->corpsenm]) || Stone_resistance)
1723         return FALSE;
1724
1725 #if 0   /* no poly_when_stoned() critter has theft capability */
1726     if (poly_when_stoned(youmonst.data) && polymon(PM_STONE_GOLEM)) {
1727         display_nhwindow(WIN_MESSAGE, FALSE);   /* --More-- */
1728         return TRUE;
1729     }
1730 #endif
1731
1732     /* stealing this corpse is fatal... */
1733 /*JP
1734     instapetrify(corpse_xname(otmp, "stolen", CXN_ARTICLE));
1735 */
1736     instapetrify(corpse_xname(otmp, "\93\90\82Ü\82ê\82½", CXN_ARTICLE));
1737     /* apparently wasn't fatal after all... */
1738     return TRUE;
1739 }
1740
1741 /*
1742  * Player uses theft attack against monster.
1743  *
1744  * If the target is wearing body armor, take all of its possessions;
1745  * otherwise, take one object.  [Is this really the behavior we want?]
1746  */
1747 STATIC_OVL void
1748 steal_it(mdef, mattk)
1749 struct monst *mdef;
1750 struct attack *mattk;
1751 {
1752     struct obj *otmp, *stealoid, **minvent_ptr;
1753     long unwornmask;
1754
1755     if (!mdef->minvent)
1756         return; /* nothing to take */
1757
1758     /* look for worn body armor */
1759     stealoid = (struct obj *) 0;
1760     if (could_seduce(&youmonst, mdef, mattk)) {
1761         /* find armor, and move it to end of inventory in the process */
1762         minvent_ptr = &mdef->minvent;
1763         while ((otmp = *minvent_ptr) != 0)
1764             if (otmp->owornmask & W_ARM) {
1765                 if (stealoid)
1766                     panic("steal_it: multiple worn suits");
1767                 *minvent_ptr = otmp->nobj; /* take armor out of minvent */
1768                 stealoid = otmp;
1769                 stealoid->nobj = (struct obj *) 0;
1770             } else {
1771                 minvent_ptr = &otmp->nobj;
1772             }
1773         *minvent_ptr = stealoid; /* put armor back into minvent */
1774     }
1775
1776     if (stealoid) { /* we will be taking everything */
1777         if (gender(mdef) == (int) u.mfemale && youmonst.data->mlet == S_NYMPH)
1778 /*JP
1779             You("charm %s.  She gladly hands over her possessions.",
1780 */
1781             You("%s\82ð\82¤\82Á\82Æ\82è\82³\82¹\82½\81D\94Þ\8f\97\82Í\82æ\82ë\82±\82ñ\82Å\8e\9d\82¿\95¨\82ð\82³\82µ\82¾\82µ\82½\81D",
1782                 mon_nam(mdef));
1783         else
1784 #if 0 /*JP:T*/
1785             You("seduce %s and %s starts to take off %s clothes.",
1786                 mon_nam(mdef), mhe(mdef), mhis(mdef));
1787 #else
1788             You("%s\82ð\97U\98f\82µ\82½\81D%s\82Í\95\9e\82ð\92E\82¬\82Í\82\82ß\82½\81D",
1789                 mon_nam(mdef), mhe(mdef));
1790 #endif
1791     }
1792
1793     while ((otmp = mdef->minvent) != 0) {
1794         if (!Upolyd)
1795             break; /* no longer have ability to steal */
1796         /* take the object away from the monster */
1797         obj_extract_self(otmp);
1798         if ((unwornmask = otmp->owornmask) != 0L) {
1799             mdef->misc_worn_check &= ~unwornmask;
1800             if (otmp->owornmask & W_WEP)
1801                 setmnotwielded(mdef, otmp);
1802             otmp->owornmask = 0L;
1803             update_mon_intrinsics(mdef, otmp, FALSE, FALSE);
1804             /* give monster a chance to wear other equipment on its next
1805                move instead of waiting until it picks something up */
1806             mdef->misc_worn_check |= I_SPECIAL;
1807
1808             if (otmp == stealoid) /* special message for final item */
1809 #if 0 /*JP:T*/
1810                 pline("%s finishes taking off %s suit.", Monnam(mdef),
1811                       mhis(mdef));
1812 #else
1813                 pline("%s\82Í\92E\82¬\8fI\82¦\82½\81D", Monnam(mdef));
1814 #endif
1815         }
1816         /* give the object to the character */
1817 #if 0 /*JP:T*/
1818         otmp = hold_another_object(otmp, "You snatched but dropped %s.",
1819                                    doname(otmp), "You steal: ");
1820 #else
1821         otmp = hold_another_object(otmp, "\82 \82È\82½\82Í%s\82ð\93\90\82ñ\82¾\82ª\97\8e\82Æ\82µ\82½\81D",
1822                                    doname(otmp), "\82ð\93\90\82ñ\82¾\81D");
1823 #endif
1824         /* might have dropped otmp, and it might have broken or left level */
1825         if (!otmp || otmp->where != OBJ_INVENT)
1826             continue;
1827         if (theft_petrifies(otmp))
1828             break; /* stop thieving even though hero survived */
1829         /* more take-away handling, after theft message */
1830         if (unwornmask & W_WEP) { /* stole wielded weapon */
1831             possibly_unwield(mdef, FALSE);
1832         } else if (unwornmask & W_ARMG) { /* stole worn gloves */
1833             mselftouch(mdef, (const char *) 0, TRUE);
1834             if (DEADMONSTER(mdef)) /* it's now a statue */
1835                 return;         /* can't continue stealing */
1836         }
1837
1838         if (!stealoid)
1839             break; /* only taking one item */
1840     }
1841 }
1842
1843 int
1844 damageum(mdef, mattk, specialdmg)
1845 register struct monst *mdef;
1846 register struct attack *mattk;
1847 int specialdmg; /* blessed and/or silver bonus against various things */
1848 {
1849     register struct permonst *pd = mdef->data;
1850     int armpro, tmp = d((int) mattk->damn, (int) mattk->damd);
1851     boolean negated;
1852     struct obj *mongold;
1853
1854     armpro = magic_negation(mdef);
1855     /* since hero can't be cancelled, only defender's armor applies */
1856     negated = !(rn2(10) >= 3 * armpro);
1857
1858     if (is_demon(youmonst.data) && !rn2(13) && !uwep
1859         && u.umonnum != PM_SUCCUBUS && u.umonnum != PM_INCUBUS
1860         && u.umonnum != PM_BALROG) {
1861         demonpet();
1862         return 0;
1863     }
1864     switch (mattk->adtyp) {
1865     case AD_STUN:
1866         if (!Blind)
1867 #if 0 /*JP:T*/
1868             pline("%s %s for a moment.", Monnam(mdef),
1869                   makeplural(stagger(pd, "stagger")));
1870 #else
1871             pline("%s\82Í\88ê\8fu%s\81D", Monnam(mdef),
1872                   jpast(stagger(pd, "\82æ\82ë\82ß\82­")));
1873 #endif
1874         mdef->mstun = 1;
1875         goto physical;
1876     case AD_LEGS:
1877 #if 0
1878         if (u.ucancelled) {
1879             tmp = 0;
1880             break;
1881         }
1882 #endif
1883         goto physical;
1884     case AD_WERE: /* no special effect on monsters */
1885     case AD_HEAL: /* likewise */
1886     case AD_PHYS:
1887  physical:
1888         if (pd == &mons[PM_SHADE]) {
1889             tmp = 0;
1890             if (!specialdmg)
1891                 impossible("bad shade attack function flow?");
1892         }
1893         tmp += specialdmg;
1894
1895         if (mattk->aatyp == AT_WEAP) {
1896             /* hmonas() uses known_hitum() to deal physical damage,
1897                then also damageum() for non-AD_PHYS; don't inflict
1898                extra physical damage for unusual damage types */
1899             tmp = 0;
1900         } else if (mattk->aatyp == AT_KICK
1901                    || mattk->aatyp == AT_CLAW
1902                    || mattk->aatyp == AT_TUCH
1903                    || mattk->aatyp == AT_HUGS) {
1904             if (thick_skinned(pd))
1905                 tmp = (mattk->aatyp == AT_KICK) ? 0 : (tmp + 1) / 2;
1906             /* add ring(s) of increase damage */
1907             if (u.udaminc > 0) {
1908                 /* applies even if damage was 0 */
1909                 tmp += u.udaminc;
1910             } else if (tmp > 0) {
1911                 /* ring(s) might be negative; avoid converting
1912                    0 to non-0 or positive to non-positive */
1913                 tmp += u.udaminc;
1914                 if (tmp < 1)
1915                     tmp = 1;
1916             }
1917         }
1918         break;
1919     case AD_FIRE:
1920         if (negated) {
1921             tmp = 0;
1922             break;
1923         }
1924         if (!Blind)
1925 /*JP
1926             pline("%s is %s!", Monnam(mdef), on_fire(pd, mattk));
1927 */
1928             pline("%s\82Í%s\81I", Monnam(mdef), on_fire(mdef->data, mattk));
1929         if (completelyburns(pd)) { /* paper golem or straw golem */
1930             if (!Blind)
1931 /*JP
1932                 pline("%s burns completely!", Monnam(mdef));
1933 */
1934                 pline("%s\82Í\8a®\91S\82É\94R\82¦\90s\82«\82½\81I", Monnam(mdef));
1935             else
1936 #if 0 /*JP:T*/
1937                 You("smell burning%s.",
1938                     (pd == &mons[PM_PAPER_GOLEM]) ? " paper"
1939                       : (pd == &mons[PM_STRAW_GOLEM]) ? " straw" : "");
1940 #else
1941                 You("%s\82ª\94R\82¦\82é\82É\82¨\82¢\82ª\82µ\82½\81D",
1942                     (pd == &mons[PM_PAPER_GOLEM]) ? "\8e\86"
1943                       : (pd == &mons[PM_STRAW_GOLEM]) ? "\82í\82ç" : "\89½\82©");
1944 #endif
1945             xkilled(mdef, XKILL_NOMSG | XKILL_NOCORPSE);
1946             tmp = 0;
1947             break;
1948             /* Don't return yet; keep hp<1 and tmp=0 for pet msg */
1949         }
1950         tmp += destroy_mitem(mdef, SCROLL_CLASS, AD_FIRE);
1951         tmp += destroy_mitem(mdef, SPBOOK_CLASS, AD_FIRE);
1952         if (resists_fire(mdef)) {
1953             if (!Blind)
1954 /*JP
1955                 pline_The("fire doesn't heat %s!", mon_nam(mdef));
1956 */
1957                 pline("\89\8a\82Í%s\82É\89e\8b¿\82ª\82È\82¢\81I", mon_nam(mdef));
1958             golemeffects(mdef, AD_FIRE, tmp);
1959             shieldeff(mdef->mx, mdef->my);
1960             tmp = 0;
1961         }
1962         /* only potions damage resistant players in destroy_item */
1963         tmp += destroy_mitem(mdef, POTION_CLASS, AD_FIRE);
1964         break;
1965     case AD_COLD:
1966         if (negated) {
1967             tmp = 0;
1968             break;
1969         }
1970         if (!Blind)
1971 /*JP
1972             pline("%s is covered in frost!", Monnam(mdef));
1973 */
1974             pline("%s\82Í\95X\82Å\95¢\82í\82ê\82½\81I", Monnam(mdef));
1975         if (resists_cold(mdef)) {
1976             shieldeff(mdef->mx, mdef->my);
1977             if (!Blind)
1978 /*JP
1979                 pline_The("frost doesn't chill %s!", mon_nam(mdef));
1980 */
1981                 pline("\95X\82Í%s\82ð\93\80\82ç\82·\82±\82Æ\82ª\82Å\82«\82È\82¢\81I", mon_nam(mdef));
1982             golemeffects(mdef, AD_COLD, tmp);
1983             tmp = 0;
1984         }
1985         tmp += destroy_mitem(mdef, POTION_CLASS, AD_COLD);
1986         break;
1987     case AD_ELEC:
1988         if (negated) {
1989             tmp = 0;
1990             break;
1991         }
1992         if (!Blind)
1993 /*JP
1994             pline("%s is zapped!", Monnam(mdef));
1995 */
1996             pline("%s\82Í\93d\8c\82\82ð\82­\82ç\82Á\82½\81I", Monnam(mdef));
1997         tmp += destroy_mitem(mdef, WAND_CLASS, AD_ELEC);
1998         if (resists_elec(mdef)) {
1999             if (!Blind)
2000 /*JP
2001                 pline_The("zap doesn't shock %s!", mon_nam(mdef));
2002 */
2003                 pline("\93d\8c\82\82Í%s\82É\89e\8b¿\82ð\97^\82¦\82È\82¢\81I", mon_nam(mdef));
2004             golemeffects(mdef, AD_ELEC, tmp);
2005             shieldeff(mdef->mx, mdef->my);
2006             tmp = 0;
2007         }
2008         /* only rings damage resistant players in destroy_item */
2009         tmp += destroy_mitem(mdef, RING_CLASS, AD_ELEC);
2010         break;
2011     case AD_ACID:
2012         if (resists_acid(mdef))
2013             tmp = 0;
2014         break;
2015     case AD_STON:
2016         if (!munstone(mdef, TRUE))
2017             minstapetrify(mdef, TRUE);
2018         tmp = 0;
2019         break;
2020     case AD_SSEX:
2021     case AD_SEDU:
2022     case AD_SITM:
2023         steal_it(mdef, mattk);
2024         tmp = 0;
2025         break;
2026     case AD_SGLD:
2027         /* This you as a leprechaun, so steal
2028            real gold only, no lesser coins */
2029         mongold = findgold(mdef->minvent);
2030         if (mongold) {
2031             obj_extract_self(mongold);
2032             if (merge_choice(invent, mongold) || inv_cnt(FALSE) < 52) {
2033                 addinv(mongold);
2034 /*JP
2035                 Your("purse feels heavier.");
2036 */
2037                 You("\8dà\95z\82ª\8fd\82­\82È\82Á\82½\82æ\82¤\82È\8bC\82ª\82µ\82½\81D");
2038             } else {
2039 /*JP
2040                 You("grab %s's gold, but find no room in your knapsack.",
2041 */
2042                 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",
2043                     mon_nam(mdef));
2044                 dropy(mongold);
2045             }
2046         }
2047         exercise(A_DEX, TRUE);
2048         tmp = 0;
2049         break;
2050     case AD_TLPT:
2051         if (tmp <= 0)
2052             tmp = 1;
2053         if (!negated) {
2054             char nambuf[BUFSZ];
2055             boolean u_saw_mon = (canseemon(mdef)
2056                                  || (u.uswallow && u.ustuck == mdef));
2057
2058             /* record the name before losing sight of monster */
2059             Strcpy(nambuf, Monnam(mdef));
2060             if (u_teleport_mon(mdef, FALSE) && u_saw_mon
2061                 && !(canseemon(mdef) || (u.uswallow && u.ustuck == mdef)))
2062 /*JP
2063                 pline("%s suddenly disappears!", nambuf);
2064 */
2065                 pline("%s\82Í\93Ë\91R\8fÁ\82¦\82½\81I", nambuf);
2066             if (tmp >= mdef->mhp) { /* see hitmu(mhitu.c) */
2067                 if (mdef->mhp == 1)
2068                     ++mdef->mhp;
2069                 tmp = mdef->mhp - 1;
2070             }
2071         }
2072         break;
2073     case AD_BLND:
2074         if (can_blnd(&youmonst, mdef, mattk->aatyp, (struct obj *) 0)) {
2075             if (!Blind && mdef->mcansee)
2076 /*JP
2077                 pline("%s is blinded.", Monnam(mdef));
2078 */
2079                 pline("%s\82Í\96Ú\82ª\8c©\82¦\82È\82­\82È\82Á\82½\81D", Monnam(mdef));
2080             mdef->mcansee = 0;
2081             tmp += mdef->mblinded;
2082             if (tmp > 127)
2083                 tmp = 127;
2084             mdef->mblinded = tmp;
2085         }
2086         tmp = 0;
2087         break;
2088     case AD_CURS:
2089         if (night() && !rn2(10) && !mdef->mcan) {
2090             if (pd == &mons[PM_CLAY_GOLEM]) {
2091                 if (!Blind)
2092 #if 0 /*JP:T*/
2093                     pline("Some writing vanishes from %s head!",
2094                           s_suffix(mon_nam(mdef)));
2095 #else
2096                     pline("%s\82Ì\93ª\82É\8f\91\82¢\82Ä\82 \82é\95\8e\9a\82Ì\82¢\82­\82Â\82©\82ª\8fÁ\82¦\82½\81I",
2097                           mon_nam(mdef));
2098 #endif
2099                 xkilled(mdef, XKILL_NOMSG);
2100                 /* Don't return yet; keep hp<1 and tmp=0 for pet msg */
2101             } else {
2102                 mdef->mcan = 1;
2103 /*JP
2104                 You("chuckle.");
2105 */
2106                 You("\82­\82·\82­\82·\8fÎ\82Á\82½\81D");
2107             }
2108         }
2109         tmp = 0;
2110         break;
2111     case AD_DRLI:
2112         if (!negated && !rn2(3) && !resists_drli(mdef)) {
2113             int xtmp = d(2, 6);
2114
2115 /*JP
2116             pline("%s suddenly seems weaker!", Monnam(mdef));
2117 */
2118             pline("%s\82Í\93Ë\91R\8eã\82­\82È\82Á\82½\82æ\82¤\82É\8c©\82¦\82½\81I", Monnam(mdef));
2119             mdef->mhpmax -= xtmp;
2120             mdef->mhp -= xtmp;
2121             /* !m_lev: level 0 monster is killed regardless of hit points
2122                rather than drop to level -1 */
2123             if (DEADMONSTER(mdef) || !mdef->m_lev) {
2124 /*JP
2125                 pline("%s dies!", Monnam(mdef));
2126 */
2127                 pline("%s\82Í\8e\80\82ñ\82¾\81I", Monnam(mdef));
2128                 xkilled(mdef, XKILL_NOMSG);
2129             } else
2130                 mdef->m_lev--;
2131             tmp = 0;
2132         }
2133         break;
2134     case AD_RUST:
2135         if (pd == &mons[PM_IRON_GOLEM]) {
2136 /*JP
2137             pline("%s falls to pieces!", Monnam(mdef));
2138 */
2139             pline("%s\82Í\83o\83\89\83o\83\89\82É\82È\82Á\82½\81I", Monnam(mdef));
2140             xkilled(mdef, XKILL_NOMSG);
2141         }
2142         erode_armor(mdef, ERODE_RUST);
2143         tmp = 0;
2144         break;
2145     case AD_CORR:
2146         erode_armor(mdef, ERODE_CORRODE);
2147         tmp = 0;
2148         break;
2149     case AD_DCAY:
2150         if (pd == &mons[PM_WOOD_GOLEM] || pd == &mons[PM_LEATHER_GOLEM]) {
2151 /*JP
2152             pline("%s falls to pieces!", Monnam(mdef));
2153 */
2154             pline("%s\82Í\83o\83\89\83o\83\89\82É\82È\82Á\82½\81I", Monnam(mdef));
2155             xkilled(mdef, XKILL_NOMSG);
2156         }
2157         erode_armor(mdef, ERODE_ROT);
2158         tmp = 0;
2159         break;
2160     case AD_DREN:
2161         if (!negated && !rn2(4))
2162             xdrainenergym(mdef, TRUE);
2163         tmp = 0;
2164         break;
2165     case AD_DRST:
2166     case AD_DRDX:
2167     case AD_DRCO:
2168         if (!negated && !rn2(8)) {
2169 /*JP
2170             Your("%s was poisoned!", mpoisons_subj(&youmonst, mattk));
2171 */
2172             Your("%s\82Í\93Å\82³\82ê\82Ä\82¢\82é\81I", mpoisons_subj(&youmonst, mattk));
2173             if (resists_poison(mdef)) {
2174 /*JP
2175                 pline_The("poison doesn't seem to affect %s.", mon_nam(mdef));
2176 */
2177                 pline("\93Å\82Í%s\82É\89e\8b¿\82ð\97^\82¦\82È\82¢\81D", mon_nam(mdef));
2178             } else {
2179                 if (!rn2(10)) {
2180 /*JP
2181                     Your("poison was deadly...");
2182 */
2183                     Your("\97^\82¦\82½\93Å\82Í\92v\8e\80\97Ê\82¾\82Á\82½\81D\81D\81D");
2184                     tmp = mdef->mhp;
2185                 } else
2186                     tmp += rn1(10, 6);
2187             }
2188         }
2189         break;
2190     case AD_DRIN: {
2191         struct obj *helmet;
2192
2193         if (notonhead || !has_head(pd)) {
2194 /*JP
2195             pline("%s doesn't seem harmed.", Monnam(mdef));
2196 */
2197             pline("%s\82Í\8f\9d\82Â\82¢\82½\82æ\82¤\82É\82Í\8c©\82¦\82È\82¢\81D", Monnam(mdef));
2198             tmp = 0;
2199             if (!Unchanging && pd == &mons[PM_GREEN_SLIME]) {
2200                 if (!Slimed) {
2201 /*JP
2202                     You("suck in some slime and don't feel very well.");
2203 */
2204                     You("\83X\83\89\83C\83\80\82ð\8bz\82¢\8eæ\82Á\82Ä\81C\8bï\8d\87\82ª\88«\82­\82È\82Á\82½\81D");
2205                     make_slimed(10L, (char *) 0);
2206                 }
2207             }
2208             break;
2209         }
2210         if (m_slips_free(mdef, mattk))
2211             break;
2212
2213         if ((helmet = which_armor(mdef, W_ARMH)) != 0 && rn2(8)) {
2214 #if 0 /*JP:T*/
2215             pline("%s %s blocks your attack to %s head.",
2216                   s_suffix(Monnam(mdef)), helm_simple_name(helmet),
2217                   mhis(mdef));
2218 #else
2219             pline("%s\82Ì%s\82ª\93ª\82Ö\82Ì\8dU\8c\82\82ð\96h\82¢\82¾\81D",
2220                   Monnam(mdef), helm_simple_name(helmet));
2221 #endif
2222             break;
2223         }
2224
2225         (void) eat_brains(&youmonst, mdef, TRUE, &tmp);
2226         break;
2227     }
2228     case AD_STCK:
2229         if (!negated && !sticks(pd))
2230             u.ustuck = mdef; /* it's now stuck to you */
2231         break;
2232     case AD_WRAP:
2233         if (!sticks(pd)) {
2234             if (!u.ustuck && !rn2(10)) {
2235                 if (m_slips_free(mdef, mattk)) {
2236                     tmp = 0;
2237                 } else {
2238 /*JP
2239                     You("swing yourself around %s!", mon_nam(mdef));
2240 */
2241                     You("%s\82É\90g\91Ì\82ð\97\8d\82Ý\82Â\82©\82¹\82½\81I", mon_nam(mdef));
2242                     u.ustuck = mdef;
2243                 }
2244             } else if (u.ustuck == mdef) {
2245                 /* Monsters don't wear amulets of magical breathing */
2246                 if (is_pool(u.ux, u.uy) && !is_swimmer(pd)
2247                     && !amphibious(pd)) {
2248 /*JP
2249                     You("drown %s...", mon_nam(mdef));
2250 */
2251                     You("%s\82ð\93M\82ê\82³\82¹\82½\81D\81D\81D", mon_nam(mdef));
2252                     tmp = mdef->mhp;
2253                 } else if (mattk->aatyp == AT_HUGS)
2254 /*JP
2255                     pline("%s is being crushed.", Monnam(mdef));
2256 */
2257                     pline("%s\82Í\89\9f\82µ\82Â\82Ô\82³\82ê\82Ä\82¢\82é\81D", Monnam(mdef));
2258             } else {
2259                 tmp = 0;
2260                 if (flags.verbose)
2261 #if 0 /*JP:T*/
2262                     You("brush against %s %s.", s_suffix(mon_nam(mdef)),
2263                         mbodypart(mdef, LEG));
2264 #else
2265                     You("%s\82Ì%s\82É\90G\82ê\82½\81D", mon_nam(mdef),
2266                         mbodypart(mdef, LEG));
2267 #endif
2268             }
2269         } else
2270             tmp = 0;
2271         break;
2272     case AD_PLYS:
2273         if (!negated && mdef->mcanmove && !rn2(3) && tmp < mdef->mhp) {
2274             if (!Blind)
2275 /*JP
2276                 pline("%s is frozen by you!", Monnam(mdef));
2277 */
2278                 pline("%s\82Í\82 \82È\82½\82Ì\82É\82ç\82Ý\82Å\93®\82¯\82È\82­\82È\82Á\82½\81I", Monnam(mdef));
2279             paralyze_monst(mdef, rnd(10));
2280         }
2281         break;
2282     case AD_SLEE:
2283         if (!negated && !mdef->msleeping && sleep_monst(mdef, rnd(10), -1)) {
2284             if (!Blind)
2285 /*JP
2286                 pline("%s is put to sleep by you!", Monnam(mdef));
2287 */
2288                 pline("%s\82Í\93Ë\91R\96°\82è\82É\82¨\82¿\82½\81I", Monnam(mdef));
2289             slept_monst(mdef);
2290         }
2291         break;
2292     case AD_SLIM:
2293         if (negated)
2294             break; /* physical damage only */
2295         if (!rn2(4) && !slimeproof(pd)) {
2296             if (!munslime(mdef, TRUE) && !DEADMONSTER(mdef)) {
2297                 /* this assumes newcham() won't fail; since hero has
2298                    a slime attack, green slimes haven't been geno'd */
2299 /*JP
2300                 You("turn %s into slime.", mon_nam(mdef));
2301 */
2302                 pline("%s\82Í\83X\83\89\83C\83\80\82É\82È\82Á\82½\81D", mon_nam(mdef));
2303                 if (newcham(mdef, &mons[PM_GREEN_SLIME], FALSE, FALSE))
2304                     pd = mdef->data;
2305             }
2306             /* munslime attempt could have been fatal */
2307             if (DEADMONSTER(mdef))
2308                 return 2; /* skip death message */
2309             tmp = 0;
2310         }
2311         break;
2312     case AD_ENCH: /* KMH -- remove enchantment (disenchanter) */
2313         /* there's no msomearmor() function, so just do damage */
2314         /* if (negated) break; */
2315         break;
2316     case AD_SLOW:
2317         if (!negated && mdef->mspeed != MSLOW) {
2318             unsigned int oldspeed = mdef->mspeed;
2319
2320             mon_adjust_speed(mdef, -1, (struct obj *) 0);
2321             if (mdef->mspeed != oldspeed && canseemon(mdef))
2322 /*JP
2323                 pline("%s slows down.", Monnam(mdef));
2324 */
2325                 pline("%s\82Í\82Ì\82ë\82­\82È\82Á\82½\81D", Monnam(mdef));
2326         }
2327         break;
2328     case AD_CONF:
2329         if (!mdef->mconf) {
2330             if (canseemon(mdef))
2331 /*JP
2332                 pline("%s looks confused.", Monnam(mdef));
2333 */
2334                 pline("%s\82Í\8d¬\97\90\82µ\82½\82æ\82¤\82¾\81D", Monnam(mdef));
2335             mdef->mconf = 1;
2336         }
2337         break;
2338     default:
2339         tmp = 0;
2340         break;
2341     }
2342
2343     mdef->mstrategy &= ~STRAT_WAITFORU; /* in case player is very fast */
2344     mdef->mhp -= tmp;
2345     if (DEADMONSTER(mdef)) {
2346         if (mdef->mtame && !cansee(mdef->mx, mdef->my)) {
2347 /*JP
2348             You_feel("embarrassed for a moment.");
2349 */
2350             You("\82µ\82Î\82ç\82­\8d¢\98f\82µ\82½\81D");
2351             if (tmp)
2352                 xkilled(mdef, XKILL_NOMSG); /* !tmp but hp<1: already killed */
2353         } else if (!flags.verbose) {
2354 /*JP
2355             You("destroy it!");
2356 */
2357             You("\93|\82µ\82½\81I");
2358             if (tmp)
2359                 xkilled(mdef, XKILL_NOMSG);
2360         } else if (tmp)
2361             killed(mdef);
2362         return 2;
2363     }
2364     return 1;
2365 }
2366
2367 STATIC_OVL int
2368 explum(mdef, mattk)
2369 register struct monst *mdef;
2370 register struct attack *mattk;
2371 {
2372     boolean resistance; /* only for cold/fire/elec */
2373     register int tmp = d((int) mattk->damn, (int) mattk->damd);
2374
2375 /*JP
2376     You("explode!");
2377 */
2378     You("\94\9a\94­\82µ\82½\81I");
2379     switch (mattk->adtyp) {
2380     case AD_BLND:
2381         if (!resists_blnd(mdef)) {
2382 /*JP
2383             pline("%s is blinded by your flash of light!", Monnam(mdef));
2384 */
2385             pline("%s\82Í\82Ü\82Î\82ä\82¢\8cõ\82Å\96Ú\82ª\82­\82ç\82ñ\82¾\81I", Monnam(mdef));
2386             mdef->mblinded = min((int) mdef->mblinded + tmp, 127);
2387             mdef->mcansee = 0;
2388         }
2389         break;
2390     case AD_HALU:
2391         if (haseyes(mdef->data) && mdef->mcansee) {
2392 /*JP
2393             pline("%s is affected by your flash of light!", Monnam(mdef));
2394 */
2395             pline("%s\82Í\82Ü\82Î\82ä\82¢\8cõ\82Å\89e\8b¿\82ð\8eó\82¯\82½\81I", Monnam(mdef));
2396             mdef->mconf = 1;
2397         }
2398         break;
2399     case AD_COLD:
2400         resistance = resists_cold(mdef);
2401         goto common;
2402     case AD_FIRE:
2403         resistance = resists_fire(mdef);
2404         goto common;
2405     case AD_ELEC:
2406         resistance = resists_elec(mdef);
2407  common:
2408         if (!resistance) {
2409 /*JP
2410             pline("%s gets blasted!", Monnam(mdef));
2411 */
2412             pline("%s\82Í\94\9a\94­\82ð\97\81\82Ñ\82½\81I", Monnam(mdef));
2413             mdef->mhp -= tmp;
2414             if (DEADMONSTER(mdef)) {
2415                 killed(mdef);
2416                 return 2;
2417             }
2418         } else {
2419             shieldeff(mdef->mx, mdef->my);
2420             if (is_golem(mdef->data))
2421                 golemeffects(mdef, (int) mattk->adtyp, tmp);
2422             else
2423 /*JP
2424                 pline_The("blast doesn't seem to affect %s.", mon_nam(mdef));
2425 */
2426                 pline("\94\9a\94­\82Í%s\82É\89e\8b¿\82ð\97^\82¦\82È\82©\82Á\82½\82æ\82¤\82¾\81D", mon_nam(mdef));
2427         }
2428         break;
2429     default:
2430         break;
2431     }
2432     return 1;
2433 }
2434
2435 STATIC_OVL void
2436 start_engulf(mdef)
2437 struct monst *mdef;
2438 {
2439     if (!Invisible) {
2440         map_location(u.ux, u.uy, TRUE);
2441         tmp_at(DISP_ALWAYS, mon_to_glyph(&youmonst, rn2_on_display_rng));
2442         tmp_at(mdef->mx, mdef->my);
2443     }
2444 /*JP
2445     You("engulf %s!", mon_nam(mdef));
2446 */
2447     You("%s\82ð\88ù\82Ý\8d\9e\82ñ\82¾\81I", mon_nam(mdef));
2448     delay_output();
2449     delay_output();
2450 }
2451
2452 STATIC_OVL void
2453 end_engulf()
2454 {
2455     if (!Invisible) {
2456         tmp_at(DISP_END, 0);
2457         newsym(u.ux, u.uy);
2458     }
2459 }
2460
2461 STATIC_OVL int
2462 gulpum(mdef, mattk)
2463 register struct monst *mdef;
2464 register struct attack *mattk;
2465 {
2466 #ifdef LINT /* static char msgbuf[BUFSZ]; */
2467     char msgbuf[BUFSZ];
2468 #else
2469     static char msgbuf[BUFSZ]; /* for nomovemsg */
2470 #endif
2471     register int tmp;
2472     register int dam = d((int) mattk->damn, (int) mattk->damd);
2473     boolean fatal_gulp;
2474     struct obj *otmp;
2475     struct permonst *pd = mdef->data;
2476
2477     /* Not totally the same as for real monsters.  Specifically, these
2478      * don't take multiple moves.  (It's just too hard, for too little
2479      * result, to program monsters which attack from inside you, which
2480      * would be necessary if done accurately.)  Instead, we arbitrarily
2481      * kill the monster immediately for AD_DGST and we regurgitate them
2482      * after exactly 1 round of attack otherwise.  -KAA
2483      */
2484
2485     if (!engulf_target(&youmonst, mdef))
2486         return 0;
2487
2488     if (u.uhunger < 1500 && !u.uswallow) {
2489         for (otmp = mdef->minvent; otmp; otmp = otmp->nobj)
2490             (void) snuff_lit(otmp);
2491
2492         /* force vampire in bat, cloud, or wolf form to revert back to
2493            vampire form now instead of dealing with that when it dies */
2494         if (is_vampshifter(mdef)
2495             && newcham(mdef, &mons[mdef->cham], FALSE, FALSE)) {
2496 /*JP
2497             You("engulf it, then expel it.");
2498 */
2499             You("\88ù\82Ý\8d\9e\82ñ\82Å\81C\93f\82«\8fo\82µ\82½\81D");
2500             if (canspotmon(mdef))
2501 /*JP
2502                 pline("It turns into %s.", a_monnam(mdef));
2503 */
2504                 pline("\82»\82ê\82Í%s\82É\82È\82Á\82½\81D", a_monnam(mdef));
2505             else
2506                 map_invisible(mdef->mx, mdef->my);
2507             return 1;
2508         }
2509
2510         /* engulfing a cockatrice or digesting a Rider or Medusa */
2511         fatal_gulp = (touch_petrifies(pd) && !Stone_resistance)
2512                      || (mattk->adtyp == AD_DGST
2513                          && (is_rider(pd) || (pd == &mons[PM_MEDUSA]
2514                                               && !Stone_resistance)));
2515
2516         if ((mattk->adtyp == AD_DGST && !Slow_digestion) || fatal_gulp)
2517             eating_conducts(pd);
2518
2519         if (fatal_gulp && !is_rider(pd)) { /* petrification */
2520             char kbuf[BUFSZ];
2521             const char *mname = pd->mname;
2522
2523             if (!type_is_pname(pd))
2524                 mname = an(mname);
2525 /*JP
2526             You("englut %s.", mon_nam(mdef));
2527 */
2528             You("%s\82ð\88ù\82Ý\8d\9e\82ñ\82¾\81D", mon_nam(mdef));
2529 /*JP
2530             Sprintf(kbuf, "swallowing %s whole", mname);
2531 */
2532             Sprintf(kbuf, "%s\82ð\88ù\82Ý\8d\9e\82ñ\82Å", mname);
2533             instapetrify(kbuf);
2534         } else {
2535             start_engulf(mdef);
2536             switch (mattk->adtyp) {
2537             case AD_DGST:
2538                 /* eating a Rider or its corpse is fatal */
2539                 if (is_rider(pd)) {
2540 /*JP
2541                     pline("Unfortunately, digesting any of it is fatal.");
2542 */
2543                     pline("\8ec\94O\82È\82ª\82ç\81C\82»\82ê\82ð\90H\82×\82é\82Ì\82Í\92v\96½\93I\82È\8aÔ\88á\82¢\82¾\81D");
2544                     end_engulf();
2545 #if 0 /*JP*/
2546                     Sprintf(killer.name, "unwisely tried to eat %s",
2547                             pd->mname);
2548                     killer.format = NO_KILLER_PREFIX;
2549 #else
2550                     Sprintf(killer.name, "\8bð\82©\82É\82à%s\82ð\90H\82×\82æ\82¤\82Æ\82µ\82Ä",
2551                             pd->mname);
2552                     killer.format = KILLED_BY;
2553 #endif
2554                     done(DIED);
2555                     return 0; /* lifesaved */
2556                 }
2557
2558                 if (Slow_digestion) {
2559                     dam = 0;
2560                     break;
2561                 }
2562
2563                 /* Use up amulet of life saving */
2564                 if ((otmp = mlifesaver(mdef)) != 0)
2565                     m_useup(mdef, otmp);
2566
2567                 newuhs(FALSE);
2568                 /* start_engulf() issues "you engulf <mdef>" above; this
2569                    used to specify XKILL_NOMSG but we need "you kill <mdef>"
2570                    in case we're also going to get "welcome to level N+1";
2571                    "you totally digest <mdef>" will be coming soon (after
2572                    several turns) but the level-gain message seems out of
2573                    order if the kill message is left implicit */
2574                 xkilled(mdef, XKILL_GIVEMSG | XKILL_NOCORPSE);
2575                 if (!DEADMONSTER(mdef)) { /* monster lifesaved */
2576 /*JP
2577                     You("hurriedly regurgitate the sizzling in your %s.",
2578 */
2579                     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",
2580                         body_part(STOMACH));
2581                 } else {
2582                     tmp = 1 + (pd->cwt >> 8);
2583                     if (corpse_chance(mdef, &youmonst, TRUE)
2584                         && !(mvitals[monsndx(pd)].mvflags & G_NOCORPSE)) {
2585                         /* nutrition only if there can be a corpse */
2586                         u.uhunger += (pd->cnutrit + 1) / 2;
2587                     } else
2588                         tmp = 0;
2589 /*JP
2590                     Sprintf(msgbuf, "You totally digest %s.", mon_nam(mdef));
2591 */
2592                     Sprintf(msgbuf, "\82 \82È\82½\82Í%s\82ð\8a®\91S\82É\8fÁ\89»\82µ\82½\81D", mon_nam(mdef));
2593                     if (tmp != 0) {
2594                         /* setting afternmv = end_engulf is tempting,
2595                          * but will cause problems if the player is
2596                          * attacked (which uses his real location) or
2597                          * if his See_invisible wears off
2598                          */
2599 /*JP
2600                         You("digest %s.", mon_nam(mdef));
2601 */
2602                         You("%s\82ð\8fÁ\89»\82µ\82Ä\82¢\82é\81D", mon_nam(mdef));
2603                         if (Slow_digestion)
2604                             tmp *= 2;
2605                         nomul(-tmp);
2606 /*JP
2607                         multi_reason = "digesting something";
2608 */
2609                         multi_reason = "\8fÁ\89»\92\86\82É";
2610                         nomovemsg = msgbuf;
2611                     } else
2612                         pline1(msgbuf);
2613                     if (pd == &mons[PM_GREEN_SLIME]) {
2614 /*JP
2615                         Sprintf(msgbuf, "%s isn't sitting well with you.",
2616 */
2617                         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",
2618                                 The(pd->mname));
2619                         if (!Unchanging) {
2620                             make_slimed(5L, (char *) 0);
2621                         }
2622                     } else
2623                         exercise(A_CON, TRUE);
2624                 }
2625                 end_engulf();
2626                 return 2;
2627             case AD_PHYS:
2628                 if (youmonst.data == &mons[PM_FOG_CLOUD]) {
2629 /*JP
2630                     pline("%s is laden with your moisture.", Monnam(mdef));
2631 */
2632                     pline("%s\82Í\82 \82È\82½\82Ì\8e¼\8bC\82É\8bê\82µ\82ß\82ç\82ê\82Ä\82¢\82é\81D", Monnam(mdef));
2633                     if (amphibious(pd) && !flaming(pd)) {
2634                         dam = 0;
2635 /*JP
2636                         pline("%s seems unharmed.", Monnam(mdef));
2637 */
2638                         pline("%s\82Í\8f\9d\82Â\82¢\82Ä\82¢\82È\82¢\82æ\82¤\82¾\81D", Monnam(mdef));
2639                     }
2640                 } else
2641 /*JP
2642                     pline("%s is pummeled with your debris!", Monnam(mdef));
2643 */
2644                     pline("%s\82Í\8a¢âI\82Å\92É\82ß\82Â\82¯\82ç\82ê\82½\81I", Monnam(mdef));
2645                 break;
2646             case AD_ACID:
2647 /*JP
2648                 pline("%s is covered with your goo!", Monnam(mdef));
2649 */
2650                 pline("%s\82Í\82Ë\82Î\82Â\82­\82à\82Ì\82Å\95¢\82í\82ê\82½\81I", Monnam(mdef));
2651                 if (resists_acid(mdef)) {
2652 /*JP
2653                     pline("It seems harmless to %s.", mon_nam(mdef));
2654 */
2655                     pline("\82µ\82©\82µ\81C%s\82Í\82È\82ñ\82Æ\82à\82È\82¢\81D", mon_nam(mdef));
2656                     dam = 0;
2657                 }
2658                 break;
2659             case AD_BLND:
2660                 if (can_blnd(&youmonst, mdef, mattk->aatyp,
2661                              (struct obj *) 0)) {
2662                     if (mdef->mcansee)
2663 /*JP
2664                         pline("%s can't see in there!", Monnam(mdef));
2665 */
2666                         pline("%s\82Í\96Ú\82ª\8c©\82¦\82È\82­\82È\82Á\82½\81I", mon_nam(mdef));
2667                     mdef->mcansee = 0;
2668                     dam += mdef->mblinded;
2669                     if (dam > 127)
2670                         dam = 127;
2671                     mdef->mblinded = dam;
2672                 }
2673                 dam = 0;
2674                 break;
2675             case AD_ELEC:
2676                 if (rn2(2)) {
2677 /*JP
2678                     pline_The("air around %s crackles with electricity.",
2679 */
2680                     pline("%s\82Ì\89ñ\82è\82Ì\8bó\8bC\82Í\93d\8bC\82Å\83s\83\8a\83s\83\8a\82µ\82Ä\82¢\82é\81D",
2681                               mon_nam(mdef));
2682                     if (resists_elec(mdef)) {
2683 /*JP
2684                         pline("%s seems unhurt.", Monnam(mdef));
2685 */
2686                         pline("\82µ\82©\82µ\81C%s\82Í\95½\8bC\82È\82æ\82¤\82¾\81D", Monnam(mdef));
2687                         dam = 0;
2688                     }
2689                     golemeffects(mdef, (int) mattk->adtyp, dam);
2690                 } else
2691                     dam = 0;
2692                 break;
2693             case AD_COLD:
2694                 if (rn2(2)) {
2695                     if (resists_cold(mdef)) {
2696 /*JP
2697                         pline("%s seems mildly chilly.", Monnam(mdef));
2698 */
2699                         pline("%s\82Í\97â\82¦\82½\82æ\82¤\82¾\81D", Monnam(mdef));
2700                         dam = 0;
2701                     } else
2702 /*JP
2703                         pline("%s is freezing to death!", Monnam(mdef));
2704 */
2705                         pline("%s\82Í\93\80\8e\80\82µ\82»\82¤\82¾\81I", Monnam(mdef));
2706                     golemeffects(mdef, (int) mattk->adtyp, dam);
2707                 } else
2708                     dam = 0;
2709                 break;
2710             case AD_FIRE:
2711                 if (rn2(2)) {
2712                     if (resists_fire(mdef)) {
2713 /*JP
2714                         pline("%s seems mildly hot.", Monnam(mdef));
2715 */
2716                         pline("%s\82Í\92g\82©\82­\82È\82Á\82½\82æ\82¤\82¾\81D", Monnam(mdef));
2717                         dam = 0;
2718                     } else
2719 /*JP
2720                         pline("%s is burning to a crisp!", Monnam(mdef));
2721 */
2722                         pline("%s\82Í\94R\82¦\82Ä\83J\83\89\83J\83\89\82É\82È\82Á\82½\81I", Monnam(mdef));
2723                     golemeffects(mdef, (int) mattk->adtyp, dam);
2724                 } else
2725                     dam = 0;
2726                 break;
2727             case AD_DREN:
2728                 if (!rn2(4))
2729                     xdrainenergym(mdef, TRUE);
2730                 dam = 0;
2731                 break;
2732             }
2733             end_engulf();
2734             mdef->mhp -= dam;
2735             if (DEADMONSTER(mdef)) {
2736                 killed(mdef);
2737                 if (DEADMONSTER(mdef)) /* not lifesaved */
2738                     return 2;
2739             }
2740 #if 0 /*JP:T*/
2741             You("%s %s!", is_animal(youmonst.data) ? "regurgitate" : "expel",
2742                 mon_nam(mdef));
2743 #else
2744             You("%s\82ð%s\82µ\82½\81I", mon_nam(mdef),
2745                 is_animal(youmonst.data) ? "\93f\82«\96ß" : "\94r\8fo");
2746 #endif
2747             if (Slow_digestion || is_animal(youmonst.data)) {
2748 #if 0 /*JP:T*/
2749                 pline("Obviously, you didn't like %s taste.",
2750                       s_suffix(mon_nam(mdef)));
2751 #else
2752                 pline("\82Ç\82¤\82à%s\82Ì\96¡\82Í\8dD\82«\82É\82È\82ê\82È\82¢\81D",
2753                       mon_nam(mdef));
2754 #endif
2755             }
2756         }
2757     }
2758     return 0;
2759 }
2760
2761 void
2762 missum(mdef, mattk, wouldhavehit)
2763 register struct monst *mdef;
2764 register struct attack *mattk;
2765 boolean wouldhavehit;
2766 {
2767     if (wouldhavehit) /* monk is missing due to penalty for wearing suit */
2768 /*JP
2769         Your("armor is rather cumbersome...");
2770 */
2771         Your("\96h\8bï\82Í\8f­\82µ\8e×\96\82\82¾\81D\81D\81D");
2772
2773     if (could_seduce(&youmonst, mdef, mattk))
2774 /*JP
2775         You("pretend to be friendly to %s.", mon_nam(mdef));
2776 */
2777         You("%s\82É\97F\8dD\93I\82È\82Ó\82è\82ð\82µ\82½\81D", mon_nam(mdef));
2778     else if (canspotmon(mdef) && flags.verbose)
2779 /*JP
2780         You("miss %s.", mon_nam(mdef));
2781 */
2782         Your("%s\82Ö\82Ì\8dU\8c\82\82Í\8aO\82ê\82½\81D", mon_nam(mdef));
2783     else
2784 /*JP
2785         You("miss it.");
2786 */
2787         Your("\89½\8eÒ\82©\82Ö\82Ì\8dU\8c\82\82Í\8aO\82ê\82½\81D");
2788     if (!mdef->msleeping && mdef->mcanmove)
2789         wakeup(mdef, TRUE);
2790 }
2791
2792 /* attack monster as a monster; returns True if mon survives */
2793 STATIC_OVL boolean
2794 hmonas(mon)
2795 register struct monst *mon;
2796 {
2797     struct attack *mattk, alt_attk;
2798     struct obj *weapon, **originalweapon;
2799     boolean altwep = FALSE, weapon_used = FALSE, odd_claw = TRUE;
2800     int i, tmp, armorpenalty, sum[NATTK], nsum = 0, dhit = 0, attknum = 0;
2801     int dieroll, multi_claw = 0;
2802
2803     /* with just one touch/claw/weapon attack, both rings matter;
2804        with more than one, alternate right and left when checking
2805        whether silver ring causes successful hit */
2806     for (i = 0; i < NATTK; i++) {
2807         sum[i] = 0;
2808         mattk = getmattk(&youmonst, mon, i, sum, &alt_attk);
2809         if (mattk->aatyp == AT_WEAP
2810             || mattk->aatyp == AT_CLAW || mattk->aatyp == AT_TUCH)
2811             ++multi_claw;
2812     }
2813     multi_claw = (multi_claw > 1); /* switch from count to yes/no */
2814
2815     for (i = 0; i < NATTK; i++) {
2816         /* sum[i] = 0; -- now done above */
2817         mattk = getmattk(&youmonst, mon, i, sum, &alt_attk);
2818         weapon = 0;
2819         switch (mattk->aatyp) {
2820         case AT_WEAP:
2821             /* if (!uwep) goto weaponless; */
2822  use_weapon:
2823             odd_claw = !odd_claw; /* see case AT_CLAW,AT_TUCH below */
2824             /* if we've already hit with a two-handed weapon, we don't
2825                get to make another weapon attack (note:  monsters who
2826                use weapons do not have this restriction, but they also
2827                never have the opportunity to use two weapons) */
2828             if (weapon_used && sum[i - 1] && uwep && bimanual(uwep))
2829                 continue;
2830             /* Certain monsters don't use weapons when encountered as enemies,
2831              * but players who polymorph into them have hands or claws and
2832              * thus should be able to use weapons.  This shouldn't prohibit
2833              * the use of most special abilities, either.
2834              * If monster has multiple claw attacks, only one can use weapon.
2835              */
2836             weapon_used = TRUE;
2837             /* Potential problem: if the monster gets multiple weapon attacks,
2838              * we currently allow the player to get each of these as a weapon
2839              * attack.  Is this really desirable?
2840              */
2841             /* approximate two-weapon mode; known_hitum() -> hmon() -> &c
2842                might destroy the weapon argument, but it might also already
2843                be Null, and we want to track that for passive() */
2844             originalweapon = (altwep && uswapwep) ? &uswapwep : &uwep;
2845             if (uswapwep /* set up 'altwep' flag for next iteration */
2846                 /* only consider seconary when wielding one-handed primary */
2847                 && uwep && (uwep->oclass == WEAPON_CLASS || is_weptool(uwep))
2848                 && !bimanual(uwep)
2849                 /* only switch if not wearing shield and not at artifact;
2850                    shield limitation is iffy since still get extra swings
2851                    if polyform has them, but it matches twoweap behavior;
2852                    twoweap also only allows primary to be an artifact, so
2853                    if alternate weapon is one, don't use it */
2854                 && !uarms && !uswapwep->oartifact
2855                 /* only switch to uswapwep if it's a weapon */
2856                 && (uswapwep->oclass == WEAPON_CLASS || is_weptool(uswapwep))
2857                 /* only switch if uswapwep is not bow, arrows, or darts */
2858                 && !(is_launcher(uswapwep) || is_ammo(uswapwep)
2859                      || is_missile(uswapwep)) /* dart, shuriken, boomerang */
2860                 /* and not two-handed and not incapable of being wielded */
2861                 && !bimanual(uswapwep)
2862                 && !(objects[uswapwep->otyp].oc_material == SILVER
2863                      && Hate_silver))
2864                 altwep = !altwep; /* toggle for next attack */
2865             weapon = *originalweapon;
2866             if (!weapon) /* no need to go beyond no-gloves to rings; not ...*/
2867                 originalweapon = &uarmg; /*... subject to erosion damage */
2868
2869             tmp = find_roll_to_hit(mon, AT_WEAP, weapon, &attknum,
2870                                    &armorpenalty);
2871             dieroll = rnd(20);
2872             dhit = (tmp > dieroll || u.uswallow);
2873             /* caller must set bhitpos */
2874             if (!known_hitum(mon, weapon, &dhit, tmp,
2875                              armorpenalty, mattk, dieroll)) {
2876                 /* enemy dead, before any special abilities used */
2877                 sum[i] = 2;
2878                 break;
2879             } else
2880                 sum[i] = dhit;
2881             /* originalweapon points to an equipment slot which might
2882                now be empty if the weapon was destroyed during the hit;
2883                passive(,weapon,...) won't call passive_obj() in that case */
2884             weapon = *originalweapon; /* might receive passive erosion */
2885             /* might be a worm that gets cut in half; if so, early return */
2886             if (m_at(u.ux + u.dx, u.uy + u.dy) != mon) {
2887                 i = NATTK; /* skip additional attacks */
2888                 /* proceed with uswapwep->cursed check, then exit loop */
2889                 goto passivedone;
2890             }
2891             /* Do not print "You hit" message; known_hitum already did it. */
2892             if (dhit && mattk->adtyp != AD_SPEL && mattk->adtyp != AD_PHYS)
2893                 sum[i] = damageum(mon, mattk, 0);
2894             break;
2895         case AT_CLAW:
2896             if (uwep && !cantwield(youmonst.data) && !weapon_used)
2897                 goto use_weapon;
2898             /*FALLTHRU*/
2899         case AT_TUCH:
2900             if (uwep && youmonst.data->mlet == S_LICH && !weapon_used)
2901                 goto use_weapon;
2902             /*FALLTHRU*/
2903         case AT_KICK:
2904         case AT_BITE:
2905         case AT_STNG:
2906         case AT_BUTT:
2907         case AT_TENT:
2908         /*weaponless:*/
2909             tmp = find_roll_to_hit(mon, mattk->aatyp, (struct obj *) 0,
2910                                    &attknum, &armorpenalty);
2911             dieroll = rnd(20);
2912             dhit = (tmp > dieroll || u.uswallow);
2913             if (dhit) {
2914                 int compat, specialdmg;
2915                 long silverhit = 0L;
2916 #if 0 /*JP*//* \82·\82×\82Ä\81u\8dU\8c\82\82µ\82½\81v\82É\82·\82é */
2917                 const char *verb = 0; /* verb or body part */
2918 #endif
2919
2920                 if (!u.uswallow
2921                     && (compat = could_seduce(&youmonst, mon, mattk)) != 0) {
2922 #if 0 /*JP:T*/
2923                     You("%s %s %s.",
2924                         (mon->mcansee && haseyes(mon->data)) ? "smile at"
2925                                                              : "talk to",
2926                         mon_nam(mon),
2927                         (compat == 2) ? "engagingly" : "seductively");
2928 #else
2929                     You("%s\82Ö%s%s\81D",
2930                         mon_nam(mon),
2931                         compat == 2 ? "\96£\97Í\93I\82É" : "\97U\98f\93I\82É",
2932                         mon->mcansee && haseyes(mon->data) ? "\94÷\8fÎ\82Ý\82©\82¯\82½"
2933                                                            : "\98b\82µ\82©\82¯\82½");
2934 #endif
2935                     /* doesn't anger it; no wakeup() */
2936                     sum[i] = damageum(mon, mattk, 0);
2937                     break;
2938                 }
2939                 wakeup(mon, TRUE);
2940
2941                 specialdmg = 0; /* blessed and/or silver bonus */
2942                 switch (mattk->aatyp) {
2943                 case AT_CLAW:
2944                 case AT_TUCH:
2945                     /* verb=="claws" may be overridden below */
2946 #if 0 /*JP*/
2947                     verb = (mattk->aatyp == AT_TUCH) ? "touch" : "claws";
2948 #endif
2949                     /* decide if silver-hater will be hit by silver ring(s);
2950                        for 'multi_claw' where attacks alternate right/left,
2951                        assume 'even' claw or touch attacks use right hand
2952                        or paw, 'odd' ones use left for ring interaction;
2953                        even vs odd is based on actual attacks rather
2954                        than on index into mon->dat->mattk[] so that {bite,
2955                        claw,claw} instead of {claw,claw,bite} doesn't
2956                        make poly'd hero mysteriously become left-handed */
2957                     odd_claw = !odd_claw;
2958                     specialdmg = special_dmgval(&youmonst, mon,
2959                                                 W_ARMG
2960                                                 | ((odd_claw || !multi_claw)
2961                                                    ? W_RINGL : 0L)
2962                                                 | ((!odd_claw || !multi_claw)
2963                                                    ? W_RINGR : 0L),
2964                                                 &silverhit);
2965                     break;
2966                 case AT_TENT:
2967                     /* assumes mind flayer's tentacles-on-head rather
2968                        than sea monster's tentacle-as-arm */
2969 #if 0 /*JP*/
2970                     verb = "tentacles";
2971 #endif
2972                     break;
2973                 case AT_KICK:
2974 #if 0 /*JP*/
2975                     verb = "kick";
2976 #endif
2977                     specialdmg = special_dmgval(&youmonst, mon, W_ARMF,
2978                                                 &silverhit);
2979                     break;
2980                 case AT_BUTT:
2981 #if 0 /*JP*/
2982                     verb = "head butt"; /* mbodypart(mon,HEAD)=="head" */
2983                     /* hypothetical; if any form with a head-butt attack
2984                        could wear a helmet, it would hit shades when
2985                        wearing a blessed (or silver) one */
2986 #endif
2987                     specialdmg = special_dmgval(&youmonst, mon, W_ARMH,
2988                                                 &silverhit);
2989                     break;
2990                 case AT_BITE:
2991 #if 0 /*JP*/
2992                     verb = "bite";
2993 #endif
2994                     break;
2995                 case AT_STNG:
2996 #if 0 /*JP*/
2997                     verb = "sting";
2998 #endif
2999                     break;
3000                 default:
3001 #if 0 /*JP*/
3002                     verb = "hit";
3003 #endif
3004                     break;
3005                 }
3006                 if (mon->data == &mons[PM_SHADE] && !specialdmg) {
3007 #if 0 /*JP*/
3008                     if (!strcmp(verb, "hit")
3009                         || (mattk->aatyp == AT_CLAW && humanoid(mon->data)))
3010                         verb = "attack";
3011 #endif
3012 #if 0 /*JP*/
3013                     Your("%s %s harmlessly through %s.",
3014                          verb, vtense(verb, "pass"), mon_nam(mon));
3015 #else
3016                     Your("\8dU\8c\82\82Í%s\82ð\92Ê\82è\82Ê\82¯\82½\81D",
3017                          mon_nam(mon));
3018 #endif
3019                 } else {
3020                     if (mattk->aatyp == AT_TENT) {
3021 /*JP
3022                         Your("tentacles suck %s.", mon_nam(mon));
3023 */
3024                         Your("\90G\8eè\82ª%s\82Ì\91Ì\89t\82ð\8bz\82¢\82Æ\82Á\82½\81D", mon_nam(mon));
3025                     } else {
3026 #if 0 /*JP*/
3027                         if (mattk->aatyp == AT_CLAW)
3028                             verb = "hit"; /* not "claws" */
3029 #endif
3030 #if 0 /*JP*/
3031                         You("%s %s.", verb, mon_nam(mon));
3032 #else
3033                         You("%s\82ð\8dU\8c\82\82µ\82½\81D", mon_nam(mon));
3034 #endif
3035                         if (silverhit && flags.verbose)
3036                             silver_sears(&youmonst, mon, silverhit);
3037                     }
3038                     sum[i] = damageum(mon, mattk, specialdmg);
3039                 }
3040             } else { /* !dhit */
3041                 missum(mon, mattk, (tmp + armorpenalty > dieroll));
3042             }
3043             break;
3044
3045         case AT_HUGS: {
3046             int specialdmg;
3047             long silverhit = 0L;
3048             boolean byhand = hug_throttles(&mons[u.umonnum]), /* rope golem */
3049                     unconcerned = (byhand && !can_be_strangled(mon));
3050
3051             if (sticks(mon->data) || u.uswallow || notonhead
3052                 || (byhand && (uwep || !has_head(mon->data)))) {
3053                 /* can't hold a holder due to subsequent ambiguity over
3054                    who is holding whom; can't hug engulfer from inside;
3055                    can't hug a worm tail (would immobilize entire worm!);
3056                    byhand: can't choke something that lacks a head;
3057                    not allowed to make a choking hug if wielding a weapon
3058                    (but might have grabbed w/o weapon, then wielded one,
3059                    and may even be attacking a different monster now) */
3060                 if (byhand && uwep && u.ustuck
3061                     && !(sticks(u.ustuck->data) || u.uswallow))
3062                     uunstick();
3063                 continue; /* not 'break'; bypass passive counter-attack */
3064             }
3065             /* automatic if prev two attacks succeed, or if
3066                already grabbed in a previous attack */
3067             dhit = 1;
3068             wakeup(mon, TRUE);
3069             /* choking hug/throttling grab uses hands (gloves or rings);
3070                normal hug uses outermost of cloak/suit/shirt */
3071             specialdmg = special_dmgval(&youmonst, mon,
3072                                         byhand ? (W_ARMG | W_RINGL | W_RINGR)
3073                                                : (W_ARMC | W_ARM | W_ARMU),
3074                                         &silverhit);
3075             if (unconcerned) {
3076                 /* strangling something which can't be strangled */
3077                 if (mattk != &alt_attk) {
3078                     alt_attk = *mattk;
3079                     mattk = &alt_attk;
3080                 }
3081                 /* change damage to 1d1; not strangling but still
3082                    doing [minimal] physical damage to victim's body */
3083                 mattk->damn = mattk->damd = 1;
3084                 /* don't give 'unconcerned' feedback if there is extra damage
3085                    or if it is nearly destroyed or if creature doesn't have
3086                    the mental ability to be concerned in the first place */
3087                 if (specialdmg || mindless(mon->data)
3088                     || mon->mhp <= 1 + max(u.udaminc, 1))
3089                     unconcerned = FALSE;
3090             }
3091             if (mon->data == &mons[PM_SHADE]) {
3092 #if 0 /*JP*/
3093                 const char *verb = byhand ? "grasp" : "hug";
3094 #endif
3095
3096                 /* hugging a shade; successful if blessed outermost armor
3097                    for normal hug, or blessed gloves or silver ring(s) for
3098                    choking hug; deals damage but never grabs hold */
3099                 if (specialdmg) {
3100 #if 0 /*JP:T*/
3101                     You("%s %s%s", verb, mon_nam(mon), exclam(specialdmg));
3102 #else
3103                     You("%s\82ð\82Â\82©\82ñ\82¾%s", mon_nam(mon), exclam(specialdmg));
3104 #endif
3105                     if (silverhit && flags.verbose)
3106                         silver_sears(&youmonst, mon, silverhit);
3107                     sum[i] = damageum(mon, mattk, specialdmg);
3108                 } else {
3109 #if 0 /*JP:T*/
3110                     Your("%s passes harmlessly through %s.",
3111                          verb, mon_nam(mon));
3112 #else
3113                     You("%s\82ð\82Â\82©\82Ü\82¦\82æ\82¤\82Æ\82µ\82½\82ª\92Ê\82è\82Ê\82¯\82½\81D",
3114                         mon_nam(mon));
3115 #endif
3116                 }
3117                 break;
3118             }
3119             /* hug attack against ordinary foe */
3120             if (mon == u.ustuck) {
3121 #if 0 /*JP:T*/
3122                 pline("%s is being %s%s.", Monnam(mon),
3123                       byhand ? "throttled" : "crushed",
3124                       /* extra feedback for non-breather being choked */
3125                       unconcerned ? " but doesn't seem concerned" : "");
3126 #else
3127                 pline("%s\82Í%s%s\81D", Monnam(mon),
3128                       byhand ? "\8eñ\82ð\8di\82ß\82ç\82ê\82Ä\82¢\82é" : "\89\9f\82µ\82Â\82Ô\82³\82ê\82Ä\82¢\82é",
3129                       /* extra feedback for non-breather being choked */
3130                       unconcerned ? "\82ª\81C\8bC\82É\82µ\82Ä\82¢\82È\82¢\82æ\82¤\82¾" : "");
3131 #endif
3132                 if (silverhit && flags.verbose)
3133                     silver_sears(&youmonst, mon, silverhit);
3134                 sum[i] = damageum(mon, mattk, specialdmg);
3135             } else if (i >= 2 && sum[i - 1] && sum[i - 2]) {
3136                 /* in case we're hugging a new target while already
3137                    holding something else; yields feedback
3138                    "<u.ustuck> is no longer in your clutches" */
3139                 if (u.ustuck && u.ustuck != mon)
3140                     uunstick();
3141 /*JP
3142                 You("grab %s!", mon_nam(mon));
3143 */
3144                 You("%s\82ð\82Â\82©\82Ü\82¦\82½\81I", mon_nam(mon));
3145                 u.ustuck = mon;
3146                 if (silverhit && flags.verbose)
3147                     silver_sears(&youmonst, mon, silverhit);
3148                 sum[i] = damageum(mon, mattk, specialdmg);
3149             }
3150             break; /* AT_HUGS */
3151         }
3152
3153         case AT_EXPL: /* automatic hit if next to */
3154             dhit = -1;
3155             wakeup(mon, TRUE);
3156             sum[i] = explum(mon, mattk);
3157             break;
3158
3159         case AT_ENGL:
3160             tmp = find_roll_to_hit(mon, mattk->aatyp, (struct obj *) 0,
3161                                    &attknum, &armorpenalty);
3162             if ((dhit = (tmp > rnd(20 + i)))) {
3163                 wakeup(mon, TRUE);
3164                 if (mon->data == &mons[PM_SHADE])
3165 /*JP
3166                     Your("attempt to surround %s is harmless.", mon_nam(mon));
3167 */
3168                     You("%s\82ð\88ù\82Ý\82±\82à\82¤\82Æ\82µ\82½\82ª\8e¸\94s\82µ\82½\81D", mon_nam(mon));
3169                 else {
3170                     sum[i] = gulpum(mon, mattk);
3171                     if (sum[i] == 2 && (mon->data->mlet == S_ZOMBIE
3172                                         || mon->data->mlet == S_MUMMY)
3173                         && rn2(5) && !Sick_resistance) {
3174 /*JP
3175                         You_feel("%ssick.", (Sick) ? "very " : "");
3176 */
3177                         You_feel("%s\8bC\95ª\82ª\88«\82¢\81D", (Sick) ? "\82Æ\82Ä\82à" : "");
3178                         mdamageu(mon, rnd(8));
3179                     }
3180                 }
3181             } else {
3182                 missum(mon, mattk, FALSE);
3183             }
3184             break;
3185
3186         case AT_MAGC:
3187             /* No check for uwep; if wielding nothing we want to
3188              * do the normal 1-2 points bare hand damage...
3189              */
3190             if ((youmonst.data->mlet == S_KOBOLD
3191                  || youmonst.data->mlet == S_ORC
3192                  || youmonst.data->mlet == S_GNOME) && !weapon_used)
3193                 goto use_weapon;
3194             /*FALLTHRU*/
3195
3196         case AT_NONE:
3197         case AT_BOOM:
3198             continue;
3199         /* Not break--avoid passive attacks from enemy */
3200
3201         case AT_BREA:
3202         case AT_SPIT:
3203         case AT_GAZE: /* all done using #monster command */
3204             dhit = 0;
3205             break;
3206
3207         default: /* Strange... */
3208             impossible("strange attack of yours (%d)", mattk->aatyp);
3209         }
3210         if (dhit == -1) {
3211             u.mh = -1; /* dead in the current form */
3212             rehumanize();
3213         }
3214         if (sum[i] == 2) {
3215             /* defender dead */
3216             (void) passive(mon, weapon, 1, 0, mattk->aatyp, FALSE);
3217             nsum = 0; /* return value below used to be 'nsum > 0' */
3218         } else {
3219             (void) passive(mon, weapon, sum[i], 1, mattk->aatyp, FALSE);
3220             nsum |= sum[i];
3221         }
3222
3223         /* don't use sum[i] beyond this point;
3224            'i' will be out of bounds if we get here via 'goto' */
3225  passivedone:
3226         /* when using dual weapons, cursed secondary weapon doesn't weld,
3227            it gets dropped; do the same when multiple AT_WEAP attacks
3228            simulate twoweap */
3229         if (uswapwep && weapon == uswapwep && weapon->cursed) {
3230             drop_uswapwep();
3231             break; /* don't proceed with additional attacks */
3232         }
3233         /* stop attacking if defender has died;
3234            needed to defer this until after uswapwep->cursed check */
3235         if (DEADMONSTER(mon))
3236             break;
3237         if (!Upolyd)
3238             break; /* No extra attacks if no longer a monster */
3239         if (multi < 0)
3240             break; /* If paralyzed while attacking, i.e. floating eye */
3241     }
3242     /* return value isn't used, but make it match hitum()'s */
3243     return !DEADMONSTER(mon);
3244 }
3245
3246 /*      Special (passive) attacks on you by monsters done here.
3247  */
3248 int
3249 passive(mon, weapon, mhit, malive, aatyp, wep_was_destroyed)
3250 struct monst *mon;
3251 struct obj *weapon; /* uwep or uswapwep or uarmg or uarmf or Null */
3252 boolean mhit;
3253 int malive;
3254 uchar aatyp;
3255 boolean wep_was_destroyed;
3256 {
3257     register struct permonst *ptr = mon->data;
3258     register int i, tmp;
3259
3260     for (i = 0;; i++) {
3261         if (i >= NATTK)
3262             return (malive | mhit); /* no passive attacks */
3263         if (ptr->mattk[i].aatyp == AT_NONE)
3264             break; /* try this one */
3265     }
3266     /* Note: tmp not always used */
3267     if (ptr->mattk[i].damn)
3268         tmp = d((int) ptr->mattk[i].damn, (int) ptr->mattk[i].damd);
3269     else if (ptr->mattk[i].damd)
3270         tmp = d((int) mon->m_lev + 1, (int) ptr->mattk[i].damd);
3271     else
3272         tmp = 0;
3273
3274     /*  These affect you even if they just died.
3275      */
3276     switch (ptr->mattk[i].adtyp) {
3277     case AD_FIRE:
3278         if (mhit && !mon->mcan && weapon) {
3279             if (aatyp == AT_KICK) {
3280                 if (uarmf && !rn2(6))
3281                     (void) erode_obj(uarmf, xname(uarmf), ERODE_BURN,
3282                                      EF_GREASE | EF_VERBOSE);
3283             } else if (aatyp == AT_WEAP || aatyp == AT_CLAW
3284                        || aatyp == AT_MAGC || aatyp == AT_TUCH)
3285                 passive_obj(mon, weapon, &(ptr->mattk[i]));
3286         }
3287         break;
3288     case AD_ACID:
3289         if (mhit && rn2(2)) {
3290             if (Blind || !flags.verbose)
3291 /*JP
3292                 You("are splashed!");
3293 */
3294                 You("\89½\82©\82ð\97\81\82Ñ\82¹\82ç\82ê\82½\81I");
3295             else
3296 #if 0 /*JP:T*/
3297                 You("are splashed by %s %s!", s_suffix(mon_nam(mon)),
3298                     hliquid("acid"));
3299 #else
3300                 You("%s\82Ì%s\82ð\97\81\82Ñ\82¹\82ç\82ê\82½\81I", mon_nam(mon),
3301                     hliquid("\8e_"));
3302 #endif
3303
3304             if (!Acid_resistance)
3305                 mdamageu(mon, tmp);
3306             if (!rn2(30))
3307                 erode_armor(&youmonst, ERODE_CORRODE);
3308         }
3309         if (mhit && weapon) {
3310             if (aatyp == AT_KICK) {
3311                 if (uarmf && !rn2(6))
3312                     (void) erode_obj(uarmf, xname(uarmf), ERODE_CORRODE,
3313                                      EF_GREASE | EF_VERBOSE);
3314             } else if (aatyp == AT_WEAP || aatyp == AT_CLAW
3315                        || aatyp == AT_MAGC || aatyp == AT_TUCH)
3316                 passive_obj(mon, weapon, &(ptr->mattk[i]));
3317         }
3318         exercise(A_STR, FALSE);
3319         break;
3320     case AD_STON:
3321         if (mhit) { /* successful attack */
3322             long protector = attk_protection((int) aatyp);
3323
3324             /* hero using monsters' AT_MAGC attack is hitting hand to
3325                hand rather than casting a spell */
3326             if (aatyp == AT_MAGC)
3327                 protector = W_ARMG;
3328
3329             if (protector == 0L /* no protection */
3330                 || (protector == W_ARMG && !uarmg
3331                     && !uwep && !wep_was_destroyed)
3332                 || (protector == W_ARMF && !uarmf)
3333                 || (protector == W_ARMH && !uarmh)
3334                 || (protector == (W_ARMC | W_ARMG) && (!uarmc || !uarmg))) {
3335                 if (!Stone_resistance
3336                     && !(poly_when_stoned(youmonst.data)
3337                          && polymon(PM_STONE_GOLEM))) {
3338                     done_in_by(mon, STONING); /* "You turn to stone..." */
3339                     return 2;
3340                 }
3341             }
3342         }
3343         break;
3344     case AD_RUST:
3345         if (mhit && !mon->mcan && weapon) {
3346             if (aatyp == AT_KICK) {
3347                 if (uarmf)
3348                     (void) erode_obj(uarmf, xname(uarmf), ERODE_RUST,
3349                                      EF_GREASE | EF_VERBOSE);
3350             } else if (aatyp == AT_WEAP || aatyp == AT_CLAW
3351                        || aatyp == AT_MAGC || aatyp == AT_TUCH)
3352                 passive_obj(mon, weapon, &(ptr->mattk[i]));
3353         }
3354         break;
3355     case AD_CORR:
3356         if (mhit && !mon->mcan && weapon) {
3357             if (aatyp == AT_KICK) {
3358                 if (uarmf)
3359                     (void) erode_obj(uarmf, xname(uarmf), ERODE_CORRODE,
3360                                      EF_GREASE | EF_VERBOSE);
3361             } else if (aatyp == AT_WEAP || aatyp == AT_CLAW
3362                        || aatyp == AT_MAGC || aatyp == AT_TUCH)
3363                 passive_obj(mon, weapon, &(ptr->mattk[i]));
3364         }
3365         break;
3366     case AD_MAGM:
3367         /* wrath of gods for attacking Oracle */
3368         if (Antimagic) {
3369             shieldeff(u.ux, u.uy);
3370 /*JP
3371             pline("A hail of magic missiles narrowly misses you!");
3372 */
3373             pline("\96\82\96@\82Ì\96î\82Ì\89J\82ª\82©\82·\82ß\82Ä\82¢\82Á\82½\81I");
3374         } else {
3375 /*JP
3376             You("are hit by magic missiles appearing from thin air!");
3377 */
3378             pline("\93Ë\94@\8bó\92\86\82É\8c»\82í\82ê\82½\96\82\96@\82Ì\96î\82ª\96½\92\86\82µ\82½\81I");
3379             mdamageu(mon, tmp);
3380         }
3381         break;
3382     case AD_ENCH: /* KMH -- remove enchantment (disenchanter) */
3383         if (mhit) {
3384             if (aatyp == AT_KICK) {
3385                 if (!weapon)
3386                     break;
3387             } else if (aatyp == AT_BITE || aatyp == AT_BUTT
3388                        || (aatyp >= AT_STNG && aatyp < AT_WEAP)) {
3389                 break; /* no object involved */
3390             }
3391             passive_obj(mon, weapon, &(ptr->mattk[i]));
3392         }
3393         break;
3394     default:
3395         break;
3396     }
3397
3398     /*  These only affect you if they still live.
3399      */
3400     if (malive && !mon->mcan && rn2(3)) {
3401         switch (ptr->mattk[i].adtyp) {
3402         case AD_PLYS:
3403             if (ptr == &mons[PM_FLOATING_EYE]) {
3404                 if (!canseemon(mon)) {
3405                     break;
3406                 }
3407                 if (mon->mcansee) {
3408 #if 0 /*JP:T*/
3409                     if (ureflects("%s gaze is reflected by your %s.",
3410                                   s_suffix(Monnam(mon)))) {
3411 #else
3412                     if (ureflects("%s\82Ì\82É\82ç\82Ý\82Í%s\82É\82æ\82Á\82Ä\94½\8eË\82³\82ê\82½\81D",
3413                                   Monnam(mon))) {
3414 #endif
3415                         ;
3416                     } else if (Free_action) {
3417 #if 0 /*JP:T*/
3418                         You("momentarily stiffen under %s gaze!",
3419                             s_suffix(mon_nam(mon)));
3420 #else
3421                         You("%s\82Ì\82É\82ç\82Ý\82Å\88ê\8fu\8dd\92¼\82µ\82½\81I",
3422                             mon_nam(mon));
3423 #endif
3424                     } else if (Hallucination && rn2(4)) {
3425 #if 0 /*JP:T*/
3426                         pline("%s looks %s%s.", Monnam(mon),
3427                               !rn2(2) ? "" : "rather ",
3428                               !rn2(2) ? "numb" : "stupified");
3429 #else
3430                         pline("%s\82Í%s\82Î\82©\82É\82È\82Á\82½\82æ\82¤\82¾\81D", Monnam(mon),
3431                               !rn2(2) ? "" : "\8f­\82µ");
3432 #endif
3433                     } else {
3434 /*JP
3435                         You("are frozen by %s gaze!", s_suffix(mon_nam(mon)));
3436 */
3437                         You("%s\82Ì\82É\82ç\82Ý\82Å\93®\82¯\82È\82­\82È\82Á\82½\81I", mon_nam(mon));
3438                         nomul((ACURR(A_WIS) > 12 || rn2(4)) ? -tmp : -127);
3439 /*JP
3440                         multi_reason = "frozen by a monster's gaze";
3441 */
3442                         multi_reason = "\89ö\95¨\82Ì\82É\82ç\82Ý\82Å\8dd\92¼\82µ\82Ä\82¢\82é\8e\9e\82É";
3443                         nomovemsg = 0;
3444                     }
3445                 } else {
3446 #if 0 /*JP:T*/
3447                     pline("%s cannot defend itself.",
3448                           Adjmonnam(mon, "blind"));
3449 #else
3450                     pline("%s\82Í\96h\8cä\82Å\82«\82È\82¢\81D",
3451                           Adjmonnam(mon,"\96Ú\82Ì\8c©\82¦\82È\82¢"));
3452 #endif
3453                     if (!rn2(500))
3454                         change_luck(-1);
3455                 }
3456             } else if (Free_action) {
3457 /*JP
3458                 You("momentarily stiffen.");
3459 */
3460                 You("\88ê\8fu\8dd\92¼\82µ\82½\81D");
3461             } else { /* gelatinous cube */
3462 /*JP
3463                 You("are frozen by %s!", mon_nam(mon));
3464 */
3465                 You("%s\82É\82æ\82Á\82Ä\93®\82¯\82È\82­\82È\82Á\82½\81I", mon_nam(mon));
3466                 nomovemsg = You_can_move_again;
3467                 nomul(-tmp);
3468 /*JP
3469                 multi_reason = "frozen by a monster";
3470 */
3471                 multi_reason = "\89ö\95¨\82É\82æ\82Á\82Ä\8dd\92¼\82µ\82Ä\82¢\82é\8e\9e\82É";
3472                 exercise(A_DEX, FALSE);
3473             }
3474             break;
3475         case AD_COLD: /* brown mold or blue jelly */
3476             if (monnear(mon, u.ux, u.uy)) {
3477                 if (Cold_resistance) {
3478                     shieldeff(u.ux, u.uy);
3479 /*JP
3480                     You_feel("a mild chill.");
3481 */
3482                     You("\8a¦\82³\82ð\8a´\82\82½\81D");
3483                     ugolemeffects(AD_COLD, tmp);
3484                     break;
3485                 }
3486 /*JP
3487                 You("are suddenly very cold!");
3488 */
3489                 You("\93Ë\91R\81C\96Ò\97ó\82É\8a¦\82­\82È\82Á\82½\81I");
3490                 mdamageu(mon, tmp);
3491                 /* monster gets stronger with your heat! */
3492                 mon->mhp += tmp / 2;
3493                 if (mon->mhpmax < mon->mhp)
3494                     mon->mhpmax = mon->mhp;
3495                 /* at a certain point, the monster will reproduce! */
3496                 if (mon->mhpmax > ((int) (mon->m_lev + 1) * 8))
3497                     (void) split_mon(mon, &youmonst);
3498             }
3499             break;
3500         case AD_STUN: /* specifically yellow mold */
3501             if (!Stunned)
3502                 make_stunned((long) tmp, TRUE);
3503             break;
3504         case AD_FIRE:
3505             if (monnear(mon, u.ux, u.uy)) {
3506                 if (Fire_resistance) {
3507                     shieldeff(u.ux, u.uy);
3508 /*JP
3509                     You_feel("mildly warm.");
3510 */
3511                     You("\92g\82©\82³\82ð\8a´\82\82½\81D");
3512                     ugolemeffects(AD_FIRE, tmp);
3513                     break;
3514                 }
3515 /*JP
3516                 You("are suddenly very hot!");
3517 */
3518                 You("\93Ë\91R\81C\96Ò\97ó\82É\94M\82­\82È\82Á\82½\81I");
3519                 mdamageu(mon, tmp); /* fire damage */
3520             }
3521             break;
3522         case AD_ELEC:
3523             if (Shock_resistance) {
3524                 shieldeff(u.ux, u.uy);
3525 /*JP
3526                 You_feel("a mild tingle.");
3527 */
3528                 You("\83s\83\8a\83s\83\8a\82Æá\83\82ê\82ð\8a´\82\82½\81D");
3529                 ugolemeffects(AD_ELEC, tmp);
3530                 break;
3531             }
3532 /*JP
3533             You("are jolted with electricity!");
3534 */
3535             You("\93d\8bC\83V\83\87\83b\83N\82ð\82¤\82¯\82½\81I");
3536             mdamageu(mon, tmp);
3537             break;
3538         default:
3539             break;
3540         }
3541     }
3542     return (malive | mhit);
3543 }
3544
3545 /*
3546  * Special (passive) attacks on an attacking object by monsters done here.
3547  * Assumes the attack was successful.
3548  */
3549 void
3550 passive_obj(mon, obj, mattk)
3551 struct monst *mon;
3552 struct obj *obj;          /* null means pick uwep, uswapwep or uarmg */
3553 struct attack *mattk;     /* null means we find one internally */
3554 {
3555     struct permonst *ptr = mon->data;
3556     int i;
3557
3558     /* [this first bit is obsolete; we're not called with Null anymore] */
3559     /* if caller hasn't specified an object, use uwep, uswapwep or uarmg */
3560     if (!obj) {
3561         obj = (u.twoweap && uswapwep && !rn2(2)) ? uswapwep : uwep;
3562         if (!obj && mattk->adtyp == AD_ENCH)
3563             obj = uarmg; /* no weapon? then must be gloves */
3564         if (!obj)
3565             return; /* no object to affect */
3566     }
3567
3568     /* if caller hasn't specified an attack, find one */
3569     if (!mattk) {
3570         for (i = 0;; i++) {
3571             if (i >= NATTK)
3572                 return; /* no passive attacks */
3573             if (ptr->mattk[i].aatyp == AT_NONE)
3574                 break; /* try this one */
3575         }
3576         mattk = &(ptr->mattk[i]);
3577     }
3578
3579     switch (mattk->adtyp) {
3580     case AD_FIRE:
3581         if (!rn2(6) && !mon->mcan
3582             /* steam vortex: fire resist applies, fire damage doesn't */
3583             && mon->data != &mons[PM_STEAM_VORTEX]) {
3584             (void) erode_obj(obj, NULL, ERODE_BURN, EF_NONE);
3585         }
3586         break;
3587     case AD_ACID:
3588         if (!rn2(6)) {
3589             (void) erode_obj(obj, NULL, ERODE_CORRODE, EF_GREASE);
3590         }
3591         break;
3592     case AD_RUST:
3593         if (!mon->mcan) {
3594             (void) erode_obj(obj, (char *) 0, ERODE_RUST, EF_GREASE);
3595         }
3596         break;
3597     case AD_CORR:
3598         if (!mon->mcan) {
3599             (void) erode_obj(obj, (char *) 0, ERODE_CORRODE, EF_GREASE);
3600         }
3601         break;
3602     case AD_ENCH:
3603         if (!mon->mcan) {
3604             if (drain_item(obj, TRUE) && carried(obj)
3605                 && (obj->known || obj->oclass == ARMOR_CLASS)) {
3606 /*JP
3607                 pline("%s less effective.", Yobjnam2(obj, "seem"));
3608 */
3609                 Your("%s\82©\82ç\96\82\97Í\82ª\8fÁ\82¦\82½\82æ\82¤\82¾\81D", xname(obj));
3610             }
3611             break;
3612         }
3613     default:
3614         break;
3615     }
3616
3617     if (carried(obj))
3618         update_inventory();
3619 }
3620
3621 /* Note: caller must ascertain mtmp is mimicking... */
3622 void
3623 stumble_onto_mimic(mtmp)
3624 struct monst *mtmp;
3625 {
3626 /*JP
3627     const char *fmt = "Wait!  That's %s!", *generic = "a monster", *what = 0;
3628 */
3629     const char *fmt = "\82¿\82å\82Á\82Æ\82Ü\82Á\82½\81I%s\82¾\81I", *generic = "\89ö\95¨", *what = 0;
3630
3631     if (!u.ustuck && !mtmp->mflee && dmgtype(mtmp->data, AD_STCK))
3632         u.ustuck = mtmp;
3633
3634     if (Blind) {
3635         if (!Blind_telepat)
3636             what = generic; /* with default fmt */
3637         else if (M_AP_TYPE(mtmp) == M_AP_MONSTER)
3638             what = a_monnam(mtmp); /* differs from what was sensed */
3639     } else {
3640         int glyph = levl[u.ux + u.dx][u.uy + u.dy].glyph;
3641
3642         if (glyph_is_cmap(glyph) && (glyph_to_cmap(glyph) == S_hcdoor
3643                                      || glyph_to_cmap(glyph) == S_vcdoor))
3644 /*JP
3645             fmt = "The door actually was %s!";
3646 */
3647             fmt = "\94à\82Í\8eÀ\8dÛ\82É\82Í%s\82¾\82Á\82½\81I";
3648         else if (glyph_is_object(glyph) && glyph_to_obj(glyph) == GOLD_PIECE)
3649 /*JP
3650             fmt = "That gold was %s!";
3651 */
3652             fmt = "\8bà\89Ý\82Í%s\82¾\82Á\82½\81I";
3653
3654         /* cloned Wiz starts out mimicking some other monster and
3655            might make himself invisible before being revealed */
3656         if (mtmp->minvis && !See_invisible)
3657             what = generic;
3658         else
3659             what = a_monnam(mtmp);
3660     }
3661     if (what)
3662         pline(fmt, what);
3663
3664     wakeup(mtmp, FALSE); /* clears mimicking */
3665     /* if hero is blind, wakeup() won't display the monster even though
3666        it's no longer concealed */
3667     if (!canspotmon(mtmp)
3668         && !glyph_is_invisible(levl[mtmp->mx][mtmp->my].glyph))
3669         map_invisible(mtmp->mx, mtmp->my);
3670 }
3671
3672 STATIC_OVL void
3673 nohandglow(mon)
3674 struct monst *mon;
3675 {
3676     char *hands = makeplural(body_part(HAND));
3677
3678     if (!u.umconf || mon->mconf)
3679         return;
3680     if (u.umconf == 1) {
3681         if (Blind)
3682 /*JP
3683             Your("%s stop tingling.", hands);
3684 */
3685             Your("%s\82Ìá\83\82ê\82ª\82Æ\82ê\82½\81D", hands);
3686         else
3687 /*JP
3688             Your("%s stop glowing %s.", hands, hcolor(NH_RED));
3689 */
3690             Your("%s\82Ì%s\8bP\82«\82Í\82È\82­\82È\82Á\82½\81D", hands, hcolor(NH_RED));
3691     } else {
3692         if (Blind)
3693 /*JP
3694             pline_The("tingling in your %s lessens.", hands);
3695 */
3696             pline("%s\82Ìá\83\82ê\82ª\82Æ\82ê\82Ä\82«\82½\81D",hands);
3697         else
3698 /*JP
3699             Your("%s no longer glow so brightly %s.", hands, hcolor(NH_RED));
3700 */
3701             Your("%s\82Ì%s\8bP\82«\82ª\82È\82­\82È\82Á\82Ä\82«\82½\81D",hands, hcolor(NH_RED));
3702     }
3703     u.umconf--;
3704 }
3705
3706 int
3707 flash_hits_mon(mtmp, otmp)
3708 struct monst *mtmp;
3709 struct obj *otmp; /* source of flash */
3710 {
3711     int tmp, amt, res = 0, useeit = canseemon(mtmp);
3712
3713     if (mtmp->msleeping) {
3714         mtmp->msleeping = 0;
3715         if (useeit) {
3716 /*JP
3717             pline_The("flash awakens %s.", mon_nam(mtmp));
3718 */
3719             pline("\91M\8cõ\82Å%s\82ª\96Ú\82ð\8ao\82Ü\82µ\82½\81D", mon_nam(mtmp));
3720             res = 1;
3721         }
3722     } else if (mtmp->data->mlet != S_LIGHT) {
3723         if (!resists_blnd(mtmp)) {
3724             tmp = dist2(otmp->ox, otmp->oy, mtmp->mx, mtmp->my);
3725             if (useeit) {
3726 /*JP
3727                 pline("%s is blinded by the flash!", Monnam(mtmp));
3728 */
3729                 pline("%s\82Í\91M\8cõ\82Å\96Ú\82ª\8c©\82¦\82È\82­\82È\82Á\82½\81I", Monnam(mtmp));
3730                 res = 1;
3731             }
3732             if (mtmp->data == &mons[PM_GREMLIN]) {
3733                 /* Rule #1: Keep them out of the light. */
3734                 amt = otmp->otyp == WAN_LIGHT ? d(1 + otmp->spe, 4)
3735                                               : rn2(min(mtmp->mhp, 4));
3736                 light_hits_gremlin(mtmp, amt);
3737             }
3738             if (!DEADMONSTER(mtmp)) {
3739                 if (!context.mon_moving)
3740                     setmangry(mtmp, TRUE);
3741                 if (tmp < 9 && !mtmp->isshk && rn2(4))
3742                     monflee(mtmp, rn2(4) ? rnd(100) : 0, FALSE, TRUE);
3743                 mtmp->mcansee = 0;
3744                 mtmp->mblinded = (tmp < 3) ? 0 : rnd(1 + 50 / tmp);
3745             }
3746         }
3747     }
3748     return res;
3749 }
3750
3751 void
3752 light_hits_gremlin(mon, dmg)
3753 struct monst *mon;
3754 int dmg;
3755 {
3756 #if 0 /*JP:T*/
3757     pline("%s %s!", Monnam(mon),
3758           (dmg > mon->mhp / 2) ? "wails in agony" : "cries out in pain");
3759 #else
3760     pline("%s\82Í%s\81I", Monnam(mon),
3761           (dmg > mon->mhp / 2) ? "\8bê\92É\82Ì\90º\82ð\82 \82°\82½" : "\8c\83\92É\82Å\8b©\82ñ\82¾");
3762 #endif
3763     mon->mhp -= dmg;
3764     wake_nearto(mon->mx, mon->my, 30);
3765     if (DEADMONSTER(mon)) {
3766         if (context.mon_moving)
3767             monkilled(mon, (char *) 0, AD_BLND);
3768         else
3769             killed(mon);
3770     } else if (cansee(mon->mx, mon->my) && !canspotmon(mon)) {
3771         map_invisible(mon->mx, mon->my);
3772     }
3773 }
3774
3775 /*uhitm.c*/