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)
200 pline("A %s %s appeared!",
201 mtmp->mtame ? "tame" : "wild", l_monnam(mtmp));
202 else if (Blind || (is_pool(mtmp->mx, mtmp->my) && !Underwater))
204 pline("Wait! There's a hidden monster there!");
206 pline("
\91Ò
\82Ä
\81I
\89ö
\95¨
\82ª
\89B
\82ê
\82Ä
\82¢
\82é
\81I");
207 else if ((obj = level.objects[mtmp->mx][mtmp->my]) != 0)
209 pline("Wait! There's %s hiding under %s!",
210 an(l_monnam(mtmp)), doname(obj));
212 pline("
\91Ò
\82Ä
\81I%s
\82Ì
\89º
\82É%s
\82ª
\89B
\82ê
\82Ä
\82¢
\82é
\81I",
213 doname(obj), l_monnam(mtmp));
220 * make sure to wake up a monster from the above cases if the
221 * hero can sense that the monster is there.
223 if ((mtmp->mundetected || M_AP_TYPE(mtmp)) && sensemon(mtmp)) {
224 mtmp->mundetected = 0;
228 if (flags.confirm && mtmp->mpeaceful
229 && !Confusion && !Hallucination && !Stunned) {
230 /* Intelligent chaotic weapons (Stormbringer) want blood */
231 if (wep && wep->oartifact == ART_STORMBRINGER) {
232 override_confirmation = TRUE;
235 if (canspotmon(mtmp)) {
239 Sprintf(qbuf, "Really attack %s?", mon_nam(mtmp));
241 Sprintf(qbuf, "
\96{
\93\96\82É%s
\82ð
\8dU
\8c\82\82·
\82é
\82Ì
\81H", mon_nam(mtmp));
242 if (!paranoid_query(ParanoidHit, qbuf)) {
253 * It is unchivalrous for a knight to attack the defenseless or from behind.
259 if (u.ualign.record <= -10)
262 if (Role_if(PM_KNIGHT) && u.ualign.type == A_LAWFUL
263 && (!mtmp->mcanmove || mtmp->msleeping
264 || (mtmp->mflee && !mtmp->mavenge))) {
268 pline("
\82±
\82ê
\82Í
\94Ú
\8b¯
\82È
\8ds
\82¢
\82¾
\81I");
270 } else if (Role_if(PM_SAMURAI) && mtmp->mpeaceful) {
271 /* attacking peaceful creatures is bad for the samurai's giri */
273 You("dishonorably attack the innocent!");
275 pline("
\96³
\8eÀ
\82Ì
\8eÒ
\82ð
\8dU
\8c\82\82·
\82é
\82Ì
\82Í
\95s
\96¼
\97_
\82¾
\81I");
281 find_roll_to_hit(mtmp, aatyp, weapon, attk_count, role_roll_penalty)
282 register struct monst *mtmp;
283 uchar aatyp; /* usually AT_WEAP or AT_KICK */
284 struct obj *weapon; /* uwep or uswapwep or NULL */
285 int *attk_count, *role_roll_penalty;
289 *role_roll_penalty = 0; /* default is `none' */
291 tmp = 1 + Luck + abon() + find_mac(mtmp) + u.uhitinc
292 + maybe_polyd(youmonst.data->mlevel, u.ulevel);
294 /* some actions should occur only once during multiple attacks */
295 if (!(*attk_count)++) {
296 /* knight's chivalry or samurai's giri */
300 /* adjust vs. (and possibly modify) monster state */
306 if (mtmp->msleeping) {
310 if (!mtmp->mcanmove) {
318 /* role/race adjustments */
319 if (Role_if(PM_MONK) && !Upolyd) {
321 tmp -= (*role_roll_penalty = urole.spelarmr);
322 else if (!uwep && !uarms)
323 tmp += (u.ulevel / 3) + 2;
325 if (is_orc(mtmp->data)
326 && maybe_polyd(is_elf(youmonst.data), Race_if(PM_ELF)))
329 /* encumbrance: with a lot of luggage, your agility diminishes */
330 if ((tmp2 = near_capacity()) != 0)
331 tmp -= (tmp2 * 2) - 1;
336 * hitval applies if making a weapon attack while wielding a weapon;
337 * weapon_hit_bonus applies if doing a weapon attack even bare-handed
338 * or if kicking as martial artist
340 if (aatyp == AT_WEAP || aatyp == AT_CLAW) {
342 tmp += hitval(weapon, mtmp);
343 tmp += weapon_hit_bonus(weapon);
344 } else if (aatyp == AT_KICK && martial_bonus()) {
345 tmp += weapon_hit_bonus((struct obj *) 0);
351 /* try to attack; return False if monster evaded;
352 u.dx and u.dy must be set */
355 register struct monst *mtmp;
357 register struct permonst *mdat = mtmp->data;
359 /* This section of code provides protection against accidentally
360 * hitting peaceful (like '@') and tame (like 'd') monsters.
361 * Protection is provided as long as player is not: blind, confused,
362 * hallucinating or stunned.
363 * changes by wwp 5/16/85
364 * More changes 12/90, -dkh-. if its tame and safepet, (and protected
365 * 07/92) then we assume that you're not trying to attack. Instead,
366 * you'll usually just swap places if this is a movement command
368 /* Intelligent chaotic weapons (Stormbringer) want blood */
369 if (is_safepet(mtmp) && !context.forcefight) {
370 if (!uwep || uwep->oartifact != ART_STORMBRINGER) {
371 /* There are some additional considerations: this won't work
372 * if in a shop or Punished or you miss a random roll or
373 * if you can walk thru walls and your pet cannot (KAA) or
374 * if your pet is a long worm with a tail.
375 * There's also a chance of displacing a "frozen" monster:
376 * sleeping monsters might magically walk in their sleep.
378 boolean foo = (Punished || !rn2(7)
379 || (is_longworm(mtmp->data) && mtmp->wormno)),
383 /* only check for in-shop if don't already have reason to stop */
385 for (p = in_rooms(mtmp->mx, mtmp->my, SHOPBASE); *p; p++)
386 if (tended_shop(&rooms[*p - ROOMOFFSET])) {
391 if (inshop || foo || (IS_ROCK(levl[u.ux][u.uy].typ)
392 && !passes_walls(mtmp->data))) {
395 monflee(mtmp, rnd(6), FALSE, FALSE);
396 Strcpy(buf, y_monnam(mtmp));
397 buf[0] = highc(buf[0]);
399 You("stop. %s is in the way!", buf);
401 You("
\8e~
\82Ü
\82Á
\82½
\81D%s
\82ª
\93¹
\82É
\82¢
\82é
\81I", buf);
402 context.travel = context.travel1 = context.mv = context.run
405 } else if ((mtmp->mfrozen || (!mtmp->mcanmove)
406 || (mtmp->data->mmove == 0)) && rn2(6)) {
408 pline("%s doesn't seem to move!", Monnam(mtmp));
410 pline("%s
\82Í
\93®
\82¯
\82È
\82¢
\82æ
\82¤
\82¾
\81I", Monnam(mtmp));
411 context.travel = context.travel1 = context.mv = context.run
419 /* possibly set in attack_checks;
420 examined in known_hitum, called via hitum or hmonas below */
421 override_confirmation = FALSE;
422 /* attack_checks() used to use <u.ux+u.dx,u.uy+u.dy> directly, now
423 it uses bhitpos instead; it might map an invisible monster there */
424 bhitpos.x = u.ux + u.dx;
425 bhitpos.y = u.uy + u.dy;
426 notonhead = (bhitpos.x != mtmp->mx || bhitpos.y != mtmp->my);
427 if (attack_checks(mtmp, uwep))
430 if (Upolyd && noattacks(youmonst.data)) {
431 /* certain "pacifist" monsters don't attack */
433 You("have no way to attack monsters physically.");
435 You("
\95¨
\97\9d\93I
\82É
\89ö
\95¨
\82ð
\8dU
\8c\82\82·
\82é
\82·
\82×
\82ª
\82È
\82¢
\81D");
436 mtmp->mstrategy &= ~STRAT_WAITMASK;
441 if (check_capacity("You cannot fight while so heavily loaded.")
443 if (check_capacity("
\82 \82È
\82½
\82Í
\95¨
\82ð
\82½
\82
\82³
\82ñ
\8e\9d\82¿
\82·
\82¬
\82Ä
\90í
\82¦
\82È
\82¢
\81D")
444 /* consume extra nutrition during combat; maybe pass out */
448 if (u.twoweap && !can_twoweapon())
456 You("begin bashing monsters with %s.", yname(uwep));
458 You("%s
\82Å
\89ö
\95¨
\82ð
\82È
\82®
\82è
\82Â
\82¯
\82½
\81D", yname(uwep));
459 else if (!cantwield(youmonst.data))
461 You("begin %s monsters with your %s %s.",
462 ing_suffix(Role_if(PM_MONK) ? "strike" : "bash"),
463 uarmg ? "gloved" : "bare", /* Del Lamb */
464 makeplural(body_part(HAND)));
466 You("%s%s
\82Å
\89ö
\95¨
\82ð%s
\82Â
\82¯
\82½
\81D",
467 uarmg ? "
\83O
\83\8d\81[
\83u
\82ð
\95t
\82¯
\82½" : "
\91f",
469 Role_if(PM_MONK) ? "
\91Å
\82¿" : "
\82È
\82®
\82è");
473 exercise(A_STR, TRUE); /* you're exercising muscles */
474 /* andrew@orca: prevent unlimited pick-axe attacks */
477 /* Is the "it died" check actually correct? */
478 if (mdat->mlet == S_LEPRECHAUN && !mtmp->mfrozen && !mtmp->msleeping
479 && !mtmp->mconf && mtmp->mcansee && !rn2(7)
480 && (m_move(mtmp, 0) == 2 /* it died */
481 || mtmp->mx != u.ux + u.dx
482 || mtmp->my != u.uy + u.dy)) { /* it moved */
483 You("miss wildly and stumble forwards.");
490 (void) hitum(mtmp, youmonst.data->mattk);
491 mtmp->mstrategy &= ~STRAT_WAITMASK;
494 /* see comment in attack_checks() */
495 /* we only need to check for this if we did an attack_checks()
496 * and it returned 0 (it's okay to attack), and the monster didn't
499 if (context.forcefight && !DEADMONSTER(mtmp) && !canspotmon(mtmp)
500 && !glyph_is_invisible(levl[u.ux + u.dx][u.uy + u.dy].glyph)
501 && !(u.uswallow && mtmp == u.ustuck))
502 map_invisible(u.ux + u.dx, u.uy + u.dy);
507 /* really hit target monster; returns TRUE if it still lives */
509 known_hitum(mon, weapon, mhit, rollneeded, armorpenalty, uattk, dieroll)
510 register struct monst *mon;
513 int rollneeded, armorpenalty; /* for monks */
514 struct attack *uattk;
517 boolean malive = TRUE,
518 /* hmon() might destroy weapon; remember aspect for cutworm */
519 slice_or_chop = (weapon && (is_blade(weapon) || is_axe(weapon)));
521 if (override_confirmation) {
522 /* this may need to be generalized if weapons other than
523 Stormbringer acquire similar anti-social behavior... */
526 Your("bloodthirsty blade attacks!");
528 Your("
\95\90\8aí
\82Í
\8c\8c\82É
\8bQ
\82¦
\82Ä
\82¢
\82é
\81I");
532 missum(mon, uattk, (rollneeded + armorpenalty > dieroll));
534 int oldhp = mon->mhp;
535 long oldweaphit = u.uconduct.weaphit;
538 if (weapon && (weapon->oclass == WEAPON_CLASS || is_weptool(weapon)))
539 u.uconduct.weaphit++;
541 /* we hit the monster; be careful: it might die or
542 be knocked into a different location */
543 notonhead = (mon->mx != bhitpos.x || mon->my != bhitpos.y);
544 malive = hmon(mon, weapon, HMON_MELEE, dieroll);
546 /* monster still alive */
547 if (!rn2(25) && mon->mhp < mon->mhpmax / 2
548 && !(u.uswallow && mon == u.ustuck)) {
549 /* maybe should regurgitate if swallowed? */
550 monflee(mon, !rn2(3) ? rnd(100) : 0, FALSE, TRUE);
552 if (u.ustuck == mon && !u.uswallow && !sticks(youmonst.data))
555 /* Vorpal Blade hit converted to miss */
556 /* could be headless monster or worm tail */
557 if (mon->mhp == oldhp) {
559 /* a miss does not break conduct */
560 u.uconduct.weaphit = oldweaphit;
562 if (mon->wormno && *mhit)
563 cutworm(mon, bhitpos.x, bhitpos.y, slice_or_chop);
569 /* hit the monster next to you and the monsters to the left and right of it;
570 return False if the primary target is killed, True otherwise */
572 hitum_cleave(target, uattk)
573 struct monst *target; /* non-Null; forcefight at nothing doesn't cleave... */
574 struct attack *uattk; /* ... but we don't enforce that here; Null works ok */
576 /* swings will be delivered in alternate directions; with consecutive
577 attacks it will simulate normal swing and backswing; when swings
578 are non-consecutive, hero will sometimes start a series of attacks
579 with a backswing--that doesn't impact actual play, just spoils the
580 simulation attempt a bit */
581 static boolean clockwise = FALSE;
584 int count, umort, x = u.ux, y = u.uy;
586 /* find the direction toward primary target */
587 for (i = 0; i < 8; ++i)
588 if (xdir[i] == u.dx && ydir[i] == u.dy)
591 impossible("hitum_cleave: unknown target direction [%d,%d,%d]?",
593 return TRUE; /* target hasn't been killed */
595 /* adjust direction by two so that loop's increment (for clockwise)
596 or decrement (for counter-clockwise) will point at the spot next
598 i = (i + (clockwise ? 6 : 2)) % 8;
599 umort = u.umortality; /* used to detect life-saving */
600 save_bhitpos = bhitpos;
603 * Three attacks: adjacent to primary, primary, adjacent on other
604 * side. Primary target must be present or we wouldn't have gotten
605 * here (forcefight at thin air won't 'cleave'). However, the
606 * first attack might kill it (gas spore explosion, weak long worm
607 * occupying both spots) so we don't assume that it's still present
608 * on the second attack.
610 for (count = 3; count > 0; --count) {
612 int tx, ty, tmp, dieroll, mhit, attknum, armorpenalty;
614 /* ++i, wrap 8 to i=0 /or/ --i, wrap -1 to i=7 */
615 i = (i + (clockwise ? 1 : 7)) % 8;
617 tx = x + xdir[i], ty = y + ydir[i]; /* current target location */
622 if (glyph_is_invisible(levl[tx][ty].glyph))
623 (void) unmap_invisible(tx, ty);
627 tmp = find_roll_to_hit(mtmp, uattk->aatyp, uwep,
628 &attknum, &armorpenalty);
630 mhit = (tmp > dieroll);
631 bhitpos.x = tx, bhitpos.y = ty; /* normally set up by attack() */
632 (void) known_hitum(mtmp, uwep, &mhit, tmp, armorpenalty,
634 (void) passive(mtmp, uwep, mhit, !DEADMONSTER(mtmp), AT_WEAP, !uwep);
636 /* stop attacking if weapon is gone or hero got killed and
637 life-saved after passive counter-attack */
638 if (!uwep || u.umortality > umort)
641 /* set up for next time */
642 clockwise = !clockwise; /* alternate */
643 bhitpos = save_bhitpos; /* in case somebody relies on bhitpos
644 * designating the primary target */
646 /* return False if primary target died, True otherwise; note: if 'target'
647 was nonNull upon entry then it's still nonNull even if *target died */
648 return (target && DEADMONSTER(target)) ? FALSE : TRUE;
651 /* hit target monster; returns TRUE if it still lives */
655 struct attack *uattk;
657 boolean malive, wep_was_destroyed = FALSE;
658 struct obj *wepbefore = uwep;
659 int armorpenalty, attknum = 0, x = u.ux + u.dx, y = u.uy + u.dy,
660 tmp = find_roll_to_hit(mon, uattk->aatyp, uwep,
661 &attknum, &armorpenalty);
662 int dieroll = rnd(20);
663 int mhit = (tmp > dieroll || u.uswallow);
665 /* Cleaver attacks three spots, 'mon' and one on either side of 'mon';
666 it can't be part of dual-wielding but we guard against that anyway;
667 cleave return value reflects status of primary target ('mon') */
668 if (uwep && uwep->oartifact == ART_CLEAVER && !u.twoweap
669 && !u.uswallow && !u.ustuck && !NODIAG(u.umonnum))
670 return hitum_cleave(mon, uattk);
673 exercise(A_DEX, TRUE);
674 /* bhitpos is set up by caller */
675 malive = known_hitum(mon, uwep, &mhit, tmp, armorpenalty, uattk, dieroll);
676 if (wepbefore && !uwep)
677 wep_was_destroyed = TRUE;
678 (void) passive(mon, uwep, mhit, malive, AT_WEAP, wep_was_destroyed);
680 /* second attack for two-weapon combat; won't occur if Stormbringer
681 overrode confirmation (assumes Stormbringer is primary weapon)
682 or if the monster was killed or knocked to different location */
683 if (u.twoweap && !override_confirmation && malive && m_at(x, y) == mon) {
684 tmp = find_roll_to_hit(mon, uattk->aatyp, uswapwep, &attknum,
687 mhit = (tmp > dieroll || u.uswallow);
688 malive = known_hitum(mon, uswapwep, &mhit, tmp, armorpenalty, uattk,
690 /* second passive counter-attack only occurs if second attack hits */
692 (void) passive(mon, uswapwep, mhit, malive, AT_WEAP, !uswapwep);
697 /* general "damage monster" routine; return True if mon still alive */
699 hmon(mon, obj, thrown, dieroll)
702 int thrown; /* HMON_xxx (0 => hand-to-hand, other => ranged) */
705 boolean result, anger_guards;
707 anger_guards = (mon->mpeaceful
708 && (mon->ispriest || mon->isshk || is_watch(mon->data)));
709 result = hmon_hitmon(mon, obj, thrown, dieroll);
710 if (mon->ispriest && !rn2(2))
713 (void) angry_guards(!!Deaf);
719 hmon_hitmon(mon, obj, thrown, dieroll)
722 int thrown; /* HMON_xxx (0 => hand-to-hand, other => ranged) */
726 struct permonst *mdat = mon->data;
727 int barehand_silver_rings = 0;
728 /* The basic reason we need all these booleans is that we don't want
729 * a "hit" message when a monster dies, so we have to know how much
730 * damage it did _before_ outputting a hit message, but any messages
731 * associated with the damage don't come out until _after_ outputting
734 boolean hittxt = FALSE, destroyed = FALSE, already_killed = FALSE;
735 boolean get_dmg_bonus = TRUE;
736 boolean ispoisoned = FALSE, needpoismsg = FALSE, poiskilled = FALSE,
738 boolean silvermsg = FALSE, silverobj = FALSE;
739 boolean lightobj = FALSE;
740 boolean valid_weapon_attack = FALSE;
741 boolean unarmed = !uwep && !uarm && !uarms;
742 boolean hand_to_hand = (thrown == HMON_MELEE
743 /* not grapnels; applied implies uwep */
744 || (thrown == HMON_APPLIED && is_pole(uwep)));
750 char unconventional[BUFSZ]; /* substituted for word "attack" in msg */
752 char saved_oname[BUFSZ];
755 unconventional[0] = '\0';
757 saved_oname[0] = '\0';
760 if (!obj) { /* attack with bare hands */
761 if (mdat == &mons[PM_SHADE])
763 else if (martial_bonus())
764 tmp = rnd(4); /* bonus for martial arts */
767 valid_weapon_attack = (tmp > 1);
768 /* Blessed gloves give bonuses when fighting 'bare-handed'. So do
769 silver rings. Note: rings are worn under gloves, so you don't
770 get both bonuses, and two silver rings don't give double bonus. */
771 tmp += special_dmgval(&youmonst, mon, (W_ARMG | W_RINGL | W_RINGR),
773 barehand_silver_rings += (((silverhit & W_RINGL) ? 1 : 0)
774 + ((silverhit & W_RINGR) ? 1 : 0));
775 if (barehand_silver_rings > 0)
778 if (!(artifact_light(obj) && obj->lamplit))
779 Strcpy(saved_oname, cxname(obj));
781 Strcpy(saved_oname, bare_artifactname(obj));
782 if (obj->oclass == WEAPON_CLASS || is_weptool(obj)
783 || obj->oclass == GEM_CLASS) {
784 /* is it not a melee weapon? */
785 if (/* if you strike with a bow... */
787 /* or strike with a missile in your hand... */
788 || (!thrown && (is_missile(obj) || is_ammo(obj)))
789 /* or use a pole at short range and not mounted... */
790 || (!thrown && !u.usteed && is_pole(obj))
791 /* or throw a missile without the proper bow... */
792 || (is_ammo(obj) && (thrown != HMON_THROWN
793 || !ammo_and_launcher(obj, uwep)))) {
794 /* then do only 1-2 points of damage */
795 if (mdat == &mons[PM_SHADE] && !shade_glare(obj))
799 if (objects[obj->otyp].oc_material == SILVER
800 && mon_hates_silver(mon)) {
803 /* if it will already inflict dmg, make it worse */
804 tmp += rnd((tmp) ? 20 : 10);
806 if (!thrown && obj == uwep && obj->otyp == BOOMERANG
807 && rnl(4) == 4 - 1) {
808 boolean more_than_1 = (obj->quan > 1L);
811 pline("As you hit %s, %s%s breaks into splinters.",
812 mon_nam(mon), more_than_1 ? "one of " : "",
815 pline("%s
\82ð
\8dU
\8c\82\82·
\82é
\82Æ
\81C%s%s
\82Í
\82±
\82Á
\82Ï
\82Ý
\82¶
\82ñ
\82É
\82È
\82Á
\82½
\81D",
816 mon_nam(mon), yname(obj),
817 more_than_1 ? "
\82Ì
\82Ð
\82Æ
\82Â" : "");
820 uwepgone(); /* set unweapon */
823 obj = (struct obj *) 0;
825 if (mdat != &mons[PM_SHADE])
829 tmp = dmgval(obj, mon);
830 /* a minimal hit doesn't exercise proficiency */
831 valid_weapon_attack = (tmp > 1);
832 if (!valid_weapon_attack || mon == u.ustuck || u.twoweap
833 /* Cleaver can hit up to three targets at once so don't
834 let it also hit from behind or shatter foes' weapons */
835 || (hand_to_hand && obj->oartifact == ART_CLEAVER)) {
836 ; /* no special bonuses */
837 } else if (mon->mflee && Role_if(PM_ROGUE) && !Upolyd
838 /* multi-shot throwing is too powerful here */
841 You("strike %s from behind!", mon_nam(mon));
843 You("%s
\82ð
\94w
\8cã
\82©
\82ç
\8dU
\8c\82\82µ
\82½
\81I", mon_nam(mon));
844 tmp += rnd(u.ulevel);
846 } else if (dieroll == 2 && obj == uwep
847 && obj->oclass == WEAPON_CLASS
849 || (Role_if(PM_SAMURAI) && obj->otyp == KATANA
851 && ((wtype = uwep_skill_type()) != P_NONE
852 && P_SKILL(wtype) >= P_SKILLED)
853 && ((monwep = MON_WEP(mon)) != 0
854 && !is_flimsy(monwep)
855 && !obj_resists(monwep,
856 50 + 15 * (greatest_erosion(obj)
857 - greatest_erosion(monwep)),
860 * 2.5% chance of shattering defender's weapon when
861 * using a two-handed weapon; less if uwep is rusted.
862 * [dieroll == 2 is most successful non-beheading or
863 * -bisecting hit, in case of special artifact damage;
864 * the percentage chance is (1/20)*(50/100).]
865 * If attacker's weapon is rustier than defender's,
866 * the obj_resists chance is increased so the shatter
867 * chance is decreased; if less rusty, then vice versa.
869 setmnotwielded(mon, monwep);
870 mon->weapon_check = NEED_WEAPON;
872 pline("%s from the force of your blow!",
873 Yobjnam2(monwep, "shatter"));
875 pline("%s
\82Ì%s
\82Í
\82 \82È
\82½
\82Ì
\88ê
\8c\82\82Å
\95²
\81X
\82É
\82È
\82Á
\82½
\81I",
876 Monnam(mon), xname(monwep));
878 m_useupall(mon, monwep);
879 /* If someone just shattered MY weapon, I'd flee! */
881 monflee(mon, d(2, 3), TRUE, TRUE);
887 && artifact_hit(&youmonst, mon, obj, &tmp, dieroll)) {
888 if (DEADMONSTER(mon)) /* artifact killed monster */
894 if (objects[obj->otyp].oc_material == SILVER
895 && mon_hates_silver(mon)) {
899 if (artifact_light(obj) && obj->lamplit
900 && mon_hates_light(mon))
902 if (u.usteed && !thrown && tmp > 0
903 && weapon_type(obj) == P_LANCE && mon != u.ustuck) {
904 jousting = joust(mon, obj);
905 /* exercise skill even for minimal damage hits */
907 valid_weapon_attack = TRUE;
909 if (thrown == HMON_THROWN
910 && (is_ammo(obj) || is_missile(obj))) {
911 if (ammo_and_launcher(obj, uwep)) {
912 /* Elves and Samurai do extra damage using
913 * their bows&arrows; they're highly trained.
915 if (Role_if(PM_SAMURAI) && obj->otyp == YA
916 && uwep->otyp == YUMI)
918 else if (Race_if(PM_ELF) && obj->otyp == ELVEN_ARROW
919 && uwep->otyp == ELVEN_BOW)
922 if (obj->opoisoned && is_poisonable(obj))
926 } else if (obj->oclass == POTION_CLASS) {
928 obj = splitobj(obj, 1L);
930 setuwep((struct obj *) 0);
933 hand_to_hand ? POTHIT_HERO_BASH : POTHIT_HERO_THROW);
934 if (DEADMONSTER(mon))
935 return FALSE; /* killed */
937 /* in case potion effect causes transformation */
939 tmp = (mdat == &mons[PM_SHADE]) ? 0 : 1;
941 if (mdat == &mons[PM_SHADE] && !shade_aware(obj)) {
944 Strcpy(unconventional, cxname(obj));
948 case BOULDER: /* 1d20 */
949 case HEAVY_IRON_BALL: /* 1d25 */
950 case IRON_CHAIN: /* 1d4+1 */
951 tmp = dmgval(obj, mon);
954 if (breaktest(obj)) {
956 You("break %s. That's bad luck!", ysimple_name(obj));
958 You("%s
\8b¾
\82ð
\89ó
\82µ
\82Ä
\82µ
\82Ü
\82Á
\82½
\81D
\82±
\82è
\82á
\82Ü
\82¢
\82Á
\82½
\81I", ysimple_name(obj));
961 obj = (struct obj *) 0;
962 unarmed = FALSE; /* avoid obj==0 confusion */
963 get_dmg_bonus = FALSE;
968 case EXPENSIVE_CAMERA:
970 You("succeed in destroying %s. Congratulations!",
972 You("%s
\83J
\83\81\83\89\82ð
\89ó
\82·
\82±
\82Æ
\82ª
\82Å
\82«
\82½
\81D
\82¨
\82ß
\82Å
\82Æ
\82¤
\81I",
974 release_camera_demon(obj, u.ux, u.uy);
977 case CORPSE: /* fixed by polder@cs.vu.nl */
978 if (touch_petrifies(&mons[obj->corpsenm])) {
982 You("hit %s with %s.", mon_nam(mon),
983 corpse_xname(obj, (const char *) 0,
984 obj->dknown ? CXN_PFX_THE
987 You("%s
\82ð%s
\82Å
\8dU
\8c\82\82µ
\82½
\81D", mon_nam(mon),
988 corpse_xname(obj, (const char *) 0,
989 obj->dknown ? CXN_PFX_THE
993 if (!munstone(mon, TRUE))
994 minstapetrify(mon, TRUE);
995 if (resists_ston(mon))
997 /* note: hp may be <= 0 even if munstoned==TRUE */
998 return (boolean) !DEADMONSTER(mon);
1000 } else if (touch_petrifies(mdat)) {
1001 ; /* maybe turn the corpse into a statue? */
1004 tmp = (obj->corpsenm >= LOW_PM ? mons[obj->corpsenm].msize
1008 #define useup_eggs(o) \
1011 obfree(o, (struct obj *) 0); \
1014 o = (struct obj *) 0; \
1015 } while (0) /* now gone */
1017 long cnt = obj->quan;
1019 tmp = 1; /* nominal physical damage */
1020 get_dmg_bonus = FALSE;
1021 hittxt = TRUE; /* message always given */
1022 /* egg is always either used up or transformed, so next
1023 hand-to-hand attack should yield a "bashing" mesg */
1026 if (obj->spe && obj->corpsenm >= LOW_PM) {
1028 change_luck((schar) - (obj->quan));
1033 if (touch_petrifies(&mons[obj->corpsenm])) {
1034 /*learn_egg_type(obj->corpsenm);*/
1036 pline("Splat! You hit %s with %s %s egg%s!",
1038 obj->known ? "the" : cnt > 1L ? "some" : "a",
1039 obj->known ? mons[obj->corpsenm].mname
1043 pline("
\83r
\83`
\83\83\83b
\81I
\82 \82È
\82½
\82Í%s
\82É%s%s
\82Ì
\97\91\82ð
\93\8a\82°
\82Â
\82¯
\82½
\81I",
1045 cnt > 1L ? "
\82¢
\82
\82Â
\82©
\82Ì" : "",
1046 obj->known ? mons[obj->corpsenm].mname
1049 obj->known = 1; /* (not much point...) */
1051 if (!munstone(mon, TRUE))
1052 minstapetrify(mon, TRUE);
1053 if (resists_ston(mon))
1055 return (boolean) (!DEADMONSTER(mon));
1056 } else { /* ordinary egg(s) */
1058 const char *eggp = (obj->corpsenm != NON_PM
1060 ? the(mons[obj->corpsenm].mname)
1061 : (cnt > 1L) ? "some" : "an";
1063 You("hit %s with %s egg%s.", mon_nam(mon), eggp,
1066 const char *eggp = (obj->corpsenm != NON_PM
1068 ? mons[obj->corpsenm].mname
1070 You("%s
\82É%s%s
\97\91\82ð
\93\8a\82°
\82Â
\82¯
\82½
\81D",
1071 mon_nam(mon), eggp, *eggp ? "
\82Ì" : "");
1073 if (touch_petrifies(mdat) && !stale_egg(obj)) {
1075 pline_The("egg%s %s alive any more...", plur(cnt),
1076 (cnt == 1L) ? "isn't" : "aren't");
1078 pline("
\82à
\82¤
\97\91\82ª
\9bz
\89»
\82·
\82é
\82±
\82Æ
\82Í
\82È
\82¢
\82¾
\82ë
\82¤
\81D
\81D
\81D");
1081 obj_stop_timers(obj);
1083 obj->oclass = GEM_CLASS;
1086 obj->known = obj->dknown = obj->bknown = 0;
1087 obj->owt = weight(obj);
1089 place_object(obj, mon->mx, mon->my);
1094 pline("
\83r
\83`
\83\83\83b
\81I");
1096 exercise(A_WIS, FALSE);
1102 case CLOVE_OF_GARLIC: /* no effect against demons */
1103 if (is_undead(mdat) || is_vampshifter(mon)) {
1104 monflee(mon, d(2, 4), FALSE, TRUE);
1109 case BLINDING_VENOM:
1111 if (can_blnd(&youmonst, mon,
1112 (uchar) ((obj->otyp == BLINDING_VENOM)
1118 pline(obj->otyp == CREAM_PIE ? "Splat!"
1121 pline(obj->otyp == CREAM_PIE ? "
\83r
\83V
\83\83\83b
\81I"
1122 : "
\83s
\83`
\83\83\83b
\81I");
1124 } else if (obj->otyp == BLINDING_VENOM) {
1126 pline_The("venom blinds %s%s!", mon_nam(mon),
1127 mon->mcansee ? "" : " further");
1129 pline("
\93Å
\89t
\82Å%s
\82Í%s
\96Ú
\82ª
\8c©
\82¦
\82È
\82
\82È
\82Á
\82½
\81I", mon_nam(mon),
1130 mon->mcansee ? "" : "
\82³
\82ç
\82É");
1133 char *whom = mon_nam(mon);
1134 char *what = The(xname(obj));
1136 if (!thrown && obj->quan > 1L)
1137 what = An(singular(obj, xname));
1138 /* note: s_suffix returns a modifiable buffer */
1140 && mdat != &mons[PM_FLOATING_EYE])
1142 whom = strcat(strcat(s_suffix(whom), " "),
1143 mbodypart(mon, FACE));
1145 whom = strcat(s_suffix(whom),
1146 mbodypart(mon, FACE));
1149 pline("%s %s over %s!", what,
1150 vtense(what, "splash"), whom);
1152 pline("%s
\82Í%s
\82É
\82Ô
\82¿
\82Ü
\82¯
\82ç
\82ê
\82½
\81I",
1156 setmangry(mon, TRUE);
1159 if (((int) mon->mblinded + tmp) > 127)
1160 mon->mblinded = 127;
1162 mon->mblinded += tmp;
1165 pline(obj->otyp == CREAM_PIE ? "Splat!" : "Splash!");
1167 pline(obj->otyp==CREAM_PIE ? "
\83r
\83V
\83\83\83b
\81I" : "
\83s
\83`
\83\83\83b
\81I");
1168 setmangry(mon, TRUE);
1171 obfree(obj, (struct obj *) 0);
1175 get_dmg_bonus = FALSE;
1178 case ACID_VENOM: /* thrown (or spit) */
1179 if (resists_acid(mon)) {
1181 Your("venom hits %s harmlessly.", mon_nam(mon));
1183 pline("
\93Å
\89t
\82Í%s
\82É
\82Í
\8cø
\89Ê
\82ª
\82È
\82©
\82Á
\82½
\81D", mon_nam(mon));
1187 Your("venom burns %s!", mon_nam(mon));
1189 Your("
\93Å
\89t
\82Í%s
\82ð
\8fÄ
\82¢
\82½
\81I", mon_nam(mon));
1190 tmp = dmgval(obj, mon);
1193 obfree(obj, (struct obj *) 0);
1197 get_dmg_bonus = FALSE;
1200 /* non-weapons can damage because of their weight */
1201 /* (but not too much) */
1202 tmp = obj->owt / 100;
1203 if (is_wet_towel(obj)) {
1204 /* wielded wet towel should probably use whip skill
1205 (but not by setting objects[TOWEL].oc_skill==P_WHIP
1206 because that would turn towel into a weptool) */
1208 if (rn2(obj->spe + 1)) /* usually lose some wetness */
1209 dry_a_towel(obj, -1, TRUE);
1218 * Things like silver wands can arrive here so
1219 * so we need another silver check.
1221 if (objects[obj->otyp].oc_material == SILVER
1222 && mon_hates_silver(mon)) {
1232 /****** NOTE: perhaps obj is undefined!! (if !thrown && BOOMERANG)
1233 * *OR* if attacking bare-handed!! */
1235 if (get_dmg_bonus && tmp > 0) {
1237 /* If you throw using a propellor, you don't get a strength
1238 * bonus but you do get an increase-damage bonus.
1240 if (thrown != HMON_THROWN || !obj || !uwep
1241 || !ammo_and_launcher(obj, uwep))
1245 if (valid_weapon_attack) {
1248 /* to be valid a projectile must have had the correct projector */
1249 wep = PROJECTILE(obj) ? uwep : obj;
1250 tmp += weapon_dam_bonus(wep);
1251 /* [this assumes that `!thrown' implies wielded...] */
1252 wtype = thrown ? weapon_type(wep) : uwep_skill_type();
1253 use_skill(wtype, 1);
1257 int nopoison = (10 - (obj->owt / 10));
1261 if (Role_if(PM_SAMURAI)) {
1263 You("dishonorably use a poisoned weapon!");
1265 You("
\95s
\96¼
\97_
\82É
\82à
\93Å
\82Ì
\95\90\8aí
\82ð
\8eg
\97p
\82µ
\82½
\81I");
1266 adjalign(-sgn(u.ualign.type));
1267 } else if (u.ualign.type == A_LAWFUL && u.ualign.record > -10) {
1269 You_feel("like an evil coward for using a poisoned weapon.");
1271 You("
\93Å
\82Ì
\95\90\8aí
\82ð
\8eg
\97p
\82·
\82é
\82Ì
\82Í
\94Ú
\8b¯
\82¾
\82Æ
\8a´
\82¶
\82½
\81D");
1274 if (obj && !rn2(nopoison)) {
1275 /* remove poison now in case obj ends up in a bones file */
1276 obj->opoisoned = FALSE;
1277 /* defer "obj is no longer poisoned" until after hit message */
1280 if (resists_poison(mon))
1288 /* make sure that negative damage adjustment can't result
1289 in inadvertently boosting the victim's hit points */
1291 if (mdat == &mons[PM_SHADE]) {
1294 const char *what = *unconventional ? unconventional : "attack";
1296 Your("%s %s harmlessly through %s.", what,
1297 vtense(what, "pass"), mon_nam(mon));
1299 Your("
\8dU
\8c\82\82Í%s
\82ð
\92Ê
\82è
\82Ê
\82¯
\82½
\81D", mon_nam(mon));
1310 tmp += d(2, (obj == uwep) ? 10 : 2); /* [was in dmgval()] */
1312 You("joust %s%s", mon_nam(mon), canseemon(mon) ? exclam(tmp) : ".");
1314 You("%s
\82É
\93Ë
\8c\82\82µ
\82½%s", mon_nam(mon), canseemon(mon) ? exclam(tmp) : "
\81D");
1317 pline("%s shatters on impact!", Yname2(obj));
1319 Your("%s
\82Í
\8fÕ
\8c\82\82Å
\89ó
\82ê
\82½
\81I", xname(obj));
1320 /* (must be either primary or secondary weapon to get here) */
1321 u.twoweap = FALSE; /* untwoweapon() is too verbose here */
1323 uwepgone(); /* set unweapon */
1324 /* minor side-effect: broken lance won't split puddings */
1328 /* avoid migrating a dead monster */
1329 if (mon->mhp > tmp) {
1330 mhurtle(mon, u.dx, u.dy, 1);
1331 mdat = mon->data; /* in case of a polymorph trap */
1332 if (DEADMONSTER(mon))
1333 already_killed = TRUE;
1336 } else if (unarmed && tmp > 1 && !thrown && !obj && !Upolyd) {
1337 /* VERY small chance of stunning opponent if unarmed. */
1338 if (rnd(100) < P_SKILL(P_BARE_HANDED_COMBAT) && !bigmonst(mdat)
1339 && !thick_skinned(mdat)) {
1340 if (canspotmon(mon))
1342 pline("%s %s from your powerful strike!", Monnam(mon),
1343 makeplural(stagger(mon->data, "stagger")));
1345 pline("%s
\82Í
\82 \82È
\82½
\82Ì
\89ï
\90S
\82Ì
\88ê
\8c\82\82Å%s
\81I", Monnam(mon),
1346 jpast(stagger(mon->data, "
\82æ
\82ë
\82ß
\82")));
1348 /* avoid migrating a dead monster */
1349 if (mon->mhp > tmp) {
1350 mhurtle(mon, u.dx, u.dy, 1);
1351 mdat = mon->data; /* in case of a polymorph trap */
1352 if (DEADMONSTER(mon))
1353 already_killed = TRUE;
1359 if (!already_killed)
1361 /* adjustments might have made tmp become less than what
1362 a level draining artifact has already done to max HP */
1363 if (mon->mhp > mon->mhpmax)
1364 mon->mhp = mon->mhpmax;
1365 if (DEADMONSTER(mon))
1367 if (mon->mtame && tmp > 0) {
1368 /* do this even if the pet is being killed (affects revival) */
1369 abuse_dog(mon); /* reduces tameness */
1370 /* flee if still alive and still tame; if already suffering from
1371 untimed fleeing, no effect, otherwise increases timed fleeing */
1372 if (mon->mtame && !destroyed)
1373 monflee(mon, 10 * rnd(tmp), FALSE, FALSE);
1375 if ((mdat == &mons[PM_BLACK_PUDDING] || mdat == &mons[PM_BROWN_PUDDING])
1376 /* pudding is alive and healthy enough to split */
1377 && mon->mhp > 1 && !mon->mcan
1378 /* iron weapon using melee or polearm hit [3.6.1: metal weapon too;
1379 also allow either or both weapons to cause split when twoweap] */
1380 && obj && (obj == uwep || (u.twoweap && obj == uswapwep))
1381 && ((objects[obj->otyp].oc_material == IRON
1382 /* allow scalpel and tsurugi to split puddings */
1383 || objects[obj->otyp].oc_material == METAL)
1384 /* but not bashing with darts, arrows or ya */
1385 && !(is_ammo(obj) || is_missile(obj)))
1387 struct monst *mclone;
1388 if ((mclone = clone_mon(mon, 0, 0)) != 0) {
1389 char withwhat[BUFSZ];
1393 if (u.twoweap && flags.verbose)
1394 Sprintf(withwhat, " with %s", yname(obj));
1395 pline("%s divides as you hit it%s!", Monnam(mon), withwhat);
1397 if (u.twoweap && flags.verbose)
1398 Sprintf(withwhat, "%s
\82Å
\82Ì", yname(obj));
1399 pline("
\82 \82È
\82½
\82Ì%s
\8dU
\8c\82\82Å%s
\82Í
\95ª
\97ô
\82µ
\82½
\81I", withwhat, Monnam(mon));
1406 if (!hittxt /*( thrown => obj exists )*/
1408 || (thrown && m_shot.n > 1 && m_shot.o == obj->otyp))) {
1410 hit(mshot_xname(obj), mon, exclam(tmp));
1411 else if (!flags.verbose)
1415 pline("
\8dU
\8c\82\82Í
\96½
\92\86\82µ
\82½
\81D");
1417 #if 0 /*JP*//*
\89£
\82è
\95û
\82ð
\95ª
\82¯
\82é
\82Ü
\82Å
\82Í
\82â
\82ç
\82È
\82¢*/
1419 (obj && (is_shield(obj) || obj->otyp == HEAVY_IRON_BALL))
1420 ? "bash" : Role_if(PM_BARBARIAN) ? "smite" : "hit",
1421 mon_nam(mon), canseemon(mon) ? exclam(tmp) : ".");
1423 Your("%s
\82Ö
\82Ì
\8dU
\8c\82\82Í
\96½
\92\86\82µ
\82½%s",
1424 mon_nam(mon), canseemon(mon) ? exclam(tmp) : "
\81D");
1430 char *whom = mon_nam(mon);
1431 char silverobjbuf[BUFSZ];
1433 if (canspotmon(mon)) {
1434 if (barehand_silver_rings == 1)
1436 fmt = "Your silver ring sears %s!";
1438 fmt = "%s
\82Í
\8bâ
\82Ì
\8ew
\97Ö
\82Å
\8fÄ
\82©
\82ê
\82½
\81I";
1439 else if (barehand_silver_rings == 2)
1441 fmt = "Your silver rings sear %s!";
1443 fmt = "%s
\82Í
\8bâ
\82Ì
\8ew
\97Ö
\82Å
\8fÄ
\82©
\82ê
\82½
\81I";
1444 else if (silverobj && saved_oname[0]) {
1445 /* guard constructed format string against '%' in
1446 saved_oname[] from xname(via cxname()) */
1448 Sprintf(silverobjbuf, "Your %s%s %s",
1449 strstri(saved_oname, "silver") ? "" : "silver ",
1450 saved_oname, vtense(saved_oname, "sear"));
1452 Sprintf(silverobjbuf, "%%s
\82Í%s%s
\82Å
\8fÄ
\82©
\82ê
\82½
\81I",
1453 strstri(saved_oname, "
\8bâ") ?
1457 (void) strNsubst(silverobjbuf, "%", "%%", 0);
1458 Strcat(silverobjbuf, " %s!");
1462 fmt = "The silver sears %s!";
1464 fmt = "%s
\82Í
\8bâ
\82Å
\8fÄ
\82©
\82ê
\82½
\81I";
1466 *whom = highc(*whom); /* "it" -> "It" */
1468 fmt = "%s is seared!";
1470 fmt = "%s
\82Í
\8fÄ
\82©
\82ê
\82½
\81I";
1472 /* note: s_suffix returns a modifiable buffer */
1473 if (!noncorporeal(mdat) && !amorphous(mdat))
1475 whom = strcat(s_suffix(whom), " flesh");
1477 whom = strcat(s_suffix(whom), "
\93÷");
1482 char *whom = mon_nam(mon);
1483 char emitlightobjbuf[BUFSZ];
1485 if (canspotmon(mon)) {
1486 if (saved_oname[0]) {
1487 Sprintf(emitlightobjbuf,
1488 "%s radiance penetrates deep into",
1489 s_suffix(saved_oname));
1490 Strcat(emitlightobjbuf, " %s!");
1491 fmt = emitlightobjbuf;
1493 fmt = "The light sears %s!";
1495 *whom = highc(*whom); /* "it" -> "It" */
1496 fmt = "%s is seared!";
1498 /* note: s_suffix returns a modifiable buffer */
1499 if (!noncorporeal(mdat) && !amorphous(mdat))
1500 whom = strcat(s_suffix(whom), " flesh");
1503 /* if a "no longer poisoned" message is coming, it will be last;
1504 obj->opoisoned was cleared above and any message referring to
1505 "poisoned <obj>" has now been given; we want just "<obj>" for
1506 last message, so reformat while obj is still accessible */
1508 Strcpy(saved_oname, cxname(obj));
1510 /* [note: thrown obj might go away during killed()/xkilled() call
1511 (via 'thrownobj'; if swallowed, it gets added to engulfer's
1512 minvent and might merge with a stack that's already there)] */
1516 pline_The("poison doesn't seem to affect %s.", mon_nam(mon));
1518 pline("
\93Å
\82Í%s
\82É
\8cø
\82©
\82È
\82©
\82Á
\82½
\82æ
\82¤
\82¾
\81D", mon_nam(mon));
1521 pline_The("poison was deadly...");
1523 pline("
\93Å
\82Í
\92v
\8e\80\97Ê
\82¾
\82Á
\82½
\81D
\81D
\81D");
1524 if (!already_killed)
1525 xkilled(mon, XKILL_NOMSG);
1526 destroyed = TRUE; /* return FALSE; */
1527 } else if (destroyed) {
1528 if (!already_killed)
1529 killed(mon); /* takes care of most messages */
1530 } else if (u.umconf && hand_to_hand) {
1532 if (!mon->mconf && !resist(mon, SPBOOK_CLASS, 0, NOTELL)) {
1534 if (!mon->mstun && mon->mcanmove && !mon->msleeping
1537 pline("%s appears confused.", Monnam(mon));
1539 pline("%s
\82Í
\8d¬
\97\90\82µ
\82Ä
\82¢
\82é
\82æ
\82¤
\82¾
\81D", Monnam(mon));
1544 Your("%s %s no longer poisoned.", saved_oname,
1545 vtense(saved_oname, "are"));
1547 Your("%s
\82Í
\82à
\82¤
\93Å
\82ª
\93h
\82ç
\82ê
\82Ä
\82¢
\82È
\82¢
\81D", xname(obj));
1550 return destroyed ? FALSE : TRUE;
1560 * The things in this list either
1563 * 2) are dealt with properly by other routines
1564 * when it comes to shades.
1566 if (obj->otyp == BOULDER
1567 || obj->otyp == HEAVY_IRON_BALL
1568 || obj->otyp == IRON_CHAIN /* dmgval handles those first three */
1569 || obj->otyp == MIRROR /* silver in the reflective surface */
1570 || obj->otyp == CLOVE_OF_GARLIC /* causes shades to flee */
1571 || objects[obj->otyp].oc_material == SILVER)
1576 /* check whether slippery clothing protects from hug or wrap attack */
1577 /* [currently assumes that you are the attacker] */
1579 m_slips_free(mdef, mattk)
1581 struct attack *mattk;
1585 if (mattk->adtyp == AD_DRIN) {
1586 /* intelligence drain attacks the head */
1587 obj = which_armor(mdef, W_ARMH);
1589 /* grabbing attacks the body */
1590 obj = which_armor(mdef, W_ARMC); /* cloak */
1592 obj = which_armor(mdef, W_ARM); /* suit */
1594 obj = which_armor(mdef, W_ARMU); /* shirt */
1597 /* if monster's cloak/armor is greased, your grab slips off; this
1598 protection might fail (33% chance) when the armor is cursed */
1599 if (obj && (obj->greased || obj->otyp == OILSKIN_CLOAK)
1600 && (!obj->cursed || rn2(3))) {
1603 mattk->adtyp == AD_WRAP ? "slip off of"
1604 : "grab, but cannot hold onto",
1605 s_suffix(mon_nam(mdef)), obj->greased ? "greased" : "slippery",
1606 /* avoid "slippery slippery cloak"
1607 for undiscovered oilskin cloak */
1608 (obj->greased || objects[obj->otyp].oc_name_known)
1610 : cloak_simple_name(obj));
1612 You("%s
\82Ì%s%s%s
\81I",
1613 mon_nam(mdef), obj->greased ? "
\96û
\82Ì
\93h
\82ç
\82ê
\82½" : "
\8a\8a\82è
\82â
\82·
\82¢",
1614 (obj->greased || objects[obj->otyp].oc_name_known)
1616 : cloak_simple_name(obj),
1617 mattk->adtyp == AD_WRAP ? "
\82Å
\8a\8a\82Á
\82½"
1618 : "
\82ð
\82Â
\82©
\82Ü
\82æ
\82¤
\82Æ
\82µ
\82½
\82ª
\81C
\82Å
\82«
\82È
\82©
\82Á
\82½");
1621 if (obj->greased && !rn2(2)) {
1623 pline_The("grease wears off.");
1625 pline("
\96û
\82Í
\97\8e\82¿
\82Ä
\82µ
\82Ü
\82Á
\82½
\81D");
1633 /* used when hitting a monster with a lance while mounted;
1634 1: joust hit; 0: ordinary hit; -1: joust but break lance */
1637 struct monst *mon; /* target */
1638 struct obj *obj; /* weapon */
1640 int skill_rating, joust_dieroll;
1642 if (Fumbling || Stunned)
1644 /* sanity check; lance must be wielded in order to joust */
1645 if (obj != uwep && (obj != uswapwep || !u.twoweap))
1648 /* if using two weapons, use worse of lance and two-weapon skills */
1649 skill_rating = P_SKILL(weapon_type(obj)); /* lance skill */
1650 if (u.twoweap && P_SKILL(P_TWO_WEAPON_COMBAT) < skill_rating)
1651 skill_rating = P_SKILL(P_TWO_WEAPON_COMBAT);
1652 if (skill_rating == P_ISRESTRICTED)
1653 skill_rating = P_UNSKILLED; /* 0=>1 */
1655 /* odds to joust are expert:80%, skilled:60%, basic:40%, unskilled:20% */
1656 if ((joust_dieroll = rn2(5)) < skill_rating) {
1657 if (joust_dieroll == 0 && rnl(50) == (50 - 1) && !unsolid(mon->data)
1658 && !obj_resists(obj, 0, 100))
1659 return -1; /* hit that breaks lance */
1660 return 1; /* successful joust */
1662 return 0; /* no joust bonus; revert to ordinary attack */
1666 * Send in a demon pet for the hero. Exercise wisdom.
1668 * This function used to be inline to damageum(), but the Metrowerks compiler
1669 * (DR4 and DR4.5) screws up with an internal error 5 "Expression Too
1671 * Pulling it out makes it work.
1677 struct permonst *pm;
1681 pline("Some hell-p has arrived!");
1683 pline("
\92n
\8d\96\82Ì
\92\87\8aÔ
\82ª
\8c»
\82í
\82ê
\82½
\81I");
1684 i = !rn2(6) ? ndemon(u.ualign.type) : NON_PM;
1685 pm = i != NON_PM ? &mons[i] : youmonst.data;
1686 if ((dtmp = makemon(pm, u.ux, u.uy, NO_MM_FLAGS)) != 0)
1687 (void) tamedog(dtmp, (struct obj *) 0);
1688 exercise(A_WIS, TRUE);
1692 theft_petrifies(otmp)
1695 if (uarmg || otmp->otyp != CORPSE
1696 || !touch_petrifies(&mons[otmp->corpsenm]) || Stone_resistance)
1699 #if 0 /* no poly_when_stoned() critter has theft capability */
1700 if (poly_when_stoned(youmonst.data) && polymon(PM_STONE_GOLEM)) {
1701 display_nhwindow(WIN_MESSAGE, FALSE); /* --More-- */
1706 /* stealing this corpse is fatal... */
1708 instapetrify(corpse_xname(otmp, "stolen", CXN_ARTICLE));
1710 instapetrify(corpse_xname(otmp, "
\93\90\82Ü
\82ê
\82½", CXN_ARTICLE));
1711 /* apparently wasn't fatal after all... */
1716 * Player uses theft attack against monster.
1718 * If the target is wearing body armor, take all of its possessions;
1719 * otherwise, take one object. [Is this really the behavior we want?]
1722 steal_it(mdef, mattk)
1724 struct attack *mattk;
1726 struct obj *otmp, *stealoid, **minvent_ptr;
1730 return; /* nothing to take */
1732 /* look for worn body armor */
1733 stealoid = (struct obj *) 0;
1734 if (could_seduce(&youmonst, mdef, mattk)) {
1735 /* find armor, and move it to end of inventory in the process */
1736 minvent_ptr = &mdef->minvent;
1737 while ((otmp = *minvent_ptr) != 0)
1738 if (otmp->owornmask & W_ARM) {
1740 panic("steal_it: multiple worn suits");
1741 *minvent_ptr = otmp->nobj; /* take armor out of minvent */
1743 stealoid->nobj = (struct obj *) 0;
1745 minvent_ptr = &otmp->nobj;
1747 *minvent_ptr = stealoid; /* put armor back into minvent */
1750 if (stealoid) { /* we will be taking everything */
1751 if (gender(mdef) == (int) u.mfemale && youmonst.data->mlet == S_NYMPH)
1753 You("charm %s. She gladly hands over her possessions.",
1755 You("%s
\82ð
\82¤
\82Á
\82Æ
\82è
\82³
\82¹
\82½
\81D
\94Þ
\8f\97\82Í
\82æ
\82ë
\82±
\82ñ
\82Å
\8e\9d\82¿
\95¨
\82ð
\82³
\82µ
\82¾
\82µ
\82½
\81D",
1759 You("seduce %s and %s starts to take off %s clothes.",
1760 mon_nam(mdef), mhe(mdef), mhis(mdef));
1762 You("%s
\82ð
\97U
\98f
\82µ
\82½
\81D%s
\82Í
\95\9e\82ð
\92E
\82¬
\82Í
\82¶
\82ß
\82½
\81D",
1763 mon_nam(mdef), mhe(mdef));
1767 while ((otmp = mdef->minvent) != 0) {
1769 break; /* no longer have ability to steal */
1770 /* take the object away from the monster */
1771 obj_extract_self(otmp);
1772 if ((unwornmask = otmp->owornmask) != 0L) {
1773 mdef->misc_worn_check &= ~unwornmask;
1774 if (otmp->owornmask & W_WEP)
1775 setmnotwielded(mdef, otmp);
1776 otmp->owornmask = 0L;
1777 update_mon_intrinsics(mdef, otmp, FALSE, FALSE);
1778 /* give monster a chance to wear other equipment on its next
1779 move instead of waiting until it picks something up */
1780 mdef->misc_worn_check |= I_SPECIAL;
1782 if (otmp == stealoid) /* special message for final item */
1784 pline("%s finishes taking off %s suit.", Monnam(mdef),
1787 pline("%s
\82Í
\92E
\82¬
\8fI
\82¦
\82½
\81D", Monnam(mdef));
1790 /* give the object to the character */
1792 otmp = hold_another_object(otmp, "You snatched but dropped %s.",
1793 doname(otmp), "You steal: ");
1795 otmp = hold_another_object(otmp, "
\82 \82È
\82½
\82Í%s
\82ð
\93\90\82ñ
\82¾
\82ª
\97\8e\82Æ
\82µ
\82½
\81D",
1796 doname(otmp), "
\82ð
\93\90\82ñ
\82¾
\81D");
1798 /* might have dropped otmp, and it might have broken or left level */
1799 if (!otmp || otmp->where != OBJ_INVENT)
1801 if (theft_petrifies(otmp))
1802 break; /* stop thieving even though hero survived */
1803 /* more take-away handling, after theft message */
1804 if (unwornmask & W_WEP) { /* stole wielded weapon */
1805 possibly_unwield(mdef, FALSE);
1806 } else if (unwornmask & W_ARMG) { /* stole worn gloves */
1807 mselftouch(mdef, (const char *) 0, TRUE);
1808 if (DEADMONSTER(mdef)) /* it's now a statue */
1809 return; /* can't continue stealing */
1813 break; /* only taking one item */
1818 damageum(mdef, mattk, specialdmg)
1819 register struct monst *mdef;
1820 register struct attack *mattk;
1821 int specialdmg; /* blessed and/or silver bonus against various things */
1823 register struct permonst *pd = mdef->data;
1824 int armpro, tmp = d((int) mattk->damn, (int) mattk->damd);
1826 struct obj *mongold;
1828 armpro = magic_negation(mdef);
1829 /* since hero can't be cancelled, only defender's armor applies */
1830 negated = !(rn2(10) >= 3 * armpro);
1832 if (is_demon(youmonst.data) && !rn2(13) && !uwep
1833 && u.umonnum != PM_SUCCUBUS && u.umonnum != PM_INCUBUS
1834 && u.umonnum != PM_BALROG) {
1838 switch (mattk->adtyp) {
1842 pline("%s %s for a moment.", Monnam(mdef),
1843 makeplural(stagger(pd, "stagger")));
1845 pline("%s
\82Í
\88ê
\8fu%s
\81D", Monnam(mdef),
1846 jpast(stagger(pd, "
\82æ
\82ë
\82ß
\82")));
1858 case AD_WERE: /* no special effect on monsters */
1859 case AD_HEAL: /* likewise */
1862 if (pd == &mons[PM_SHADE]) {
1865 impossible("bad shade attack function flow?");
1869 if (mattk->aatyp == AT_WEAP) {
1870 /* hmonas() uses known_hitum() to deal physical damage,
1871 then also damageum() for non-AD_PHYS; don't inflict
1872 extra physical damage for unusual damage types */
1874 } else if (mattk->aatyp == AT_KICK
1875 || mattk->aatyp == AT_CLAW
1876 || mattk->aatyp == AT_TUCH
1877 || mattk->aatyp == AT_HUGS) {
1878 if (thick_skinned(pd))
1879 tmp = (mattk->aatyp == AT_KICK) ? 0 : (tmp + 1) / 2;
1880 /* add ring(s) of increase damage */
1881 if (u.udaminc > 0) {
1882 /* applies even if damage was 0 */
1884 } else if (tmp > 0) {
1885 /* ring(s) might be negative; avoid converting
1886 0 to non-0 or positive to non-positive */
1900 pline("%s is %s!", Monnam(mdef), on_fire(pd, mattk));
1902 pline("%s
\82Í%s
\81I", Monnam(mdef), on_fire(mdef->data, mattk));
1903 if (completelyburns(pd)) { /* paper golem or straw golem */
1906 pline("%s burns completely!", Monnam(mdef));
1908 pline("%s
\82Í
\8a®
\91S
\82É
\94R
\82¦
\90s
\82«
\82½
\81I", Monnam(mdef));
1910 You("smell burning%s.",
1911 (pd == &mons[PM_PAPER_GOLEM]) ? " paper"
1912 : (pd == &mons[PM_STRAW_GOLEM]) ? " straw" : "");
1913 xkilled(mdef, XKILL_NOMSG | XKILL_NOCORPSE);
1916 /* Don't return yet; keep hp<1 and tmp=0 for pet msg */
1918 tmp += destroy_mitem(mdef, SCROLL_CLASS, AD_FIRE);
1919 tmp += destroy_mitem(mdef, SPBOOK_CLASS, AD_FIRE);
1920 if (resists_fire(mdef)) {
1923 pline_The("fire doesn't heat %s!", mon_nam(mdef));
1925 pline("
\89\8a\82Í%s
\82É
\89e
\8b¿
\82ª
\82È
\82¢
\81I", mon_nam(mdef));
1926 golemeffects(mdef, AD_FIRE, tmp);
1927 shieldeff(mdef->mx, mdef->my);
1930 /* only potions damage resistant players in destroy_item */
1931 tmp += destroy_mitem(mdef, POTION_CLASS, AD_FIRE);
1940 pline("%s is covered in frost!", Monnam(mdef));
1942 pline("%s
\82Í
\95X
\82Å
\95¢
\82í
\82ê
\82½
\81I", Monnam(mdef));
1943 if (resists_cold(mdef)) {
1944 shieldeff(mdef->mx, mdef->my);
1947 pline_The("frost doesn't chill %s!", mon_nam(mdef));
1949 pline("
\95X
\82Í%s
\82ð
\93\80\82ç
\82·
\82±
\82Æ
\82ª
\82Å
\82«
\82È
\82¢
\81I", mon_nam(mdef));
1950 golemeffects(mdef, AD_COLD, tmp);
1953 tmp += destroy_mitem(mdef, POTION_CLASS, AD_COLD);
1962 pline("%s is zapped!", Monnam(mdef));
1964 pline("%s
\82Í
\93d
\8c\82\82ð
\82
\82ç
\82Á
\82½
\81I", Monnam(mdef));
1965 tmp += destroy_mitem(mdef, WAND_CLASS, AD_ELEC);
1966 if (resists_elec(mdef)) {
1969 pline_The("zap doesn't shock %s!", mon_nam(mdef));
1971 pline("
\93d
\8c\82\82Í%s
\82É
\89e
\8b¿
\82ð
\97^
\82¦
\82È
\82¢
\81I", mon_nam(mdef));
1972 golemeffects(mdef, AD_ELEC, tmp);
1973 shieldeff(mdef->mx, mdef->my);
1976 /* only rings damage resistant players in destroy_item */
1977 tmp += destroy_mitem(mdef, RING_CLASS, AD_ELEC);
1980 if (resists_acid(mdef))
1984 if (!munstone(mdef, TRUE))
1985 minstapetrify(mdef, TRUE);
1991 steal_it(mdef, mattk);
1995 /* This you as a leprechaun, so steal
1996 real gold only, no lesser coins */
1997 mongold = findgold(mdef->minvent);
1999 obj_extract_self(mongold);
2000 if (merge_choice(invent, mongold) || inv_cnt(FALSE) < 52) {
2003 Your("purse feels heavier.");
2005 You("
\8dà
\95z
\82ª
\8fd
\82
\82È
\82Á
\82½
\82æ
\82¤
\82È
\8bC
\82ª
\82µ
\82½
\81D");
2008 You("grab %s's gold, but find no room in your knapsack.",
2010 You("%s
\82Ì
\82¨
\8bà
\82ð
\82Â
\82©
\82ñ
\82¾
\82ª
\81C
\8e\9d\82¿
\95¨
\91Ü
\82É
\93ü
\82ç
\82È
\82©
\82Á
\82½
\81D",
2015 exercise(A_DEX, TRUE);
2023 boolean u_saw_mon = (canseemon(mdef)
2024 || (u.uswallow && u.ustuck == mdef));
2026 /* record the name before losing sight of monster */
2027 Strcpy(nambuf, Monnam(mdef));
2028 if (u_teleport_mon(mdef, FALSE) && u_saw_mon
2029 && !(canseemon(mdef) || (u.uswallow && u.ustuck == mdef)))
2031 pline("%s suddenly disappears!", nambuf);
2033 pline("%s
\82Í
\93Ë
\91R
\8fÁ
\82¦
\82½
\81I", nambuf);
2034 if (tmp >= mdef->mhp) { /* see hitmu(mhitu.c) */
2037 tmp = mdef->mhp - 1;
2042 if (can_blnd(&youmonst, mdef, mattk->aatyp, (struct obj *) 0)) {
2043 if (!Blind && mdef->mcansee)
2045 pline("%s is blinded.", Monnam(mdef));
2047 pline("%s
\82Í
\96Ú
\82ª
\8c©
\82¦
\82È
\82
\82È
\82Á
\82½
\81D", Monnam(mdef));
2049 tmp += mdef->mblinded;
2052 mdef->mblinded = tmp;
2057 if (night() && !rn2(10) && !mdef->mcan) {
2058 if (pd == &mons[PM_CLAY_GOLEM]) {
2061 pline("Some writing vanishes from %s head!",
2062 s_suffix(mon_nam(mdef)));
2064 pline("%s
\82Ì
\93ª
\82É
\8f\91\82¢
\82Ä
\82 \82é
\95¶
\8e\9a\82Ì
\82¢
\82
\82Â
\82©
\82ª
\8fÁ
\82¦
\82½
\81I",
2067 xkilled(mdef, XKILL_NOMSG);
2068 /* Don't return yet; keep hp<1 and tmp=0 for pet msg */
2074 You("
\82
\82·
\82
\82·
\8fÎ
\82Á
\82½
\81D");
2080 if (!negated && !rn2(3) && !resists_drli(mdef)) {
2084 pline("%s suddenly seems weaker!", Monnam(mdef));
2086 pline("%s
\82Í
\93Ë
\91R
\8eã
\82
\82È
\82Á
\82½
\82æ
\82¤
\82É
\8c©
\82¦
\82½
\81I", Monnam(mdef));
2087 mdef->mhpmax -= xtmp;
2089 /* !m_lev: level 0 monster is killed regardless of hit points
2090 rather than drop to level -1 */
2091 if (DEADMONSTER(mdef) || !mdef->m_lev) {
2093 pline("%s dies!", Monnam(mdef));
2095 pline("%s
\82Í
\8e\80\82ñ
\82¾
\81I", Monnam(mdef));
2096 xkilled(mdef, XKILL_NOMSG);
2103 if (pd == &mons[PM_IRON_GOLEM]) {
2105 pline("%s falls to pieces!", Monnam(mdef));
2107 pline("%s
\82Í
\83o
\83\89\83o
\83\89\82É
\82È
\82Á
\82½
\81I", Monnam(mdef));
2108 xkilled(mdef, XKILL_NOMSG);
2110 erode_armor(mdef, ERODE_RUST);
2114 erode_armor(mdef, ERODE_CORRODE);
2118 if (pd == &mons[PM_WOOD_GOLEM] || pd == &mons[PM_LEATHER_GOLEM]) {
2120 pline("%s falls to pieces!", Monnam(mdef));
2122 pline("%s
\82Í
\83o
\83\89\83o
\83\89\82É
\82È
\82Á
\82½
\81I", Monnam(mdef));
2123 xkilled(mdef, XKILL_NOMSG);
2125 erode_armor(mdef, ERODE_ROT);
2129 if (!negated && !rn2(4))
2130 xdrainenergym(mdef, TRUE);
2136 if (!negated && !rn2(8)) {
2138 Your("%s was poisoned!", mpoisons_subj(&youmonst, mattk));
2140 Your("%s
\82Í
\93Å
\82³
\82ê
\82Ä
\82¢
\82é
\81I", mpoisons_subj(&youmonst, mattk));
2141 if (resists_poison(mdef)) {
2143 pline_The("poison doesn't seem to affect %s.", mon_nam(mdef));
2145 pline("
\93Å
\82Í%s
\82É
\89e
\8b¿
\82ð
\97^
\82¦
\82È
\82¢
\81D", mon_nam(mdef));
2149 Your("poison was deadly...");
2151 Your("
\97^
\82¦
\82½
\93Å
\82Í
\92v
\8e\80\97Ê
\82¾
\82Á
\82½
\81D
\81D
\81D");
2161 if (notonhead || !has_head(pd)) {
2163 pline("%s doesn't seem harmed.", Monnam(mdef));
2165 pline("%s
\82Í
\8f\9d\82Â
\82¢
\82½
\82æ
\82¤
\82É
\82Í
\8c©
\82¦
\82È
\82¢
\81D", Monnam(mdef));
2167 if (!Unchanging && pd == &mons[PM_GREEN_SLIME]) {
2170 You("suck in some slime and don't feel very well.");
2172 You("
\83X
\83\89\83C
\83\80\82ð
\8bz
\82¢
\8eæ
\82Á
\82Ä
\81C
\8bï
\8d\87\82ª
\88«
\82
\82È
\82Á
\82½
\81D");
2173 make_slimed(10L, (char *) 0);
2178 if (m_slips_free(mdef, mattk))
2181 if ((helmet = which_armor(mdef, W_ARMH)) != 0 && rn2(8)) {
2183 pline("%s %s blocks your attack to %s head.",
2184 s_suffix(Monnam(mdef)), helm_simple_name(helmet),
2187 pline("%s
\82Ì%s
\82ª
\93ª
\82Ö
\82Ì
\8dU
\8c\82\82ð
\96h
\82¢
\82¾
\81D",
2188 Monnam(mdef), helm_simple_name(helmet));
2193 (void) eat_brains(&youmonst, mdef, TRUE, &tmp);
2197 if (!negated && !sticks(pd))
2198 u.ustuck = mdef; /* it's now stuck to you */
2202 if (!u.ustuck && !rn2(10)) {
2203 if (m_slips_free(mdef, mattk)) {
2207 You("swing yourself around %s!", mon_nam(mdef));
2209 You("%s
\82É
\90g
\91Ì
\82ð
\97\8d\82Ý
\82Â
\82©
\82¹
\82½
\81I", mon_nam(mdef));
2212 } else if (u.ustuck == mdef) {
2213 /* Monsters don't wear amulets of magical breathing */
2214 if (is_pool(u.ux, u.uy) && !is_swimmer(pd)
2215 && !amphibious(pd)) {
2217 You("drown %s...", mon_nam(mdef));
2219 You("%s
\82ð
\93M
\82ê
\82³
\82¹
\82½
\81D
\81D
\81D", mon_nam(mdef));
2221 } else if (mattk->aatyp == AT_HUGS)
2223 pline("%s is being crushed.", Monnam(mdef));
2225 pline("%s
\82Í
\89\9f\82µ
\82Â
\82Ô
\82³
\82ê
\82Ä
\82¢
\82é
\81D", Monnam(mdef));
2230 You("brush against %s %s.", s_suffix(mon_nam(mdef)),
2231 mbodypart(mdef, LEG));
2233 You("%s
\82Ì%s
\82É
\90G
\82ê
\82½
\81D", mon_nam(mdef),
2234 mbodypart(mdef, LEG));
2241 if (!negated && mdef->mcanmove && !rn2(3) && tmp < mdef->mhp) {
2244 pline("%s is frozen by you!", Monnam(mdef));
2246 pline("%s
\82Í
\82 \82È
\82½
\82Ì
\82É
\82ç
\82Ý
\82Å
\93®
\82¯
\82È
\82
\82È
\82Á
\82½
\81I", Monnam(mdef));
2247 paralyze_monst(mdef, rnd(10));
2251 if (!negated && !mdef->msleeping && sleep_monst(mdef, rnd(10), -1)) {
2254 pline("%s is put to sleep by you!", Monnam(mdef));
2256 pline("%s
\82Í
\93Ë
\91R
\96°
\82è
\82É
\82¨
\82¿
\82½
\81I", Monnam(mdef));
2262 break; /* physical damage only */
2263 if (!rn2(4) && !slimeproof(pd)) {
2264 if (!munslime(mdef, TRUE) && !DEADMONSTER(mdef)) {
2265 /* this assumes newcham() won't fail; since hero has
2266 a slime attack, green slimes haven't been geno'd */
2268 You("turn %s into slime.", mon_nam(mdef));
2270 pline("%s
\82Í
\83X
\83\89\83C
\83\80\82É
\82È
\82Á
\82½
\81D", mon_nam(mdef));
2271 if (newcham(mdef, &mons[PM_GREEN_SLIME], FALSE, FALSE))
2274 /* munslime attempt could have been fatal */
2275 if (DEADMONSTER(mdef))
2276 return 2; /* skip death message */
2280 case AD_ENCH: /* KMH -- remove enchantment (disenchanter) */
2281 /* there's no msomearmor() function, so just do damage */
2282 /* if (negated) break; */
2285 if (!negated && mdef->mspeed != MSLOW) {
2286 unsigned int oldspeed = mdef->mspeed;
2288 mon_adjust_speed(mdef, -1, (struct obj *) 0);
2289 if (mdef->mspeed != oldspeed && canseemon(mdef))
2291 pline("%s slows down.", Monnam(mdef));
2293 pline("%s
\82Í
\82Ì
\82ë
\82
\82È
\82Á
\82½
\81D", Monnam(mdef));
2298 if (canseemon(mdef))
2300 pline("%s looks confused.", Monnam(mdef));
2302 pline("%s
\82Í
\8d¬
\97\90\82µ
\82½
\82æ
\82¤
\82¾
\81D", Monnam(mdef));
2311 mdef->mstrategy &= ~STRAT_WAITFORU; /* in case player is very fast */
2313 if (DEADMONSTER(mdef)) {
2314 if (mdef->mtame && !cansee(mdef->mx, mdef->my)) {
2316 You_feel("embarrassed for a moment.");
2318 You("
\82µ
\82Î
\82ç
\82
\8d¢
\98f
\82µ
\82½
\81D");
2320 xkilled(mdef, XKILL_NOMSG); /* !tmp but hp<1: already killed */
2321 } else if (!flags.verbose) {
2325 You("
\93|
\82µ
\82½
\81I");
2327 xkilled(mdef, XKILL_NOMSG);
2337 register struct monst *mdef;
2338 register struct attack *mattk;
2340 boolean resistance; /* only for cold/fire/elec */
2341 register int tmp = d((int) mattk->damn, (int) mattk->damd);
2346 You("
\94\9a\94
\82µ
\82½
\81I");
2347 switch (mattk->adtyp) {
2349 if (!resists_blnd(mdef)) {
2351 pline("%s is blinded by your flash of light!", Monnam(mdef));
2353 pline("%s
\82Í
\82Ü
\82Î
\82ä
\82¢
\8cõ
\82Å
\96Ú
\82ª
\82
\82ç
\82ñ
\82¾
\81I", Monnam(mdef));
2354 mdef->mblinded = min((int) mdef->mblinded + tmp, 127);
2359 if (haseyes(mdef->data) && mdef->mcansee) {
2361 pline("%s is affected by your flash of light!", Monnam(mdef));
2363 pline("%s
\82Í
\82Ü
\82Î
\82ä
\82¢
\8cõ
\82Å
\89e
\8b¿
\82ð
\8eó
\82¯
\82½
\81I", Monnam(mdef));
2368 resistance = resists_cold(mdef);
2371 resistance = resists_fire(mdef);
2374 resistance = resists_elec(mdef);
2378 pline("%s gets blasted!", Monnam(mdef));
2380 pline("%s
\82Í
\94\9a\94
\82ð
\97\81\82Ñ
\82½
\81I", Monnam(mdef));
2382 if (DEADMONSTER(mdef)) {
2387 shieldeff(mdef->mx, mdef->my);
2388 if (is_golem(mdef->data))
2389 golemeffects(mdef, (int) mattk->adtyp, tmp);
2392 pline_The("blast doesn't seem to affect %s.", mon_nam(mdef));
2394 pline("
\94\9a\94
\82Í%s
\82É
\89e
\8b¿
\82ð
\97^
\82¦
\82È
\82©
\82Á
\82½
\82æ
\82¤
\82¾
\81D", mon_nam(mdef));
2408 map_location(u.ux, u.uy, TRUE);
2409 tmp_at(DISP_ALWAYS, mon_to_glyph(&youmonst, rn2_on_display_rng));
2410 tmp_at(mdef->mx, mdef->my);
2413 You("engulf %s!", mon_nam(mdef));
2415 You("%s
\82ð
\88ù
\82Ý
\8d\9e\82ñ
\82¾
\81I", mon_nam(mdef));
2424 tmp_at(DISP_END, 0);
2431 register struct monst *mdef;
2432 register struct attack *mattk;
2434 #ifdef LINT /* static char msgbuf[BUFSZ]; */
2437 static char msgbuf[BUFSZ]; /* for nomovemsg */
2440 register int dam = d((int) mattk->damn, (int) mattk->damd);
2443 struct permonst *pd = mdef->data;
2445 /* Not totally the same as for real monsters. Specifically, these
2446 * don't take multiple moves. (It's just too hard, for too little
2447 * result, to program monsters which attack from inside you, which
2448 * would be necessary if done accurately.) Instead, we arbitrarily
2449 * kill the monster immediately for AD_DGST and we regurgitate them
2450 * after exactly 1 round of attack otherwise. -KAA
2453 if (!engulf_target(&youmonst, mdef))
2456 if (u.uhunger < 1500 && !u.uswallow) {
2457 for (otmp = mdef->minvent; otmp; otmp = otmp->nobj)
2458 (void) snuff_lit(otmp);
2460 /* force vampire in bat, cloud, or wolf form to revert back to
2461 vampire form now instead of dealing with that when it dies */
2462 if (is_vampshifter(mdef)
2463 && newcham(mdef, &mons[mdef->cham], FALSE, FALSE)) {
2465 You("engulf it, then expel it.");
2467 You("
\88ù
\82Ý
\8d\9e\82ñ
\82Å
\81C
\93f
\82«
\8fo
\82µ
\82½
\81D");
2468 if (canspotmon(mdef))
2470 pline("It turns into %s.", a_monnam(mdef));
2472 pline("
\82»
\82ê
\82Í%s
\82É
\82È
\82Á
\82½
\81D", a_monnam(mdef));
2474 map_invisible(mdef->mx, mdef->my);
2478 /* engulfing a cockatrice or digesting a Rider or Medusa */
2479 fatal_gulp = (touch_petrifies(pd) && !Stone_resistance)
2480 || (mattk->adtyp == AD_DGST
2481 && (is_rider(pd) || (pd == &mons[PM_MEDUSA]
2482 && !Stone_resistance)));
2484 if ((mattk->adtyp == AD_DGST && !Slow_digestion) || fatal_gulp)
2485 eating_conducts(pd);
2487 if (fatal_gulp && !is_rider(pd)) { /* petrification */
2489 const char *mname = pd->mname;
2491 if (!type_is_pname(pd))
2494 You("englut %s.", mon_nam(mdef));
2496 You("%s
\82ð
\88ù
\82Ý
\8d\9e\82ñ
\82¾
\81D", mon_nam(mdef));
2498 Sprintf(kbuf, "swallowing %s whole", mname);
2500 Sprintf(kbuf, "%s
\82ð
\88ù
\82Ý
\8d\9e\82ñ
\82Å", mname);
2504 switch (mattk->adtyp) {
2506 /* eating a Rider or its corpse is fatal */
2509 pline("Unfortunately, digesting any of it is fatal.");
2511 pline("
\8ec
\94O
\82È
\82ª
\82ç
\81C
\82»
\82ê
\82ð
\90H
\82×
\82é
\82Ì
\82Í
\92v
\96½
\93I
\82È
\8aÔ
\88á
\82¢
\82¾
\81D");
2514 Sprintf(killer.name, "unwisely tried to eat %s",
2516 killer.format = NO_KILLER_PREFIX;
2518 Sprintf(killer.name, "
\8bð
\82©
\82É
\82à%s
\82ð
\90H
\82×
\82æ
\82¤
\82Æ
\82µ
\82Ä",
2520 killer.format = KILLED_BY;
2523 return 0; /* lifesaved */
2526 if (Slow_digestion) {
2531 /* Use up amulet of life saving */
2532 if ((otmp = mlifesaver(mdef)) != 0)
2533 m_useup(mdef, otmp);
2536 /* start_engulf() issues "you engulf <mdef>" above; this
2537 used to specify XKILL_NOMSG but we need "you kill <mdef>"
2538 in case we're also going to get "welcome to level N+1";
2539 "you totally digest <mdef>" will be coming soon (after
2540 several turns) but the level-gain message seems out of
2541 order if the kill message is left implicit */
2542 xkilled(mdef, XKILL_GIVEMSG | XKILL_NOCORPSE);
2543 if (!DEADMONSTER(mdef)) { /* monster lifesaved */
2545 You("hurriedly regurgitate the sizzling in your %s.",
2547 You("%s
\82Ì
\92\86\82Å
\83V
\83\85\81[
\83V
\83\85\81[
\82Æ
\82¢
\82¤
\89¹
\82ð
\97§
\82Ä
\82Ä
\82¢
\82é
\82à
\82Ì
\82ð
\91å
\8b}
\82¬
\82Å
\93f
\82«
\96ß
\82µ
\82½
\81D",
2548 body_part(STOMACH));
2550 tmp = 1 + (pd->cwt >> 8);
2551 if (corpse_chance(mdef, &youmonst, TRUE)
2552 && !(mvitals[monsndx(pd)].mvflags & G_NOCORPSE)) {
2553 /* nutrition only if there can be a corpse */
2554 u.uhunger += (pd->cnutrit + 1) / 2;
2558 Sprintf(msgbuf, "You totally digest %s.", mon_nam(mdef));
2560 Sprintf(msgbuf, "
\82 \82È
\82½
\82Í%s
\82ð
\8a®
\91S
\82É
\8fÁ
\89»
\82µ
\82½
\81D", mon_nam(mdef));
2562 /* setting afternmv = end_engulf is tempting,
2563 * but will cause problems if the player is
2564 * attacked (which uses his real location) or
2565 * if his See_invisible wears off
2568 You("digest %s.", mon_nam(mdef));
2570 You("%s
\82ð
\8fÁ
\89»
\82µ
\82Ä
\82¢
\82é
\81D", mon_nam(mdef));
2575 multi_reason = "digesting something";
2577 multi_reason = "
\8fÁ
\89»
\92\86\82É";
2581 if (pd == &mons[PM_GREEN_SLIME]) {
2583 Sprintf(msgbuf, "%s isn't sitting well with you.",
2585 Sprintf(msgbuf, "%s
\82Í
\82 \82È
\82½
\82Æ
\82¤
\82Ü
\82
\90Ü
\82è
\8d\87\82¢
\82ð
\82Â
\82¯
\82ç
\82ê
\82È
\82¢
\82æ
\82¤
\82¾
\81D",
2588 make_slimed(5L, (char *) 0);
2591 exercise(A_CON, TRUE);
2596 if (youmonst.data == &mons[PM_FOG_CLOUD]) {
2598 pline("%s is laden with your moisture.", Monnam(mdef));
2600 pline("%s
\82Í
\82 \82È
\82½
\82Ì
\8e¼
\8bC
\82É
\8bê
\82µ
\82ß
\82ç
\82ê
\82Ä
\82¢
\82é
\81D", Monnam(mdef));
2601 if (amphibious(pd) && !flaming(pd)) {
2604 pline("%s seems unharmed.", Monnam(mdef));
2606 pline("%s
\82Í
\8f\9d\82Â
\82¢
\82Ä
\82¢
\82È
\82¢
\82æ
\82¤
\82¾
\81D", Monnam(mdef));
2610 pline("%s is pummeled with your debris!", Monnam(mdef));
2612 pline("%s
\82Í
\8a¢âI
\82Å
\92É
\82ß
\82Â
\82¯
\82ç
\82ê
\82½
\81I", Monnam(mdef));
2616 pline("%s is covered with your goo!", Monnam(mdef));
2618 pline("%s
\82Í
\82Ë
\82Î
\82Â
\82
\82à
\82Ì
\82Å
\95¢
\82í
\82ê
\82½
\81I", Monnam(mdef));
2619 if (resists_acid(mdef)) {
2621 pline("It seems harmless to %s.", mon_nam(mdef));
2623 pline("
\82µ
\82©
\82µ
\81C%s
\82Í
\82È
\82ñ
\82Æ
\82à
\82È
\82¢
\81D", mon_nam(mdef));
2628 if (can_blnd(&youmonst, mdef, mattk->aatyp,
2629 (struct obj *) 0)) {
2632 pline("%s can't see in there!", Monnam(mdef));
2634 pline("%s
\82Í
\96Ú
\82ª
\8c©
\82¦
\82È
\82
\82È
\82Á
\82½
\81I", mon_nam(mdef));
2636 dam += mdef->mblinded;
2639 mdef->mblinded = dam;
2646 pline_The("air around %s crackles with electricity.",
2648 pline("%s
\82Ì
\89ñ
\82è
\82Ì
\8bó
\8bC
\82Í
\93d
\8bC
\82Å
\83s
\83\8a\83s
\83\8a\82µ
\82Ä
\82¢
\82é
\81D",
2650 if (resists_elec(mdef)) {
2652 pline("%s seems unhurt.", Monnam(mdef));
2654 pline("
\82µ
\82©
\82µ
\81C%s
\82Í
\95½
\8bC
\82È
\82æ
\82¤
\82¾
\81D", Monnam(mdef));
2657 golemeffects(mdef, (int) mattk->adtyp, dam);
2663 if (resists_cold(mdef)) {
2665 pline("%s seems mildly chilly.", Monnam(mdef));
2667 pline("%s
\82Í
\97â
\82¦
\82½
\82æ
\82¤
\82¾
\81D", Monnam(mdef));
2671 pline("%s is freezing to death!", Monnam(mdef));
2673 pline("%s
\82Í
\93\80\8e\80\82µ
\82»
\82¤
\82¾
\81I", Monnam(mdef));
2674 golemeffects(mdef, (int) mattk->adtyp, dam);
2680 if (resists_fire(mdef)) {
2682 pline("%s seems mildly hot.", Monnam(mdef));
2684 pline("%s
\82Í
\92g
\82©
\82
\82È
\82Á
\82½
\82æ
\82¤
\82¾
\81D", Monnam(mdef));
2688 pline("%s is burning to a crisp!", Monnam(mdef));
2690 pline("%s
\82Í
\94R
\82¦
\82Ä
\83J
\83\89\83J
\83\89\82É
\82È
\82Á
\82½
\81I", Monnam(mdef));
2691 golemeffects(mdef, (int) mattk->adtyp, dam);
2697 xdrainenergym(mdef, TRUE);
2703 if (DEADMONSTER(mdef)) {
2705 if (DEADMONSTER(mdef)) /* not lifesaved */
2709 You("%s %s!", is_animal(youmonst.data) ? "regurgitate" : "expel",
2712 You("%s
\82ð%s
\82µ
\82½
\81I", mon_nam(mdef),
2713 is_animal(youmonst.data) ? "
\93f
\82«
\96ß" : "
\94r
\8fo");
2715 if (Slow_digestion || is_animal(youmonst.data)) {
2717 pline("Obviously, you didn't like %s taste.",
2718 s_suffix(mon_nam(mdef)));
2720 pline("
\82Ç
\82¤
\82à%s
\82Ì
\96¡
\82Í
\8dD
\82«
\82É
\82È
\82ê
\82È
\82¢
\81D",
2730 missum(mdef, mattk, wouldhavehit)
2731 register struct monst *mdef;
2732 register struct attack *mattk;
2733 boolean wouldhavehit;
2735 if (wouldhavehit) /* monk is missing due to penalty for wearing suit */
2737 Your("armor is rather cumbersome...");
2739 Your("
\96h
\8bï
\82Í
\8f
\82µ
\8e×
\96\82\82¾
\81D
\81D
\81D");
2741 if (could_seduce(&youmonst, mdef, mattk))
2743 You("pretend to be friendly to %s.", mon_nam(mdef));
2745 You("%s
\82É
\97F
\8dD
\93I
\82È
\82Ó
\82è
\82ð
\82µ
\82½
\81D", mon_nam(mdef));
2746 else if (canspotmon(mdef) && flags.verbose)
2748 You("miss %s.", mon_nam(mdef));
2750 Your("%s
\82Ö
\82Ì
\8dU
\8c\82\82Í
\8aO
\82ê
\82½
\81D", mon_nam(mdef));
2755 Your("
\89½
\8eÒ
\82©
\82Ö
\82Ì
\8dU
\8c\82\82Í
\8aO
\82ê
\82½
\81D");
2756 if (!mdef->msleeping && mdef->mcanmove)
2760 /* attack monster as a monster; returns True if mon survives */
2763 register struct monst *mon;
2765 struct attack *mattk, alt_attk;
2766 struct obj *weapon, **originalweapon;
2767 boolean altwep = FALSE, weapon_used = FALSE, odd_claw = TRUE;
2768 int i, tmp, armorpenalty, sum[NATTK], nsum = 0, dhit = 0, attknum = 0;
2769 int dieroll, multi_claw = 0;
2771 /* with just one touch/claw/weapon attack, both rings matter;
2772 with more than one, alternate right and left when checking
2773 whether silver ring causes successful hit */
2774 for (i = 0; i < NATTK; i++) {
2776 mattk = getmattk(&youmonst, mon, i, sum, &alt_attk);
2777 if (mattk->aatyp == AT_WEAP
2778 || mattk->aatyp == AT_CLAW || mattk->aatyp == AT_TUCH)
2781 multi_claw = (multi_claw > 1); /* switch from count to yes/no */
2783 for (i = 0; i < NATTK; i++) {
2784 /* sum[i] = 0; -- now done above */
2785 mattk = getmattk(&youmonst, mon, i, sum, &alt_attk);
2787 switch (mattk->aatyp) {
2789 /* if (!uwep) goto weaponless; */
2791 odd_claw = !odd_claw; /* see case AT_CLAW,AT_TUCH below */
2792 /* if we've already hit with a two-handed weapon, we don't
2793 get to make another weapon attack (note: monsters who
2794 use weapons do not have this restriction, but they also
2795 never have the opportunity to use two weapons) */
2796 if (weapon_used && sum[i - 1] && uwep && bimanual(uwep))
2798 /* Certain monsters don't use weapons when encountered as enemies,
2799 * but players who polymorph into them have hands or claws and
2800 * thus should be able to use weapons. This shouldn't prohibit
2801 * the use of most special abilities, either.
2802 * If monster has multiple claw attacks, only one can use weapon.
2805 /* Potential problem: if the monster gets multiple weapon attacks,
2806 * we currently allow the player to get each of these as a weapon
2807 * attack. Is this really desirable?
2809 /* approximate two-weapon mode; known_hitum() -> hmon() -> &c
2810 might destroy the weapon argument, but it might also already
2811 be Null, and we want to track that for passive() */
2812 originalweapon = (altwep && uswapwep) ? &uswapwep : &uwep;
2813 if (uswapwep /* set up 'altwep' flag for next iteration */
2814 /* only consider seconary when wielding one-handed primary */
2815 && uwep && (uwep->oclass == WEAPON_CLASS || is_weptool(uwep))
2817 /* only switch if not wearing shield and not at artifact;
2818 shield limitation is iffy since still get extra swings
2819 if polyform has them, but it matches twoweap behavior;
2820 twoweap also only allows primary to be an artifact, so
2821 if alternate weapon is one, don't use it */
2822 && !uarms && !uswapwep->oartifact
2823 /* only switch to uswapwep if it's a weapon */
2824 && (uswapwep->oclass == WEAPON_CLASS || is_weptool(uswapwep))
2825 /* only switch if uswapwep is not bow, arrows, or darts */
2826 && !(is_launcher(uswapwep) || is_ammo(uswapwep)
2827 || is_missile(uswapwep)) /* dart, shuriken, boomerang */
2828 /* and not two-handed and not incapable of being wielded */
2829 && !bimanual(uswapwep)
2830 && !(objects[uswapwep->otyp].oc_material == SILVER
2832 altwep = !altwep; /* toggle for next attack */
2833 weapon = *originalweapon;
2834 if (!weapon) /* no need to go beyond no-gloves to rings; not ...*/
2835 originalweapon = &uarmg; /*... subject to erosion damage */
2837 tmp = find_roll_to_hit(mon, AT_WEAP, weapon, &attknum,
2840 dhit = (tmp > dieroll || u.uswallow);
2841 /* caller must set bhitpos */
2842 if (!known_hitum(mon, weapon, &dhit, tmp,
2843 armorpenalty, mattk, dieroll)) {
2844 /* enemy dead, before any special abilities used */
2849 /* originalweapon points to an equipment slot which might
2850 now be empty if the weapon was destroyed during the hit;
2851 passive(,weapon,...) won't call passive_obj() in that case */
2852 weapon = *originalweapon; /* might receive passive erosion */
2853 /* might be a worm that gets cut in half; if so, early return */
2854 if (m_at(u.ux + u.dx, u.uy + u.dy) != mon) {
2855 i = NATTK; /* skip additional attacks */
2856 /* proceed with uswapwep->cursed check, then exit loop */
2859 /* Do not print "You hit" message; known_hitum already did it. */
2860 if (dhit && mattk->adtyp != AD_SPEL && mattk->adtyp != AD_PHYS)
2861 sum[i] = damageum(mon, mattk, 0);
2864 if (uwep && !cantwield(youmonst.data) && !weapon_used)
2868 if (uwep && youmonst.data->mlet == S_LICH && !weapon_used)
2877 tmp = find_roll_to_hit(mon, mattk->aatyp, (struct obj *) 0,
2878 &attknum, &armorpenalty);
2880 dhit = (tmp > dieroll || u.uswallow);
2882 int compat, specialdmg;
2883 long silverhit = 0L;
2884 const char *verb = 0; /* verb or body part */
2887 && (compat = could_seduce(&youmonst, mon, mattk)) != 0) {
2890 (mon->mcansee && haseyes(mon->data)) ? "smile at"
2893 (compat == 2) ? "engagingly" : "seductively");
2895 You("%s
\82Ö%s%s
\81D",
2897 compat == 2 ? "
\96£
\97Í
\93I
\82É" : "
\97U
\98f
\93I
\82É",
2898 mon->mcansee && haseyes(mon->data) ? "
\94÷
\8fÎ
\82Ý
\82©
\82¯
\82½"
2899 : "
\98b
\82µ
\82©
\82¯
\82½");
2901 /* doesn't anger it; no wakeup() */
2902 sum[i] = damageum(mon, mattk, 0);
2907 specialdmg = 0; /* blessed and/or silver bonus */
2908 switch (mattk->aatyp) {
2911 /* verb=="claws" may be overridden below */
2912 verb = (mattk->aatyp == AT_TUCH) ? "touch" : "claws";
2913 /* decide if silver-hater will be hit by silver ring(s);
2914 for 'multi_claw' where attacks alternate right/left,
2915 assume 'even' claw or touch attacks use right hand
2916 or paw, 'odd' ones use left for ring interaction;
2917 even vs odd is based on actual attacks rather
2918 than on index into mon->dat->mattk[] so that {bite,
2919 claw,claw} instead of {claw,claw,bite} doesn't
2920 make poly'd hero mysteriously become left-handed */
2921 odd_claw = !odd_claw;
2922 specialdmg = special_dmgval(&youmonst, mon,
2924 | ((odd_claw || !multi_claw)
2926 | ((!odd_claw || !multi_claw)
2931 /* assumes mind flayer's tentacles-on-head rather
2932 than sea monster's tentacle-as-arm */
2937 specialdmg = special_dmgval(&youmonst, mon, W_ARMF,
2941 verb = "head butt"; /* mbodypart(mon,HEAD)=="head" */
2942 /* hypothetical; if any form with a head-butt attack
2943 could wear a helmet, it would hit shades when
2944 wearing a blessed (or silver) one */
2945 specialdmg = special_dmgval(&youmonst, mon, W_ARMH,
2958 if (mon->data == &mons[PM_SHADE] && !specialdmg) {
2959 if (!strcmp(verb, "hit")
2960 || (mattk->aatyp == AT_CLAW && humanoid(mon->data)))
2963 Your("%s %s harmlessly through %s.",
2964 verb, vtense(verb, "pass"), mon_nam(mon));
2966 Your("
\8dU
\8c\82\82Í%s
\82ð
\92Ê
\82è
\82Ê
\82¯
\82½
\81D",
2970 if (mattk->aatyp == AT_TENT) {
2972 Your("tentacles suck %s.", mon_nam(mon));
2974 Your("
\90G
\8eè
\82ª%s
\82Ì
\91Ì
\89t
\82ð
\8bz
\82¢
\82Æ
\82Á
\82½
\81D", mon_nam(mon));
2976 if (mattk->aatyp == AT_CLAW)
2977 verb = "hit"; /* not "claws" */
2978 You("%s %s.", verb, mon_nam(mon));
2979 if (silverhit && flags.verbose)
2980 silver_sears(&youmonst, mon, silverhit);
2982 sum[i] = damageum(mon, mattk, specialdmg);
2984 } else { /* !dhit */
2985 missum(mon, mattk, (tmp + armorpenalty > dieroll));
2991 long silverhit = 0L;
2992 boolean byhand = hug_throttles(&mons[u.umonnum]), /* rope golem */
2993 unconcerned = (byhand && !can_be_strangled(mon));
2995 if (sticks(mon->data) || u.uswallow || notonhead
2996 || (byhand && (uwep || !has_head(mon->data)))) {
2997 /* can't hold a holder due to subsequent ambiguity over
2998 who is holding whom; can't hug engulfer from inside;
2999 can't hug a worm tail (would immobilize entire worm!);
3000 byhand: can't choke something that lacks a head;
3001 not allowed to make a choking hug if wielding a weapon
3002 (but might have grabbed w/o weapon, then wielded one,
3003 and may even be attacking a different monster now) */
3004 if (byhand && uwep && u.ustuck
3005 && !(sticks(u.ustuck->data) || u.uswallow))
3007 continue; /* not 'break'; bypass passive counter-attack */
3009 /* automatic if prev two attacks succeed, or if
3010 already grabbed in a previous attack */
3013 /* choking hug/throttling grab uses hands (gloves or rings);
3014 normal hug uses outermost of cloak/suit/shirt */
3015 specialdmg = special_dmgval(&youmonst, mon,
3016 byhand ? (W_ARMG | W_RINGL | W_RINGR)
3017 : (W_ARMC | W_ARM | W_ARMU),
3020 /* strangling something which can't be strangled */
3021 if (mattk != &alt_attk) {
3025 /* change damage to 1d1; not strangling but still
3026 doing [minimal] physical damage to victim's body */
3027 mattk->damn = mattk->damd = 1;
3028 /* don't give 'unconcerned' feedback if there is extra damage
3029 or if it is nearly destroyed or if creature doesn't have
3030 the mental ability to be concerned in the first place */
3031 if (specialdmg || mindless(mon->data)
3032 || mon->mhp <= 1 + max(u.udaminc, 1))
3033 unconcerned = FALSE;
3035 if (mon->data == &mons[PM_SHADE]) {
3036 const char *verb = byhand ? "grasp" : "hug";
3038 /* hugging a shade; successful if blessed outermost armor
3039 for normal hug, or blessed gloves or silver ring(s) for
3040 choking hug; deals damage but never grabs hold */
3042 You("%s %s%s", verb, mon_nam(mon), exclam(specialdmg));
3043 if (silverhit && flags.verbose)
3044 silver_sears(&youmonst, mon, silverhit);
3045 sum[i] = damageum(mon, mattk, specialdmg);
3048 Your("%s passes harmlessly through %s.",
3049 verb, mon_nam(mon));
3051 You("%s
\82ð
\82Â
\82©
\82Ü
\82¦
\82æ
\82¤
\82Æ
\82µ
\82½
\82ª
\92Ê
\82è
\82Ê
\82¯
\82½
\81D",
3057 /* hug attack against ordinary foe */
3058 if (mon == u.ustuck) {
3060 pline("%s is being %s%s.", Monnam(mon),
3061 byhand ? "throttled" : "crushed",
3062 /* extra feedback for non-breather being choked */
3063 unconcerned ? " but doesn't seem concerned" : "");
3065 pline("%s
\82Í%s%s
\81D", Monnam(mon),
3066 byhand ? "
\8eñ
\82ð
\8di
\82ß
\82ç
\82ê
\82Ä
\82¢
\82é" : "
\89\9f\82µ
\82Â
\82Ô
\82³
\82ê
\82Ä
\82¢
\82é",
3067 /* extra feedback for non-breather being choked */
3068 unconcerned ? "
\82ª
\81C
\8bC
\82É
\82µ
\82Ä
\82¢
\82È
\82¢
\82æ
\82¤
\82¾" : "");
3070 if (silverhit && flags.verbose)
3071 silver_sears(&youmonst, mon, silverhit);
3072 sum[i] = damageum(mon, mattk, specialdmg);
3073 } else if (i >= 2 && sum[i - 1] && sum[i - 2]) {
3074 /* in case we're hugging a new target while already
3075 holding something else; yields feedback
3076 "<u.ustuck> is no longer in your clutches" */
3077 if (u.ustuck && u.ustuck != mon)
3080 You("grab %s!", mon_nam(mon));
3082 You("%s
\82ð
\82Â
\82©
\82Ü
\82¦
\82½
\81I", mon_nam(mon));
3084 if (silverhit && flags.verbose)
3085 silver_sears(&youmonst, mon, silverhit);
3086 sum[i] = damageum(mon, mattk, specialdmg);
3088 break; /* AT_HUGS */
3091 case AT_EXPL: /* automatic hit if next to */
3094 sum[i] = explum(mon, mattk);
3098 tmp = find_roll_to_hit(mon, mattk->aatyp, (struct obj *) 0,
3099 &attknum, &armorpenalty);
3100 if ((dhit = (tmp > rnd(20 + i)))) {
3102 if (mon->data == &mons[PM_SHADE])
3104 Your("attempt to surround %s is harmless.", mon_nam(mon));
3106 You("%s
\82ð
\88ù
\82Ý
\82±
\82à
\82¤
\82Æ
\82µ
\82½
\82ª
\8e¸
\94s
\82µ
\82½
\81D", mon_nam(mon));
3108 sum[i] = gulpum(mon, mattk);
3109 if (sum[i] == 2 && (mon->data->mlet == S_ZOMBIE
3110 || mon->data->mlet == S_MUMMY)
3111 && rn2(5) && !Sick_resistance) {
3113 You_feel("%ssick.", (Sick) ? "very " : "");
3115 You_feel("%s
\8bC
\95ª
\82ª
\88«
\82¢
\81D", (Sick) ? "
\82Æ
\82Ä
\82à" : "");
3116 mdamageu(mon, rnd(8));
3120 missum(mon, mattk, FALSE);
3125 /* No check for uwep; if wielding nothing we want to
3126 * do the normal 1-2 points bare hand damage...
3128 if ((youmonst.data->mlet == S_KOBOLD
3129 || youmonst.data->mlet == S_ORC
3130 || youmonst.data->mlet == S_GNOME) && !weapon_used)
3137 /* Not break--avoid passive attacks from enemy */
3141 case AT_GAZE: /* all done using #monster command */
3145 default: /* Strange... */
3146 impossible("strange attack of yours (%d)", mattk->aatyp);
3149 u.mh = -1; /* dead in the current form */
3154 (void) passive(mon, weapon, 1, 0, mattk->aatyp, FALSE);
3155 nsum = 0; /* return value below used to be 'nsum > 0' */
3157 (void) passive(mon, weapon, sum[i], 1, mattk->aatyp, FALSE);
3161 /* don't use sum[i] beyond this point;
3162 'i' will be out of bounds if we get here via 'goto' */
3164 /* when using dual weapons, cursed secondary weapon doesn't weld,
3165 it gets dropped; do the same when multiple AT_WEAP attacks
3167 if (uswapwep && weapon == uswapwep && weapon->cursed) {
3169 break; /* don't proceed with additional attacks */
3171 /* stop attacking if defender has died;
3172 needed to defer this until after uswapwep->cursed check */
3173 if (DEADMONSTER(mon))
3176 break; /* No extra attacks if no longer a monster */
3178 break; /* If paralyzed while attacking, i.e. floating eye */
3180 /* return value isn't used, but make it match hitum()'s */
3181 return !DEADMONSTER(mon);
3184 /* Special (passive) attacks on you by monsters done here.
3187 passive(mon, weapon, mhit, malive, aatyp, wep_was_destroyed)
3189 struct obj *weapon; /* uwep or uswapwep or uarmg or uarmf or Null */
3193 boolean wep_was_destroyed;
3195 register struct permonst *ptr = mon->data;
3196 register int i, tmp;
3200 return (malive | mhit); /* no passive attacks */
3201 if (ptr->mattk[i].aatyp == AT_NONE)
3202 break; /* try this one */
3204 /* Note: tmp not always used */
3205 if (ptr->mattk[i].damn)
3206 tmp = d((int) ptr->mattk[i].damn, (int) ptr->mattk[i].damd);
3207 else if (ptr->mattk[i].damd)
3208 tmp = d((int) mon->m_lev + 1, (int) ptr->mattk[i].damd);
3212 /* These affect you even if they just died.
3214 switch (ptr->mattk[i].adtyp) {
3216 if (mhit && !mon->mcan && weapon) {
3217 if (aatyp == AT_KICK) {
3218 if (uarmf && !rn2(6))
3219 (void) erode_obj(uarmf, xname(uarmf), ERODE_BURN,
3220 EF_GREASE | EF_VERBOSE);
3221 } else if (aatyp == AT_WEAP || aatyp == AT_CLAW
3222 || aatyp == AT_MAGC || aatyp == AT_TUCH)
3223 passive_obj(mon, weapon, &(ptr->mattk[i]));
3227 if (mhit && rn2(2)) {
3228 if (Blind || !flags.verbose)
3230 You("are splashed!");
3232 You("
\89½
\82©
\82ð
\97\81\82Ñ
\82¹
\82ç
\82ê
\82½
\81I");
3235 You("are splashed by %s %s!", s_suffix(mon_nam(mon)),
3238 You("%s
\82Ì%s
\82ð
\97\81\82Ñ
\82¹
\82ç
\82ê
\82½
\81I", mon_nam(mon),
3242 if (!Acid_resistance)
3245 erode_armor(&youmonst, ERODE_CORRODE);
3247 if (mhit && weapon) {
3248 if (aatyp == AT_KICK) {
3249 if (uarmf && !rn2(6))
3250 (void) erode_obj(uarmf, xname(uarmf), ERODE_CORRODE,
3251 EF_GREASE | EF_VERBOSE);
3252 } else if (aatyp == AT_WEAP || aatyp == AT_CLAW
3253 || aatyp == AT_MAGC || aatyp == AT_TUCH)
3254 passive_obj(mon, weapon, &(ptr->mattk[i]));
3256 exercise(A_STR, FALSE);
3259 if (mhit) { /* successful attack */
3260 long protector = attk_protection((int) aatyp);
3262 /* hero using monsters' AT_MAGC attack is hitting hand to
3263 hand rather than casting a spell */
3264 if (aatyp == AT_MAGC)
3267 if (protector == 0L /* no protection */
3268 || (protector == W_ARMG && !uarmg
3269 && !uwep && !wep_was_destroyed)
3270 || (protector == W_ARMF && !uarmf)
3271 || (protector == W_ARMH && !uarmh)
3272 || (protector == (W_ARMC | W_ARMG) && (!uarmc || !uarmg))) {
3273 if (!Stone_resistance
3274 && !(poly_when_stoned(youmonst.data)
3275 && polymon(PM_STONE_GOLEM))) {
3276 done_in_by(mon, STONING); /* "You turn to stone..." */
3283 if (mhit && !mon->mcan && weapon) {
3284 if (aatyp == AT_KICK) {
3286 (void) erode_obj(uarmf, xname(uarmf), ERODE_RUST,
3287 EF_GREASE | EF_VERBOSE);
3288 } else if (aatyp == AT_WEAP || aatyp == AT_CLAW
3289 || aatyp == AT_MAGC || aatyp == AT_TUCH)
3290 passive_obj(mon, weapon, &(ptr->mattk[i]));
3294 if (mhit && !mon->mcan && weapon) {
3295 if (aatyp == AT_KICK) {
3297 (void) erode_obj(uarmf, xname(uarmf), ERODE_CORRODE,
3298 EF_GREASE | EF_VERBOSE);
3299 } else if (aatyp == AT_WEAP || aatyp == AT_CLAW
3300 || aatyp == AT_MAGC || aatyp == AT_TUCH)
3301 passive_obj(mon, weapon, &(ptr->mattk[i]));
3305 /* wrath of gods for attacking Oracle */
3307 shieldeff(u.ux, u.uy);
3309 pline("A hail of magic missiles narrowly misses you!");
3311 pline("
\96\82\96@
\82Ì
\96î
\82Ì
\89J
\82ð
\82È
\82ñ
\82Æ
\82©
\82©
\82í
\82µ
\82½
\81I");
3314 You("are hit by magic missiles appearing from thin air!");
3316 pline("
\93Ë
\94@
\8bó
\92\86\82É
\8c»
\82í
\82ê
\82½
\96\82\96@
\82Ì
\96î
\82ª
\96½
\92\86\82µ
\82½
\81I");
3320 case AD_ENCH: /* KMH -- remove enchantment (disenchanter) */
3322 if (aatyp == AT_KICK) {
3325 } else if (aatyp == AT_BITE || aatyp == AT_BUTT
3326 || (aatyp >= AT_STNG && aatyp < AT_WEAP)) {
3327 break; /* no object involved */
3329 passive_obj(mon, weapon, &(ptr->mattk[i]));
3336 /* These only affect you if they still live.
3338 if (malive && !mon->mcan && rn2(3)) {
3339 switch (ptr->mattk[i].adtyp) {
3341 if (ptr == &mons[PM_FLOATING_EYE]) {
3342 if (!canseemon(mon)) {
3347 if (ureflects("%s gaze is reflected by your %s.",
3348 s_suffix(Monnam(mon)))) {
3350 if (ureflects("%s
\82Ì
\82É
\82ç
\82Ý
\82Í%s
\82É
\82æ
\82Á
\82Ä
\94½
\8eË
\82³
\82ê
\82½
\81D",
3354 } else if (Free_action) {
3356 You("momentarily stiffen under %s gaze!",
3357 s_suffix(mon_nam(mon)));
3359 You("%s
\82Ì
\82É
\82ç
\82Ý
\82Å
\88ê
\8fu
\8dd
\92¼
\82µ
\82½
\81I",
3362 } else if (Hallucination && rn2(4)) {
3364 pline("%s looks %s%s.", Monnam(mon),
3365 !rn2(2) ? "" : "rather ",
3366 !rn2(2) ? "numb" : "stupified");
3368 pline("%s
\82Í%s
\82Î
\82©
\82É
\82È
\82Á
\82½
\82æ
\82¤
\82¾
\81D", Monnam(mon),
3369 !rn2(2) ? "" : "
\8f
\82µ");
3373 You("are frozen by %s gaze!", s_suffix(mon_nam(mon)));
3375 You("%s
\82Ì
\82É
\82ç
\82Ý
\82Å
\93®
\82¯
\82È
\82
\82È
\82Á
\82½
\81I", mon_nam(mon));
3376 nomul((ACURR(A_WIS) > 12 || rn2(4)) ? -tmp : -127);
3378 multi_reason = "frozen by a monster's gaze";
3380 multi_reason = "
\89ö
\95¨
\82Ì
\82É
\82ç
\82Ý
\82Å
\8dd
\92¼
\82µ
\82Ä
\82¢
\82é
\8e\9e\82É";
3385 pline("%s cannot defend itself.",
3386 Adjmonnam(mon, "blind"));
3388 pline("%s
\82Í
\96h
\8cä
\82Å
\82«
\82È
\82¢
\81D",
3389 Adjmonnam(mon,"
\96Ú
\82Ì
\8c©
\82¦
\82È
\82¢"));
3394 } else if (Free_action) {
3396 You("momentarily stiffen.");
3398 You("
\88ê
\8fu
\8dd
\92¼
\82µ
\82½
\81D");
3399 } else { /* gelatinous cube */
3401 You("are frozen by %s!", mon_nam(mon));
3403 You("%s
\82É
\82æ
\82Á
\82Ä
\93®
\82¯
\82È
\82
\82È
\82Á
\82½
\81I", mon_nam(mon));
3404 nomovemsg = You_can_move_again;
3407 multi_reason = "frozen by a monster";
3409 multi_reason = "
\89ö
\95¨
\82É
\82æ
\82Á
\82Ä
\8dd
\92¼
\82µ
\82Ä
\82¢
\82é
\8e\9e\82É";
3410 exercise(A_DEX, FALSE);
3413 case AD_COLD: /* brown mold or blue jelly */
3414 if (monnear(mon, u.ux, u.uy)) {
3415 if (Cold_resistance) {
3416 shieldeff(u.ux, u.uy);
3418 You_feel("a mild chill.");
3420 You("
\8a¦
\82³
\82ð
\8a´
\82¶
\82½
\81D");
3421 ugolemeffects(AD_COLD, tmp);
3425 You("are suddenly very cold!");
3427 You("
\93Ë
\91R
\81C
\96Ò
\97ó
\82É
\8a¦
\82
\82È
\82Á
\82½
\81I");
3429 /* monster gets stronger with your heat! */
3430 mon->mhp += tmp / 2;
3431 if (mon->mhpmax < mon->mhp)
3432 mon->mhpmax = mon->mhp;
3433 /* at a certain point, the monster will reproduce! */
3434 if (mon->mhpmax > ((int) (mon->m_lev + 1) * 8))
3435 (void) split_mon(mon, &youmonst);
3438 case AD_STUN: /* specifically yellow mold */
3440 make_stunned((long) tmp, TRUE);
3443 if (monnear(mon, u.ux, u.uy)) {
3444 if (Fire_resistance) {
3445 shieldeff(u.ux, u.uy);
3447 You_feel("mildly warm.");
3449 You("
\92g
\82©
\82³
\82ð
\8a´
\82¶
\82½
\81D");
3450 ugolemeffects(AD_FIRE, tmp);
3454 You("are suddenly very hot!");
3456 You("
\93Ë
\91R
\81C
\96Ò
\97ó
\82É
\94M
\82
\82È
\82Á
\82½
\81I");
3457 mdamageu(mon, tmp); /* fire damage */
3461 if (Shock_resistance) {
3462 shieldeff(u.ux, u.uy);
3464 You_feel("a mild tingle.");
3466 You("
\83s
\83\8a\83s
\83\8a\82Æá
\83\82ê
\82ð
\8a´
\82¶
\82½
\81D");
3467 ugolemeffects(AD_ELEC, tmp);
3471 You("are jolted with electricity!");
3473 You("
\93d
\8bC
\83V
\83\87\83b
\83N
\82ð
\82¤
\82¯
\82½
\81I");
3480 return (malive | mhit);
3484 * Special (passive) attacks on an attacking object by monsters done here.
3485 * Assumes the attack was successful.
3488 passive_obj(mon, obj, mattk)
3490 struct obj *obj; /* null means pick uwep, uswapwep or uarmg */
3491 struct attack *mattk; /* null means we find one internally */
3493 struct permonst *ptr = mon->data;
3496 /* [this first bit is obsolete; we're not called with Null anymore] */
3497 /* if caller hasn't specified an object, use uwep, uswapwep or uarmg */
3499 obj = (u.twoweap && uswapwep && !rn2(2)) ? uswapwep : uwep;
3500 if (!obj && mattk->adtyp == AD_ENCH)
3501 obj = uarmg; /* no weapon? then must be gloves */
3503 return; /* no object to affect */
3506 /* if caller hasn't specified an attack, find one */
3510 return; /* no passive attacks */
3511 if (ptr->mattk[i].aatyp == AT_NONE)
3512 break; /* try this one */
3514 mattk = &(ptr->mattk[i]);
3517 switch (mattk->adtyp) {
3519 if (!rn2(6) && !mon->mcan
3520 /* steam vortex: fire resist applies, fire damage doesn't */
3521 && mon->data != &mons[PM_STEAM_VORTEX]) {
3522 (void) erode_obj(obj, NULL, ERODE_BURN, EF_NONE);
3527 (void) erode_obj(obj, NULL, ERODE_CORRODE, EF_GREASE);
3532 (void) erode_obj(obj, (char *) 0, ERODE_RUST, EF_GREASE);
3537 (void) erode_obj(obj, (char *) 0, ERODE_CORRODE, EF_GREASE);
3542 if (drain_item(obj, TRUE) && carried(obj)
3543 && (obj->known || obj->oclass == ARMOR_CLASS)) {
3545 pline("%s less effective.", Yobjnam2(obj, "seem"));
3547 Your("%s
\82©
\82ç
\96\82\97Í
\82ª
\8fÁ
\82¦
\82½
\82æ
\82¤
\82¾
\81D", xname(obj));
3559 /* Note: caller must ascertain mtmp is mimicking... */
3561 stumble_onto_mimic(mtmp)
3565 const char *fmt = "Wait! That's %s!", *generic = "a monster", *what = 0;
3567 const char *fmt = "
\82¿
\82å
\82Á
\82Æ
\82Ü
\82Á
\82½
\81I%s
\82¾
\81I", *generic = "
\89ö
\95¨", *what = 0;
3569 if (!u.ustuck && !mtmp->mflee && dmgtype(mtmp->data, AD_STCK))
3574 what = generic; /* with default fmt */
3575 else if (M_AP_TYPE(mtmp) == M_AP_MONSTER)
3576 what = a_monnam(mtmp); /* differs from what was sensed */
3578 int glyph = levl[u.ux + u.dx][u.uy + u.dy].glyph;
3580 if (glyph_is_cmap(glyph) && (glyph_to_cmap(glyph) == S_hcdoor
3581 || glyph_to_cmap(glyph) == S_vcdoor))
3583 fmt = "The door actually was %s!";
3585 fmt = "
\94à
\82Í
\8eÀ
\8dÛ
\82É
\82Í%s
\82¾
\82Á
\82½
\81I";
3586 else if (glyph_is_object(glyph) && glyph_to_obj(glyph) == GOLD_PIECE)
3588 fmt = "That gold was %s!";
3590 fmt = "
\8bà
\89Ý
\82Í%s
\82¾
\82Á
\82½
\81I";
3592 /* cloned Wiz starts out mimicking some other monster and
3593 might make himself invisible before being revealed */
3594 if (mtmp->minvis && !See_invisible)
3597 what = a_monnam(mtmp);
3602 wakeup(mtmp, FALSE); /* clears mimicking */
3603 /* if hero is blind, wakeup() won't display the monster even though
3604 it's no longer concealed */
3605 if (!canspotmon(mtmp)
3606 && !glyph_is_invisible(levl[mtmp->mx][mtmp->my].glyph))
3607 map_invisible(mtmp->mx, mtmp->my);
3614 char *hands = makeplural(body_part(HAND));
3616 if (!u.umconf || mon->mconf)
3618 if (u.umconf == 1) {
3621 Your("%s stop tingling.", hands);
3623 Your("%s
\82Ìá
\83\82ê
\82ª
\82Æ
\82ê
\82½
\81D", hands);
3626 Your("%s stop glowing %s.", hands, hcolor(NH_RED));
3628 Your("%s
\82Ì%s
\8bP
\82«
\82Í
\82È
\82
\82È
\82Á
\82½
\81D", hands, hcolor(NH_RED));
3632 pline_The("tingling in your %s lessens.", hands);
3634 pline("%s
\82Ìá
\83\82ê
\82ª
\82Æ
\82ê
\82Ä
\82«
\82½
\81D",hands);
3637 Your("%s no longer glow so brightly %s.", hands, hcolor(NH_RED));
3639 Your("%s
\82Ì%s
\8bP
\82«
\82ª
\82È
\82
\82È
\82Á
\82Ä
\82«
\82½
\81D",hands, hcolor(NH_RED));
3645 flash_hits_mon(mtmp, otmp)
3647 struct obj *otmp; /* source of flash */
3649 int tmp, amt, res = 0, useeit = canseemon(mtmp);
3651 if (mtmp->msleeping) {
3652 mtmp->msleeping = 0;
3655 pline_The("flash awakens %s.", mon_nam(mtmp));
3657 pline("
\91M
\8cõ
\82Å%s
\82ª
\96Ú
\82ð
\8ao
\82Ü
\82µ
\82½
\81D", mon_nam(mtmp));
3660 } else if (mtmp->data->mlet != S_LIGHT) {
3661 if (!resists_blnd(mtmp)) {
3662 tmp = dist2(otmp->ox, otmp->oy, mtmp->mx, mtmp->my);
3665 pline("%s is blinded by the flash!", Monnam(mtmp));
3667 pline("%s
\82Í
\91M
\8cõ
\82Å
\96Ú
\82ª
\8c©
\82¦
\82È
\82
\82È
\82Á
\82½
\81I", Monnam(mtmp));
3670 if (mtmp->data == &mons[PM_GREMLIN]) {
3671 /* Rule #1: Keep them out of the light. */
3672 amt = otmp->otyp == WAN_LIGHT ? d(1 + otmp->spe, 4)
3673 : rn2(min(mtmp->mhp, 4));
3674 light_hits_gremlin(mtmp, amt);
3676 if (!DEADMONSTER(mtmp)) {
3677 if (!context.mon_moving)
3678 setmangry(mtmp, TRUE);
3679 if (tmp < 9 && !mtmp->isshk && rn2(4))
3680 monflee(mtmp, rn2(4) ? rnd(100) : 0, FALSE, TRUE);
3682 mtmp->mblinded = (tmp < 3) ? 0 : rnd(1 + 50 / tmp);
3690 light_hits_gremlin(mon, dmg)
3695 pline("%s %s!", Monnam(mon),
3696 (dmg > mon->mhp / 2) ? "wails in agony" : "cries out in pain");
3698 pline("%s
\82Í%s
\81I", Monnam(mon),
3699 (dmg > mon->mhp / 2) ? "
\8bê
\92É
\82Ì
\90º
\82ð
\82 \82°
\82½" : "
\8c\83\92É
\82Å
\8b©
\82ñ
\82¾");
3702 wake_nearto(mon->mx, mon->my, 30);
3703 if (DEADMONSTER(mon)) {
3704 if (context.mon_moving)
3705 monkilled(mon, (char *) 0, AD_BLND);
3708 } else if (cansee(mon->mx, mon->my) && !canspotmon(mon)) {
3709 map_invisible(mon->mx, mon->my);