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. */
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. */
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,
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 *));
32 extern boolean notonhead; /* for long worms */
34 /* Used to flag attacks caused by Stormbringer's maliciousness. */
35 static boolean override_confirmation = FALSE;
37 #define PROJECTILE(obj) ((obj) && is_ammo(obj))
40 erode_armor(mdef, hurt)
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.
55 target = which_armor(mdef, W_ARMH);
57 || erode_obj(target, xname(target), hurt, EF_GREASE)
62 target = which_armor(mdef, W_ARMC);
64 (void) erode_obj(target, xname(target), hurt,
65 EF_GREASE | EF_VERBOSE);
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);
78 target = which_armor(mdef, W_ARMS);
80 || erode_obj(target, xname(target), hurt, EF_GREASE)
85 target = which_armor(mdef, W_ARMG);
87 || erode_obj(target, xname(target), hurt, EF_GREASE)
92 target = which_armor(mdef, W_ARMF);
94 || erode_obj(target, xname(target), hurt, EF_GREASE)
99 break; /* Out of while loop */
103 /* FALSE means it's OK to attack */
105 attack_checks(mtmp, wep)
106 register struct monst *mtmp;
107 struct obj *wep; /* uwep for attack(), null for kick_monster() */
111 /* if you're close enough to attack, alert any waiting monster */
112 mtmp->mstrategy &= ~STRAT_WAITMASK;
114 if (u.uswallow && mtmp == u.ustuck)
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);
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);
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.
146 if (!canspotmon(mtmp)
147 && !glyph_is_warning(glyph) && !glyph_is_invisible(glyph)
148 && !(!Blind && mtmp->mundetected && hides_under(mtmp->data))) {
150 pline("Wait! There's %s there you can't see!", something);
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
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))
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.
169 wakeup(mtmp, TRUE); /* always necessary; also un-mimics mimics */
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.
179 if (glyph_is_invisible(glyph)) {
183 stumble_onto_mimic(mtmp);
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)) {
196 if (!((Blind ? Blind_telepat : Unblind_telepat) || Detect_monsters)) {
199 if (!Blind && Hallucination)
201 pline("A %s %s appeared!",
202 mtmp->mtame ? "tame" : "wild", l_monnam(mtmp));
204 pline("%s%s
\82ª
\8c»
\82ê
\82½
\81I",
205 mtmp->mtame ? "
\8eè
\82È
\82Ã
\82¯
\82ç
\82ê
\82½" : "
\96ì
\90¶
\82Ì", l_monnam(mtmp));
207 else if (Blind || (is_pool(mtmp->mx, mtmp->my) && !Underwater))
209 pline("Wait! There's a hidden monster there!");
211 pline("
\91Ò
\82Ä
\81I
\89ö
\95¨
\82ª
\89B
\82ê
\82Ä
\82¢
\82é
\81I");
212 else if ((obj = level.objects[mtmp->mx][mtmp->my]) != 0)
214 pline("Wait! There's %s hiding under %s!",
215 an(l_monnam(mtmp)), doname(obj));
217 pline("
\91Ò
\82Ä
\81I%s
\82Ì
\89º
\82É%s
\82ª
\89B
\82ê
\82Ä
\82¢
\82é
\81I",
218 doname(obj), l_monnam(mtmp));
225 * make sure to wake up a monster from the above cases if the
226 * hero can sense that the monster is there.
228 if ((mtmp->mundetected || M_AP_TYPE(mtmp)) && sensemon(mtmp)) {
229 mtmp->mundetected = 0;
233 if (flags.confirm && mtmp->mpeaceful
234 && !Confusion && !Hallucination && !Stunned) {
235 /* Intelligent chaotic weapons (Stormbringer) want blood */
236 if (wep && wep->oartifact == ART_STORMBRINGER) {
237 override_confirmation = TRUE;
240 if (canspotmon(mtmp)) {
244 Sprintf(qbuf, "Really attack %s?", mon_nam(mtmp));
246 Sprintf(qbuf, "
\96{
\93\96\82É%s
\82ð
\8dU
\8c\82\82·
\82é
\82Ì
\81H", mon_nam(mtmp));
247 if (!paranoid_query(ParanoidHit, qbuf)) {
258 * It is unchivalrous for a knight to attack the defenseless or from behind.
264 if (u.ualign.record <= -10)
267 if (Role_if(PM_KNIGHT) && u.ualign.type == A_LAWFUL
268 && (!mtmp->mcanmove || mtmp->msleeping
269 || (mtmp->mflee && !mtmp->mavenge))) {
273 pline("
\82±
\82ê
\82Í
\94Ú
\8b¯
\82È
\8ds
\82¢
\82¾
\81I");
275 } else if (Role_if(PM_SAMURAI) && mtmp->mpeaceful) {
276 /* attacking peaceful creatures is bad for the samurai's giri */
278 You("dishonorably attack the innocent!");
280 pline("
\96³
\8eÀ
\82Ì
\8eÒ
\82ð
\8dU
\8c\82\82·
\82é
\82Ì
\82Í
\95s
\96¼
\97_
\82¾
\81I");
286 find_roll_to_hit(mtmp, aatyp, weapon, attk_count, role_roll_penalty)
287 register struct monst *mtmp;
288 uchar aatyp; /* usually AT_WEAP or AT_KICK */
289 struct obj *weapon; /* uwep or uswapwep or NULL */
290 int *attk_count, *role_roll_penalty;
294 *role_roll_penalty = 0; /* default is `none' */
296 tmp = 1 + Luck + abon() + find_mac(mtmp) + u.uhitinc
297 + maybe_polyd(youmonst.data->mlevel, u.ulevel);
299 /* some actions should occur only once during multiple attacks */
300 if (!(*attk_count)++) {
301 /* knight's chivalry or samurai's giri */
305 /* adjust vs. (and possibly modify) monster state */
311 if (mtmp->msleeping) {
315 if (!mtmp->mcanmove) {
323 /* role/race adjustments */
324 if (Role_if(PM_MONK) && !Upolyd) {
326 tmp -= (*role_roll_penalty = urole.spelarmr);
327 else if (!uwep && !uarms)
328 tmp += (u.ulevel / 3) + 2;
330 if (is_orc(mtmp->data)
331 && maybe_polyd(is_elf(youmonst.data), Race_if(PM_ELF)))
334 /* encumbrance: with a lot of luggage, your agility diminishes */
335 if ((tmp2 = near_capacity()) != 0)
336 tmp -= (tmp2 * 2) - 1;
341 * hitval applies if making a weapon attack while wielding a weapon;
342 * weapon_hit_bonus applies if doing a weapon attack even bare-handed
343 * or if kicking as martial artist
345 if (aatyp == AT_WEAP || aatyp == AT_CLAW) {
347 tmp += hitval(weapon, mtmp);
348 tmp += weapon_hit_bonus(weapon);
349 } else if (aatyp == AT_KICK && martial_bonus()) {
350 tmp += weapon_hit_bonus((struct obj *) 0);
356 /* try to attack; return False if monster evaded;
357 u.dx and u.dy must be set */
360 register struct monst *mtmp;
362 register struct permonst *mdat = mtmp->data;
364 /* This section of code provides protection against accidentally
365 * hitting peaceful (like '@') and tame (like 'd') monsters.
366 * Protection is provided as long as player is not: blind, confused,
367 * hallucinating or stunned.
368 * changes by wwp 5/16/85
369 * More changes 12/90, -dkh-. if its tame and safepet, (and protected
370 * 07/92) then we assume that you're not trying to attack. Instead,
371 * you'll usually just swap places if this is a movement command
373 /* Intelligent chaotic weapons (Stormbringer) want blood */
374 if (is_safepet(mtmp) && !context.forcefight) {
375 if (!uwep || uwep->oartifact != ART_STORMBRINGER) {
376 /* There are some additional considerations: this won't work
377 * if in a shop or Punished or you miss a random roll or
378 * if you can walk thru walls and your pet cannot (KAA) or
379 * if your pet is a long worm with a tail.
380 * There's also a chance of displacing a "frozen" monster:
381 * sleeping monsters might magically walk in their sleep.
383 boolean foo = (Punished || !rn2(7)
384 || (is_longworm(mtmp->data) && mtmp->wormno)),
388 /* only check for in-shop if don't already have reason to stop */
390 for (p = in_rooms(mtmp->mx, mtmp->my, SHOPBASE); *p; p++)
391 if (tended_shop(&rooms[*p - ROOMOFFSET])) {
396 if (inshop || foo || (IS_ROCK(levl[u.ux][u.uy].typ)
397 && !passes_walls(mtmp->data))) {
400 monflee(mtmp, rnd(6), FALSE, FALSE);
401 Strcpy(buf, y_monnam(mtmp));
402 buf[0] = highc(buf[0]);
404 You("stop. %s is in the way!", buf);
406 You("
\8e~
\82Ü
\82Á
\82½
\81D%s
\82ª
\93¹
\82É
\82¢
\82é
\81I", buf);
407 context.travel = context.travel1 = context.mv = context.run
410 } else if ((mtmp->mfrozen || (!mtmp->mcanmove)
411 || (mtmp->data->mmove == 0)) && rn2(6)) {
413 pline("%s doesn't seem to move!", Monnam(mtmp));
415 pline("%s
\82Í
\93®
\82¯
\82È
\82¢
\82æ
\82¤
\82¾
\81I", Monnam(mtmp));
416 context.travel = context.travel1 = context.mv = context.run
424 /* possibly set in attack_checks;
425 examined in known_hitum, called via hitum or hmonas below */
426 override_confirmation = FALSE;
427 /* attack_checks() used to use <u.ux+u.dx,u.uy+u.dy> directly, now
428 it uses bhitpos instead; it might map an invisible monster there */
429 bhitpos.x = u.ux + u.dx;
430 bhitpos.y = u.uy + u.dy;
431 notonhead = (bhitpos.x != mtmp->mx || bhitpos.y != mtmp->my);
432 if (attack_checks(mtmp, uwep))
435 if (Upolyd && noattacks(youmonst.data)) {
436 /* certain "pacifist" monsters don't attack */
438 You("have no way to attack monsters physically.");
440 You("
\95¨
\97\9d\93I
\82É
\89ö
\95¨
\82ð
\8dU
\8c\82\82·
\82é
\82·
\82×
\82ª
\82È
\82¢
\81D");
441 mtmp->mstrategy &= ~STRAT_WAITMASK;
446 if (check_capacity("You cannot fight while so heavily loaded.")
448 if (check_capacity("
\82 \82È
\82½
\82Í
\95¨
\82ð
\82½
\82
\82³
\82ñ
\8e\9d\82¿
\82·
\82¬
\82Ä
\90í
\82¦
\82È
\82¢
\81D")
449 /* consume extra nutrition during combat; maybe pass out */
453 if (u.twoweap && !can_twoweapon())
461 You("begin bashing monsters with %s.", yname(uwep));
463 You("%s
\82Å
\89ö
\95¨
\82ð
\82È
\82®
\82è
\82Â
\82¯
\82½
\81D", yname(uwep));
464 else if (!cantwield(youmonst.data))
466 You("begin %s monsters with your %s %s.",
467 ing_suffix(Role_if(PM_MONK) ? "strike" : "bash"),
468 uarmg ? "gloved" : "bare", /* Del Lamb */
469 makeplural(body_part(HAND)));
471 You("%s%s
\82Å
\89ö
\95¨
\82ð%s
\82Â
\82¯
\82½
\81D",
472 uarmg ? "
\83O
\83\8d\81[
\83u
\82ð
\95t
\82¯
\82½" : "
\91f",
474 Role_if(PM_MONK) ? "
\91Å
\82¿" : "
\82È
\82®
\82è");
478 exercise(A_STR, TRUE); /* you're exercising muscles */
479 /* andrew@orca: prevent unlimited pick-axe attacks */
482 /* Is the "it died" check actually correct? */
483 if (mdat->mlet == S_LEPRECHAUN && !mtmp->mfrozen && !mtmp->msleeping
484 && !mtmp->mconf && mtmp->mcansee && !rn2(7)
485 && (m_move(mtmp, 0) == 2 /* it died */
486 || mtmp->mx != u.ux + u.dx
487 || mtmp->my != u.uy + u.dy)) { /* it moved */
489 You("miss wildly and stumble forwards.");
491 You("
\91å
\82«
\82
\8aO
\82µ
\82Ä
\91O
\82É
\82Â
\82Ü
\82Ã
\82¢
\82½
\81D");
498 (void) hitum(mtmp, youmonst.data->mattk);
499 mtmp->mstrategy &= ~STRAT_WAITMASK;
502 /* see comment in attack_checks() */
503 /* we only need to check for this if we did an attack_checks()
504 * and it returned 0 (it's okay to attack), and the monster didn't
507 if (context.forcefight && !DEADMONSTER(mtmp) && !canspotmon(mtmp)
508 && !glyph_is_invisible(levl[u.ux + u.dx][u.uy + u.dy].glyph)
509 && !(u.uswallow && mtmp == u.ustuck))
510 map_invisible(u.ux + u.dx, u.uy + u.dy);
515 /* really hit target monster; returns TRUE if it still lives */
517 known_hitum(mon, weapon, mhit, rollneeded, armorpenalty, uattk, dieroll)
518 register struct monst *mon;
521 int rollneeded, armorpenalty; /* for monks */
522 struct attack *uattk;
525 boolean malive = TRUE,
526 /* hmon() might destroy weapon; remember aspect for cutworm */
527 slice_or_chop = (weapon && (is_blade(weapon) || is_axe(weapon)));
529 if (override_confirmation) {
530 /* this may need to be generalized if weapons other than
531 Stormbringer acquire similar anti-social behavior... */
534 Your("bloodthirsty blade attacks!");
536 Your("
\95\90\8aí
\82Í
\8c\8c\82É
\8bQ
\82¦
\82Ä
\82¢
\82é
\81I");
540 missum(mon, uattk, (rollneeded + armorpenalty > dieroll));
542 int oldhp = mon->mhp;
543 long oldweaphit = u.uconduct.weaphit;
546 if (weapon && (weapon->oclass == WEAPON_CLASS || is_weptool(weapon)))
547 u.uconduct.weaphit++;
549 /* we hit the monster; be careful: it might die or
550 be knocked into a different location */
551 notonhead = (mon->mx != bhitpos.x || mon->my != bhitpos.y);
552 malive = hmon(mon, weapon, HMON_MELEE, dieroll);
554 /* monster still alive */
555 if (!rn2(25) && mon->mhp < mon->mhpmax / 2
556 && !(u.uswallow && mon == u.ustuck)) {
557 /* maybe should regurgitate if swallowed? */
558 monflee(mon, !rn2(3) ? rnd(100) : 0, FALSE, TRUE);
560 if (u.ustuck == mon && !u.uswallow && !sticks(youmonst.data))
563 /* Vorpal Blade hit converted to miss */
564 /* could be headless monster or worm tail */
565 if (mon->mhp == oldhp) {
567 /* a miss does not break conduct */
568 u.uconduct.weaphit = oldweaphit;
570 if (mon->wormno && *mhit)
571 cutworm(mon, bhitpos.x, bhitpos.y, slice_or_chop);
577 /* hit the monster next to you and the monsters to the left and right of it;
578 return False if the primary target is killed, True otherwise */
580 hitum_cleave(target, uattk)
581 struct monst *target; /* non-Null; forcefight at nothing doesn't cleave... */
582 struct attack *uattk; /* ... but we don't enforce that here; Null works ok */
584 /* swings will be delivered in alternate directions; with consecutive
585 attacks it will simulate normal swing and backswing; when swings
586 are non-consecutive, hero will sometimes start a series of attacks
587 with a backswing--that doesn't impact actual play, just spoils the
588 simulation attempt a bit */
589 static boolean clockwise = FALSE;
592 int count, umort, x = u.ux, y = u.uy;
594 /* find the direction toward primary target */
595 for (i = 0; i < 8; ++i)
596 if (xdir[i] == u.dx && ydir[i] == u.dy)
599 impossible("hitum_cleave: unknown target direction [%d,%d,%d]?",
601 return TRUE; /* target hasn't been killed */
603 /* adjust direction by two so that loop's increment (for clockwise)
604 or decrement (for counter-clockwise) will point at the spot next
606 i = (i + (clockwise ? 6 : 2)) % 8;
607 umort = u.umortality; /* used to detect life-saving */
608 save_bhitpos = bhitpos;
611 * Three attacks: adjacent to primary, primary, adjacent on other
612 * side. Primary target must be present or we wouldn't have gotten
613 * here (forcefight at thin air won't 'cleave'). However, the
614 * first attack might kill it (gas spore explosion, weak long worm
615 * occupying both spots) so we don't assume that it's still present
616 * on the second attack.
618 for (count = 3; count > 0; --count) {
620 int tx, ty, tmp, dieroll, mhit, attknum, armorpenalty;
622 /* ++i, wrap 8 to i=0 /or/ --i, wrap -1 to i=7 */
623 i = (i + (clockwise ? 1 : 7)) % 8;
625 tx = x + xdir[i], ty = y + ydir[i]; /* current target location */
630 if (glyph_is_invisible(levl[tx][ty].glyph))
631 (void) unmap_invisible(tx, ty);
635 tmp = find_roll_to_hit(mtmp, uattk->aatyp, uwep,
636 &attknum, &armorpenalty);
638 mhit = (tmp > dieroll);
639 bhitpos.x = tx, bhitpos.y = ty; /* normally set up by attack() */
640 (void) known_hitum(mtmp, uwep, &mhit, tmp, armorpenalty,
642 (void) passive(mtmp, uwep, mhit, !DEADMONSTER(mtmp), AT_WEAP, !uwep);
644 /* stop attacking if weapon is gone or hero got killed and
645 life-saved after passive counter-attack */
646 if (!uwep || u.umortality > umort)
649 /* set up for next time */
650 clockwise = !clockwise; /* alternate */
651 bhitpos = save_bhitpos; /* in case somebody relies on bhitpos
652 * designating the primary target */
654 /* return False if primary target died, True otherwise; note: if 'target'
655 was nonNull upon entry then it's still nonNull even if *target died */
656 return (target && DEADMONSTER(target)) ? FALSE : TRUE;
659 /* hit target monster; returns TRUE if it still lives */
663 struct attack *uattk;
665 boolean malive, wep_was_destroyed = FALSE;
666 struct obj *wepbefore = uwep;
667 int armorpenalty, attknum = 0, x = u.ux + u.dx, y = u.uy + u.dy,
668 tmp = find_roll_to_hit(mon, uattk->aatyp, uwep,
669 &attknum, &armorpenalty);
670 int dieroll = rnd(20);
671 int mhit = (tmp > dieroll || u.uswallow);
673 /* Cleaver attacks three spots, 'mon' and one on either side of 'mon';
674 it can't be part of dual-wielding but we guard against that anyway;
675 cleave return value reflects status of primary target ('mon') */
676 if (uwep && uwep->oartifact == ART_CLEAVER && !u.twoweap
677 && !u.uswallow && !u.ustuck && !NODIAG(u.umonnum))
678 return hitum_cleave(mon, uattk);
681 exercise(A_DEX, TRUE);
682 /* bhitpos is set up by caller */
683 malive = known_hitum(mon, uwep, &mhit, tmp, armorpenalty, uattk, dieroll);
684 if (wepbefore && !uwep)
685 wep_was_destroyed = TRUE;
686 (void) passive(mon, uwep, mhit, malive, AT_WEAP, wep_was_destroyed);
688 /* second attack for two-weapon combat; won't occur if Stormbringer
689 overrode confirmation (assumes Stormbringer is primary weapon)
690 or if the monster was killed or knocked to different location */
691 if (u.twoweap && !override_confirmation && malive && m_at(x, y) == mon) {
692 tmp = find_roll_to_hit(mon, uattk->aatyp, uswapwep, &attknum,
695 mhit = (tmp > dieroll || u.uswallow);
696 malive = known_hitum(mon, uswapwep, &mhit, tmp, armorpenalty, uattk,
698 /* second passive counter-attack only occurs if second attack hits */
700 (void) passive(mon, uswapwep, mhit, malive, AT_WEAP, !uswapwep);
705 /* general "damage monster" routine; return True if mon still alive */
707 hmon(mon, obj, thrown, dieroll)
710 int thrown; /* HMON_xxx (0 => hand-to-hand, other => ranged) */
713 boolean result, anger_guards;
715 anger_guards = (mon->mpeaceful
716 && (mon->ispriest || mon->isshk || is_watch(mon->data)));
717 result = hmon_hitmon(mon, obj, thrown, dieroll);
718 if (mon->ispriest && !rn2(2))
721 (void) angry_guards(!!Deaf);
727 hmon_hitmon(mon, obj, thrown, dieroll)
730 int thrown; /* HMON_xxx (0 => hand-to-hand, other => ranged) */
734 struct permonst *mdat = mon->data;
735 int barehand_silver_rings = 0;
736 /* The basic reason we need all these booleans is that we don't want
737 * a "hit" message when a monster dies, so we have to know how much
738 * damage it did _before_ outputting a hit message, but any messages
739 * associated with the damage don't come out until _after_ outputting
742 boolean hittxt = FALSE, destroyed = FALSE, already_killed = FALSE;
743 boolean get_dmg_bonus = TRUE;
744 boolean ispoisoned = FALSE, needpoismsg = FALSE, poiskilled = FALSE,
746 boolean silvermsg = FALSE, silverobj = FALSE;
747 boolean lightobj = FALSE;
748 boolean valid_weapon_attack = FALSE;
749 boolean unarmed = !uwep && !uarm && !uarms;
750 boolean hand_to_hand = (thrown == HMON_MELEE
751 /* not grapnels; applied implies uwep */
752 || (thrown == HMON_APPLIED && is_pole(uwep)));
758 char unconventional[BUFSZ]; /* substituted for word "attack" in msg */
760 char saved_oname[BUFSZ];
763 unconventional[0] = '\0';
765 saved_oname[0] = '\0';
768 if (!obj) { /* attack with bare hands */
769 if (mdat == &mons[PM_SHADE])
771 else if (martial_bonus())
772 tmp = rnd(4); /* bonus for martial arts */
775 valid_weapon_attack = (tmp > 1);
776 /* Blessed gloves give bonuses when fighting 'bare-handed'. So do
777 silver rings. Note: rings are worn under gloves, so you don't
778 get both bonuses, and two silver rings don't give double bonus. */
779 tmp += special_dmgval(&youmonst, mon, (W_ARMG | W_RINGL | W_RINGR),
781 barehand_silver_rings += (((silverhit & W_RINGL) ? 1 : 0)
782 + ((silverhit & W_RINGR) ? 1 : 0));
783 if (barehand_silver_rings > 0)
786 if (!(artifact_light(obj) && obj->lamplit))
787 Strcpy(saved_oname, cxname(obj));
789 Strcpy(saved_oname, bare_artifactname(obj));
790 if (obj->oclass == WEAPON_CLASS || is_weptool(obj)
791 || obj->oclass == GEM_CLASS) {
792 /* is it not a melee weapon? */
793 if (/* if you strike with a bow... */
795 /* or strike with a missile in your hand... */
796 || (!thrown && (is_missile(obj) || is_ammo(obj)))
797 /* or use a pole at short range and not mounted... */
798 || (!thrown && !u.usteed && is_pole(obj))
799 /* or throw a missile without the proper bow... */
800 || (is_ammo(obj) && (thrown != HMON_THROWN
801 || !ammo_and_launcher(obj, uwep)))) {
802 /* then do only 1-2 points of damage */
803 if (mdat == &mons[PM_SHADE] && !shade_glare(obj))
807 if (objects[obj->otyp].oc_material == SILVER
808 && mon_hates_silver(mon)) {
811 /* if it will already inflict dmg, make it worse */
812 tmp += rnd((tmp) ? 20 : 10);
814 if (!thrown && obj == uwep && obj->otyp == BOOMERANG
815 && rnl(4) == 4 - 1) {
816 boolean more_than_1 = (obj->quan > 1L);
819 pline("As you hit %s, %s%s breaks into splinters.",
820 mon_nam(mon), more_than_1 ? "one of " : "",
823 pline("%s
\82ð
\8dU
\8c\82\82·
\82é
\82Æ
\81C%s%s
\82Í
\82±
\82Á
\82Ï
\82Ý
\82¶
\82ñ
\82É
\82È
\82Á
\82½
\81D",
824 mon_nam(mon), yname(obj),
825 more_than_1 ? "
\82Ì
\82Ð
\82Æ
\82Â" : "");
828 uwepgone(); /* set unweapon */
831 obj = (struct obj *) 0;
833 if (mdat != &mons[PM_SHADE])
837 tmp = dmgval(obj, mon);
838 /* a minimal hit doesn't exercise proficiency */
839 valid_weapon_attack = (tmp > 1);
840 if (!valid_weapon_attack || mon == u.ustuck || u.twoweap
841 /* Cleaver can hit up to three targets at once so don't
842 let it also hit from behind or shatter foes' weapons */
843 || (hand_to_hand && obj->oartifact == ART_CLEAVER)) {
844 ; /* no special bonuses */
845 } else if (mon->mflee && Role_if(PM_ROGUE) && !Upolyd
846 /* multi-shot throwing is too powerful here */
849 You("strike %s from behind!", mon_nam(mon));
851 You("%s
\82ð
\94w
\8cã
\82©
\82ç
\8dU
\8c\82\82µ
\82½
\81I", mon_nam(mon));
852 tmp += rnd(u.ulevel);
854 } else if (dieroll == 2 && obj == uwep
855 && obj->oclass == WEAPON_CLASS
857 || (Role_if(PM_SAMURAI) && obj->otyp == KATANA
859 && ((wtype = uwep_skill_type()) != P_NONE
860 && P_SKILL(wtype) >= P_SKILLED)
861 && ((monwep = MON_WEP(mon)) != 0
862 && !is_flimsy(monwep)
863 && !obj_resists(monwep,
864 50 + 15 * (greatest_erosion(obj)
865 - greatest_erosion(monwep)),
868 * 2.5% chance of shattering defender's weapon when
869 * using a two-handed weapon; less if uwep is rusted.
870 * [dieroll == 2 is most successful non-beheading or
871 * -bisecting hit, in case of special artifact damage;
872 * the percentage chance is (1/20)*(50/100).]
873 * If attacker's weapon is rustier than defender's,
874 * the obj_resists chance is increased so the shatter
875 * chance is decreased; if less rusty, then vice versa.
877 setmnotwielded(mon, monwep);
878 mon->weapon_check = NEED_WEAPON;
880 pline("%s from the force of your blow!",
881 Yobjnam2(monwep, "shatter"));
883 pline("%s
\82Ì%s
\82Í
\82 \82È
\82½
\82Ì
\88ê
\8c\82\82Å
\95²
\81X
\82É
\82È
\82Á
\82½
\81I",
884 Monnam(mon), xname(monwep));
886 m_useupall(mon, monwep);
887 /* If someone just shattered MY weapon, I'd flee! */
889 monflee(mon, d(2, 3), TRUE, TRUE);
895 && artifact_hit(&youmonst, mon, obj, &tmp, dieroll)) {
896 if (DEADMONSTER(mon)) /* artifact killed monster */
902 if (objects[obj->otyp].oc_material == SILVER
903 && mon_hates_silver(mon)) {
907 if (artifact_light(obj) && obj->lamplit
908 && mon_hates_light(mon))
910 if (u.usteed && !thrown && tmp > 0
911 && weapon_type(obj) == P_LANCE && mon != u.ustuck) {
912 jousting = joust(mon, obj);
913 /* exercise skill even for minimal damage hits */
915 valid_weapon_attack = TRUE;
917 if (thrown == HMON_THROWN
918 && (is_ammo(obj) || is_missile(obj))) {
919 if (ammo_and_launcher(obj, uwep)) {
920 /* Elves and Samurai do extra damage using
921 * their bows&arrows; they're highly trained.
923 if (Role_if(PM_SAMURAI) && obj->otyp == YA
924 && uwep->otyp == YUMI)
926 else if (Race_if(PM_ELF) && obj->otyp == ELVEN_ARROW
927 && uwep->otyp == ELVEN_BOW)
930 if (obj->opoisoned && is_poisonable(obj))
934 } else if (obj->oclass == POTION_CLASS) {
936 obj = splitobj(obj, 1L);
938 setuwep((struct obj *) 0);
941 hand_to_hand ? POTHIT_HERO_BASH : POTHIT_HERO_THROW);
942 if (DEADMONSTER(mon))
943 return FALSE; /* killed */
945 /* in case potion effect causes transformation */
947 tmp = (mdat == &mons[PM_SHADE]) ? 0 : 1;
949 if (mdat == &mons[PM_SHADE] && !shade_aware(obj)) {
952 Strcpy(unconventional, cxname(obj));
956 case BOULDER: /* 1d20 */
957 case HEAVY_IRON_BALL: /* 1d25 */
958 case IRON_CHAIN: /* 1d4+1 */
959 tmp = dmgval(obj, mon);
962 if (breaktest(obj)) {
964 You("break %s. That's bad luck!", ysimple_name(obj));
966 You("%s
\8b¾
\82ð
\89ó
\82µ
\82Ä
\82µ
\82Ü
\82Á
\82½
\81D
\82±
\82è
\82á
\82Ü
\82¢
\82Á
\82½
\81I", ysimple_name(obj));
969 obj = (struct obj *) 0;
970 unarmed = FALSE; /* avoid obj==0 confusion */
971 get_dmg_bonus = FALSE;
976 case EXPENSIVE_CAMERA:
978 You("succeed in destroying %s. Congratulations!",
980 You("%s
\83J
\83\81\83\89\82ð
\89ó
\82·
\82±
\82Æ
\82ª
\82Å
\82«
\82½
\81D
\82¨
\82ß
\82Å
\82Æ
\82¤
\81I",
982 release_camera_demon(obj, u.ux, u.uy);
985 case CORPSE: /* fixed by polder@cs.vu.nl */
986 if (touch_petrifies(&mons[obj->corpsenm])) {
990 You("hit %s with %s.", mon_nam(mon),
991 corpse_xname(obj, (const char *) 0,
992 obj->dknown ? CXN_PFX_THE
995 You("%s
\82ð%s
\82Å
\8dU
\8c\82\82µ
\82½
\81D", mon_nam(mon),
996 corpse_xname(obj, (const char *) 0,
997 obj->dknown ? CXN_PFX_THE
1001 if (!munstone(mon, TRUE))
1002 minstapetrify(mon, TRUE);
1003 if (resists_ston(mon))
1005 /* note: hp may be <= 0 even if munstoned==TRUE */
1006 return (boolean) !DEADMONSTER(mon);
1008 } else if (touch_petrifies(mdat)) {
1009 ; /* maybe turn the corpse into a statue? */
1012 tmp = (obj->corpsenm >= LOW_PM ? mons[obj->corpsenm].msize
1016 #define useup_eggs(o) \
1019 obfree(o, (struct obj *) 0); \
1022 o = (struct obj *) 0; \
1023 } while (0) /* now gone */
1025 long cnt = obj->quan;
1027 tmp = 1; /* nominal physical damage */
1028 get_dmg_bonus = FALSE;
1029 hittxt = TRUE; /* message always given */
1030 /* egg is always either used up or transformed, so next
1031 hand-to-hand attack should yield a "bashing" mesg */
1034 if (obj->spe && obj->corpsenm >= LOW_PM) {
1036 change_luck((schar) - (obj->quan));
1041 if (touch_petrifies(&mons[obj->corpsenm])) {
1042 /*learn_egg_type(obj->corpsenm);*/
1044 pline("Splat! You hit %s with %s %s egg%s!",
1046 obj->known ? "the" : cnt > 1L ? "some" : "a",
1047 obj->known ? mons[obj->corpsenm].mname
1051 pline("
\83r
\83`
\83\83\83b
\81I
\82 \82È
\82½
\82Í%s
\82É%s%s
\82Ì
\97\91\82ð
\93\8a\82°
\82Â
\82¯
\82½
\81I",
1053 cnt > 1L ? "
\82¢
\82
\82Â
\82©
\82Ì" : "",
1054 obj->known ? mons[obj->corpsenm].mname
1057 obj->known = 1; /* (not much point...) */
1059 if (!munstone(mon, TRUE))
1060 minstapetrify(mon, TRUE);
1061 if (resists_ston(mon))
1063 return (boolean) (!DEADMONSTER(mon));
1064 } else { /* ordinary egg(s) */
1066 const char *eggp = (obj->corpsenm != NON_PM
1068 ? the(mons[obj->corpsenm].mname)
1069 : (cnt > 1L) ? "some" : "an";
1071 You("hit %s with %s egg%s.", mon_nam(mon), eggp,
1074 const char *eggp = (obj->corpsenm != NON_PM
1076 ? mons[obj->corpsenm].mname
1078 You("%s
\82É%s%s
\97\91\82ð
\93\8a\82°
\82Â
\82¯
\82½
\81D",
1079 mon_nam(mon), eggp, *eggp ? "
\82Ì" : "");
1081 if (touch_petrifies(mdat) && !stale_egg(obj)) {
1083 pline_The("egg%s %s alive any more...", plur(cnt),
1084 (cnt == 1L) ? "isn't" : "aren't");
1086 pline("
\82à
\82¤
\97\91\82ª
\9bz
\89»
\82·
\82é
\82±
\82Æ
\82Í
\82È
\82¢
\82¾
\82ë
\82¤
\81D
\81D
\81D");
1089 obj_stop_timers(obj);
1091 obj->oclass = GEM_CLASS;
1094 obj->known = obj->dknown = obj->bknown = 0;
1095 obj->owt = weight(obj);
1097 place_object(obj, mon->mx, mon->my);
1102 pline("
\83r
\83`
\83\83\83b
\81I");
1104 exercise(A_WIS, FALSE);
1110 case CLOVE_OF_GARLIC: /* no effect against demons */
1111 if (is_undead(mdat) || is_vampshifter(mon)) {
1112 monflee(mon, d(2, 4), FALSE, TRUE);
1117 case BLINDING_VENOM:
1119 if (can_blnd(&youmonst, mon,
1120 (uchar) ((obj->otyp == BLINDING_VENOM)
1126 pline(obj->otyp == CREAM_PIE ? "Splat!"
1129 pline(obj->otyp == CREAM_PIE ? "
\83r
\83V
\83\83\83b
\81I"
1130 : "
\83s
\83`
\83\83\83b
\81I");
1132 } else if (obj->otyp == BLINDING_VENOM) {
1134 pline_The("venom blinds %s%s!", mon_nam(mon),
1135 mon->mcansee ? "" : " further");
1137 pline("
\93Å
\89t
\82Å%s
\82Í%s
\96Ú
\82ª
\8c©
\82¦
\82È
\82
\82È
\82Á
\82½
\81I", mon_nam(mon),
1138 mon->mcansee ? "" : "
\82³
\82ç
\82É");
1141 char *whom = mon_nam(mon);
1142 char *what = The(xname(obj));
1144 if (!thrown && obj->quan > 1L)
1145 what = An(singular(obj, xname));
1146 /* note: s_suffix returns a modifiable buffer */
1148 && mdat != &mons[PM_FLOATING_EYE])
1150 whom = strcat(strcat(s_suffix(whom), " "),
1151 mbodypart(mon, FACE));
1153 whom = strcat(s_suffix(whom),
1154 mbodypart(mon, FACE));
1157 pline("%s %s over %s!", what,
1158 vtense(what, "splash"), whom);
1160 pline("%s
\82Í%s
\82É
\82Ô
\82¿
\82Ü
\82¯
\82ç
\82ê
\82½
\81I",
1164 setmangry(mon, TRUE);
1167 if (((int) mon->mblinded + tmp) > 127)
1168 mon->mblinded = 127;
1170 mon->mblinded += tmp;
1173 pline(obj->otyp == CREAM_PIE ? "Splat!" : "Splash!");
1175 pline(obj->otyp==CREAM_PIE ? "
\83r
\83V
\83\83\83b
\81I" : "
\83s
\83`
\83\83\83b
\81I");
1176 setmangry(mon, TRUE);
1179 obfree(obj, (struct obj *) 0);
1183 get_dmg_bonus = FALSE;
1186 case ACID_VENOM: /* thrown (or spit) */
1187 if (resists_acid(mon)) {
1189 Your("venom hits %s harmlessly.", mon_nam(mon));
1191 pline("
\93Å
\89t
\82Í%s
\82É
\82Í
\8cø
\89Ê
\82ª
\82È
\82©
\82Á
\82½
\81D", mon_nam(mon));
1195 Your("venom burns %s!", mon_nam(mon));
1197 Your("
\93Å
\89t
\82Í%s
\82ð
\8fÄ
\82¢
\82½
\81I", mon_nam(mon));
1198 tmp = dmgval(obj, mon);
1201 obfree(obj, (struct obj *) 0);
1205 get_dmg_bonus = FALSE;
1208 /* non-weapons can damage because of their weight */
1209 /* (but not too much) */
1210 tmp = obj->owt / 100;
1211 if (is_wet_towel(obj)) {
1212 /* wielded wet towel should probably use whip skill
1213 (but not by setting objects[TOWEL].oc_skill==P_WHIP
1214 because that would turn towel into a weptool) */
1216 if (rn2(obj->spe + 1)) /* usually lose some wetness */
1217 dry_a_towel(obj, -1, TRUE);
1226 * Things like silver wands can arrive here so
1227 * so we need another silver check.
1229 if (objects[obj->otyp].oc_material == SILVER
1230 && mon_hates_silver(mon)) {
1240 /****** NOTE: perhaps obj is undefined!! (if !thrown && BOOMERANG)
1241 * *OR* if attacking bare-handed!! */
1243 if (get_dmg_bonus && tmp > 0) {
1245 /* If you throw using a propellor, you don't get a strength
1246 * bonus but you do get an increase-damage bonus.
1248 if (thrown != HMON_THROWN || !obj || !uwep
1249 || !ammo_and_launcher(obj, uwep))
1253 if (valid_weapon_attack) {
1256 /* to be valid a projectile must have had the correct projector */
1257 wep = PROJECTILE(obj) ? uwep : obj;
1258 tmp += weapon_dam_bonus(wep);
1259 /* [this assumes that `!thrown' implies wielded...] */
1260 wtype = thrown ? weapon_type(wep) : uwep_skill_type();
1261 use_skill(wtype, 1);
1265 int nopoison = (10 - (obj->owt / 10));
1269 if (Role_if(PM_SAMURAI)) {
1271 You("dishonorably use a poisoned weapon!");
1273 You("
\95s
\96¼
\97_
\82É
\82à
\93Å
\82Ì
\95\90\8aí
\82ð
\8eg
\97p
\82µ
\82½
\81I");
1274 adjalign(-sgn(u.ualign.type));
1275 } else if (u.ualign.type == A_LAWFUL && u.ualign.record > -10) {
1277 You_feel("like an evil coward for using a poisoned weapon.");
1279 You("
\93Å
\82Ì
\95\90\8aí
\82ð
\8eg
\97p
\82·
\82é
\82Ì
\82Í
\94Ú
\8b¯
\82¾
\82Æ
\8a´
\82¶
\82½
\81D");
1282 if (obj && !rn2(nopoison)) {
1283 /* remove poison now in case obj ends up in a bones file */
1284 obj->opoisoned = FALSE;
1285 /* defer "obj is no longer poisoned" until after hit message */
1288 if (resists_poison(mon))
1296 /* make sure that negative damage adjustment can't result
1297 in inadvertently boosting the victim's hit points */
1299 if (mdat == &mons[PM_SHADE]) {
1302 const char *what = *unconventional ? unconventional : "attack";
1304 Your("%s %s harmlessly through %s.", what,
1305 vtense(what, "pass"), mon_nam(mon));
1307 Your("
\8dU
\8c\82\82Í%s
\82ð
\92Ê
\82è
\82Ê
\82¯
\82½
\81D", mon_nam(mon));
1318 tmp += d(2, (obj == uwep) ? 10 : 2); /* [was in dmgval()] */
1320 You("joust %s%s", mon_nam(mon), canseemon(mon) ? exclam(tmp) : ".");
1322 You("%s
\82É
\93Ë
\8c\82\82µ
\82½%s", mon_nam(mon), canseemon(mon) ? exclam(tmp) : "
\81D");
1325 pline("%s shatters on impact!", Yname2(obj));
1327 Your("%s
\82Í
\8fÕ
\8c\82\82Å
\89ó
\82ê
\82½
\81I", xname(obj));
1328 /* (must be either primary or secondary weapon to get here) */
1329 u.twoweap = FALSE; /* untwoweapon() is too verbose here */
1331 uwepgone(); /* set unweapon */
1332 /* minor side-effect: broken lance won't split puddings */
1336 /* avoid migrating a dead monster */
1337 if (mon->mhp > tmp) {
1338 mhurtle(mon, u.dx, u.dy, 1);
1339 mdat = mon->data; /* in case of a polymorph trap */
1340 if (DEADMONSTER(mon))
1341 already_killed = TRUE;
1344 } else if (unarmed && tmp > 1 && !thrown && !obj && !Upolyd) {
1345 /* VERY small chance of stunning opponent if unarmed. */
1346 if (rnd(100) < P_SKILL(P_BARE_HANDED_COMBAT) && !bigmonst(mdat)
1347 && !thick_skinned(mdat)) {
1348 if (canspotmon(mon))
1350 pline("%s %s from your powerful strike!", Monnam(mon),
1351 makeplural(stagger(mon->data, "stagger")));
1353 pline("%s
\82Í
\82 \82È
\82½
\82Ì
\89ï
\90S
\82Ì
\88ê
\8c\82\82Å%s
\81I", Monnam(mon),
1354 jpast(stagger(mon->data, "
\82æ
\82ë
\82ß
\82")));
1356 /* avoid migrating a dead monster */
1357 if (mon->mhp > tmp) {
1358 mhurtle(mon, u.dx, u.dy, 1);
1359 mdat = mon->data; /* in case of a polymorph trap */
1360 if (DEADMONSTER(mon))
1361 already_killed = TRUE;
1367 if (!already_killed)
1369 /* adjustments might have made tmp become less than what
1370 a level draining artifact has already done to max HP */
1371 if (mon->mhp > mon->mhpmax)
1372 mon->mhp = mon->mhpmax;
1373 if (DEADMONSTER(mon))
1375 if (mon->mtame && tmp > 0) {
1376 /* do this even if the pet is being killed (affects revival) */
1377 abuse_dog(mon); /* reduces tameness */
1378 /* flee if still alive and still tame; if already suffering from
1379 untimed fleeing, no effect, otherwise increases timed fleeing */
1380 if (mon->mtame && !destroyed)
1381 monflee(mon, 10 * rnd(tmp), FALSE, FALSE);
1383 if ((mdat == &mons[PM_BLACK_PUDDING] || mdat == &mons[PM_BROWN_PUDDING])
1384 /* pudding is alive and healthy enough to split */
1385 && mon->mhp > 1 && !mon->mcan
1386 /* iron weapon using melee or polearm hit [3.6.1: metal weapon too;
1387 also allow either or both weapons to cause split when twoweap] */
1388 && obj && (obj == uwep || (u.twoweap && obj == uswapwep))
1389 && ((objects[obj->otyp].oc_material == IRON
1390 /* allow scalpel and tsurugi to split puddings */
1391 || objects[obj->otyp].oc_material == METAL)
1392 /* but not bashing with darts, arrows or ya */
1393 && !(is_ammo(obj) || is_missile(obj)))
1395 struct monst *mclone;
1396 if ((mclone = clone_mon(mon, 0, 0)) != 0) {
1397 char withwhat[BUFSZ];
1401 if (u.twoweap && flags.verbose)
1402 Sprintf(withwhat, " with %s", yname(obj));
1403 pline("%s divides as you hit it%s!", Monnam(mon), withwhat);
1405 if (u.twoweap && flags.verbose)
1406 Sprintf(withwhat, "%s
\82Å
\82Ì", yname(obj));
1407 pline("
\82 \82È
\82½
\82Ì%s
\8dU
\8c\82\82Å%s
\82Í
\95ª
\97ô
\82µ
\82½
\81I", withwhat, Monnam(mon));
1414 if (!hittxt /*( thrown => obj exists )*/
1416 || (thrown && m_shot.n > 1 && m_shot.o == obj->otyp))) {
1418 hit(mshot_xname(obj), mon, exclam(tmp));
1419 else if (!flags.verbose)
1423 pline("
\8dU
\8c\82\82Í
\96½
\92\86\82µ
\82½
\81D");
1425 #if 0 /*JP*//*
\89£
\82è
\95û
\82ð
\95ª
\82¯
\82é
\82Ü
\82Å
\82Í
\82â
\82ç
\82È
\82¢*/
1427 (obj && (is_shield(obj) || obj->otyp == HEAVY_IRON_BALL))
1428 ? "bash" : Role_if(PM_BARBARIAN) ? "smite" : "hit",
1429 mon_nam(mon), canseemon(mon) ? exclam(tmp) : ".");
1431 Your("%s
\82Ö
\82Ì
\8dU
\8c\82\82Í
\96½
\92\86\82µ
\82½%s",
1432 mon_nam(mon), canseemon(mon) ? exclam(tmp) : "
\81D");
1438 char *whom = mon_nam(mon);
1439 char silverobjbuf[BUFSZ];
1441 if (canspotmon(mon)) {
1442 if (barehand_silver_rings == 1)
1444 fmt = "Your silver ring sears %s!";
1446 fmt = "%s
\82Í
\8bâ
\82Ì
\8ew
\97Ö
\82Å
\8fÄ
\82©
\82ê
\82½
\81I";
1447 else if (barehand_silver_rings == 2)
1449 fmt = "Your silver rings sear %s!";
1451 fmt = "%s
\82Í
\8bâ
\82Ì
\8ew
\97Ö
\82Å
\8fÄ
\82©
\82ê
\82½
\81I";
1452 else if (silverobj && saved_oname[0]) {
1453 /* guard constructed format string against '%' in
1454 saved_oname[] from xname(via cxname()) */
1456 Sprintf(silverobjbuf, "Your %s%s %s",
1457 strstri(saved_oname, "silver") ? "" : "silver ",
1458 saved_oname, vtense(saved_oname, "sear"));
1459 (void) strNsubst(silverobjbuf, "%", "%%", 0);
1460 Strcat(silverobjbuf, " %s!");
1462 Sprintf(silverobjbuf, "%%s
\82Í%s%s
\82Å
\8fÄ
\82©
\82ê
\82½
\81I",
1463 strstri(saved_oname, "
\8bâ") ?
1466 (void) strNsubst(silverobjbuf, "%%", "%", 0);
1471 fmt = "The silver sears %s!";
1473 fmt = "%s
\82Í
\8bâ
\82Å
\8fÄ
\82©
\82ê
\82½
\81I";
1475 *whom = highc(*whom); /* "it" -> "It" */
1477 fmt = "%s is seared!";
1479 fmt = "%s
\82Í
\8fÄ
\82©
\82ê
\82½
\81I";
1481 /* note: s_suffix returns a modifiable buffer */
1482 if (!noncorporeal(mdat) && !amorphous(mdat))
1484 whom = strcat(s_suffix(whom), " flesh");
1486 whom = strcat(s_suffix(whom), "
\93÷");
1491 char *whom = mon_nam(mon);
1492 char emitlightobjbuf[BUFSZ];
1494 if (canspotmon(mon)) {
1495 if (saved_oname[0]) {
1497 Sprintf(emitlightobjbuf,
1498 "%s radiance penetrates deep into",
1499 s_suffix(saved_oname));
1500 Strcat(emitlightobjbuf, " %s!");
1502 Sprintf(emitlightobjbuf,
1503 "%s
\8cõ
\82ª%%s
\82É
\90[
\82
\8aÑ
\92Ê
\82µ
\82½
\81I",
1504 s_suffix(saved_oname));
1506 fmt = emitlightobjbuf;
1509 fmt = "The light sears %s!";
1511 fmt = "
\8cõ
\82Í%s
\82ð
\8fÄ
\82¢
\82½
\81I";
1514 *whom = highc(*whom); /* "it" -> "It" */
1517 fmt = "%s is seared!";
1519 fmt = "%s
\82Í
\8fÄ
\82©
\82ê
\82½
\81I";
1521 /* note: s_suffix returns a modifiable buffer */
1522 if (!noncorporeal(mdat) && !amorphous(mdat))
1524 whom = strcat(s_suffix(whom), " flesh");
1526 whom = strcat(s_suffix(whom), "
\93÷");
1529 /* if a "no longer poisoned" message is coming, it will be last;
1530 obj->opoisoned was cleared above and any message referring to
1531 "poisoned <obj>" has now been given; we want just "<obj>" for
1532 last message, so reformat while obj is still accessible */
1534 Strcpy(saved_oname, cxname(obj));
1536 /* [note: thrown obj might go away during killed()/xkilled() call
1537 (via 'thrownobj'; if swallowed, it gets added to engulfer's
1538 minvent and might merge with a stack that's already there)] */
1542 pline_The("poison doesn't seem to affect %s.", mon_nam(mon));
1544 pline("
\93Å
\82Í%s
\82É
\8cø
\82©
\82È
\82©
\82Á
\82½
\82æ
\82¤
\82¾
\81D", mon_nam(mon));
1547 pline_The("poison was deadly...");
1549 pline("
\93Å
\82Í
\92v
\8e\80\97Ê
\82¾
\82Á
\82½
\81D
\81D
\81D");
1550 if (!already_killed)
1551 xkilled(mon, XKILL_NOMSG);
1552 destroyed = TRUE; /* return FALSE; */
1553 } else if (destroyed) {
1554 if (!already_killed)
1555 killed(mon); /* takes care of most messages */
1556 } else if (u.umconf && hand_to_hand) {
1558 if (!mon->mconf && !resist(mon, SPBOOK_CLASS, 0, NOTELL)) {
1560 if (!mon->mstun && mon->mcanmove && !mon->msleeping
1563 pline("%s appears confused.", Monnam(mon));
1565 pline("%s
\82Í
\8d¬
\97\90\82µ
\82Ä
\82¢
\82é
\82æ
\82¤
\82¾
\81D", Monnam(mon));
1570 Your("%s %s no longer poisoned.", saved_oname,
1571 vtense(saved_oname, "are"));
1573 Your("%s
\82Í
\82à
\82¤
\93Å
\82ª
\93h
\82ç
\82ê
\82Ä
\82¢
\82È
\82¢
\81D", xname(obj));
1576 return destroyed ? FALSE : TRUE;
1586 * The things in this list either
1589 * 2) are dealt with properly by other routines
1590 * when it comes to shades.
1592 if (obj->otyp == BOULDER
1593 || obj->otyp == HEAVY_IRON_BALL
1594 || obj->otyp == IRON_CHAIN /* dmgval handles those first three */
1595 || obj->otyp == MIRROR /* silver in the reflective surface */
1596 || obj->otyp == CLOVE_OF_GARLIC /* causes shades to flee */
1597 || objects[obj->otyp].oc_material == SILVER)
1602 /* check whether slippery clothing protects from hug or wrap attack */
1603 /* [currently assumes that you are the attacker] */
1605 m_slips_free(mdef, mattk)
1607 struct attack *mattk;
1611 if (mattk->adtyp == AD_DRIN) {
1612 /* intelligence drain attacks the head */
1613 obj = which_armor(mdef, W_ARMH);
1615 /* grabbing attacks the body */
1616 obj = which_armor(mdef, W_ARMC); /* cloak */
1618 obj = which_armor(mdef, W_ARM); /* suit */
1620 obj = which_armor(mdef, W_ARMU); /* shirt */
1623 /* if monster's cloak/armor is greased, your grab slips off; this
1624 protection might fail (33% chance) when the armor is cursed */
1625 if (obj && (obj->greased || obj->otyp == OILSKIN_CLOAK)
1626 && (!obj->cursed || rn2(3))) {
1629 mattk->adtyp == AD_WRAP ? "slip off of"
1630 : "grab, but cannot hold onto",
1631 s_suffix(mon_nam(mdef)), obj->greased ? "greased" : "slippery",
1632 /* avoid "slippery slippery cloak"
1633 for undiscovered oilskin cloak */
1634 (obj->greased || objects[obj->otyp].oc_name_known)
1636 : cloak_simple_name(obj));
1638 You("%s
\82Ì%s%s%s
\81I",
1639 mon_nam(mdef), obj->greased ? "
\96û
\82Ì
\93h
\82ç
\82ê
\82½" : "
\8a\8a\82è
\82â
\82·
\82¢",
1640 (obj->greased || objects[obj->otyp].oc_name_known)
1642 : cloak_simple_name(obj),
1643 mattk->adtyp == AD_WRAP ? "
\82Å
\8a\8a\82Á
\82½"
1644 : "
\82ð
\82Â
\82©
\82Ü
\82æ
\82¤
\82Æ
\82µ
\82½
\82ª
\81C
\82Å
\82«
\82È
\82©
\82Á
\82½");
1647 if (obj->greased && !rn2(2)) {
1649 pline_The("grease wears off.");
1651 pline("
\96û
\82Í
\97\8e\82¿
\82Ä
\82µ
\82Ü
\82Á
\82½
\81D");
1659 /* used when hitting a monster with a lance while mounted;
1660 1: joust hit; 0: ordinary hit; -1: joust but break lance */
1663 struct monst *mon; /* target */
1664 struct obj *obj; /* weapon */
1666 int skill_rating, joust_dieroll;
1668 if (Fumbling || Stunned)
1670 /* sanity check; lance must be wielded in order to joust */
1671 if (obj != uwep && (obj != uswapwep || !u.twoweap))
1674 /* if using two weapons, use worse of lance and two-weapon skills */
1675 skill_rating = P_SKILL(weapon_type(obj)); /* lance skill */
1676 if (u.twoweap && P_SKILL(P_TWO_WEAPON_COMBAT) < skill_rating)
1677 skill_rating = P_SKILL(P_TWO_WEAPON_COMBAT);
1678 if (skill_rating == P_ISRESTRICTED)
1679 skill_rating = P_UNSKILLED; /* 0=>1 */
1681 /* odds to joust are expert:80%, skilled:60%, basic:40%, unskilled:20% */
1682 if ((joust_dieroll = rn2(5)) < skill_rating) {
1683 if (joust_dieroll == 0 && rnl(50) == (50 - 1) && !unsolid(mon->data)
1684 && !obj_resists(obj, 0, 100))
1685 return -1; /* hit that breaks lance */
1686 return 1; /* successful joust */
1688 return 0; /* no joust bonus; revert to ordinary attack */
1692 * Send in a demon pet for the hero. Exercise wisdom.
1694 * This function used to be inline to damageum(), but the Metrowerks compiler
1695 * (DR4 and DR4.5) screws up with an internal error 5 "Expression Too
1697 * Pulling it out makes it work.
1703 struct permonst *pm;
1707 pline("Some hell-p has arrived!");
1709 pline("
\92n
\8d\96\82Ì
\92\87\8aÔ
\82ª
\8c»
\82í
\82ê
\82½
\81I");
1710 i = !rn2(6) ? ndemon(u.ualign.type) : NON_PM;
1711 pm = i != NON_PM ? &mons[i] : youmonst.data;
1712 if ((dtmp = makemon(pm, u.ux, u.uy, NO_MM_FLAGS)) != 0)
1713 (void) tamedog(dtmp, (struct obj *) 0);
1714 exercise(A_WIS, TRUE);
1718 theft_petrifies(otmp)
1721 if (uarmg || otmp->otyp != CORPSE
1722 || !touch_petrifies(&mons[otmp->corpsenm]) || Stone_resistance)
1725 #if 0 /* no poly_when_stoned() critter has theft capability */
1726 if (poly_when_stoned(youmonst.data) && polymon(PM_STONE_GOLEM)) {
1727 display_nhwindow(WIN_MESSAGE, FALSE); /* --More-- */
1732 /* stealing this corpse is fatal... */
1734 instapetrify(corpse_xname(otmp, "stolen", CXN_ARTICLE));
1736 instapetrify(corpse_xname(otmp, "
\93\90\82Ü
\82ê
\82½", CXN_ARTICLE));
1737 /* apparently wasn't fatal after all... */
1742 * Player uses theft attack against monster.
1744 * If the target is wearing body armor, take all of its possessions;
1745 * otherwise, take one object. [Is this really the behavior we want?]
1748 steal_it(mdef, mattk)
1750 struct attack *mattk;
1752 struct obj *otmp, *stealoid, **minvent_ptr;
1756 return; /* nothing to take */
1758 /* look for worn body armor */
1759 stealoid = (struct obj *) 0;
1760 if (could_seduce(&youmonst, mdef, mattk)) {
1761 /* find armor, and move it to end of inventory in the process */
1762 minvent_ptr = &mdef->minvent;
1763 while ((otmp = *minvent_ptr) != 0)
1764 if (otmp->owornmask & W_ARM) {
1766 panic("steal_it: multiple worn suits");
1767 *minvent_ptr = otmp->nobj; /* take armor out of minvent */
1769 stealoid->nobj = (struct obj *) 0;
1771 minvent_ptr = &otmp->nobj;
1773 *minvent_ptr = stealoid; /* put armor back into minvent */
1776 if (stealoid) { /* we will be taking everything */
1777 if (gender(mdef) == (int) u.mfemale && youmonst.data->mlet == S_NYMPH)
1779 You("charm %s. She gladly hands over her possessions.",
1781 You("%s
\82ð
\82¤
\82Á
\82Æ
\82è
\82³
\82¹
\82½
\81D
\94Þ
\8f\97\82Í
\82æ
\82ë
\82±
\82ñ
\82Å
\8e\9d\82¿
\95¨
\82ð
\82³
\82µ
\82¾
\82µ
\82½
\81D",
1785 You("seduce %s and %s starts to take off %s clothes.",
1786 mon_nam(mdef), mhe(mdef), mhis(mdef));
1788 You("%s
\82ð
\97U
\98f
\82µ
\82½
\81D%s
\82Í
\95\9e\82ð
\92E
\82¬
\82Í
\82¶
\82ß
\82½
\81D",
1789 mon_nam(mdef), mhe(mdef));
1793 while ((otmp = mdef->minvent) != 0) {
1795 break; /* no longer have ability to steal */
1796 /* take the object away from the monster */
1797 obj_extract_self(otmp);
1798 if ((unwornmask = otmp->owornmask) != 0L) {
1799 mdef->misc_worn_check &= ~unwornmask;
1800 if (otmp->owornmask & W_WEP)
1801 setmnotwielded(mdef, otmp);
1802 otmp->owornmask = 0L;
1803 update_mon_intrinsics(mdef, otmp, FALSE, FALSE);
1804 /* give monster a chance to wear other equipment on its next
1805 move instead of waiting until it picks something up */
1806 mdef->misc_worn_check |= I_SPECIAL;
1808 if (otmp == stealoid) /* special message for final item */
1810 pline("%s finishes taking off %s suit.", Monnam(mdef),
1813 pline("%s
\82Í
\92E
\82¬
\8fI
\82¦
\82½
\81D", Monnam(mdef));
1816 /* give the object to the character */
1818 otmp = hold_another_object(otmp, "You snatched but dropped %s.",
1819 doname(otmp), "You steal: ");
1821 otmp = hold_another_object(otmp, "
\82 \82È
\82½
\82Í%s
\82ð
\93\90\82ñ
\82¾
\82ª
\97\8e\82Æ
\82µ
\82½
\81D",
1822 doname(otmp), "
\82ð
\93\90\82ñ
\82¾
\81D");
1824 /* might have dropped otmp, and it might have broken or left level */
1825 if (!otmp || otmp->where != OBJ_INVENT)
1827 if (theft_petrifies(otmp))
1828 break; /* stop thieving even though hero survived */
1829 /* more take-away handling, after theft message */
1830 if (unwornmask & W_WEP) { /* stole wielded weapon */
1831 possibly_unwield(mdef, FALSE);
1832 } else if (unwornmask & W_ARMG) { /* stole worn gloves */
1833 mselftouch(mdef, (const char *) 0, TRUE);
1834 if (DEADMONSTER(mdef)) /* it's now a statue */
1835 return; /* can't continue stealing */
1839 break; /* only taking one item */
1844 damageum(mdef, mattk, specialdmg)
1845 register struct monst *mdef;
1846 register struct attack *mattk;
1847 int specialdmg; /* blessed and/or silver bonus against various things */
1849 register struct permonst *pd = mdef->data;
1850 int armpro, tmp = d((int) mattk->damn, (int) mattk->damd);
1852 struct obj *mongold;
1854 armpro = magic_negation(mdef);
1855 /* since hero can't be cancelled, only defender's armor applies */
1856 negated = !(rn2(10) >= 3 * armpro);
1858 if (is_demon(youmonst.data) && !rn2(13) && !uwep
1859 && u.umonnum != PM_SUCCUBUS && u.umonnum != PM_INCUBUS
1860 && u.umonnum != PM_BALROG) {
1864 switch (mattk->adtyp) {
1868 pline("%s %s for a moment.", Monnam(mdef),
1869 makeplural(stagger(pd, "stagger")));
1871 pline("%s
\82Í
\88ê
\8fu%s
\81D", Monnam(mdef),
1872 jpast(stagger(pd, "
\82æ
\82ë
\82ß
\82")));
1884 case AD_WERE: /* no special effect on monsters */
1885 case AD_HEAL: /* likewise */
1888 if (pd == &mons[PM_SHADE]) {
1891 impossible("bad shade attack function flow?");
1895 if (mattk->aatyp == AT_WEAP) {
1896 /* hmonas() uses known_hitum() to deal physical damage,
1897 then also damageum() for non-AD_PHYS; don't inflict
1898 extra physical damage for unusual damage types */
1900 } else if (mattk->aatyp == AT_KICK
1901 || mattk->aatyp == AT_CLAW
1902 || mattk->aatyp == AT_TUCH
1903 || mattk->aatyp == AT_HUGS) {
1904 if (thick_skinned(pd))
1905 tmp = (mattk->aatyp == AT_KICK) ? 0 : (tmp + 1) / 2;
1906 /* add ring(s) of increase damage */
1907 if (u.udaminc > 0) {
1908 /* applies even if damage was 0 */
1910 } else if (tmp > 0) {
1911 /* ring(s) might be negative; avoid converting
1912 0 to non-0 or positive to non-positive */
1926 pline("%s is %s!", Monnam(mdef), on_fire(pd, mattk));
1928 pline("%s
\82Í%s
\81I", Monnam(mdef), on_fire(mdef->data, mattk));
1929 if (completelyburns(pd)) { /* paper golem or straw golem */
1932 pline("%s burns completely!", Monnam(mdef));
1934 pline("%s
\82Í
\8a®
\91S
\82É
\94R
\82¦
\90s
\82«
\82½
\81I", Monnam(mdef));
1937 You("smell burning%s.",
1938 (pd == &mons[PM_PAPER_GOLEM]) ? " paper"
1939 : (pd == &mons[PM_STRAW_GOLEM]) ? " straw" : "");
1941 You("%s
\82ª
\94R
\82¦
\82é
\82É
\82¨
\82¢
\82ª
\82µ
\82½
\81D",
1942 (pd == &mons[PM_PAPER_GOLEM]) ? "
\8e\86"
1943 : (pd == &mons[PM_STRAW_GOLEM]) ? "
\82í
\82ç" : "
\89½
\82©");
1945 xkilled(mdef, XKILL_NOMSG | XKILL_NOCORPSE);
1948 /* Don't return yet; keep hp<1 and tmp=0 for pet msg */
1950 tmp += destroy_mitem(mdef, SCROLL_CLASS, AD_FIRE);
1951 tmp += destroy_mitem(mdef, SPBOOK_CLASS, AD_FIRE);
1952 if (resists_fire(mdef)) {
1955 pline_The("fire doesn't heat %s!", mon_nam(mdef));
1957 pline("
\89\8a\82Í%s
\82É
\89e
\8b¿
\82ª
\82È
\82¢
\81I", mon_nam(mdef));
1958 golemeffects(mdef, AD_FIRE, tmp);
1959 shieldeff(mdef->mx, mdef->my);
1962 /* only potions damage resistant players in destroy_item */
1963 tmp += destroy_mitem(mdef, POTION_CLASS, AD_FIRE);
1972 pline("%s is covered in frost!", Monnam(mdef));
1974 pline("%s
\82Í
\95X
\82Å
\95¢
\82í
\82ê
\82½
\81I", Monnam(mdef));
1975 if (resists_cold(mdef)) {
1976 shieldeff(mdef->mx, mdef->my);
1979 pline_The("frost doesn't chill %s!", mon_nam(mdef));
1981 pline("
\95X
\82Í%s
\82ð
\93\80\82ç
\82·
\82±
\82Æ
\82ª
\82Å
\82«
\82È
\82¢
\81I", mon_nam(mdef));
1982 golemeffects(mdef, AD_COLD, tmp);
1985 tmp += destroy_mitem(mdef, POTION_CLASS, AD_COLD);
1994 pline("%s is zapped!", Monnam(mdef));
1996 pline("%s
\82Í
\93d
\8c\82\82ð
\82
\82ç
\82Á
\82½
\81I", Monnam(mdef));
1997 tmp += destroy_mitem(mdef, WAND_CLASS, AD_ELEC);
1998 if (resists_elec(mdef)) {
2001 pline_The("zap doesn't shock %s!", mon_nam(mdef));
2003 pline("
\93d
\8c\82\82Í%s
\82É
\89e
\8b¿
\82ð
\97^
\82¦
\82È
\82¢
\81I", mon_nam(mdef));
2004 golemeffects(mdef, AD_ELEC, tmp);
2005 shieldeff(mdef->mx, mdef->my);
2008 /* only rings damage resistant players in destroy_item */
2009 tmp += destroy_mitem(mdef, RING_CLASS, AD_ELEC);
2012 if (resists_acid(mdef))
2016 if (!munstone(mdef, TRUE))
2017 minstapetrify(mdef, TRUE);
2023 steal_it(mdef, mattk);
2027 /* This you as a leprechaun, so steal
2028 real gold only, no lesser coins */
2029 mongold = findgold(mdef->minvent);
2031 obj_extract_self(mongold);
2032 if (merge_choice(invent, mongold) || inv_cnt(FALSE) < 52) {
2035 Your("purse feels heavier.");
2037 You("
\8dà
\95z
\82ª
\8fd
\82
\82È
\82Á
\82½
\82æ
\82¤
\82È
\8bC
\82ª
\82µ
\82½
\81D");
2040 You("grab %s's gold, but find no room in your knapsack.",
2042 You("%s
\82Ì
\82¨
\8bà
\82ð
\82Â
\82©
\82ñ
\82¾
\82ª
\81C
\8e\9d\82¿
\95¨
\91Ü
\82É
\93ü
\82ç
\82È
\82©
\82Á
\82½
\81D",
2047 exercise(A_DEX, TRUE);
2055 boolean u_saw_mon = (canseemon(mdef)
2056 || (u.uswallow && u.ustuck == mdef));
2058 /* record the name before losing sight of monster */
2059 Strcpy(nambuf, Monnam(mdef));
2060 if (u_teleport_mon(mdef, FALSE) && u_saw_mon
2061 && !(canseemon(mdef) || (u.uswallow && u.ustuck == mdef)))
2063 pline("%s suddenly disappears!", nambuf);
2065 pline("%s
\82Í
\93Ë
\91R
\8fÁ
\82¦
\82½
\81I", nambuf);
2066 if (tmp >= mdef->mhp) { /* see hitmu(mhitu.c) */
2069 tmp = mdef->mhp - 1;
2074 if (can_blnd(&youmonst, mdef, mattk->aatyp, (struct obj *) 0)) {
2075 if (!Blind && mdef->mcansee)
2077 pline("%s is blinded.", Monnam(mdef));
2079 pline("%s
\82Í
\96Ú
\82ª
\8c©
\82¦
\82È
\82
\82È
\82Á
\82½
\81D", Monnam(mdef));
2081 tmp += mdef->mblinded;
2084 mdef->mblinded = tmp;
2089 if (night() && !rn2(10) && !mdef->mcan) {
2090 if (pd == &mons[PM_CLAY_GOLEM]) {
2093 pline("Some writing vanishes from %s head!",
2094 s_suffix(mon_nam(mdef)));
2096 pline("%s
\82Ì
\93ª
\82É
\8f\91\82¢
\82Ä
\82 \82é
\95¶
\8e\9a\82Ì
\82¢
\82
\82Â
\82©
\82ª
\8fÁ
\82¦
\82½
\81I",
2099 xkilled(mdef, XKILL_NOMSG);
2100 /* Don't return yet; keep hp<1 and tmp=0 for pet msg */
2106 You("
\82
\82·
\82
\82·
\8fÎ
\82Á
\82½
\81D");
2112 if (!negated && !rn2(3) && !resists_drli(mdef)) {
2116 pline("%s suddenly seems weaker!", Monnam(mdef));
2118 pline("%s
\82Í
\93Ë
\91R
\8eã
\82
\82È
\82Á
\82½
\82æ
\82¤
\82É
\8c©
\82¦
\82½
\81I", Monnam(mdef));
2119 mdef->mhpmax -= xtmp;
2121 /* !m_lev: level 0 monster is killed regardless of hit points
2122 rather than drop to level -1 */
2123 if (DEADMONSTER(mdef) || !mdef->m_lev) {
2125 pline("%s dies!", Monnam(mdef));
2127 pline("%s
\82Í
\8e\80\82ñ
\82¾
\81I", Monnam(mdef));
2128 xkilled(mdef, XKILL_NOMSG);
2135 if (pd == &mons[PM_IRON_GOLEM]) {
2137 pline("%s falls to pieces!", Monnam(mdef));
2139 pline("%s
\82Í
\83o
\83\89\83o
\83\89\82É
\82È
\82Á
\82½
\81I", Monnam(mdef));
2140 xkilled(mdef, XKILL_NOMSG);
2142 erode_armor(mdef, ERODE_RUST);
2146 erode_armor(mdef, ERODE_CORRODE);
2150 if (pd == &mons[PM_WOOD_GOLEM] || pd == &mons[PM_LEATHER_GOLEM]) {
2152 pline("%s falls to pieces!", Monnam(mdef));
2154 pline("%s
\82Í
\83o
\83\89\83o
\83\89\82É
\82È
\82Á
\82½
\81I", Monnam(mdef));
2155 xkilled(mdef, XKILL_NOMSG);
2157 erode_armor(mdef, ERODE_ROT);
2161 if (!negated && !rn2(4))
2162 xdrainenergym(mdef, TRUE);
2168 if (!negated && !rn2(8)) {
2170 Your("%s was poisoned!", mpoisons_subj(&youmonst, mattk));
2172 Your("%s
\82Í
\93Å
\82³
\82ê
\82Ä
\82¢
\82é
\81I", mpoisons_subj(&youmonst, mattk));
2173 if (resists_poison(mdef)) {
2175 pline_The("poison doesn't seem to affect %s.", mon_nam(mdef));
2177 pline("
\93Å
\82Í%s
\82É
\89e
\8b¿
\82ð
\97^
\82¦
\82È
\82¢
\81D", mon_nam(mdef));
2181 Your("poison was deadly...");
2183 Your("
\97^
\82¦
\82½
\93Å
\82Í
\92v
\8e\80\97Ê
\82¾
\82Á
\82½
\81D
\81D
\81D");
2193 if (notonhead || !has_head(pd)) {
2195 pline("%s doesn't seem harmed.", Monnam(mdef));
2197 pline("%s
\82Í
\8f\9d\82Â
\82¢
\82½
\82æ
\82¤
\82É
\82Í
\8c©
\82¦
\82È
\82¢
\81D", Monnam(mdef));
2199 if (!Unchanging && pd == &mons[PM_GREEN_SLIME]) {
2202 You("suck in some slime and don't feel very well.");
2204 You("
\83X
\83\89\83C
\83\80\82ð
\8bz
\82¢
\8eæ
\82Á
\82Ä
\81C
\8bï
\8d\87\82ª
\88«
\82
\82È
\82Á
\82½
\81D");
2205 make_slimed(10L, (char *) 0);
2210 if (m_slips_free(mdef, mattk))
2213 if ((helmet = which_armor(mdef, W_ARMH)) != 0 && rn2(8)) {
2215 pline("%s %s blocks your attack to %s head.",
2216 s_suffix(Monnam(mdef)), helm_simple_name(helmet),
2219 pline("%s
\82Ì%s
\82ª
\93ª
\82Ö
\82Ì
\8dU
\8c\82\82ð
\96h
\82¢
\82¾
\81D",
2220 Monnam(mdef), helm_simple_name(helmet));
2225 (void) eat_brains(&youmonst, mdef, TRUE, &tmp);
2229 if (!negated && !sticks(pd))
2230 u.ustuck = mdef; /* it's now stuck to you */
2234 if (!u.ustuck && !rn2(10)) {
2235 if (m_slips_free(mdef, mattk)) {
2239 You("swing yourself around %s!", mon_nam(mdef));
2241 You("%s
\82É
\90g
\91Ì
\82ð
\97\8d\82Ý
\82Â
\82©
\82¹
\82½
\81I", mon_nam(mdef));
2244 } else if (u.ustuck == mdef) {
2245 /* Monsters don't wear amulets of magical breathing */
2246 if (is_pool(u.ux, u.uy) && !is_swimmer(pd)
2247 && !amphibious(pd)) {
2249 You("drown %s...", mon_nam(mdef));
2251 You("%s
\82ð
\93M
\82ê
\82³
\82¹
\82½
\81D
\81D
\81D", mon_nam(mdef));
2253 } else if (mattk->aatyp == AT_HUGS)
2255 pline("%s is being crushed.", Monnam(mdef));
2257 pline("%s
\82Í
\89\9f\82µ
\82Â
\82Ô
\82³
\82ê
\82Ä
\82¢
\82é
\81D", Monnam(mdef));
2262 You("brush against %s %s.", s_suffix(mon_nam(mdef)),
2263 mbodypart(mdef, LEG));
2265 You("%s
\82Ì%s
\82É
\90G
\82ê
\82½
\81D", mon_nam(mdef),
2266 mbodypart(mdef, LEG));
2273 if (!negated && mdef->mcanmove && !rn2(3) && tmp < mdef->mhp) {
2276 pline("%s is frozen by you!", Monnam(mdef));
2278 pline("%s
\82Í
\82 \82È
\82½
\82Ì
\82É
\82ç
\82Ý
\82Å
\93®
\82¯
\82È
\82
\82È
\82Á
\82½
\81I", Monnam(mdef));
2279 paralyze_monst(mdef, rnd(10));
2283 if (!negated && !mdef->msleeping && sleep_monst(mdef, rnd(10), -1)) {
2286 pline("%s is put to sleep by you!", Monnam(mdef));
2288 pline("%s
\82Í
\93Ë
\91R
\96°
\82è
\82É
\82¨
\82¿
\82½
\81I", Monnam(mdef));
2294 break; /* physical damage only */
2295 if (!rn2(4) && !slimeproof(pd)) {
2296 if (!munslime(mdef, TRUE) && !DEADMONSTER(mdef)) {
2297 /* this assumes newcham() won't fail; since hero has
2298 a slime attack, green slimes haven't been geno'd */
2300 You("turn %s into slime.", mon_nam(mdef));
2302 pline("%s
\82Í
\83X
\83\89\83C
\83\80\82É
\82È
\82Á
\82½
\81D", mon_nam(mdef));
2303 if (newcham(mdef, &mons[PM_GREEN_SLIME], FALSE, FALSE))
2306 /* munslime attempt could have been fatal */
2307 if (DEADMONSTER(mdef))
2308 return 2; /* skip death message */
2312 case AD_ENCH: /* KMH -- remove enchantment (disenchanter) */
2313 /* there's no msomearmor() function, so just do damage */
2314 /* if (negated) break; */
2317 if (!negated && mdef->mspeed != MSLOW) {
2318 unsigned int oldspeed = mdef->mspeed;
2320 mon_adjust_speed(mdef, -1, (struct obj *) 0);
2321 if (mdef->mspeed != oldspeed && canseemon(mdef))
2323 pline("%s slows down.", Monnam(mdef));
2325 pline("%s
\82Í
\82Ì
\82ë
\82
\82È
\82Á
\82½
\81D", Monnam(mdef));
2330 if (canseemon(mdef))
2332 pline("%s looks confused.", Monnam(mdef));
2334 pline("%s
\82Í
\8d¬
\97\90\82µ
\82½
\82æ
\82¤
\82¾
\81D", Monnam(mdef));
2343 mdef->mstrategy &= ~STRAT_WAITFORU; /* in case player is very fast */
2345 if (DEADMONSTER(mdef)) {
2346 if (mdef->mtame && !cansee(mdef->mx, mdef->my)) {
2348 You_feel("embarrassed for a moment.");
2350 You("
\82µ
\82Î
\82ç
\82
\8d¢
\98f
\82µ
\82½
\81D");
2352 xkilled(mdef, XKILL_NOMSG); /* !tmp but hp<1: already killed */
2353 } else if (!flags.verbose) {
2357 You("
\93|
\82µ
\82½
\81I");
2359 xkilled(mdef, XKILL_NOMSG);
2369 register struct monst *mdef;
2370 register struct attack *mattk;
2372 boolean resistance; /* only for cold/fire/elec */
2373 register int tmp = d((int) mattk->damn, (int) mattk->damd);
2378 You("
\94\9a\94
\82µ
\82½
\81I");
2379 switch (mattk->adtyp) {
2381 if (!resists_blnd(mdef)) {
2383 pline("%s is blinded by your flash of light!", Monnam(mdef));
2385 pline("%s
\82Í
\82Ü
\82Î
\82ä
\82¢
\8cõ
\82Å
\96Ú
\82ª
\82
\82ç
\82ñ
\82¾
\81I", Monnam(mdef));
2386 mdef->mblinded = min((int) mdef->mblinded + tmp, 127);
2391 if (haseyes(mdef->data) && mdef->mcansee) {
2393 pline("%s is affected by your flash of light!", Monnam(mdef));
2395 pline("%s
\82Í
\82Ü
\82Î
\82ä
\82¢
\8cõ
\82Å
\89e
\8b¿
\82ð
\8eó
\82¯
\82½
\81I", Monnam(mdef));
2400 resistance = resists_cold(mdef);
2403 resistance = resists_fire(mdef);
2406 resistance = resists_elec(mdef);
2410 pline("%s gets blasted!", Monnam(mdef));
2412 pline("%s
\82Í
\94\9a\94
\82ð
\97\81\82Ñ
\82½
\81I", Monnam(mdef));
2414 if (DEADMONSTER(mdef)) {
2419 shieldeff(mdef->mx, mdef->my);
2420 if (is_golem(mdef->data))
2421 golemeffects(mdef, (int) mattk->adtyp, tmp);
2424 pline_The("blast doesn't seem to affect %s.", mon_nam(mdef));
2426 pline("
\94\9a\94
\82Í%s
\82É
\89e
\8b¿
\82ð
\97^
\82¦
\82È
\82©
\82Á
\82½
\82æ
\82¤
\82¾
\81D", mon_nam(mdef));
2440 map_location(u.ux, u.uy, TRUE);
2441 tmp_at(DISP_ALWAYS, mon_to_glyph(&youmonst, rn2_on_display_rng));
2442 tmp_at(mdef->mx, mdef->my);
2445 You("engulf %s!", mon_nam(mdef));
2447 You("%s
\82ð
\88ù
\82Ý
\8d\9e\82ñ
\82¾
\81I", mon_nam(mdef));
2456 tmp_at(DISP_END, 0);
2463 register struct monst *mdef;
2464 register struct attack *mattk;
2466 #ifdef LINT /* static char msgbuf[BUFSZ]; */
2469 static char msgbuf[BUFSZ]; /* for nomovemsg */
2472 register int dam = d((int) mattk->damn, (int) mattk->damd);
2475 struct permonst *pd = mdef->data;
2477 /* Not totally the same as for real monsters. Specifically, these
2478 * don't take multiple moves. (It's just too hard, for too little
2479 * result, to program monsters which attack from inside you, which
2480 * would be necessary if done accurately.) Instead, we arbitrarily
2481 * kill the monster immediately for AD_DGST and we regurgitate them
2482 * after exactly 1 round of attack otherwise. -KAA
2485 if (!engulf_target(&youmonst, mdef))
2488 if (u.uhunger < 1500 && !u.uswallow) {
2489 for (otmp = mdef->minvent; otmp; otmp = otmp->nobj)
2490 (void) snuff_lit(otmp);
2492 /* force vampire in bat, cloud, or wolf form to revert back to
2493 vampire form now instead of dealing with that when it dies */
2494 if (is_vampshifter(mdef)
2495 && newcham(mdef, &mons[mdef->cham], FALSE, FALSE)) {
2497 You("engulf it, then expel it.");
2499 You("
\88ù
\82Ý
\8d\9e\82ñ
\82Å
\81C
\93f
\82«
\8fo
\82µ
\82½
\81D");
2500 if (canspotmon(mdef))
2502 pline("It turns into %s.", a_monnam(mdef));
2504 pline("
\82»
\82ê
\82Í%s
\82É
\82È
\82Á
\82½
\81D", a_monnam(mdef));
2506 map_invisible(mdef->mx, mdef->my);
2510 /* engulfing a cockatrice or digesting a Rider or Medusa */
2511 fatal_gulp = (touch_petrifies(pd) && !Stone_resistance)
2512 || (mattk->adtyp == AD_DGST
2513 && (is_rider(pd) || (pd == &mons[PM_MEDUSA]
2514 && !Stone_resistance)));
2516 if ((mattk->adtyp == AD_DGST && !Slow_digestion) || fatal_gulp)
2517 eating_conducts(pd);
2519 if (fatal_gulp && !is_rider(pd)) { /* petrification */
2521 const char *mname = pd->mname;
2523 if (!type_is_pname(pd))
2526 You("englut %s.", mon_nam(mdef));
2528 You("%s
\82ð
\88ù
\82Ý
\8d\9e\82ñ
\82¾
\81D", mon_nam(mdef));
2530 Sprintf(kbuf, "swallowing %s whole", mname);
2532 Sprintf(kbuf, "%s
\82ð
\88ù
\82Ý
\8d\9e\82ñ
\82Å", mname);
2536 switch (mattk->adtyp) {
2538 /* eating a Rider or its corpse is fatal */
2541 pline("Unfortunately, digesting any of it is fatal.");
2543 pline("
\8ec
\94O
\82È
\82ª
\82ç
\81C
\82»
\82ê
\82ð
\90H
\82×
\82é
\82Ì
\82Í
\92v
\96½
\93I
\82È
\8aÔ
\88á
\82¢
\82¾
\81D");
2546 Sprintf(killer.name, "unwisely tried to eat %s",
2548 killer.format = NO_KILLER_PREFIX;
2550 Sprintf(killer.name, "
\8bð
\82©
\82É
\82à%s
\82ð
\90H
\82×
\82æ
\82¤
\82Æ
\82µ
\82Ä",
2552 killer.format = KILLED_BY;
2555 return 0; /* lifesaved */
2558 if (Slow_digestion) {
2563 /* Use up amulet of life saving */
2564 if ((otmp = mlifesaver(mdef)) != 0)
2565 m_useup(mdef, otmp);
2568 /* start_engulf() issues "you engulf <mdef>" above; this
2569 used to specify XKILL_NOMSG but we need "you kill <mdef>"
2570 in case we're also going to get "welcome to level N+1";
2571 "you totally digest <mdef>" will be coming soon (after
2572 several turns) but the level-gain message seems out of
2573 order if the kill message is left implicit */
2574 xkilled(mdef, XKILL_GIVEMSG | XKILL_NOCORPSE);
2575 if (!DEADMONSTER(mdef)) { /* monster lifesaved */
2577 You("hurriedly regurgitate the sizzling in your %s.",
2579 You("%s
\82Ì
\92\86\82Å
\83V
\83\85\81[
\83V
\83\85\81[
\82Æ
\82¢
\82¤
\89¹
\82ð
\97§
\82Ä
\82Ä
\82¢
\82é
\82à
\82Ì
\82ð
\91å
\8b}
\82¬
\82Å
\93f
\82«
\96ß
\82µ
\82½
\81D",
2580 body_part(STOMACH));
2582 tmp = 1 + (pd->cwt >> 8);
2583 if (corpse_chance(mdef, &youmonst, TRUE)
2584 && !(mvitals[monsndx(pd)].mvflags & G_NOCORPSE)) {
2585 /* nutrition only if there can be a corpse */
2586 u.uhunger += (pd->cnutrit + 1) / 2;
2590 Sprintf(msgbuf, "You totally digest %s.", mon_nam(mdef));
2592 Sprintf(msgbuf, "
\82 \82È
\82½
\82Í%s
\82ð
\8a®
\91S
\82É
\8fÁ
\89»
\82µ
\82½
\81D", mon_nam(mdef));
2594 /* setting afternmv = end_engulf is tempting,
2595 * but will cause problems if the player is
2596 * attacked (which uses his real location) or
2597 * if his See_invisible wears off
2600 You("digest %s.", mon_nam(mdef));
2602 You("%s
\82ð
\8fÁ
\89»
\82µ
\82Ä
\82¢
\82é
\81D", mon_nam(mdef));
2607 multi_reason = "digesting something";
2609 multi_reason = "
\8fÁ
\89»
\92\86\82É";
2613 if (pd == &mons[PM_GREEN_SLIME]) {
2615 Sprintf(msgbuf, "%s isn't sitting well with you.",
2617 Sprintf(msgbuf, "%s
\82Í
\82 \82È
\82½
\82Æ
\82¤
\82Ü
\82
\90Ü
\82è
\8d\87\82¢
\82ð
\82Â
\82¯
\82ç
\82ê
\82È
\82¢
\82æ
\82¤
\82¾
\81D",
2620 make_slimed(5L, (char *) 0);
2623 exercise(A_CON, TRUE);
2628 if (youmonst.data == &mons[PM_FOG_CLOUD]) {
2630 pline("%s is laden with your moisture.", Monnam(mdef));
2632 pline("%s
\82Í
\82 \82È
\82½
\82Ì
\8e¼
\8bC
\82É
\8bê
\82µ
\82ß
\82ç
\82ê
\82Ä
\82¢
\82é
\81D", Monnam(mdef));
2633 if (amphibious(pd) && !flaming(pd)) {
2636 pline("%s seems unharmed.", Monnam(mdef));
2638 pline("%s
\82Í
\8f\9d\82Â
\82¢
\82Ä
\82¢
\82È
\82¢
\82æ
\82¤
\82¾
\81D", Monnam(mdef));
2642 pline("%s is pummeled with your debris!", Monnam(mdef));
2644 pline("%s
\82Í
\8a¢âI
\82Å
\92É
\82ß
\82Â
\82¯
\82ç
\82ê
\82½
\81I", Monnam(mdef));
2648 pline("%s is covered with your goo!", Monnam(mdef));
2650 pline("%s
\82Í
\82Ë
\82Î
\82Â
\82
\82à
\82Ì
\82Å
\95¢
\82í
\82ê
\82½
\81I", Monnam(mdef));
2651 if (resists_acid(mdef)) {
2653 pline("It seems harmless to %s.", mon_nam(mdef));
2655 pline("
\82µ
\82©
\82µ
\81C%s
\82Í
\82È
\82ñ
\82Æ
\82à
\82È
\82¢
\81D", mon_nam(mdef));
2660 if (can_blnd(&youmonst, mdef, mattk->aatyp,
2661 (struct obj *) 0)) {
2664 pline("%s can't see in there!", Monnam(mdef));
2666 pline("%s
\82Í
\96Ú
\82ª
\8c©
\82¦
\82È
\82
\82È
\82Á
\82½
\81I", mon_nam(mdef));
2668 dam += mdef->mblinded;
2671 mdef->mblinded = dam;
2678 pline_The("air around %s crackles with electricity.",
2680 pline("%s
\82Ì
\89ñ
\82è
\82Ì
\8bó
\8bC
\82Í
\93d
\8bC
\82Å
\83s
\83\8a\83s
\83\8a\82µ
\82Ä
\82¢
\82é
\81D",
2682 if (resists_elec(mdef)) {
2684 pline("%s seems unhurt.", Monnam(mdef));
2686 pline("
\82µ
\82©
\82µ
\81C%s
\82Í
\95½
\8bC
\82È
\82æ
\82¤
\82¾
\81D", Monnam(mdef));
2689 golemeffects(mdef, (int) mattk->adtyp, dam);
2695 if (resists_cold(mdef)) {
2697 pline("%s seems mildly chilly.", Monnam(mdef));
2699 pline("%s
\82Í
\97â
\82¦
\82½
\82æ
\82¤
\82¾
\81D", Monnam(mdef));
2703 pline("%s is freezing to death!", Monnam(mdef));
2705 pline("%s
\82Í
\93\80\8e\80\82µ
\82»
\82¤
\82¾
\81I", Monnam(mdef));
2706 golemeffects(mdef, (int) mattk->adtyp, dam);
2712 if (resists_fire(mdef)) {
2714 pline("%s seems mildly hot.", Monnam(mdef));
2716 pline("%s
\82Í
\92g
\82©
\82
\82È
\82Á
\82½
\82æ
\82¤
\82¾
\81D", Monnam(mdef));
2720 pline("%s is burning to a crisp!", Monnam(mdef));
2722 pline("%s
\82Í
\94R
\82¦
\82Ä
\83J
\83\89\83J
\83\89\82É
\82È
\82Á
\82½
\81I", Monnam(mdef));
2723 golemeffects(mdef, (int) mattk->adtyp, dam);
2729 xdrainenergym(mdef, TRUE);
2735 if (DEADMONSTER(mdef)) {
2737 if (DEADMONSTER(mdef)) /* not lifesaved */
2741 You("%s %s!", is_animal(youmonst.data) ? "regurgitate" : "expel",
2744 You("%s
\82ð%s
\82µ
\82½
\81I", mon_nam(mdef),
2745 is_animal(youmonst.data) ? "
\93f
\82«
\96ß" : "
\94r
\8fo");
2747 if (Slow_digestion || is_animal(youmonst.data)) {
2749 pline("Obviously, you didn't like %s taste.",
2750 s_suffix(mon_nam(mdef)));
2752 pline("
\82Ç
\82¤
\82à%s
\82Ì
\96¡
\82Í
\8dD
\82«
\82É
\82È
\82ê
\82È
\82¢
\81D",
2762 missum(mdef, mattk, wouldhavehit)
2763 register struct monst *mdef;
2764 register struct attack *mattk;
2765 boolean wouldhavehit;
2767 if (wouldhavehit) /* monk is missing due to penalty for wearing suit */
2769 Your("armor is rather cumbersome...");
2771 Your("
\96h
\8bï
\82Í
\8f
\82µ
\8e×
\96\82\82¾
\81D
\81D
\81D");
2773 if (could_seduce(&youmonst, mdef, mattk))
2775 You("pretend to be friendly to %s.", mon_nam(mdef));
2777 You("%s
\82É
\97F
\8dD
\93I
\82È
\82Ó
\82è
\82ð
\82µ
\82½
\81D", mon_nam(mdef));
2778 else if (canspotmon(mdef) && flags.verbose)
2780 You("miss %s.", mon_nam(mdef));
2782 Your("%s
\82Ö
\82Ì
\8dU
\8c\82\82Í
\8aO
\82ê
\82½
\81D", mon_nam(mdef));
2787 Your("
\89½
\8eÒ
\82©
\82Ö
\82Ì
\8dU
\8c\82\82Í
\8aO
\82ê
\82½
\81D");
2788 if (!mdef->msleeping && mdef->mcanmove)
2792 /* attack monster as a monster; returns True if mon survives */
2795 register struct monst *mon;
2797 struct attack *mattk, alt_attk;
2798 struct obj *weapon, **originalweapon;
2799 boolean altwep = FALSE, weapon_used = FALSE, odd_claw = TRUE;
2800 int i, tmp, armorpenalty, sum[NATTK], nsum = 0, dhit = 0, attknum = 0;
2801 int dieroll, multi_claw = 0;
2803 /* with just one touch/claw/weapon attack, both rings matter;
2804 with more than one, alternate right and left when checking
2805 whether silver ring causes successful hit */
2806 for (i = 0; i < NATTK; i++) {
2808 mattk = getmattk(&youmonst, mon, i, sum, &alt_attk);
2809 if (mattk->aatyp == AT_WEAP
2810 || mattk->aatyp == AT_CLAW || mattk->aatyp == AT_TUCH)
2813 multi_claw = (multi_claw > 1); /* switch from count to yes/no */
2815 for (i = 0; i < NATTK; i++) {
2816 /* sum[i] = 0; -- now done above */
2817 mattk = getmattk(&youmonst, mon, i, sum, &alt_attk);
2819 switch (mattk->aatyp) {
2821 /* if (!uwep) goto weaponless; */
2823 odd_claw = !odd_claw; /* see case AT_CLAW,AT_TUCH below */
2824 /* if we've already hit with a two-handed weapon, we don't
2825 get to make another weapon attack (note: monsters who
2826 use weapons do not have this restriction, but they also
2827 never have the opportunity to use two weapons) */
2828 if (weapon_used && sum[i - 1] && uwep && bimanual(uwep))
2830 /* Certain monsters don't use weapons when encountered as enemies,
2831 * but players who polymorph into them have hands or claws and
2832 * thus should be able to use weapons. This shouldn't prohibit
2833 * the use of most special abilities, either.
2834 * If monster has multiple claw attacks, only one can use weapon.
2837 /* Potential problem: if the monster gets multiple weapon attacks,
2838 * we currently allow the player to get each of these as a weapon
2839 * attack. Is this really desirable?
2841 /* approximate two-weapon mode; known_hitum() -> hmon() -> &c
2842 might destroy the weapon argument, but it might also already
2843 be Null, and we want to track that for passive() */
2844 originalweapon = (altwep && uswapwep) ? &uswapwep : &uwep;
2845 if (uswapwep /* set up 'altwep' flag for next iteration */
2846 /* only consider seconary when wielding one-handed primary */
2847 && uwep && (uwep->oclass == WEAPON_CLASS || is_weptool(uwep))
2849 /* only switch if not wearing shield and not at artifact;
2850 shield limitation is iffy since still get extra swings
2851 if polyform has them, but it matches twoweap behavior;
2852 twoweap also only allows primary to be an artifact, so
2853 if alternate weapon is one, don't use it */
2854 && !uarms && !uswapwep->oartifact
2855 /* only switch to uswapwep if it's a weapon */
2856 && (uswapwep->oclass == WEAPON_CLASS || is_weptool(uswapwep))
2857 /* only switch if uswapwep is not bow, arrows, or darts */
2858 && !(is_launcher(uswapwep) || is_ammo(uswapwep)
2859 || is_missile(uswapwep)) /* dart, shuriken, boomerang */
2860 /* and not two-handed and not incapable of being wielded */
2861 && !bimanual(uswapwep)
2862 && !(objects[uswapwep->otyp].oc_material == SILVER
2864 altwep = !altwep; /* toggle for next attack */
2865 weapon = *originalweapon;
2866 if (!weapon) /* no need to go beyond no-gloves to rings; not ...*/
2867 originalweapon = &uarmg; /*... subject to erosion damage */
2869 tmp = find_roll_to_hit(mon, AT_WEAP, weapon, &attknum,
2872 dhit = (tmp > dieroll || u.uswallow);
2873 /* caller must set bhitpos */
2874 if (!known_hitum(mon, weapon, &dhit, tmp,
2875 armorpenalty, mattk, dieroll)) {
2876 /* enemy dead, before any special abilities used */
2881 /* originalweapon points to an equipment slot which might
2882 now be empty if the weapon was destroyed during the hit;
2883 passive(,weapon,...) won't call passive_obj() in that case */
2884 weapon = *originalweapon; /* might receive passive erosion */
2885 /* might be a worm that gets cut in half; if so, early return */
2886 if (m_at(u.ux + u.dx, u.uy + u.dy) != mon) {
2887 i = NATTK; /* skip additional attacks */
2888 /* proceed with uswapwep->cursed check, then exit loop */
2891 /* Do not print "You hit" message; known_hitum already did it. */
2892 if (dhit && mattk->adtyp != AD_SPEL && mattk->adtyp != AD_PHYS)
2893 sum[i] = damageum(mon, mattk, 0);
2896 if (uwep && !cantwield(youmonst.data) && !weapon_used)
2900 if (uwep && youmonst.data->mlet == S_LICH && !weapon_used)
2909 tmp = find_roll_to_hit(mon, mattk->aatyp, (struct obj *) 0,
2910 &attknum, &armorpenalty);
2912 dhit = (tmp > dieroll || u.uswallow);
2914 int compat, specialdmg;
2915 long silverhit = 0L;
2916 #if 0 /*JP*//*
\82·
\82×
\82Ä
\81u
\8dU
\8c\82\82µ
\82½
\81v
\82É
\82·
\82é */
2917 const char *verb = 0; /* verb or body part */
2921 && (compat = could_seduce(&youmonst, mon, mattk)) != 0) {
2924 (mon->mcansee && haseyes(mon->data)) ? "smile at"
2927 (compat == 2) ? "engagingly" : "seductively");
2929 You("%s
\82Ö%s%s
\81D",
2931 compat == 2 ? "
\96£
\97Í
\93I
\82É" : "
\97U
\98f
\93I
\82É",
2932 mon->mcansee && haseyes(mon->data) ? "
\94÷
\8fÎ
\82Ý
\82©
\82¯
\82½"
2933 : "
\98b
\82µ
\82©
\82¯
\82½");
2935 /* doesn't anger it; no wakeup() */
2936 sum[i] = damageum(mon, mattk, 0);
2941 specialdmg = 0; /* blessed and/or silver bonus */
2942 switch (mattk->aatyp) {
2945 /* verb=="claws" may be overridden below */
2947 verb = (mattk->aatyp == AT_TUCH) ? "touch" : "claws";
2949 /* decide if silver-hater will be hit by silver ring(s);
2950 for 'multi_claw' where attacks alternate right/left,
2951 assume 'even' claw or touch attacks use right hand
2952 or paw, 'odd' ones use left for ring interaction;
2953 even vs odd is based on actual attacks rather
2954 than on index into mon->dat->mattk[] so that {bite,
2955 claw,claw} instead of {claw,claw,bite} doesn't
2956 make poly'd hero mysteriously become left-handed */
2957 odd_claw = !odd_claw;
2958 specialdmg = special_dmgval(&youmonst, mon,
2960 | ((odd_claw || !multi_claw)
2962 | ((!odd_claw || !multi_claw)
2967 /* assumes mind flayer's tentacles-on-head rather
2968 than sea monster's tentacle-as-arm */
2977 specialdmg = special_dmgval(&youmonst, mon, W_ARMF,
2982 verb = "head butt"; /* mbodypart(mon,HEAD)=="head" */
2983 /* hypothetical; if any form with a head-butt attack
2984 could wear a helmet, it would hit shades when
2985 wearing a blessed (or silver) one */
2987 specialdmg = special_dmgval(&youmonst, mon, W_ARMH,
3006 if (mon->data == &mons[PM_SHADE] && !specialdmg) {
3008 if (!strcmp(verb, "hit")
3009 || (mattk->aatyp == AT_CLAW && humanoid(mon->data)))
3013 Your("%s %s harmlessly through %s.",
3014 verb, vtense(verb, "pass"), mon_nam(mon));
3016 Your("
\8dU
\8c\82\82Í%s
\82ð
\92Ê
\82è
\82Ê
\82¯
\82½
\81D",
3020 if (mattk->aatyp == AT_TENT) {
3022 Your("tentacles suck %s.", mon_nam(mon));
3024 Your("
\90G
\8eè
\82ª%s
\82Ì
\91Ì
\89t
\82ð
\8bz
\82¢
\82Æ
\82Á
\82½
\81D", mon_nam(mon));
3027 if (mattk->aatyp == AT_CLAW)
3028 verb = "hit"; /* not "claws" */
3031 You("%s %s.", verb, mon_nam(mon));
3033 You("%s
\82ð
\8dU
\8c\82\82µ
\82½
\81D", mon_nam(mon));
3035 if (silverhit && flags.verbose)
3036 silver_sears(&youmonst, mon, silverhit);
3038 sum[i] = damageum(mon, mattk, specialdmg);
3040 } else { /* !dhit */
3041 missum(mon, mattk, (tmp + armorpenalty > dieroll));
3047 long silverhit = 0L;
3048 boolean byhand = hug_throttles(&mons[u.umonnum]), /* rope golem */
3049 unconcerned = (byhand && !can_be_strangled(mon));
3051 if (sticks(mon->data) || u.uswallow || notonhead
3052 || (byhand && (uwep || !has_head(mon->data)))) {
3053 /* can't hold a holder due to subsequent ambiguity over
3054 who is holding whom; can't hug engulfer from inside;
3055 can't hug a worm tail (would immobilize entire worm!);
3056 byhand: can't choke something that lacks a head;
3057 not allowed to make a choking hug if wielding a weapon
3058 (but might have grabbed w/o weapon, then wielded one,
3059 and may even be attacking a different monster now) */
3060 if (byhand && uwep && u.ustuck
3061 && !(sticks(u.ustuck->data) || u.uswallow))
3063 continue; /* not 'break'; bypass passive counter-attack */
3065 /* automatic if prev two attacks succeed, or if
3066 already grabbed in a previous attack */
3069 /* choking hug/throttling grab uses hands (gloves or rings);
3070 normal hug uses outermost of cloak/suit/shirt */
3071 specialdmg = special_dmgval(&youmonst, mon,
3072 byhand ? (W_ARMG | W_RINGL | W_RINGR)
3073 : (W_ARMC | W_ARM | W_ARMU),
3076 /* strangling something which can't be strangled */
3077 if (mattk != &alt_attk) {
3081 /* change damage to 1d1; not strangling but still
3082 doing [minimal] physical damage to victim's body */
3083 mattk->damn = mattk->damd = 1;
3084 /* don't give 'unconcerned' feedback if there is extra damage
3085 or if it is nearly destroyed or if creature doesn't have
3086 the mental ability to be concerned in the first place */
3087 if (specialdmg || mindless(mon->data)
3088 || mon->mhp <= 1 + max(u.udaminc, 1))
3089 unconcerned = FALSE;
3091 if (mon->data == &mons[PM_SHADE]) {
3093 const char *verb = byhand ? "grasp" : "hug";
3096 /* hugging a shade; successful if blessed outermost armor
3097 for normal hug, or blessed gloves or silver ring(s) for
3098 choking hug; deals damage but never grabs hold */
3101 You("%s %s%s", verb, mon_nam(mon), exclam(specialdmg));
3103 You("%s
\82ð
\82Â
\82©
\82ñ
\82¾%s", mon_nam(mon), exclam(specialdmg));
3105 if (silverhit && flags.verbose)
3106 silver_sears(&youmonst, mon, silverhit);
3107 sum[i] = damageum(mon, mattk, specialdmg);
3110 Your("%s passes harmlessly through %s.",
3111 verb, mon_nam(mon));
3113 You("%s
\82ð
\82Â
\82©
\82Ü
\82¦
\82æ
\82¤
\82Æ
\82µ
\82½
\82ª
\92Ê
\82è
\82Ê
\82¯
\82½
\81D",
3119 /* hug attack against ordinary foe */
3120 if (mon == u.ustuck) {
3122 pline("%s is being %s%s.", Monnam(mon),
3123 byhand ? "throttled" : "crushed",
3124 /* extra feedback for non-breather being choked */
3125 unconcerned ? " but doesn't seem concerned" : "");
3127 pline("%s
\82Í%s%s
\81D", Monnam(mon),
3128 byhand ? "
\8eñ
\82ð
\8di
\82ß
\82ç
\82ê
\82Ä
\82¢
\82é" : "
\89\9f\82µ
\82Â
\82Ô
\82³
\82ê
\82Ä
\82¢
\82é",
3129 /* extra feedback for non-breather being choked */
3130 unconcerned ? "
\82ª
\81C
\8bC
\82É
\82µ
\82Ä
\82¢
\82È
\82¢
\82æ
\82¤
\82¾" : "");
3132 if (silverhit && flags.verbose)
3133 silver_sears(&youmonst, mon, silverhit);
3134 sum[i] = damageum(mon, mattk, specialdmg);
3135 } else if (i >= 2 && sum[i - 1] && sum[i - 2]) {
3136 /* in case we're hugging a new target while already
3137 holding something else; yields feedback
3138 "<u.ustuck> is no longer in your clutches" */
3139 if (u.ustuck && u.ustuck != mon)
3142 You("grab %s!", mon_nam(mon));
3144 You("%s
\82ð
\82Â
\82©
\82Ü
\82¦
\82½
\81I", mon_nam(mon));
3146 if (silverhit && flags.verbose)
3147 silver_sears(&youmonst, mon, silverhit);
3148 sum[i] = damageum(mon, mattk, specialdmg);
3150 break; /* AT_HUGS */
3153 case AT_EXPL: /* automatic hit if next to */
3156 sum[i] = explum(mon, mattk);
3160 tmp = find_roll_to_hit(mon, mattk->aatyp, (struct obj *) 0,
3161 &attknum, &armorpenalty);
3162 if ((dhit = (tmp > rnd(20 + i)))) {
3164 if (mon->data == &mons[PM_SHADE])
3166 Your("attempt to surround %s is harmless.", mon_nam(mon));
3168 You("%s
\82ð
\88ù
\82Ý
\82±
\82à
\82¤
\82Æ
\82µ
\82½
\82ª
\8e¸
\94s
\82µ
\82½
\81D", mon_nam(mon));
3170 sum[i] = gulpum(mon, mattk);
3171 if (sum[i] == 2 && (mon->data->mlet == S_ZOMBIE
3172 || mon->data->mlet == S_MUMMY)
3173 && rn2(5) && !Sick_resistance) {
3175 You_feel("%ssick.", (Sick) ? "very " : "");
3177 You_feel("%s
\8bC
\95ª
\82ª
\88«
\82¢
\81D", (Sick) ? "
\82Æ
\82Ä
\82à" : "");
3178 mdamageu(mon, rnd(8));
3182 missum(mon, mattk, FALSE);
3187 /* No check for uwep; if wielding nothing we want to
3188 * do the normal 1-2 points bare hand damage...
3190 if ((youmonst.data->mlet == S_KOBOLD
3191 || youmonst.data->mlet == S_ORC
3192 || youmonst.data->mlet == S_GNOME) && !weapon_used)
3199 /* Not break--avoid passive attacks from enemy */
3203 case AT_GAZE: /* all done using #monster command */
3207 default: /* Strange... */
3208 impossible("strange attack of yours (%d)", mattk->aatyp);
3211 u.mh = -1; /* dead in the current form */
3216 (void) passive(mon, weapon, 1, 0, mattk->aatyp, FALSE);
3217 nsum = 0; /* return value below used to be 'nsum > 0' */
3219 (void) passive(mon, weapon, sum[i], 1, mattk->aatyp, FALSE);
3223 /* don't use sum[i] beyond this point;
3224 'i' will be out of bounds if we get here via 'goto' */
3226 /* when using dual weapons, cursed secondary weapon doesn't weld,
3227 it gets dropped; do the same when multiple AT_WEAP attacks
3229 if (uswapwep && weapon == uswapwep && weapon->cursed) {
3231 break; /* don't proceed with additional attacks */
3233 /* stop attacking if defender has died;
3234 needed to defer this until after uswapwep->cursed check */
3235 if (DEADMONSTER(mon))
3238 break; /* No extra attacks if no longer a monster */
3240 break; /* If paralyzed while attacking, i.e. floating eye */
3242 /* return value isn't used, but make it match hitum()'s */
3243 return !DEADMONSTER(mon);
3246 /* Special (passive) attacks on you by monsters done here.
3249 passive(mon, weapon, mhit, malive, aatyp, wep_was_destroyed)
3251 struct obj *weapon; /* uwep or uswapwep or uarmg or uarmf or Null */
3255 boolean wep_was_destroyed;
3257 register struct permonst *ptr = mon->data;
3258 register int i, tmp;
3262 return (malive | mhit); /* no passive attacks */
3263 if (ptr->mattk[i].aatyp == AT_NONE)
3264 break; /* try this one */
3266 /* Note: tmp not always used */
3267 if (ptr->mattk[i].damn)
3268 tmp = d((int) ptr->mattk[i].damn, (int) ptr->mattk[i].damd);
3269 else if (ptr->mattk[i].damd)
3270 tmp = d((int) mon->m_lev + 1, (int) ptr->mattk[i].damd);
3274 /* These affect you even if they just died.
3276 switch (ptr->mattk[i].adtyp) {
3278 if (mhit && !mon->mcan && weapon) {
3279 if (aatyp == AT_KICK) {
3280 if (uarmf && !rn2(6))
3281 (void) erode_obj(uarmf, xname(uarmf), ERODE_BURN,
3282 EF_GREASE | EF_VERBOSE);
3283 } else if (aatyp == AT_WEAP || aatyp == AT_CLAW
3284 || aatyp == AT_MAGC || aatyp == AT_TUCH)
3285 passive_obj(mon, weapon, &(ptr->mattk[i]));
3289 if (mhit && rn2(2)) {
3290 if (Blind || !flags.verbose)
3292 You("are splashed!");
3294 You("
\89½
\82©
\82ð
\97\81\82Ñ
\82¹
\82ç
\82ê
\82½
\81I");
3297 You("are splashed by %s %s!", s_suffix(mon_nam(mon)),
3300 You("%s
\82Ì%s
\82ð
\97\81\82Ñ
\82¹
\82ç
\82ê
\82½
\81I", mon_nam(mon),
3304 if (!Acid_resistance)
3307 erode_armor(&youmonst, ERODE_CORRODE);
3309 if (mhit && weapon) {
3310 if (aatyp == AT_KICK) {
3311 if (uarmf && !rn2(6))
3312 (void) erode_obj(uarmf, xname(uarmf), ERODE_CORRODE,
3313 EF_GREASE | EF_VERBOSE);
3314 } else if (aatyp == AT_WEAP || aatyp == AT_CLAW
3315 || aatyp == AT_MAGC || aatyp == AT_TUCH)
3316 passive_obj(mon, weapon, &(ptr->mattk[i]));
3318 exercise(A_STR, FALSE);
3321 if (mhit) { /* successful attack */
3322 long protector = attk_protection((int) aatyp);
3324 /* hero using monsters' AT_MAGC attack is hitting hand to
3325 hand rather than casting a spell */
3326 if (aatyp == AT_MAGC)
3329 if (protector == 0L /* no protection */
3330 || (protector == W_ARMG && !uarmg
3331 && !uwep && !wep_was_destroyed)
3332 || (protector == W_ARMF && !uarmf)
3333 || (protector == W_ARMH && !uarmh)
3334 || (protector == (W_ARMC | W_ARMG) && (!uarmc || !uarmg))) {
3335 if (!Stone_resistance
3336 && !(poly_when_stoned(youmonst.data)
3337 && polymon(PM_STONE_GOLEM))) {
3338 done_in_by(mon, STONING); /* "You turn to stone..." */
3345 if (mhit && !mon->mcan && weapon) {
3346 if (aatyp == AT_KICK) {
3348 (void) erode_obj(uarmf, xname(uarmf), ERODE_RUST,
3349 EF_GREASE | EF_VERBOSE);
3350 } else if (aatyp == AT_WEAP || aatyp == AT_CLAW
3351 || aatyp == AT_MAGC || aatyp == AT_TUCH)
3352 passive_obj(mon, weapon, &(ptr->mattk[i]));
3356 if (mhit && !mon->mcan && weapon) {
3357 if (aatyp == AT_KICK) {
3359 (void) erode_obj(uarmf, xname(uarmf), ERODE_CORRODE,
3360 EF_GREASE | EF_VERBOSE);
3361 } else if (aatyp == AT_WEAP || aatyp == AT_CLAW
3362 || aatyp == AT_MAGC || aatyp == AT_TUCH)
3363 passive_obj(mon, weapon, &(ptr->mattk[i]));
3367 /* wrath of gods for attacking Oracle */
3369 shieldeff(u.ux, u.uy);
3371 pline("A hail of magic missiles narrowly misses you!");
3373 pline("
\96\82\96@
\82Ì
\96î
\82Ì
\89J
\82ª
\82©
\82·
\82ß
\82Ä
\82¢
\82Á
\82½
\81I");
3376 You("are hit by magic missiles appearing from thin air!");
3378 pline("
\93Ë
\94@
\8bó
\92\86\82É
\8c»
\82í
\82ê
\82½
\96\82\96@
\82Ì
\96î
\82ª
\96½
\92\86\82µ
\82½
\81I");
3382 case AD_ENCH: /* KMH -- remove enchantment (disenchanter) */
3384 if (aatyp == AT_KICK) {
3387 } else if (aatyp == AT_BITE || aatyp == AT_BUTT
3388 || (aatyp >= AT_STNG && aatyp < AT_WEAP)) {
3389 break; /* no object involved */
3391 passive_obj(mon, weapon, &(ptr->mattk[i]));
3398 /* These only affect you if they still live.
3400 if (malive && !mon->mcan && rn2(3)) {
3401 switch (ptr->mattk[i].adtyp) {
3403 if (ptr == &mons[PM_FLOATING_EYE]) {
3404 if (!canseemon(mon)) {
3409 if (ureflects("%s gaze is reflected by your %s.",
3410 s_suffix(Monnam(mon)))) {
3412 if (ureflects("%s
\82Ì
\82É
\82ç
\82Ý
\82Í%s
\82É
\82æ
\82Á
\82Ä
\94½
\8eË
\82³
\82ê
\82½
\81D",
3416 } else if (Free_action) {
3418 You("momentarily stiffen under %s gaze!",
3419 s_suffix(mon_nam(mon)));
3421 You("%s
\82Ì
\82É
\82ç
\82Ý
\82Å
\88ê
\8fu
\8dd
\92¼
\82µ
\82½
\81I",
3424 } else if (Hallucination && rn2(4)) {
3426 pline("%s looks %s%s.", Monnam(mon),
3427 !rn2(2) ? "" : "rather ",
3428 !rn2(2) ? "numb" : "stupified");
3430 pline("%s
\82Í%s
\82Î
\82©
\82É
\82È
\82Á
\82½
\82æ
\82¤
\82¾
\81D", Monnam(mon),
3431 !rn2(2) ? "" : "
\8f
\82µ");
3435 You("are frozen by %s gaze!", s_suffix(mon_nam(mon)));
3437 You("%s
\82Ì
\82É
\82ç
\82Ý
\82Å
\93®
\82¯
\82È
\82
\82È
\82Á
\82½
\81I", mon_nam(mon));
3438 nomul((ACURR(A_WIS) > 12 || rn2(4)) ? -tmp : -127);
3440 multi_reason = "frozen by a monster's gaze";
3442 multi_reason = "
\89ö
\95¨
\82Ì
\82É
\82ç
\82Ý
\82Å
\8dd
\92¼
\82µ
\82Ä
\82¢
\82é
\8e\9e\82É";
3447 pline("%s cannot defend itself.",
3448 Adjmonnam(mon, "blind"));
3450 pline("%s
\82Í
\96h
\8cä
\82Å
\82«
\82È
\82¢
\81D",
3451 Adjmonnam(mon,"
\96Ú
\82Ì
\8c©
\82¦
\82È
\82¢"));
3456 } else if (Free_action) {
3458 You("momentarily stiffen.");
3460 You("
\88ê
\8fu
\8dd
\92¼
\82µ
\82½
\81D");
3461 } else { /* gelatinous cube */
3463 You("are frozen by %s!", mon_nam(mon));
3465 You("%s
\82É
\82æ
\82Á
\82Ä
\93®
\82¯
\82È
\82
\82È
\82Á
\82½
\81I", mon_nam(mon));
3466 nomovemsg = You_can_move_again;
3469 multi_reason = "frozen by a monster";
3471 multi_reason = "
\89ö
\95¨
\82É
\82æ
\82Á
\82Ä
\8dd
\92¼
\82µ
\82Ä
\82¢
\82é
\8e\9e\82É";
3472 exercise(A_DEX, FALSE);
3475 case AD_COLD: /* brown mold or blue jelly */
3476 if (monnear(mon, u.ux, u.uy)) {
3477 if (Cold_resistance) {
3478 shieldeff(u.ux, u.uy);
3480 You_feel("a mild chill.");
3482 You("
\8a¦
\82³
\82ð
\8a´
\82¶
\82½
\81D");
3483 ugolemeffects(AD_COLD, tmp);
3487 You("are suddenly very cold!");
3489 You("
\93Ë
\91R
\81C
\96Ò
\97ó
\82É
\8a¦
\82
\82È
\82Á
\82½
\81I");
3491 /* monster gets stronger with your heat! */
3492 mon->mhp += tmp / 2;
3493 if (mon->mhpmax < mon->mhp)
3494 mon->mhpmax = mon->mhp;
3495 /* at a certain point, the monster will reproduce! */
3496 if (mon->mhpmax > ((int) (mon->m_lev + 1) * 8))
3497 (void) split_mon(mon, &youmonst);
3500 case AD_STUN: /* specifically yellow mold */
3502 make_stunned((long) tmp, TRUE);
3505 if (monnear(mon, u.ux, u.uy)) {
3506 if (Fire_resistance) {
3507 shieldeff(u.ux, u.uy);
3509 You_feel("mildly warm.");
3511 You("
\92g
\82©
\82³
\82ð
\8a´
\82¶
\82½
\81D");
3512 ugolemeffects(AD_FIRE, tmp);
3516 You("are suddenly very hot!");
3518 You("
\93Ë
\91R
\81C
\96Ò
\97ó
\82É
\94M
\82
\82È
\82Á
\82½
\81I");
3519 mdamageu(mon, tmp); /* fire damage */
3523 if (Shock_resistance) {
3524 shieldeff(u.ux, u.uy);
3526 You_feel("a mild tingle.");
3528 You("
\83s
\83\8a\83s
\83\8a\82Æá
\83\82ê
\82ð
\8a´
\82¶
\82½
\81D");
3529 ugolemeffects(AD_ELEC, tmp);
3533 You("are jolted with electricity!");
3535 You("
\93d
\8bC
\83V
\83\87\83b
\83N
\82ð
\82¤
\82¯
\82½
\81I");
3542 return (malive | mhit);
3546 * Special (passive) attacks on an attacking object by monsters done here.
3547 * Assumes the attack was successful.
3550 passive_obj(mon, obj, mattk)
3552 struct obj *obj; /* null means pick uwep, uswapwep or uarmg */
3553 struct attack *mattk; /* null means we find one internally */
3555 struct permonst *ptr = mon->data;
3558 /* [this first bit is obsolete; we're not called with Null anymore] */
3559 /* if caller hasn't specified an object, use uwep, uswapwep or uarmg */
3561 obj = (u.twoweap && uswapwep && !rn2(2)) ? uswapwep : uwep;
3562 if (!obj && mattk->adtyp == AD_ENCH)
3563 obj = uarmg; /* no weapon? then must be gloves */
3565 return; /* no object to affect */
3568 /* if caller hasn't specified an attack, find one */
3572 return; /* no passive attacks */
3573 if (ptr->mattk[i].aatyp == AT_NONE)
3574 break; /* try this one */
3576 mattk = &(ptr->mattk[i]);
3579 switch (mattk->adtyp) {
3581 if (!rn2(6) && !mon->mcan
3582 /* steam vortex: fire resist applies, fire damage doesn't */
3583 && mon->data != &mons[PM_STEAM_VORTEX]) {
3584 (void) erode_obj(obj, NULL, ERODE_BURN, EF_NONE);
3589 (void) erode_obj(obj, NULL, ERODE_CORRODE, EF_GREASE);
3594 (void) erode_obj(obj, (char *) 0, ERODE_RUST, EF_GREASE);
3599 (void) erode_obj(obj, (char *) 0, ERODE_CORRODE, EF_GREASE);
3604 if (drain_item(obj, TRUE) && carried(obj)
3605 && (obj->known || obj->oclass == ARMOR_CLASS)) {
3607 pline("%s less effective.", Yobjnam2(obj, "seem"));
3609 Your("%s
\82©
\82ç
\96\82\97Í
\82ª
\8fÁ
\82¦
\82½
\82æ
\82¤
\82¾
\81D", xname(obj));
3621 /* Note: caller must ascertain mtmp is mimicking... */
3623 stumble_onto_mimic(mtmp)
3627 const char *fmt = "Wait! That's %s!", *generic = "a monster", *what = 0;
3629 const char *fmt = "
\82¿
\82å
\82Á
\82Æ
\82Ü
\82Á
\82½
\81I%s
\82¾
\81I", *generic = "
\89ö
\95¨", *what = 0;
3631 if (!u.ustuck && !mtmp->mflee && dmgtype(mtmp->data, AD_STCK))
3636 what = generic; /* with default fmt */
3637 else if (M_AP_TYPE(mtmp) == M_AP_MONSTER)
3638 what = a_monnam(mtmp); /* differs from what was sensed */
3640 int glyph = levl[u.ux + u.dx][u.uy + u.dy].glyph;
3642 if (glyph_is_cmap(glyph) && (glyph_to_cmap(glyph) == S_hcdoor
3643 || glyph_to_cmap(glyph) == S_vcdoor))
3645 fmt = "The door actually was %s!";
3647 fmt = "
\94à
\82Í
\8eÀ
\8dÛ
\82É
\82Í%s
\82¾
\82Á
\82½
\81I";
3648 else if (glyph_is_object(glyph) && glyph_to_obj(glyph) == GOLD_PIECE)
3650 fmt = "That gold was %s!";
3652 fmt = "
\8bà
\89Ý
\82Í%s
\82¾
\82Á
\82½
\81I";
3654 /* cloned Wiz starts out mimicking some other monster and
3655 might make himself invisible before being revealed */
3656 if (mtmp->minvis && !See_invisible)
3659 what = a_monnam(mtmp);
3664 wakeup(mtmp, FALSE); /* clears mimicking */
3665 /* if hero is blind, wakeup() won't display the monster even though
3666 it's no longer concealed */
3667 if (!canspotmon(mtmp)
3668 && !glyph_is_invisible(levl[mtmp->mx][mtmp->my].glyph))
3669 map_invisible(mtmp->mx, mtmp->my);
3676 char *hands = makeplural(body_part(HAND));
3678 if (!u.umconf || mon->mconf)
3680 if (u.umconf == 1) {
3683 Your("%s stop tingling.", hands);
3685 Your("%s
\82Ìá
\83\82ê
\82ª
\82Æ
\82ê
\82½
\81D", hands);
3688 Your("%s stop glowing %s.", hands, hcolor(NH_RED));
3690 Your("%s
\82Ì%s
\8bP
\82«
\82Í
\82È
\82
\82È
\82Á
\82½
\81D", hands, hcolor(NH_RED));
3694 pline_The("tingling in your %s lessens.", hands);
3696 pline("%s
\82Ìá
\83\82ê
\82ª
\82Æ
\82ê
\82Ä
\82«
\82½
\81D",hands);
3699 Your("%s no longer glow so brightly %s.", hands, hcolor(NH_RED));
3701 Your("%s
\82Ì%s
\8bP
\82«
\82ª
\82È
\82
\82È
\82Á
\82Ä
\82«
\82½
\81D",hands, hcolor(NH_RED));
3707 flash_hits_mon(mtmp, otmp)
3709 struct obj *otmp; /* source of flash */
3711 int tmp, amt, res = 0, useeit = canseemon(mtmp);
3713 if (mtmp->msleeping) {
3714 mtmp->msleeping = 0;
3717 pline_The("flash awakens %s.", mon_nam(mtmp));
3719 pline("
\91M
\8cõ
\82Å%s
\82ª
\96Ú
\82ð
\8ao
\82Ü
\82µ
\82½
\81D", mon_nam(mtmp));
3722 } else if (mtmp->data->mlet != S_LIGHT) {
3723 if (!resists_blnd(mtmp)) {
3724 tmp = dist2(otmp->ox, otmp->oy, mtmp->mx, mtmp->my);
3727 pline("%s is blinded by the flash!", Monnam(mtmp));
3729 pline("%s
\82Í
\91M
\8cõ
\82Å
\96Ú
\82ª
\8c©
\82¦
\82È
\82
\82È
\82Á
\82½
\81I", Monnam(mtmp));
3732 if (mtmp->data == &mons[PM_GREMLIN]) {
3733 /* Rule #1: Keep them out of the light. */
3734 amt = otmp->otyp == WAN_LIGHT ? d(1 + otmp->spe, 4)
3735 : rn2(min(mtmp->mhp, 4));
3736 light_hits_gremlin(mtmp, amt);
3738 if (!DEADMONSTER(mtmp)) {
3739 if (!context.mon_moving)
3740 setmangry(mtmp, TRUE);
3741 if (tmp < 9 && !mtmp->isshk && rn2(4))
3742 monflee(mtmp, rn2(4) ? rnd(100) : 0, FALSE, TRUE);
3744 mtmp->mblinded = (tmp < 3) ? 0 : rnd(1 + 50 / tmp);
3752 light_hits_gremlin(mon, dmg)
3757 pline("%s %s!", Monnam(mon),
3758 (dmg > mon->mhp / 2) ? "wails in agony" : "cries out in pain");
3760 pline("%s
\82Í%s
\81I", Monnam(mon),
3761 (dmg > mon->mhp / 2) ? "
\8bê
\92É
\82Ì
\90º
\82ð
\82 \82°
\82½" : "
\8c\83\92É
\82Å
\8b©
\82ñ
\82¾");
3764 wake_nearto(mon->mx, mon->my, 30);
3765 if (DEADMONSTER(mon)) {
3766 if (context.mon_moving)
3767 monkilled(mon, (char *) 0, AD_BLND);
3770 } else if (cansee(mon->mx, mon->my) && !canspotmon(mon)) {
3771 map_invisible(mon->mx, mon->my);