OSDN Git Service

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