OSDN Git Service

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