1 /* NetHack 3.6 uhitm.c $NHDT-Date: 1555720104 2019/04/20 00:28:24 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.207 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /*-Copyright (c) Robert Patrick Rankin, 2012. */
4 /* NetHack may be freely redistributed. See license for details. */
6 /* JNetHack Copyright */
7 /* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000 */
8 /* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2019 */
9 /* JNetHack may be freely redistributed. See license for details. */
13 STATIC_DCL boolean FDECL(known_hitum, (struct monst *, struct obj *, int *,
14 int, int, struct attack *, int));
15 STATIC_DCL boolean FDECL(theft_petrifies, (struct obj *));
16 STATIC_DCL void FDECL(steal_it, (struct monst *, struct attack *));
17 STATIC_DCL boolean FDECL(hitum_cleave, (struct monst *, struct attack *));
18 STATIC_DCL boolean FDECL(hitum, (struct monst *, struct attack *));
19 STATIC_DCL boolean FDECL(hmon_hitmon, (struct monst *, struct obj *, int,
21 STATIC_DCL int FDECL(joust, (struct monst *, struct obj *));
22 STATIC_DCL void NDECL(demonpet);
23 STATIC_DCL boolean FDECL(m_slips_free, (struct monst *, struct attack *));
24 STATIC_DCL int FDECL(explum, (struct monst *, struct attack *));
25 STATIC_DCL void FDECL(start_engulf, (struct monst *));
26 STATIC_DCL void NDECL(end_engulf);
27 STATIC_DCL int FDECL(gulpum, (struct monst *, struct attack *));
28 STATIC_DCL boolean FDECL(hmonas, (struct monst *));
29 STATIC_DCL void FDECL(nohandglow, (struct monst *));
30 STATIC_DCL boolean FDECL(shade_aware, (struct obj *));
32 extern boolean notonhead; /* for long worms */
34 /* Used to flag attacks caused by Stormbringer's maliciousness. */
35 static boolean override_confirmation = FALSE;
37 #define PROJECTILE(obj) ((obj) && is_ammo(obj))
40 erode_armor(mdef, hurt)
46 /* What the following code does: it keeps looping until it
47 * finds a target for the rust monster.
48 * Head, feet, etc... not covered by metal, or covered by
49 * rusty metal, are not targets. However, your body always
50 * is, no matter what covers it.
55 target = which_armor(mdef, W_ARMH);
57 || erode_obj(target, xname(target), hurt, EF_GREASE)
62 target = which_armor(mdef, W_ARMC);
64 (void) erode_obj(target, xname(target), hurt,
65 EF_GREASE | EF_VERBOSE);
68 if ((target = which_armor(mdef, W_ARM)) != (struct obj *) 0) {
69 (void) erode_obj(target, xname(target), hurt,
70 EF_GREASE | EF_VERBOSE);
71 } else if ((target = which_armor(mdef, W_ARMU))
72 != (struct obj *) 0) {
73 (void) erode_obj(target, xname(target), hurt,
74 EF_GREASE | EF_VERBOSE);
78 target = which_armor(mdef, W_ARMS);
80 || erode_obj(target, xname(target), hurt, EF_GREASE)
85 target = which_armor(mdef, W_ARMG);
87 || erode_obj(target, xname(target), hurt, EF_GREASE)
92 target = which_armor(mdef, W_ARMF);
94 || erode_obj(target, xname(target), hurt, EF_GREASE)
99 break; /* Out of while loop */
103 /* FALSE means it's OK to attack */
105 attack_checks(mtmp, wep)
106 register struct monst *mtmp;
107 struct obj *wep; /* uwep for attack(), null for kick_monster() */
111 /* if you're close enough to attack, alert any waiting monster */
112 mtmp->mstrategy &= ~STRAT_WAITMASK;
114 if (u.uswallow && mtmp == u.ustuck)
117 if (context.forcefight) {
118 /* Do this in the caller, after we checked that the monster
119 * didn't die from the blow. Reason: putting the 'I' there
120 * causes the hero to forget the square's contents since
121 * both 'I' and remembered contents are stored in .glyph.
122 * If the monster dies immediately from the blow, the 'I' will
123 * not stay there, so the player will have suddenly forgotten
124 * the square's contents for no apparent reason.
125 if (!canspotmon(mtmp)
126 && !glyph_is_invisible(levl[bhitpos.x][bhitpos.y].glyph))
127 map_invisible(bhitpos.x, bhitpos.y);
132 /* cache the shown glyph;
133 cases which might change it (by placing or removing
134 'rembered, unseen monster' glyph or revealing a mimic)
135 always return without further reference to this */
136 glyph = glyph_at(bhitpos.x, bhitpos.y);
138 /* Put up an invisible monster marker, but with exceptions for
139 * monsters that hide and monsters you've been warned about.
140 * The former already prints a warning message and
141 * prevents you from hitting the monster just via the hidden monster
142 * code below; if we also did that here, similar behavior would be
143 * happening two turns in a row. The latter shows a glyph on
144 * the screen, so you know something is there.
146 if (!canspotmon(mtmp)
147 && !glyph_is_warning(glyph) && !glyph_is_invisible(glyph)
148 && !(!Blind && mtmp->mundetected && hides_under(mtmp->data))) {
150 pline("Wait! There's %s there you can't see!", something);
152 pline("
\82¿
\82å
\82Á
\82Æ
\91Ò
\82Á
\82½
\81I
\8ep
\82Ì
\8c©
\82¦
\82È
\82¢%s
\82ª
\82¢
\82é
\81I", something);
153 map_invisible(bhitpos.x, bhitpos.y);
154 /* if it was an invisible mimic, treat it as if we stumbled
155 * onto a visible mimic
157 if (M_AP_TYPE(mtmp) && !Protection_from_shape_changers
158 /* applied pole-arm attack is too far to get stuck */
159 && distu(mtmp->mx, mtmp->my) <= 2) {
160 if (!u.ustuck && !mtmp->mflee && dmgtype(mtmp->data, AD_STCK))
163 /* #H7329 - if hero is on engraved "Elbereth", this will end up
164 * assessing an alignment penalty and removing the engraving
165 * even though no attack actually occurs. Since it also angers
166 * peacefuls, we're operating as if an attack attempt did occur
167 * and the Elbereth behavior is consistent.
169 wakeup(mtmp, TRUE); /* always necessary; also un-mimics mimics */
173 if (M_AP_TYPE(mtmp) && !Protection_from_shape_changers && !sensemon(mtmp)
174 && !glyph_is_warning(glyph)) {
175 /* If a hidden mimic was in a square where a player remembers
176 * some (probably different) unseen monster, the player is in
177 * luck--he attacks it even though it's hidden.
179 if (glyph_is_invisible(glyph)) {
183 stumble_onto_mimic(mtmp);
187 if (mtmp->mundetected && !canseemon(mtmp)
188 && !glyph_is_warning(glyph)
189 && (hides_under(mtmp->data) || mtmp->data->mlet == S_EEL)) {
190 mtmp->mundetected = mtmp->msleeping = 0;
191 newsym(mtmp->mx, mtmp->my);
192 if (glyph_is_invisible(glyph)) {
196 if (!((Blind ? Blind_telepat : Unblind_telepat) || Detect_monsters)) {
199 if (!Blind && Hallucination)
201 pline("A %s %s appeared!",
202 mtmp->mtame ? "tame" : "wild", l_monnam(mtmp));
204 pline("%s%s
\82ª
\8c»
\82ê
\82½
\81I",
205 mtmp->mtame ? "
\8eè
\82È
\82Ã
\82¯
\82ç
\82ê
\82½" : "
\96ì
\90¶
\82Ì", l_monnam(mtmp));
207 else if (Blind || (is_pool(mtmp->mx, mtmp->my) && !Underwater))
209 pline("Wait! There's a hidden monster there!");
211 pline("
\91Ò
\82Ä
\81I
\89ö
\95¨
\82ª
\89B
\82ê
\82Ä
\82¢
\82é
\81I");
212 else if ((obj = level.objects[mtmp->mx][mtmp->my]) != 0)
214 pline("Wait! There's %s hiding under %s!",
215 an(l_monnam(mtmp)), doname(obj));
217 pline("
\91Ò
\82Ä
\81I%s
\82Ì
\89º
\82É%s
\82ª
\89B
\82ê
\82Ä
\82¢
\82é
\81I",
218 doname(obj), l_monnam(mtmp));
225 * make sure to wake up a monster from the above cases if the
226 * hero can sense that the monster is there.
228 if ((mtmp->mundetected || M_AP_TYPE(mtmp)) && sensemon(mtmp)) {
229 mtmp->mundetected = 0;
233 if (flags.confirm && mtmp->mpeaceful
234 && !Confusion && !Hallucination && !Stunned) {
235 /* Intelligent chaotic weapons (Stormbringer) want blood */
236 if (wep && wep->oartifact == ART_STORMBRINGER) {
237 override_confirmation = TRUE;
240 if (canspotmon(mtmp)) {
244 Sprintf(qbuf, "Really attack %s?", mon_nam(mtmp));
246 Sprintf(qbuf, "
\96{
\93\96\82É%s
\82ð
\8dU
\8c\82\82·
\82é
\82Ì
\81H", mon_nam(mtmp));
247 if (!paranoid_query(ParanoidHit, qbuf)) {
258 * It is unchivalrous for a knight to attack the defenseless or from behind.
264 if (u.ualign.record <= -10)
267 if (Role_if(PM_KNIGHT) && u.ualign.type == A_LAWFUL
268 && (!mtmp->mcanmove || mtmp->msleeping
269 || (mtmp->mflee && !mtmp->mavenge))) {
273 pline("
\82±
\82ê
\82Í
\94Ú
\8b¯
\82È
\8ds
\82¢
\82¾
\81I");
275 } else if (Role_if(PM_SAMURAI) && mtmp->mpeaceful) {
276 /* attacking peaceful creatures is bad for the samurai's giri */
278 You("dishonorably attack the innocent!");
280 pline("
\96³
\8eÀ
\82Ì
\8eÒ
\82ð
\8dU
\8c\82\82·
\82é
\82Ì
\82Í
\95s
\96¼
\97_
\82¾
\81I");
286 find_roll_to_hit(mtmp, aatyp, weapon, attk_count, role_roll_penalty)
287 register struct monst *mtmp;
288 uchar aatyp; /* usually AT_WEAP or AT_KICK */
289 struct obj *weapon; /* uwep or uswapwep or NULL */
290 int *attk_count, *role_roll_penalty;
294 *role_roll_penalty = 0; /* default is `none' */
296 tmp = 1 + Luck + abon() + find_mac(mtmp) + u.uhitinc
297 + maybe_polyd(youmonst.data->mlevel, u.ulevel);
299 /* some actions should occur only once during multiple attacks */
300 if (!(*attk_count)++) {
301 /* knight's chivalry or samurai's giri */
305 /* adjust vs. (and possibly modify) monster state */
311 if (mtmp->msleeping) {
315 if (!mtmp->mcanmove) {
323 /* role/race adjustments */
324 if (Role_if(PM_MONK) && !Upolyd) {
326 tmp -= (*role_roll_penalty = urole.spelarmr);
327 else if (!uwep && !uarms)
328 tmp += (u.ulevel / 3) + 2;
330 if (is_orc(mtmp->data)
331 && maybe_polyd(is_elf(youmonst.data), Race_if(PM_ELF)))
334 /* encumbrance: with a lot of luggage, your agility diminishes */
335 if ((tmp2 = near_capacity()) != 0)
336 tmp -= (tmp2 * 2) - 1;
341 * hitval applies if making a weapon attack while wielding a weapon;
342 * weapon_hit_bonus applies if doing a weapon attack even bare-handed
343 * or if kicking as martial artist
345 if (aatyp == AT_WEAP || aatyp == AT_CLAW) {
347 tmp += hitval(weapon, mtmp);
348 tmp += weapon_hit_bonus(weapon);
349 } else if (aatyp == AT_KICK && martial_bonus()) {
350 tmp += weapon_hit_bonus((struct obj *) 0);
356 /* try to attack; return False if monster evaded;
357 u.dx and u.dy must be set */
360 register struct monst *mtmp;
362 register struct permonst *mdat = mtmp->data;
364 /* This section of code provides protection against accidentally
365 * hitting peaceful (like '@') and tame (like 'd') monsters.
366 * Protection is provided as long as player is not: blind, confused,
367 * hallucinating or stunned.
368 * changes by wwp 5/16/85
369 * More changes 12/90, -dkh-. if its tame and safepet, (and protected
370 * 07/92) then we assume that you're not trying to attack. Instead,
371 * you'll usually just swap places if this is a movement command
373 /* Intelligent chaotic weapons (Stormbringer) want blood */
374 if (is_safepet(mtmp) && !context.forcefight) {
375 if (!uwep || uwep->oartifact != ART_STORMBRINGER) {
376 /* There are some additional considerations: this won't work
377 * if in a shop or Punished or you miss a random roll or
378 * if you can walk thru walls and your pet cannot (KAA) or
379 * if your pet is a long worm with a tail.
380 * There's also a chance of displacing a "frozen" monster:
381 * sleeping monsters might magically walk in their sleep.
383 boolean foo = (Punished || !rn2(7)
384 || (is_longworm(mtmp->data) && mtmp->wormno)),
388 /* only check for in-shop if don't already have reason to stop */
390 for (p = in_rooms(mtmp->mx, mtmp->my, SHOPBASE); *p; p++)
391 if (tended_shop(&rooms[*p - ROOMOFFSET])) {
396 if (inshop || foo || (IS_ROCK(levl[u.ux][u.uy].typ)
397 && !passes_walls(mtmp->data))) {
400 monflee(mtmp, rnd(6), FALSE, FALSE);
401 Strcpy(buf, y_monnam(mtmp));
402 buf[0] = highc(buf[0]);
404 You("stop. %s is in the way!", buf);
406 You("
\8e~
\82Ü
\82Á
\82½
\81D%s
\82ª
\93¹
\82É
\82¢
\82é
\81I", buf);
407 context.travel = context.travel1 = context.mv = context.run
410 } else if ((mtmp->mfrozen || (!mtmp->mcanmove)
411 || (mtmp->data->mmove == 0)) && rn2(6)) {
413 pline("%s doesn't seem to move!", Monnam(mtmp));
415 pline("%s
\82Í
\93®
\82¯
\82È
\82¢
\82æ
\82¤
\82¾
\81I", Monnam(mtmp));
416 context.travel = context.travel1 = context.mv = context.run
424 /* possibly set in attack_checks;
425 examined in known_hitum, called via hitum or hmonas below */
426 override_confirmation = FALSE;
427 /* attack_checks() used to use <u.ux+u.dx,u.uy+u.dy> directly, now
428 it uses bhitpos instead; it might map an invisible monster there */
429 bhitpos.x = u.ux + u.dx;
430 bhitpos.y = u.uy + u.dy;
431 notonhead = (bhitpos.x != mtmp->mx || bhitpos.y != mtmp->my);
432 if (attack_checks(mtmp, uwep))
435 if (Upolyd && noattacks(youmonst.data)) {
436 /* certain "pacifist" monsters don't attack */
438 You("have no way to attack monsters physically.");
440 You("
\95¨
\97\9d\93I
\82É
\89ö
\95¨
\82ð
\8dU
\8c\82\82·
\82é
\82·
\82×
\82ª
\82È
\82¢
\81D");
441 mtmp->mstrategy &= ~STRAT_WAITMASK;
446 if (check_capacity("You cannot fight while so heavily loaded.")
448 if (check_capacity("
\82 \82È
\82½
\82Í
\95¨
\82ð
\82½
\82
\82³
\82ñ
\8e\9d\82¿
\82·
\82¬
\82Ä
\90í
\82¦
\82È
\82¢
\81D")
449 /* consume extra nutrition during combat; maybe pass out */
453 if (u.twoweap && !can_twoweapon())
461 You("begin bashing monsters with %s.", yname(uwep));
463 You("%s
\82Å
\89ö
\95¨
\82ð
\82È
\82®
\82è
\82Â
\82¯
\82½
\81D", yname(uwep));
464 else if (!cantwield(youmonst.data))
466 You("begin %s monsters with your %s %s.",
467 ing_suffix(Role_if(PM_MONK) ? "strike" : "bash"),
468 uarmg ? "gloved" : "bare", /* Del Lamb */
469 makeplural(body_part(HAND)));
471 You("%s%s
\82Å
\89ö
\95¨
\82ð%s
\82Â
\82¯
\82½
\81D",
472 uarmg ? "
\83O
\83\8d\81[
\83u
\82ð
\95t
\82¯
\82½" : "
\91f",
474 Role_if(PM_MONK) ? "
\91Å
\82¿" : "
\82È
\82®
\82è");
478 exercise(A_STR, TRUE); /* you're exercising muscles */
479 /* andrew@orca: prevent unlimited pick-axe attacks */
482 /* Is the "it died" check actually correct? */
483 if (mdat->mlet == S_LEPRECHAUN && !mtmp->mfrozen && !mtmp->msleeping
484 && !mtmp->mconf && mtmp->mcansee && !rn2(7)
485 && (m_move(mtmp, 0) == 2 /* it died */
486 || mtmp->mx != u.ux + u.dx
487 || mtmp->my != u.uy + u.dy)) { /* it moved */
489 You("miss wildly and stumble forwards.");
491 You("
\91å
\82«
\82
\8aO
\82µ
\82Ä
\91O
\82É
\82Â
\82Ü
\82Ã
\82¢
\82½
\81D");
498 (void) hitum(mtmp, youmonst.data->mattk);
499 mtmp->mstrategy &= ~STRAT_WAITMASK;
502 /* see comment in attack_checks() */
503 /* we only need to check for this if we did an attack_checks()
504 * and it returned 0 (it's okay to attack), and the monster didn't
507 if (context.forcefight && !DEADMONSTER(mtmp) && !canspotmon(mtmp)
508 && !glyph_is_invisible(levl[u.ux + u.dx][u.uy + u.dy].glyph)
509 && !(u.uswallow && mtmp == u.ustuck))
510 map_invisible(u.ux + u.dx, u.uy + u.dy);
515 /* really hit target monster; returns TRUE if it still lives */
517 known_hitum(mon, weapon, mhit, rollneeded, armorpenalty, uattk, dieroll)
518 register struct monst *mon;
521 int rollneeded, armorpenalty; /* for monks */
522 struct attack *uattk;
525 boolean malive = TRUE,
526 /* hmon() might destroy weapon; remember aspect for cutworm */
527 slice_or_chop = (weapon && (is_blade(weapon) || is_axe(weapon)));
529 if (override_confirmation) {
530 /* this may need to be generalized if weapons other than
531 Stormbringer acquire similar anti-social behavior... */
534 Your("bloodthirsty blade attacks!");
536 Your("
\95\90\8aí
\82Í
\8c\8c\82É
\8bQ
\82¦
\82Ä
\82¢
\82é
\81I");
540 missum(mon, uattk, (rollneeded + armorpenalty > dieroll));
542 int oldhp = mon->mhp;
543 long oldweaphit = u.uconduct.weaphit;
546 if (weapon && (weapon->oclass == WEAPON_CLASS || is_weptool(weapon)))
547 u.uconduct.weaphit++;
549 /* we hit the monster; be careful: it might die or
550 be knocked into a different location */
551 notonhead = (mon->mx != bhitpos.x || mon->my != bhitpos.y);
552 malive = hmon(mon, weapon, HMON_MELEE, dieroll);
554 /* monster still alive */
555 if (!rn2(25) && mon->mhp < mon->mhpmax / 2
556 && !(u.uswallow && mon == u.ustuck)) {
557 /* maybe should regurgitate if swallowed? */
558 monflee(mon, !rn2(3) ? rnd(100) : 0, FALSE, TRUE);
560 if (u.ustuck == mon && !u.uswallow && !sticks(youmonst.data))
563 /* Vorpal Blade hit converted to miss */
564 /* could be headless monster or worm tail */
565 if (mon->mhp == oldhp) {
567 /* a miss does not break conduct */
568 u.uconduct.weaphit = oldweaphit;
570 if (mon->wormno && *mhit)
571 cutworm(mon, bhitpos.x, bhitpos.y, slice_or_chop);
577 /* hit the monster next to you and the monsters to the left and right of it;
578 return False if the primary target is killed, True otherwise */
580 hitum_cleave(target, uattk)
581 struct monst *target; /* non-Null; forcefight at nothing doesn't cleave... */
582 struct attack *uattk; /* ... but we don't enforce that here; Null works ok */
584 /* swings will be delivered in alternate directions; with consecutive
585 attacks it will simulate normal swing and backswing; when swings
586 are non-consecutive, hero will sometimes start a series of attacks
587 with a backswing--that doesn't impact actual play, just spoils the
588 simulation attempt a bit */
589 static boolean clockwise = FALSE;
592 int count, umort, x = u.ux, y = u.uy;
594 /* find the direction toward primary target */
595 for (i = 0; i < 8; ++i)
596 if (xdir[i] == u.dx && ydir[i] == u.dy)
599 impossible("hitum_cleave: unknown target direction [%d,%d,%d]?",
601 return TRUE; /* target hasn't been killed */
603 /* adjust direction by two so that loop's increment (for clockwise)
604 or decrement (for counter-clockwise) will point at the spot next
606 i = (i + (clockwise ? 6 : 2)) % 8;
607 umort = u.umortality; /* used to detect life-saving */
608 save_bhitpos = bhitpos;
611 * Three attacks: adjacent to primary, primary, adjacent on other
612 * side. Primary target must be present or we wouldn't have gotten
613 * here (forcefight at thin air won't 'cleave'). However, the
614 * first attack might kill it (gas spore explosion, weak long worm
615 * occupying both spots) so we don't assume that it's still present
616 * on the second attack.
618 for (count = 3; count > 0; --count) {
620 int tx, ty, tmp, dieroll, mhit, attknum, armorpenalty;
622 /* ++i, wrap 8 to i=0 /or/ --i, wrap -1 to i=7 */
623 i = (i + (clockwise ? 1 : 7)) % 8;
625 tx = x + xdir[i], ty = y + ydir[i]; /* current target location */
630 if (glyph_is_invisible(levl[tx][ty].glyph))
631 (void) unmap_invisible(tx, ty);
635 tmp = find_roll_to_hit(mtmp, uattk->aatyp, uwep,
636 &attknum, &armorpenalty);
638 mhit = (tmp > dieroll);
639 bhitpos.x = tx, bhitpos.y = ty; /* normally set up by attack() */
640 (void) known_hitum(mtmp, uwep, &mhit, tmp, armorpenalty,
642 (void) passive(mtmp, uwep, mhit, !DEADMONSTER(mtmp), AT_WEAP, !uwep);
644 /* stop attacking if weapon is gone or hero got killed and
645 life-saved after passive counter-attack */
646 if (!uwep || u.umortality > umort)
649 /* set up for next time */
650 clockwise = !clockwise; /* alternate */
651 bhitpos = save_bhitpos; /* in case somebody relies on bhitpos
652 * designating the primary target */
654 /* return False if primary target died, True otherwise; note: if 'target'
655 was nonNull upon entry then it's still nonNull even if *target died */
656 return (target && DEADMONSTER(target)) ? FALSE : TRUE;
659 /* hit target monster; returns TRUE if it still lives */
663 struct attack *uattk;
665 boolean malive, wep_was_destroyed = FALSE;
666 struct obj *wepbefore = uwep;
667 int armorpenalty, attknum = 0, x = u.ux + u.dx, y = u.uy + u.dy,
668 tmp = find_roll_to_hit(mon, uattk->aatyp, uwep,
669 &attknum, &armorpenalty);
670 int dieroll = rnd(20);
671 int mhit = (tmp > dieroll || u.uswallow);
673 /* Cleaver attacks three spots, 'mon' and one on either side of 'mon';
674 it can't be part of dual-wielding but we guard against that anyway;
675 cleave return value reflects status of primary target ('mon') */
676 if (uwep && uwep->oartifact == ART_CLEAVER && !u.twoweap
677 && !u.uswallow && !u.ustuck && !NODIAG(u.umonnum))
678 return hitum_cleave(mon, uattk);
681 exercise(A_DEX, TRUE);
682 /* bhitpos is set up by caller */
683 malive = known_hitum(mon, uwep, &mhit, tmp, armorpenalty, uattk, dieroll);
684 if (wepbefore && !uwep)
685 wep_was_destroyed = TRUE;
686 (void) passive(mon, uwep, mhit, malive, AT_WEAP, wep_was_destroyed);
688 /* second attack for two-weapon combat; won't occur if Stormbringer
689 overrode confirmation (assumes Stormbringer is primary weapon)
690 or if the monster was killed or knocked to different location */
691 if (u.twoweap && !override_confirmation && malive && m_at(x, y) == mon) {
692 tmp = find_roll_to_hit(mon, uattk->aatyp, uswapwep, &attknum,
695 mhit = (tmp > dieroll || u.uswallow);
696 malive = known_hitum(mon, uswapwep, &mhit, tmp, armorpenalty, uattk,
698 /* second passive counter-attack only occurs if second attack hits */
700 (void) passive(mon, uswapwep, mhit, malive, AT_WEAP, !uswapwep);
705 /* general "damage monster" routine; return True if mon still alive */
707 hmon(mon, obj, thrown, dieroll)
710 int thrown; /* HMON_xxx (0 => hand-to-hand, other => ranged) */
713 boolean result, anger_guards;
715 anger_guards = (mon->mpeaceful
716 && (mon->ispriest || mon->isshk || is_watch(mon->data)));
717 result = hmon_hitmon(mon, obj, thrown, dieroll);
718 if (mon->ispriest && !rn2(2))
721 (void) angry_guards(!!Deaf);
727 hmon_hitmon(mon, obj, thrown, dieroll)
730 int thrown; /* HMON_xxx (0 => hand-to-hand, other => ranged) */
734 struct permonst *mdat = mon->data;
735 int barehand_silver_rings = 0;
736 /* The basic reason we need all these booleans is that we don't want
737 * a "hit" message when a monster dies, so we have to know how much
738 * damage it did _before_ outputting a hit message, but any messages
739 * associated with the damage don't come out until _after_ outputting
742 boolean hittxt = FALSE, destroyed = FALSE, already_killed = FALSE;
743 boolean get_dmg_bonus = TRUE;
744 boolean ispoisoned = FALSE, needpoismsg = FALSE, poiskilled = FALSE,
746 boolean silvermsg = FALSE, silverobj = FALSE;
747 boolean lightobj = FALSE;
748 boolean valid_weapon_attack = FALSE;
749 boolean unarmed = !uwep && !uarm && !uarms;
750 boolean hand_to_hand = (thrown == HMON_MELEE
751 /* not grapnels; applied implies uwep */
752 || (thrown == HMON_APPLIED && is_pole(uwep)));
758 char unconventional[BUFSZ]; /* substituted for word "attack" in msg */
760 char saved_oname[BUFSZ];
763 unconventional[0] = '\0';
765 saved_oname[0] = '\0';
768 if (!obj) { /* attack with bare hands */
769 if (mdat == &mons[PM_SHADE])
771 else if (martial_bonus())
772 tmp = rnd(4); /* bonus for martial arts */
775 valid_weapon_attack = (tmp > 1);
776 /* Blessed gloves give bonuses when fighting 'bare-handed'. So do
777 silver rings. Note: rings are worn under gloves, so you don't
778 get both bonuses, and two silver rings don't give double bonus. */
779 tmp += special_dmgval(&youmonst, mon, (W_ARMG | W_RINGL | W_RINGR),
781 barehand_silver_rings += (((silverhit & W_RINGL) ? 1 : 0)
782 + ((silverhit & W_RINGR) ? 1 : 0));
783 if (barehand_silver_rings > 0)
786 if (!(artifact_light(obj) && obj->lamplit))
787 Strcpy(saved_oname, cxname(obj));
789 Strcpy(saved_oname, bare_artifactname(obj));
790 if (obj->oclass == WEAPON_CLASS || is_weptool(obj)
791 || obj->oclass == GEM_CLASS) {
792 /* is it not a melee weapon? */
793 if (/* if you strike with a bow... */
795 /* or strike with a missile in your hand... */
796 || (!thrown && (is_missile(obj) || is_ammo(obj)))
797 /* or use a pole at short range and not mounted... */
798 || (!thrown && !u.usteed && is_pole(obj))
799 /* or throw a missile without the proper bow... */
800 || (is_ammo(obj) && (thrown != HMON_THROWN
801 || !ammo_and_launcher(obj, uwep)))) {
802 /* then do only 1-2 points of damage */
803 if (mdat == &mons[PM_SHADE] && !shade_glare(obj))
807 if (objects[obj->otyp].oc_material == SILVER
808 && mon_hates_silver(mon)) {
811 /* if it will already inflict dmg, make it worse */
812 tmp += rnd((tmp) ? 20 : 10);
814 if (!thrown && obj == uwep && obj->otyp == BOOMERANG
815 && rnl(4) == 4 - 1) {
816 boolean more_than_1 = (obj->quan > 1L);
819 pline("As you hit %s, %s%s breaks into splinters.",
820 mon_nam(mon), more_than_1 ? "one of " : "",
823 pline("%s
\82ð
\8dU
\8c\82\82·
\82é
\82Æ
\81C%s%s
\82Í
\82±
\82Á
\82Ï
\82Ý
\82¶
\82ñ
\82É
\82È
\82Á
\82½
\81D",
824 mon_nam(mon), yname(obj),
825 more_than_1 ? "
\82Ì
\82Ð
\82Æ
\82Â" : "");
828 uwepgone(); /* set unweapon */
831 obj = (struct obj *) 0;
833 if (mdat != &mons[PM_SHADE])
837 tmp = dmgval(obj, mon);
838 /* a minimal hit doesn't exercise proficiency */
839 valid_weapon_attack = (tmp > 1);
840 if (!valid_weapon_attack || mon == u.ustuck || u.twoweap
841 /* Cleaver can hit up to three targets at once so don't
842 let it also hit from behind or shatter foes' weapons */
843 || (hand_to_hand && obj->oartifact == ART_CLEAVER)) {
844 ; /* no special bonuses */
845 } else if (mon->mflee && Role_if(PM_ROGUE) && !Upolyd
846 /* multi-shot throwing is too powerful here */
849 You("strike %s from behind!", mon_nam(mon));
851 You("%s
\82ð
\94w
\8cã
\82©
\82ç
\8dU
\8c\82\82µ
\82½
\81I", mon_nam(mon));
852 tmp += rnd(u.ulevel);
854 } else if (dieroll == 2 && obj == uwep
855 && obj->oclass == WEAPON_CLASS
857 || (Role_if(PM_SAMURAI) && obj->otyp == KATANA
859 && ((wtype = uwep_skill_type()) != P_NONE
860 && P_SKILL(wtype) >= P_SKILLED)
861 && ((monwep = MON_WEP(mon)) != 0
862 && !is_flimsy(monwep)
863 && !obj_resists(monwep,
864 50 + 15 * (greatest_erosion(obj)
865 - greatest_erosion(monwep)),
868 * 2.5% chance of shattering defender's weapon when
869 * using a two-handed weapon; less if uwep is rusted.
870 * [dieroll == 2 is most successful non-beheading or
871 * -bisecting hit, in case of special artifact damage;
872 * the percentage chance is (1/20)*(50/100).]
873 * If attacker's weapon is rustier than defender's,
874 * the obj_resists chance is increased so the shatter
875 * chance is decreased; if less rusty, then vice versa.
877 setmnotwielded(mon, monwep);
878 mon->weapon_check = NEED_WEAPON;
880 pline("%s from the force of your blow!",
881 Yobjnam2(monwep, "shatter"));
883 pline("%s
\82Ì%s
\82Í
\82 \82È
\82½
\82Ì
\88ê
\8c\82\82Å
\95²
\81X
\82É
\82È
\82Á
\82½
\81I",
884 Monnam(mon), xname(monwep));
886 m_useupall(mon, monwep);
887 /* If someone just shattered MY weapon, I'd flee! */
889 monflee(mon, d(2, 3), TRUE, TRUE);
895 && artifact_hit(&youmonst, mon, obj, &tmp, dieroll)) {
896 if (DEADMONSTER(mon)) /* artifact killed monster */
902 if (objects[obj->otyp].oc_material == SILVER
903 && mon_hates_silver(mon)) {
907 if (artifact_light(obj) && obj->lamplit
908 && mon_hates_light(mon))
910 if (u.usteed && !thrown && tmp > 0
911 && weapon_type(obj) == P_LANCE && mon != u.ustuck) {
912 jousting = joust(mon, obj);
913 /* exercise skill even for minimal damage hits */
915 valid_weapon_attack = TRUE;
917 if (thrown == HMON_THROWN
918 && (is_ammo(obj) || is_missile(obj))) {
919 if (ammo_and_launcher(obj, uwep)) {
920 /* Elves and Samurai do extra damage using
921 * their bows&arrows; they're highly trained.
923 if (Role_if(PM_SAMURAI) && obj->otyp == YA
924 && uwep->otyp == YUMI)
926 else if (Race_if(PM_ELF) && obj->otyp == ELVEN_ARROW
927 && uwep->otyp == ELVEN_BOW)
930 if (obj->opoisoned && is_poisonable(obj))
934 } else if (obj->oclass == POTION_CLASS) {
936 obj = splitobj(obj, 1L);
938 setuwep((struct obj *) 0);
941 hand_to_hand ? POTHIT_HERO_BASH : POTHIT_HERO_THROW);
942 if (DEADMONSTER(mon))
943 return FALSE; /* killed */
945 /* in case potion effect causes transformation */
947 tmp = (mdat == &mons[PM_SHADE]) ? 0 : 1;
949 if (mdat == &mons[PM_SHADE] && !shade_aware(obj)) {
952 Strcpy(unconventional, cxname(obj));
956 case BOULDER: /* 1d20 */
957 case HEAVY_IRON_BALL: /* 1d25 */
958 case IRON_CHAIN: /* 1d4+1 */
959 tmp = dmgval(obj, mon);
962 if (breaktest(obj)) {
964 You("break %s. That's bad luck!", ysimple_name(obj));
966 You("%s
\8b¾
\82ð
\89ó
\82µ
\82Ä
\82µ
\82Ü
\82Á
\82½
\81D
\82±
\82è
\82á
\82Ü
\82¢
\82Á
\82½
\81I", ysimple_name(obj));
969 obj = (struct obj *) 0;
970 unarmed = FALSE; /* avoid obj==0 confusion */
971 get_dmg_bonus = FALSE;
976 case EXPENSIVE_CAMERA:
978 You("succeed in destroying %s. Congratulations!",
980 You("%s
\83J
\83\81\83\89\82ð
\89ó
\82·
\82±
\82Æ
\82ª
\82Å
\82«
\82½
\81D
\82¨
\82ß
\82Å
\82Æ
\82¤
\81I",
982 release_camera_demon(obj, u.ux, u.uy);
985 case CORPSE: /* fixed by polder@cs.vu.nl */
986 if (touch_petrifies(&mons[obj->corpsenm])) {
990 You("hit %s with %s.", mon_nam(mon),
991 corpse_xname(obj, (const char *) 0,
992 obj->dknown ? CXN_PFX_THE
995 You("%s
\82ð%s
\82Å
\8dU
\8c\82\82µ
\82½
\81D", mon_nam(mon),
996 corpse_xname(obj, (const char *) 0,
997 obj->dknown ? CXN_PFX_THE
1001 if (!munstone(mon, TRUE))
1002 minstapetrify(mon, TRUE);
1003 if (resists_ston(mon))
1005 /* note: hp may be <= 0 even if munstoned==TRUE */
1006 return (boolean) !DEADMONSTER(mon);
1008 } else if (touch_petrifies(mdat)) {
1009 ; /* maybe turn the corpse into a statue? */
1012 tmp = (obj->corpsenm >= LOW_PM ? mons[obj->corpsenm].msize
1016 #define useup_eggs(o) \
1019 obfree(o, (struct obj *) 0); \
1022 o = (struct obj *) 0; \
1023 } while (0) /* now gone */
1025 long cnt = obj->quan;
1027 tmp = 1; /* nominal physical damage */
1028 get_dmg_bonus = FALSE;
1029 hittxt = TRUE; /* message always given */
1030 /* egg is always either used up or transformed, so next
1031 hand-to-hand attack should yield a "bashing" mesg */
1034 if (obj->spe && obj->corpsenm >= LOW_PM) {
1036 change_luck((schar) - (obj->quan));
1041 if (touch_petrifies(&mons[obj->corpsenm])) {
1042 /*learn_egg_type(obj->corpsenm);*/
1044 pline("Splat! You hit %s with %s %s egg%s!",
1046 obj->known ? "the" : cnt > 1L ? "some" : "a",
1047 obj->known ? mons[obj->corpsenm].mname
1051 pline("
\83r
\83`
\83\83\83b
\81I
\82 \82È
\82½
\82Í%s
\82É%s%s
\82Ì
\97\91\82ð
\93\8a\82°
\82Â
\82¯
\82½
\81I",
1053 cnt > 1L ? "
\82¢
\82
\82Â
\82©
\82Ì" : "",
1054 obj->known ? mons[obj->corpsenm].mname
1057 obj->known = 1; /* (not much point...) */
1059 if (!munstone(mon, TRUE))
1060 minstapetrify(mon, TRUE);
1061 if (resists_ston(mon))
1063 return (boolean) (!DEADMONSTER(mon));
1064 } else { /* ordinary egg(s) */
1066 const char *eggp = (obj->corpsenm != NON_PM
1068 ? the(mons[obj->corpsenm].mname)
1069 : (cnt > 1L) ? "some" : "an";
1071 You("hit %s with %s egg%s.", mon_nam(mon), eggp,
1074 const char *eggp = (obj->corpsenm != NON_PM
1076 ? mons[obj->corpsenm].mname
1078 You("%s
\82É%s%s
\97\91\82ð
\93\8a\82°
\82Â
\82¯
\82½
\81D",
1079 mon_nam(mon), eggp, *eggp ? "
\82Ì" : "");
1081 if (touch_petrifies(mdat) && !stale_egg(obj)) {
1083 pline_The("egg%s %s alive any more...", plur(cnt),
1084 (cnt == 1L) ? "isn't" : "aren't");
1086 pline("
\82à
\82¤
\97\91\82ª
\9bz
\89»
\82·
\82é
\82±
\82Æ
\82Í
\82È
\82¢
\82¾
\82ë
\82¤
\81D
\81D
\81D");
1089 obj_stop_timers(obj);
1091 obj->oclass = GEM_CLASS;
1094 obj->known = obj->dknown = obj->bknown = 0;
1095 obj->owt = weight(obj);
1097 place_object(obj, mon->mx, mon->my);
1102 pline("
\83r
\83`
\83\83\83b
\81I");
1104 exercise(A_WIS, FALSE);
1110 case CLOVE_OF_GARLIC: /* no effect against demons */
1111 if (is_undead(mdat) || is_vampshifter(mon)) {
1112 monflee(mon, d(2, 4), FALSE, TRUE);
1117 case BLINDING_VENOM:
1119 if (can_blnd(&youmonst, mon,
1120 (uchar) ((obj->otyp == BLINDING_VENOM)
1126 pline(obj->otyp == CREAM_PIE ? "Splat!"
1129 pline(obj->otyp == CREAM_PIE ? "
\83r
\83V
\83\83\83b
\81I"
1130 : "
\83s
\83`
\83\83\83b
\81I");
1132 } else if (obj->otyp == BLINDING_VENOM) {
1134 pline_The("venom blinds %s%s!", mon_nam(mon),
1135 mon->mcansee ? "" : " further");
1137 pline("
\93Å
\89t
\82Å%s
\82Í%s
\96Ú
\82ª
\8c©
\82¦
\82È
\82
\82È
\82Á
\82½
\81I", mon_nam(mon),
1138 mon->mcansee ? "" : "
\82³
\82ç
\82É");
1141 char *whom = mon_nam(mon);
1142 char *what = The(xname(obj));
1144 if (!thrown && obj->quan > 1L)
1145 what = An(singular(obj, xname));
1146 /* note: s_suffix returns a modifiable buffer */
1148 && mdat != &mons[PM_FLOATING_EYE])
1150 whom = strcat(strcat(s_suffix(whom), " "),
1151 mbodypart(mon, FACE));
1153 whom = strcat(s_suffix(whom),
1154 mbodypart(mon, FACE));
1157 pline("%s %s over %s!", what,
1158 vtense(what, "splash"), whom);
1160 pline("%s
\82Í%s
\82É
\82Ô
\82¿
\82Ü
\82¯
\82ç
\82ê
\82½
\81I",
1164 setmangry(mon, TRUE);
1167 if (((int) mon->mblinded + tmp) > 127)
1168 mon->mblinded = 127;
1170 mon->mblinded += tmp;
1173 pline(obj->otyp == CREAM_PIE ? "Splat!" : "Splash!");
1175 pline(obj->otyp==CREAM_PIE ? "
\83r
\83V
\83\83\83b
\81I" : "
\83s
\83`
\83\83\83b
\81I");
1176 setmangry(mon, TRUE);
1179 obfree(obj, (struct obj *) 0);
1183 get_dmg_bonus = FALSE;
1186 case ACID_VENOM: /* thrown (or spit) */
1187 if (resists_acid(mon)) {
1189 Your("venom hits %s harmlessly.", mon_nam(mon));
1191 pline("
\93Å
\89t
\82Í%s
\82É
\82Í
\8cø
\89Ê
\82ª
\82È
\82©
\82Á
\82½
\81D", mon_nam(mon));
1195 Your("venom burns %s!", mon_nam(mon));
1197 Your("
\93Å
\89t
\82Í%s
\82ð
\8fÄ
\82¢
\82½
\81I", mon_nam(mon));
1198 tmp = dmgval(obj, mon);
1201 obfree(obj, (struct obj *) 0);
1205 get_dmg_bonus = FALSE;
1208 /* non-weapons can damage because of their weight */
1209 /* (but not too much) */
1210 tmp = obj->owt / 100;
1211 if (is_wet_towel(obj)) {
1212 /* wielded wet towel should probably use whip skill
1213 (but not by setting objects[TOWEL].oc_skill==P_WHIP
1214 because that would turn towel into a weptool) */
1216 if (rn2(obj->spe + 1)) /* usually lose some wetness */
1217 dry_a_towel(obj, -1, TRUE);
1226 * Things like silver wands can arrive here so
1227 * so we need another silver check.
1229 if (objects[obj->otyp].oc_material == SILVER
1230 && mon_hates_silver(mon)) {
1240 /****** NOTE: perhaps obj is undefined!! (if !thrown && BOOMERANG)
1241 * *OR* if attacking bare-handed!! */
1243 if (get_dmg_bonus && tmp > 0) {
1245 /* If you throw using a propellor, you don't get a strength
1246 * bonus but you do get an increase-damage bonus.
1248 if (thrown != HMON_THROWN || !obj || !uwep
1249 || !ammo_and_launcher(obj, uwep))
1253 if (valid_weapon_attack) {
1256 /* to be valid a projectile must have had the correct projector */
1257 wep = PROJECTILE(obj) ? uwep : obj;
1258 tmp += weapon_dam_bonus(wep);
1259 /* [this assumes that `!thrown' implies wielded...] */
1260 wtype = thrown ? weapon_type(wep) : uwep_skill_type();
1261 use_skill(wtype, 1);
1265 int nopoison = (10 - (obj->owt / 10));
1269 if (Role_if(PM_SAMURAI)) {
1271 You("dishonorably use a poisoned weapon!");
1273 You("
\95s
\96¼
\97_
\82É
\82à
\93Å
\82Ì
\95\90\8aí
\82ð
\8eg
\97p
\82µ
\82½
\81I");
1274 adjalign(-sgn(u.ualign.type));
1275 } else if (u.ualign.type == A_LAWFUL && u.ualign.record > -10) {
1277 You_feel("like an evil coward for using a poisoned weapon.");
1279 You("
\93Å
\82Ì
\95\90\8aí
\82ð
\8eg
\97p
\82·
\82é
\82Ì
\82Í
\94Ú
\8b¯
\82¾
\82Æ
\8a´
\82¶
\82½
\81D");
1282 if (obj && !rn2(nopoison)) {
1283 /* remove poison now in case obj ends up in a bones file */
1284 obj->opoisoned = FALSE;
1285 /* defer "obj is no longer poisoned" until after hit message */
1288 if (resists_poison(mon))
1296 /* make sure that negative damage adjustment can't result
1297 in inadvertently boosting the victim's hit points */
1299 if (mdat == &mons[PM_SHADE]) {
1302 const char *what = *unconventional ? unconventional : "attack";
1304 Your("%s %s harmlessly through %s.", what,
1305 vtense(what, "pass"), mon_nam(mon));
1307 Your("
\8dU
\8c\82\82Í%s
\82ð
\92Ê
\82è
\82Ê
\82¯
\82½
\81D", mon_nam(mon));
1318 tmp += d(2, (obj == uwep) ? 10 : 2); /* [was in dmgval()] */
1320 You("joust %s%s", mon_nam(mon), canseemon(mon) ? exclam(tmp) : ".");
1322 You("%s
\82É
\93Ë
\8c\82\82µ
\82½%s", mon_nam(mon), canseemon(mon) ? exclam(tmp) : "
\81D");
1325 pline("%s shatters on impact!", Yname2(obj));
1327 Your("%s
\82Í
\8fÕ
\8c\82\82Å
\89ó
\82ê
\82½
\81I", xname(obj));
1328 /* (must be either primary or secondary weapon to get here) */
1329 u.twoweap = FALSE; /* untwoweapon() is too verbose here */
1331 uwepgone(); /* set unweapon */
1332 /* minor side-effect: broken lance won't split puddings */
1336 /* avoid migrating a dead monster */
1337 if (mon->mhp > tmp) {
1338 mhurtle(mon, u.dx, u.dy, 1);
1339 mdat = mon->data; /* in case of a polymorph trap */
1340 if (DEADMONSTER(mon))
1341 already_killed = TRUE;
1344 } else if (unarmed && tmp > 1 && !thrown && !obj && !Upolyd) {
1345 /* VERY small chance of stunning opponent if unarmed. */
1346 if (rnd(100) < P_SKILL(P_BARE_HANDED_COMBAT) && !bigmonst(mdat)
1347 && !thick_skinned(mdat)) {
1348 if (canspotmon(mon))
1350 pline("%s %s from your powerful strike!", Monnam(mon),
1351 makeplural(stagger(mon->data, "stagger")));
1353 pline("%s
\82Í
\82 \82È
\82½
\82Ì
\89ï
\90S
\82Ì
\88ê
\8c\82\82Å%s
\81I", Monnam(mon),
1354 jpast(stagger(mon->data, "
\82æ
\82ë
\82ß
\82")));
1356 /* avoid migrating a dead monster */
1357 if (mon->mhp > tmp) {
1358 mhurtle(mon, u.dx, u.dy, 1);
1359 mdat = mon->data; /* in case of a polymorph trap */
1360 if (DEADMONSTER(mon))
1361 already_killed = TRUE;
1367 if (!already_killed)
1369 /* adjustments might have made tmp become less than what
1370 a level draining artifact has already done to max HP */
1371 if (mon->mhp > mon->mhpmax)
1372 mon->mhp = mon->mhpmax;
1373 if (DEADMONSTER(mon))
1375 if (mon->mtame && tmp > 0) {
1376 /* do this even if the pet is being killed (affects revival) */
1377 abuse_dog(mon); /* reduces tameness */
1378 /* flee if still alive and still tame; if already suffering from
1379 untimed fleeing, no effect, otherwise increases timed fleeing */
1380 if (mon->mtame && !destroyed)
1381 monflee(mon, 10 * rnd(tmp), FALSE, FALSE);
1383 if ((mdat == &mons[PM_BLACK_PUDDING] || mdat == &mons[PM_BROWN_PUDDING])
1384 /* pudding is alive and healthy enough to split */
1385 && mon->mhp > 1 && !mon->mcan
1386 /* iron weapon using melee or polearm hit [3.6.1: metal weapon too;
1387 also allow either or both weapons to cause split when twoweap] */
1388 && obj && (obj == uwep || (u.twoweap && obj == uswapwep))
1389 && ((objects[obj->otyp].oc_material == IRON
1390 /* allow scalpel and tsurugi to split puddings */
1391 || objects[obj->otyp].oc_material == METAL)
1392 /* but not bashing with darts, arrows or ya */
1393 && !(is_ammo(obj) || is_missile(obj)))
1395 struct monst *mclone;
1396 if ((mclone = clone_mon(mon, 0, 0)) != 0) {
1397 char withwhat[BUFSZ];
1401 if (u.twoweap && flags.verbose)
1402 Sprintf(withwhat, " with %s", yname(obj));
1403 pline("%s divides as you hit it%s!", Monnam(mon), withwhat);
1405 if (u.twoweap && flags.verbose)
1406 Sprintf(withwhat, "%s
\82Å
\82Ì", yname(obj));
1407 pline("
\82 \82È
\82½
\82Ì%s
\8dU
\8c\82\82Å%s
\82Í
\95ª
\97ô
\82µ
\82½
\81I", withwhat, Monnam(mon));
1414 if (!hittxt /*( thrown => obj exists )*/
1416 || (thrown && m_shot.n > 1 && m_shot.o == obj->otyp))) {
1418 hit(mshot_xname(obj), mon, exclam(tmp));
1419 else if (!flags.verbose)
1423 pline("
\8dU
\8c\82\82Í
\96½
\92\86\82µ
\82½
\81D");
1425 #if 0 /*JP*//*
\89£
\82è
\95û
\82ð
\95ª
\82¯
\82é
\82Ü
\82Å
\82Í
\82â
\82ç
\82È
\82¢*/
1427 (obj && (is_shield(obj) || obj->otyp == HEAVY_IRON_BALL))
1428 ? "bash" : Role_if(PM_BARBARIAN) ? "smite" : "hit",
1429 mon_nam(mon), canseemon(mon) ? exclam(tmp) : ".");
1431 Your("%s
\82Ö
\82Ì
\8dU
\8c\82\82Í
\96½
\92\86\82µ
\82½%s",
1432 mon_nam(mon), canseemon(mon) ? exclam(tmp) : "
\81D");
1438 char *whom = mon_nam(mon);
1439 char silverobjbuf[BUFSZ];
1441 if (canspotmon(mon)) {
1442 if (barehand_silver_rings == 1)
1444 fmt = "Your silver ring sears %s!";
1446 fmt = "%s
\82Í
\8bâ
\82Ì
\8ew
\97Ö
\82Å
\8fÄ
\82©
\82ê
\82½
\81I";
1447 else if (barehand_silver_rings == 2)
1449 fmt = "Your silver rings sear %s!";
1451 fmt = "%s
\82Í
\8bâ
\82Ì
\8ew
\97Ö
\82Å
\8fÄ
\82©
\82ê
\82½
\81I";
1452 else if (silverobj && saved_oname[0]) {
1453 /* guard constructed format string against '%' in
1454 saved_oname[] from xname(via cxname()) */
1456 Sprintf(silverobjbuf, "Your %s%s %s",
1457 strstri(saved_oname, "silver") ? "" : "silver ",
1458 saved_oname, vtense(saved_oname, "sear"));
1460 Sprintf(silverobjbuf, "%%s
\82Í%s%s
\82Å
\8fÄ
\82©
\82ê
\82½
\81I",
1461 strstri(saved_oname, "
\8bâ") ?
1465 (void) strNsubst(silverobjbuf, "%", "%%", 0);
1466 Strcat(silverobjbuf, " %s!");
1470 fmt = "The silver sears %s!";
1472 fmt = "%s
\82Í
\8bâ
\82Å
\8fÄ
\82©
\82ê
\82½
\81I";
1474 *whom = highc(*whom); /* "it" -> "It" */
1476 fmt = "%s is seared!";
1478 fmt = "%s
\82Í
\8fÄ
\82©
\82ê
\82½
\81I";
1480 /* note: s_suffix returns a modifiable buffer */
1481 if (!noncorporeal(mdat) && !amorphous(mdat))
1483 whom = strcat(s_suffix(whom), " flesh");
1485 whom = strcat(s_suffix(whom), "
\93÷");
1490 char *whom = mon_nam(mon);
1491 char emitlightobjbuf[BUFSZ];
1493 if (canspotmon(mon)) {
1494 if (saved_oname[0]) {
1496 Sprintf(emitlightobjbuf,
1497 "%s radiance penetrates deep into",
1498 s_suffix(saved_oname));
1499 Strcat(emitlightobjbuf, " %s!");
1501 Sprintf(emitlightobjbuf,
1502 "%s
\8cõ
\82ª%%s
\82É
\90[
\82
\8aÑ
\92Ê
\82µ
\82½
\81I",
1503 s_suffix(saved_oname));
1505 fmt = emitlightobjbuf;
1508 fmt = "The light sears %s!";
1510 fmt = "
\8cõ
\82Í%s
\82ð
\8fÄ
\82¢
\82½
\81I";
1513 *whom = highc(*whom); /* "it" -> "It" */
1516 fmt = "%s is seared!";
1518 fmt = "%s
\82Í
\8fÄ
\82©
\82ê
\82½
\81I";
1520 /* note: s_suffix returns a modifiable buffer */
1521 if (!noncorporeal(mdat) && !amorphous(mdat))
1523 whom = strcat(s_suffix(whom), " flesh");
1525 whom = strcat(s_suffix(whom), "
\93÷");
1528 /* if a "no longer poisoned" message is coming, it will be last;
1529 obj->opoisoned was cleared above and any message referring to
1530 "poisoned <obj>" has now been given; we want just "<obj>" for
1531 last message, so reformat while obj is still accessible */
1533 Strcpy(saved_oname, cxname(obj));
1535 /* [note: thrown obj might go away during killed()/xkilled() call
1536 (via 'thrownobj'; if swallowed, it gets added to engulfer's
1537 minvent and might merge with a stack that's already there)] */
1541 pline_The("poison doesn't seem to affect %s.", mon_nam(mon));
1543 pline("
\93Å
\82Í%s
\82É
\8cø
\82©
\82È
\82©
\82Á
\82½
\82æ
\82¤
\82¾
\81D", mon_nam(mon));
1546 pline_The("poison was deadly...");
1548 pline("
\93Å
\82Í
\92v
\8e\80\97Ê
\82¾
\82Á
\82½
\81D
\81D
\81D");
1549 if (!already_killed)
1550 xkilled(mon, XKILL_NOMSG);
1551 destroyed = TRUE; /* return FALSE; */
1552 } else if (destroyed) {
1553 if (!already_killed)
1554 killed(mon); /* takes care of most messages */
1555 } else if (u.umconf && hand_to_hand) {
1557 if (!mon->mconf && !resist(mon, SPBOOK_CLASS, 0, NOTELL)) {
1559 if (!mon->mstun && mon->mcanmove && !mon->msleeping
1562 pline("%s appears confused.", Monnam(mon));
1564 pline("%s
\82Í
\8d¬
\97\90\82µ
\82Ä
\82¢
\82é
\82æ
\82¤
\82¾
\81D", Monnam(mon));
1569 Your("%s %s no longer poisoned.", saved_oname,
1570 vtense(saved_oname, "are"));
1572 Your("%s
\82Í
\82à
\82¤
\93Å
\82ª
\93h
\82ç
\82ê
\82Ä
\82¢
\82È
\82¢
\81D", xname(obj));
1575 return destroyed ? FALSE : TRUE;
1585 * The things in this list either
1588 * 2) are dealt with properly by other routines
1589 * when it comes to shades.
1591 if (obj->otyp == BOULDER
1592 || obj->otyp == HEAVY_IRON_BALL
1593 || obj->otyp == IRON_CHAIN /* dmgval handles those first three */
1594 || obj->otyp == MIRROR /* silver in the reflective surface */
1595 || obj->otyp == CLOVE_OF_GARLIC /* causes shades to flee */
1596 || objects[obj->otyp].oc_material == SILVER)
1601 /* check whether slippery clothing protects from hug or wrap attack */
1602 /* [currently assumes that you are the attacker] */
1604 m_slips_free(mdef, mattk)
1606 struct attack *mattk;
1610 if (mattk->adtyp == AD_DRIN) {
1611 /* intelligence drain attacks the head */
1612 obj = which_armor(mdef, W_ARMH);
1614 /* grabbing attacks the body */
1615 obj = which_armor(mdef, W_ARMC); /* cloak */
1617 obj = which_armor(mdef, W_ARM); /* suit */
1619 obj = which_armor(mdef, W_ARMU); /* shirt */
1622 /* if monster's cloak/armor is greased, your grab slips off; this
1623 protection might fail (33% chance) when the armor is cursed */
1624 if (obj && (obj->greased || obj->otyp == OILSKIN_CLOAK)
1625 && (!obj->cursed || rn2(3))) {
1628 mattk->adtyp == AD_WRAP ? "slip off of"
1629 : "grab, but cannot hold onto",
1630 s_suffix(mon_nam(mdef)), obj->greased ? "greased" : "slippery",
1631 /* avoid "slippery slippery cloak"
1632 for undiscovered oilskin cloak */
1633 (obj->greased || objects[obj->otyp].oc_name_known)
1635 : cloak_simple_name(obj));
1637 You("%s
\82Ì%s%s%s
\81I",
1638 mon_nam(mdef), obj->greased ? "
\96û
\82Ì
\93h
\82ç
\82ê
\82½" : "
\8a\8a\82è
\82â
\82·
\82¢",
1639 (obj->greased || objects[obj->otyp].oc_name_known)
1641 : cloak_simple_name(obj),
1642 mattk->adtyp == AD_WRAP ? "
\82Å
\8a\8a\82Á
\82½"
1643 : "
\82ð
\82Â
\82©
\82Ü
\82æ
\82¤
\82Æ
\82µ
\82½
\82ª
\81C
\82Å
\82«
\82È
\82©
\82Á
\82½");
1646 if (obj->greased && !rn2(2)) {
1648 pline_The("grease wears off.");
1650 pline("
\96û
\82Í
\97\8e\82¿
\82Ä
\82µ
\82Ü
\82Á
\82½
\81D");
1658 /* used when hitting a monster with a lance while mounted;
1659 1: joust hit; 0: ordinary hit; -1: joust but break lance */
1662 struct monst *mon; /* target */
1663 struct obj *obj; /* weapon */
1665 int skill_rating, joust_dieroll;
1667 if (Fumbling || Stunned)
1669 /* sanity check; lance must be wielded in order to joust */
1670 if (obj != uwep && (obj != uswapwep || !u.twoweap))
1673 /* if using two weapons, use worse of lance and two-weapon skills */
1674 skill_rating = P_SKILL(weapon_type(obj)); /* lance skill */
1675 if (u.twoweap && P_SKILL(P_TWO_WEAPON_COMBAT) < skill_rating)
1676 skill_rating = P_SKILL(P_TWO_WEAPON_COMBAT);
1677 if (skill_rating == P_ISRESTRICTED)
1678 skill_rating = P_UNSKILLED; /* 0=>1 */
1680 /* odds to joust are expert:80%, skilled:60%, basic:40%, unskilled:20% */
1681 if ((joust_dieroll = rn2(5)) < skill_rating) {
1682 if (joust_dieroll == 0 && rnl(50) == (50 - 1) && !unsolid(mon->data)
1683 && !obj_resists(obj, 0, 100))
1684 return -1; /* hit that breaks lance */
1685 return 1; /* successful joust */
1687 return 0; /* no joust bonus; revert to ordinary attack */
1691 * Send in a demon pet for the hero. Exercise wisdom.
1693 * This function used to be inline to damageum(), but the Metrowerks compiler
1694 * (DR4 and DR4.5) screws up with an internal error 5 "Expression Too
1696 * Pulling it out makes it work.
1702 struct permonst *pm;
1706 pline("Some hell-p has arrived!");
1708 pline("
\92n
\8d\96\82Ì
\92\87\8aÔ
\82ª
\8c»
\82í
\82ê
\82½
\81I");
1709 i = !rn2(6) ? ndemon(u.ualign.type) : NON_PM;
1710 pm = i != NON_PM ? &mons[i] : youmonst.data;
1711 if ((dtmp = makemon(pm, u.ux, u.uy, NO_MM_FLAGS)) != 0)
1712 (void) tamedog(dtmp, (struct obj *) 0);
1713 exercise(A_WIS, TRUE);
1717 theft_petrifies(otmp)
1720 if (uarmg || otmp->otyp != CORPSE
1721 || !touch_petrifies(&mons[otmp->corpsenm]) || Stone_resistance)
1724 #if 0 /* no poly_when_stoned() critter has theft capability */
1725 if (poly_when_stoned(youmonst.data) && polymon(PM_STONE_GOLEM)) {
1726 display_nhwindow(WIN_MESSAGE, FALSE); /* --More-- */
1731 /* stealing this corpse is fatal... */
1733 instapetrify(corpse_xname(otmp, "stolen", CXN_ARTICLE));
1735 instapetrify(corpse_xname(otmp, "
\93\90\82Ü
\82ê
\82½", CXN_ARTICLE));
1736 /* apparently wasn't fatal after all... */
1741 * Player uses theft attack against monster.
1743 * If the target is wearing body armor, take all of its possessions;
1744 * otherwise, take one object. [Is this really the behavior we want?]
1747 steal_it(mdef, mattk)
1749 struct attack *mattk;
1751 struct obj *otmp, *stealoid, **minvent_ptr;
1755 return; /* nothing to take */
1757 /* look for worn body armor */
1758 stealoid = (struct obj *) 0;
1759 if (could_seduce(&youmonst, mdef, mattk)) {
1760 /* find armor, and move it to end of inventory in the process */
1761 minvent_ptr = &mdef->minvent;
1762 while ((otmp = *minvent_ptr) != 0)
1763 if (otmp->owornmask & W_ARM) {
1765 panic("steal_it: multiple worn suits");
1766 *minvent_ptr = otmp->nobj; /* take armor out of minvent */
1768 stealoid->nobj = (struct obj *) 0;
1770 minvent_ptr = &otmp->nobj;
1772 *minvent_ptr = stealoid; /* put armor back into minvent */
1775 if (stealoid) { /* we will be taking everything */
1776 if (gender(mdef) == (int) u.mfemale && youmonst.data->mlet == S_NYMPH)
1778 You("charm %s. She gladly hands over her possessions.",
1780 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",
1784 You("seduce %s and %s starts to take off %s clothes.",
1785 mon_nam(mdef), mhe(mdef), mhis(mdef));
1787 You("%s
\82ð
\97U
\98f
\82µ
\82½
\81D%s
\82Í
\95\9e\82ð
\92E
\82¬
\82Í
\82¶
\82ß
\82½
\81D",
1788 mon_nam(mdef), mhe(mdef));
1792 while ((otmp = mdef->minvent) != 0) {
1794 break; /* no longer have ability to steal */
1795 /* take the object away from the monster */
1796 obj_extract_self(otmp);
1797 if ((unwornmask = otmp->owornmask) != 0L) {
1798 mdef->misc_worn_check &= ~unwornmask;
1799 if (otmp->owornmask & W_WEP)
1800 setmnotwielded(mdef, otmp);
1801 otmp->owornmask = 0L;
1802 update_mon_intrinsics(mdef, otmp, FALSE, FALSE);
1803 /* give monster a chance to wear other equipment on its next
1804 move instead of waiting until it picks something up */
1805 mdef->misc_worn_check |= I_SPECIAL;
1807 if (otmp == stealoid) /* special message for final item */
1809 pline("%s finishes taking off %s suit.", Monnam(mdef),
1812 pline("%s
\82Í
\92E
\82¬
\8fI
\82¦
\82½
\81D", Monnam(mdef));
1815 /* give the object to the character */
1817 otmp = hold_another_object(otmp, "You snatched but dropped %s.",
1818 doname(otmp), "You steal: ");
1820 otmp = hold_another_object(otmp, "
\82 \82È
\82½
\82Í%s
\82ð
\93\90\82ñ
\82¾
\82ª
\97\8e\82Æ
\82µ
\82½
\81D",
1821 doname(otmp), "
\82ð
\93\90\82ñ
\82¾
\81D");
1823 /* might have dropped otmp, and it might have broken or left level */
1824 if (!otmp || otmp->where != OBJ_INVENT)
1826 if (theft_petrifies(otmp))
1827 break; /* stop thieving even though hero survived */
1828 /* more take-away handling, after theft message */
1829 if (unwornmask & W_WEP) { /* stole wielded weapon */
1830 possibly_unwield(mdef, FALSE);
1831 } else if (unwornmask & W_ARMG) { /* stole worn gloves */
1832 mselftouch(mdef, (const char *) 0, TRUE);
1833 if (DEADMONSTER(mdef)) /* it's now a statue */
1834 return; /* can't continue stealing */
1838 break; /* only taking one item */
1843 damageum(mdef, mattk, specialdmg)
1844 register struct monst *mdef;
1845 register struct attack *mattk;
1846 int specialdmg; /* blessed and/or silver bonus against various things */
1848 register struct permonst *pd = mdef->data;
1849 int armpro, tmp = d((int) mattk->damn, (int) mattk->damd);
1851 struct obj *mongold;
1853 armpro = magic_negation(mdef);
1854 /* since hero can't be cancelled, only defender's armor applies */
1855 negated = !(rn2(10) >= 3 * armpro);
1857 if (is_demon(youmonst.data) && !rn2(13) && !uwep
1858 && u.umonnum != PM_SUCCUBUS && u.umonnum != PM_INCUBUS
1859 && u.umonnum != PM_BALROG) {
1863 switch (mattk->adtyp) {
1867 pline("%s %s for a moment.", Monnam(mdef),
1868 makeplural(stagger(pd, "stagger")));
1870 pline("%s
\82Í
\88ê
\8fu%s
\81D", Monnam(mdef),
1871 jpast(stagger(pd, "
\82æ
\82ë
\82ß
\82")));
1883 case AD_WERE: /* no special effect on monsters */
1884 case AD_HEAL: /* likewise */
1887 if (pd == &mons[PM_SHADE]) {
1890 impossible("bad shade attack function flow?");
1894 if (mattk->aatyp == AT_WEAP) {
1895 /* hmonas() uses known_hitum() to deal physical damage,
1896 then also damageum() for non-AD_PHYS; don't inflict
1897 extra physical damage for unusual damage types */
1899 } else if (mattk->aatyp == AT_KICK
1900 || mattk->aatyp == AT_CLAW
1901 || mattk->aatyp == AT_TUCH
1902 || mattk->aatyp == AT_HUGS) {
1903 if (thick_skinned(pd))
1904 tmp = (mattk->aatyp == AT_KICK) ? 0 : (tmp + 1) / 2;
1905 /* add ring(s) of increase damage */
1906 if (u.udaminc > 0) {
1907 /* applies even if damage was 0 */
1909 } else if (tmp > 0) {
1910 /* ring(s) might be negative; avoid converting
1911 0 to non-0 or positive to non-positive */
1925 pline("%s is %s!", Monnam(mdef), on_fire(pd, mattk));
1927 pline("%s
\82Í%s
\81I", Monnam(mdef), on_fire(mdef->data, mattk));
1928 if (completelyburns(pd)) { /* paper golem or straw golem */
1931 pline("%s burns completely!", Monnam(mdef));
1933 pline("%s
\82Í
\8a®
\91S
\82É
\94R
\82¦
\90s
\82«
\82½
\81I", Monnam(mdef));
1936 You("smell burning%s.",
1937 (pd == &mons[PM_PAPER_GOLEM]) ? " paper"
1938 : (pd == &mons[PM_STRAW_GOLEM]) ? " straw" : "");
1940 You("%s
\82ª
\94R
\82¦
\82é
\82É
\82¨
\82¢
\82ª
\82µ
\82½
\81D",
1941 (pd == &mons[PM_PAPER_GOLEM]) ? "
\8e\86"
1942 : (pd == &mons[PM_STRAW_GOLEM]) ? "
\82í
\82ç" : "
\89½
\82©");
1944 xkilled(mdef, XKILL_NOMSG | XKILL_NOCORPSE);
1947 /* Don't return yet; keep hp<1 and tmp=0 for pet msg */
1949 tmp += destroy_mitem(mdef, SCROLL_CLASS, AD_FIRE);
1950 tmp += destroy_mitem(mdef, SPBOOK_CLASS, AD_FIRE);
1951 if (resists_fire(mdef)) {
1954 pline_The("fire doesn't heat %s!", mon_nam(mdef));
1956 pline("
\89\8a\82Í%s
\82É
\89e
\8b¿
\82ª
\82È
\82¢
\81I", mon_nam(mdef));
1957 golemeffects(mdef, AD_FIRE, tmp);
1958 shieldeff(mdef->mx, mdef->my);
1961 /* only potions damage resistant players in destroy_item */
1962 tmp += destroy_mitem(mdef, POTION_CLASS, AD_FIRE);
1971 pline("%s is covered in frost!", Monnam(mdef));
1973 pline("%s
\82Í
\95X
\82Å
\95¢
\82í
\82ê
\82½
\81I", Monnam(mdef));
1974 if (resists_cold(mdef)) {
1975 shieldeff(mdef->mx, mdef->my);
1978 pline_The("frost doesn't chill %s!", mon_nam(mdef));
1980 pline("
\95X
\82Í%s
\82ð
\93\80\82ç
\82·
\82±
\82Æ
\82ª
\82Å
\82«
\82È
\82¢
\81I", mon_nam(mdef));
1981 golemeffects(mdef, AD_COLD, tmp);
1984 tmp += destroy_mitem(mdef, POTION_CLASS, AD_COLD);
1993 pline("%s is zapped!", Monnam(mdef));
1995 pline("%s
\82Í
\93d
\8c\82\82ð
\82
\82ç
\82Á
\82½
\81I", Monnam(mdef));
1996 tmp += destroy_mitem(mdef, WAND_CLASS, AD_ELEC);
1997 if (resists_elec(mdef)) {
2000 pline_The("zap doesn't shock %s!", mon_nam(mdef));
2002 pline("
\93d
\8c\82\82Í%s
\82É
\89e
\8b¿
\82ð
\97^
\82¦
\82È
\82¢
\81I", mon_nam(mdef));
2003 golemeffects(mdef, AD_ELEC, tmp);
2004 shieldeff(mdef->mx, mdef->my);
2007 /* only rings damage resistant players in destroy_item */
2008 tmp += destroy_mitem(mdef, RING_CLASS, AD_ELEC);
2011 if (resists_acid(mdef))
2015 if (!munstone(mdef, TRUE))
2016 minstapetrify(mdef, TRUE);
2022 steal_it(mdef, mattk);
2026 /* This you as a leprechaun, so steal
2027 real gold only, no lesser coins */
2028 mongold = findgold(mdef->minvent);
2030 obj_extract_self(mongold);
2031 if (merge_choice(invent, mongold) || inv_cnt(FALSE) < 52) {
2034 Your("purse feels heavier.");
2036 You("
\8dà
\95z
\82ª
\8fd
\82
\82È
\82Á
\82½
\82æ
\82¤
\82È
\8bC
\82ª
\82µ
\82½
\81D");
2039 You("grab %s's gold, but find no room in your knapsack.",
2041 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",
2046 exercise(A_DEX, TRUE);
2054 boolean u_saw_mon = (canseemon(mdef)
2055 || (u.uswallow && u.ustuck == mdef));
2057 /* record the name before losing sight of monster */
2058 Strcpy(nambuf, Monnam(mdef));
2059 if (u_teleport_mon(mdef, FALSE) && u_saw_mon
2060 && !(canseemon(mdef) || (u.uswallow && u.ustuck == mdef)))
2062 pline("%s suddenly disappears!", nambuf);
2064 pline("%s
\82Í
\93Ë
\91R
\8fÁ
\82¦
\82½
\81I", nambuf);
2065 if (tmp >= mdef->mhp) { /* see hitmu(mhitu.c) */
2068 tmp = mdef->mhp - 1;
2073 if (can_blnd(&youmonst, mdef, mattk->aatyp, (struct obj *) 0)) {
2074 if (!Blind && mdef->mcansee)
2076 pline("%s is blinded.", Monnam(mdef));
2078 pline("%s
\82Í
\96Ú
\82ª
\8c©
\82¦
\82È
\82
\82È
\82Á
\82½
\81D", Monnam(mdef));
2080 tmp += mdef->mblinded;
2083 mdef->mblinded = tmp;
2088 if (night() && !rn2(10) && !mdef->mcan) {
2089 if (pd == &mons[PM_CLAY_GOLEM]) {
2092 pline("Some writing vanishes from %s head!",
2093 s_suffix(mon_nam(mdef)));
2095 pline("%s
\82Ì
\93ª
\82É
\8f\91\82¢
\82Ä
\82 \82é
\95¶
\8e\9a\82Ì
\82¢
\82
\82Â
\82©
\82ª
\8fÁ
\82¦
\82½
\81I",
2098 xkilled(mdef, XKILL_NOMSG);
2099 /* Don't return yet; keep hp<1 and tmp=0 for pet msg */
2105 You("
\82
\82·
\82
\82·
\8fÎ
\82Á
\82½
\81D");
2111 if (!negated && !rn2(3) && !resists_drli(mdef)) {
2115 pline("%s suddenly seems weaker!", Monnam(mdef));
2117 pline("%s
\82Í
\93Ë
\91R
\8eã
\82
\82È
\82Á
\82½
\82æ
\82¤
\82É
\8c©
\82¦
\82½
\81I", Monnam(mdef));
2118 mdef->mhpmax -= xtmp;
2120 /* !m_lev: level 0 monster is killed regardless of hit points
2121 rather than drop to level -1 */
2122 if (DEADMONSTER(mdef) || !mdef->m_lev) {
2124 pline("%s dies!", Monnam(mdef));
2126 pline("%s
\82Í
\8e\80\82ñ
\82¾
\81I", Monnam(mdef));
2127 xkilled(mdef, XKILL_NOMSG);
2134 if (pd == &mons[PM_IRON_GOLEM]) {
2136 pline("%s falls to pieces!", Monnam(mdef));
2138 pline("%s
\82Í
\83o
\83\89\83o
\83\89\82É
\82È
\82Á
\82½
\81I", Monnam(mdef));
2139 xkilled(mdef, XKILL_NOMSG);
2141 erode_armor(mdef, ERODE_RUST);
2145 erode_armor(mdef, ERODE_CORRODE);
2149 if (pd == &mons[PM_WOOD_GOLEM] || pd == &mons[PM_LEATHER_GOLEM]) {
2151 pline("%s falls to pieces!", Monnam(mdef));
2153 pline("%s
\82Í
\83o
\83\89\83o
\83\89\82É
\82È
\82Á
\82½
\81I", Monnam(mdef));
2154 xkilled(mdef, XKILL_NOMSG);
2156 erode_armor(mdef, ERODE_ROT);
2160 if (!negated && !rn2(4))
2161 xdrainenergym(mdef, TRUE);
2167 if (!negated && !rn2(8)) {
2169 Your("%s was poisoned!", mpoisons_subj(&youmonst, mattk));
2171 Your("%s
\82Í
\93Å
\82³
\82ê
\82Ä
\82¢
\82é
\81I", mpoisons_subj(&youmonst, mattk));
2172 if (resists_poison(mdef)) {
2174 pline_The("poison doesn't seem to affect %s.", mon_nam(mdef));
2176 pline("
\93Å
\82Í%s
\82É
\89e
\8b¿
\82ð
\97^
\82¦
\82È
\82¢
\81D", mon_nam(mdef));
2180 Your("poison was deadly...");
2182 Your("
\97^
\82¦
\82½
\93Å
\82Í
\92v
\8e\80\97Ê
\82¾
\82Á
\82½
\81D
\81D
\81D");
2192 if (notonhead || !has_head(pd)) {
2194 pline("%s doesn't seem harmed.", Monnam(mdef));
2196 pline("%s
\82Í
\8f\9d\82Â
\82¢
\82½
\82æ
\82¤
\82É
\82Í
\8c©
\82¦
\82È
\82¢
\81D", Monnam(mdef));
2198 if (!Unchanging && pd == &mons[PM_GREEN_SLIME]) {
2201 You("suck in some slime and don't feel very well.");
2203 You("
\83X
\83\89\83C
\83\80\82ð
\8bz
\82¢
\8eæ
\82Á
\82Ä
\81C
\8bï
\8d\87\82ª
\88«
\82
\82È
\82Á
\82½
\81D");
2204 make_slimed(10L, (char *) 0);
2209 if (m_slips_free(mdef, mattk))
2212 if ((helmet = which_armor(mdef, W_ARMH)) != 0 && rn2(8)) {
2214 pline("%s %s blocks your attack to %s head.",
2215 s_suffix(Monnam(mdef)), helm_simple_name(helmet),
2218 pline("%s
\82Ì%s
\82ª
\93ª
\82Ö
\82Ì
\8dU
\8c\82\82ð
\96h
\82¢
\82¾
\81D",
2219 Monnam(mdef), helm_simple_name(helmet));
2224 (void) eat_brains(&youmonst, mdef, TRUE, &tmp);
2228 if (!negated && !sticks(pd))
2229 u.ustuck = mdef; /* it's now stuck to you */
2233 if (!u.ustuck && !rn2(10)) {
2234 if (m_slips_free(mdef, mattk)) {
2238 You("swing yourself around %s!", mon_nam(mdef));
2240 You("%s
\82É
\90g
\91Ì
\82ð
\97\8d\82Ý
\82Â
\82©
\82¹
\82½
\81I", mon_nam(mdef));
2243 } else if (u.ustuck == mdef) {
2244 /* Monsters don't wear amulets of magical breathing */
2245 if (is_pool(u.ux, u.uy) && !is_swimmer(pd)
2246 && !amphibious(pd)) {
2248 You("drown %s...", mon_nam(mdef));
2250 You("%s
\82ð
\93M
\82ê
\82³
\82¹
\82½
\81D
\81D
\81D", mon_nam(mdef));
2252 } else if (mattk->aatyp == AT_HUGS)
2254 pline("%s is being crushed.", Monnam(mdef));
2256 pline("%s
\82Í
\89\9f\82µ
\82Â
\82Ô
\82³
\82ê
\82Ä
\82¢
\82é
\81D", Monnam(mdef));
2261 You("brush against %s %s.", s_suffix(mon_nam(mdef)),
2262 mbodypart(mdef, LEG));
2264 You("%s
\82Ì%s
\82É
\90G
\82ê
\82½
\81D", mon_nam(mdef),
2265 mbodypart(mdef, LEG));
2272 if (!negated && mdef->mcanmove && !rn2(3) && tmp < mdef->mhp) {
2275 pline("%s is frozen by you!", Monnam(mdef));
2277 pline("%s
\82Í
\82 \82È
\82½
\82Ì
\82É
\82ç
\82Ý
\82Å
\93®
\82¯
\82È
\82
\82È
\82Á
\82½
\81I", Monnam(mdef));
2278 paralyze_monst(mdef, rnd(10));
2282 if (!negated && !mdef->msleeping && sleep_monst(mdef, rnd(10), -1)) {
2285 pline("%s is put to sleep by you!", Monnam(mdef));
2287 pline("%s
\82Í
\93Ë
\91R
\96°
\82è
\82É
\82¨
\82¿
\82½
\81I", Monnam(mdef));
2293 break; /* physical damage only */
2294 if (!rn2(4) && !slimeproof(pd)) {
2295 if (!munslime(mdef, TRUE) && !DEADMONSTER(mdef)) {
2296 /* this assumes newcham() won't fail; since hero has
2297 a slime attack, green slimes haven't been geno'd */
2299 You("turn %s into slime.", mon_nam(mdef));
2301 pline("%s
\82Í
\83X
\83\89\83C
\83\80\82É
\82È
\82Á
\82½
\81D", mon_nam(mdef));
2302 if (newcham(mdef, &mons[PM_GREEN_SLIME], FALSE, FALSE))
2305 /* munslime attempt could have been fatal */
2306 if (DEADMONSTER(mdef))
2307 return 2; /* skip death message */
2311 case AD_ENCH: /* KMH -- remove enchantment (disenchanter) */
2312 /* there's no msomearmor() function, so just do damage */
2313 /* if (negated) break; */
2316 if (!negated && mdef->mspeed != MSLOW) {
2317 unsigned int oldspeed = mdef->mspeed;
2319 mon_adjust_speed(mdef, -1, (struct obj *) 0);
2320 if (mdef->mspeed != oldspeed && canseemon(mdef))
2322 pline("%s slows down.", Monnam(mdef));
2324 pline("%s
\82Í
\82Ì
\82ë
\82
\82È
\82Á
\82½
\81D", Monnam(mdef));
2329 if (canseemon(mdef))
2331 pline("%s looks confused.", Monnam(mdef));
2333 pline("%s
\82Í
\8d¬
\97\90\82µ
\82½
\82æ
\82¤
\82¾
\81D", Monnam(mdef));
2342 mdef->mstrategy &= ~STRAT_WAITFORU; /* in case player is very fast */
2344 if (DEADMONSTER(mdef)) {
2345 if (mdef->mtame && !cansee(mdef->mx, mdef->my)) {
2347 You_feel("embarrassed for a moment.");
2349 You("
\82µ
\82Î
\82ç
\82
\8d¢
\98f
\82µ
\82½
\81D");
2351 xkilled(mdef, XKILL_NOMSG); /* !tmp but hp<1: already killed */
2352 } else if (!flags.verbose) {
2356 You("
\93|
\82µ
\82½
\81I");
2358 xkilled(mdef, XKILL_NOMSG);
2368 register struct monst *mdef;
2369 register struct attack *mattk;
2371 boolean resistance; /* only for cold/fire/elec */
2372 register int tmp = d((int) mattk->damn, (int) mattk->damd);
2377 You("
\94\9a\94
\82µ
\82½
\81I");
2378 switch (mattk->adtyp) {
2380 if (!resists_blnd(mdef)) {
2382 pline("%s is blinded by your flash of light!", Monnam(mdef));
2384 pline("%s
\82Í
\82Ü
\82Î
\82ä
\82¢
\8cõ
\82Å
\96Ú
\82ª
\82
\82ç
\82ñ
\82¾
\81I", Monnam(mdef));
2385 mdef->mblinded = min((int) mdef->mblinded + tmp, 127);
2390 if (haseyes(mdef->data) && mdef->mcansee) {
2392 pline("%s is affected by your flash of light!", Monnam(mdef));
2394 pline("%s
\82Í
\82Ü
\82Î
\82ä
\82¢
\8cõ
\82Å
\89e
\8b¿
\82ð
\8eó
\82¯
\82½
\81I", Monnam(mdef));
2399 resistance = resists_cold(mdef);
2402 resistance = resists_fire(mdef);
2405 resistance = resists_elec(mdef);
2409 pline("%s gets blasted!", Monnam(mdef));
2411 pline("%s
\82Í
\94\9a\94
\82ð
\97\81\82Ñ
\82½
\81I", Monnam(mdef));
2413 if (DEADMONSTER(mdef)) {
2418 shieldeff(mdef->mx, mdef->my);
2419 if (is_golem(mdef->data))
2420 golemeffects(mdef, (int) mattk->adtyp, tmp);
2423 pline_The("blast doesn't seem to affect %s.", mon_nam(mdef));
2425 pline("
\94\9a\94
\82Í%s
\82É
\89e
\8b¿
\82ð
\97^
\82¦
\82È
\82©
\82Á
\82½
\82æ
\82¤
\82¾
\81D", mon_nam(mdef));
2439 map_location(u.ux, u.uy, TRUE);
2440 tmp_at(DISP_ALWAYS, mon_to_glyph(&youmonst, rn2_on_display_rng));
2441 tmp_at(mdef->mx, mdef->my);
2444 You("engulf %s!", mon_nam(mdef));
2446 You("%s
\82ð
\88ù
\82Ý
\8d\9e\82ñ
\82¾
\81I", mon_nam(mdef));
2455 tmp_at(DISP_END, 0);
2462 register struct monst *mdef;
2463 register struct attack *mattk;
2465 #ifdef LINT /* static char msgbuf[BUFSZ]; */
2468 static char msgbuf[BUFSZ]; /* for nomovemsg */
2471 register int dam = d((int) mattk->damn, (int) mattk->damd);
2474 struct permonst *pd = mdef->data;
2476 /* Not totally the same as for real monsters. Specifically, these
2477 * don't take multiple moves. (It's just too hard, for too little
2478 * result, to program monsters which attack from inside you, which
2479 * would be necessary if done accurately.) Instead, we arbitrarily
2480 * kill the monster immediately for AD_DGST and we regurgitate them
2481 * after exactly 1 round of attack otherwise. -KAA
2484 if (!engulf_target(&youmonst, mdef))
2487 if (u.uhunger < 1500 && !u.uswallow) {
2488 for (otmp = mdef->minvent; otmp; otmp = otmp->nobj)
2489 (void) snuff_lit(otmp);
2491 /* force vampire in bat, cloud, or wolf form to revert back to
2492 vampire form now instead of dealing with that when it dies */
2493 if (is_vampshifter(mdef)
2494 && newcham(mdef, &mons[mdef->cham], FALSE, FALSE)) {
2496 You("engulf it, then expel it.");
2498 You("
\88ù
\82Ý
\8d\9e\82ñ
\82Å
\81C
\93f
\82«
\8fo
\82µ
\82½
\81D");
2499 if (canspotmon(mdef))
2501 pline("It turns into %s.", a_monnam(mdef));
2503 pline("
\82»
\82ê
\82Í%s
\82É
\82È
\82Á
\82½
\81D", a_monnam(mdef));
2505 map_invisible(mdef->mx, mdef->my);
2509 /* engulfing a cockatrice or digesting a Rider or Medusa */
2510 fatal_gulp = (touch_petrifies(pd) && !Stone_resistance)
2511 || (mattk->adtyp == AD_DGST
2512 && (is_rider(pd) || (pd == &mons[PM_MEDUSA]
2513 && !Stone_resistance)));
2515 if ((mattk->adtyp == AD_DGST && !Slow_digestion) || fatal_gulp)
2516 eating_conducts(pd);
2518 if (fatal_gulp && !is_rider(pd)) { /* petrification */
2520 const char *mname = pd->mname;
2522 if (!type_is_pname(pd))
2525 You("englut %s.", mon_nam(mdef));
2527 You("%s
\82ð
\88ù
\82Ý
\8d\9e\82ñ
\82¾
\81D", mon_nam(mdef));
2529 Sprintf(kbuf, "swallowing %s whole", mname);
2531 Sprintf(kbuf, "%s
\82ð
\88ù
\82Ý
\8d\9e\82ñ
\82Å", mname);
2535 switch (mattk->adtyp) {
2537 /* eating a Rider or its corpse is fatal */
2540 pline("Unfortunately, digesting any of it is fatal.");
2542 pline("
\8ec
\94O
\82È
\82ª
\82ç
\81C
\82»
\82ê
\82ð
\90H
\82×
\82é
\82Ì
\82Í
\92v
\96½
\93I
\82È
\8aÔ
\88á
\82¢
\82¾
\81D");
2545 Sprintf(killer.name, "unwisely tried to eat %s",
2547 killer.format = NO_KILLER_PREFIX;
2549 Sprintf(killer.name, "
\8bð
\82©
\82É
\82à%s
\82ð
\90H
\82×
\82æ
\82¤
\82Æ
\82µ
\82Ä",
2551 killer.format = KILLED_BY;
2554 return 0; /* lifesaved */
2557 if (Slow_digestion) {
2562 /* Use up amulet of life saving */
2563 if ((otmp = mlifesaver(mdef)) != 0)
2564 m_useup(mdef, otmp);
2567 /* start_engulf() issues "you engulf <mdef>" above; this
2568 used to specify XKILL_NOMSG but we need "you kill <mdef>"
2569 in case we're also going to get "welcome to level N+1";
2570 "you totally digest <mdef>" will be coming soon (after
2571 several turns) but the level-gain message seems out of
2572 order if the kill message is left implicit */
2573 xkilled(mdef, XKILL_GIVEMSG | XKILL_NOCORPSE);
2574 if (!DEADMONSTER(mdef)) { /* monster lifesaved */
2576 You("hurriedly regurgitate the sizzling in your %s.",
2578 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",
2579 body_part(STOMACH));
2581 tmp = 1 + (pd->cwt >> 8);
2582 if (corpse_chance(mdef, &youmonst, TRUE)
2583 && !(mvitals[monsndx(pd)].mvflags & G_NOCORPSE)) {
2584 /* nutrition only if there can be a corpse */
2585 u.uhunger += (pd->cnutrit + 1) / 2;
2589 Sprintf(msgbuf, "You totally digest %s.", mon_nam(mdef));
2591 Sprintf(msgbuf, "
\82 \82È
\82½
\82Í%s
\82ð
\8a®
\91S
\82É
\8fÁ
\89»
\82µ
\82½
\81D", mon_nam(mdef));
2593 /* setting afternmv = end_engulf is tempting,
2594 * but will cause problems if the player is
2595 * attacked (which uses his real location) or
2596 * if his See_invisible wears off
2599 You("digest %s.", mon_nam(mdef));
2601 You("%s
\82ð
\8fÁ
\89»
\82µ
\82Ä
\82¢
\82é
\81D", mon_nam(mdef));
2606 multi_reason = "digesting something";
2608 multi_reason = "
\8fÁ
\89»
\92\86\82É";
2612 if (pd == &mons[PM_GREEN_SLIME]) {
2614 Sprintf(msgbuf, "%s isn't sitting well with you.",
2616 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",
2619 make_slimed(5L, (char *) 0);
2622 exercise(A_CON, TRUE);
2627 if (youmonst.data == &mons[PM_FOG_CLOUD]) {
2629 pline("%s is laden with your moisture.", Monnam(mdef));
2631 pline("%s
\82Í
\82 \82È
\82½
\82Ì
\8e¼
\8bC
\82É
\8bê
\82µ
\82ß
\82ç
\82ê
\82Ä
\82¢
\82é
\81D", Monnam(mdef));
2632 if (amphibious(pd) && !flaming(pd)) {
2635 pline("%s seems unharmed.", Monnam(mdef));
2637 pline("%s
\82Í
\8f\9d\82Â
\82¢
\82Ä
\82¢
\82È
\82¢
\82æ
\82¤
\82¾
\81D", Monnam(mdef));
2641 pline("%s is pummeled with your debris!", Monnam(mdef));
2643 pline("%s
\82Í
\8a¢âI
\82Å
\92É
\82ß
\82Â
\82¯
\82ç
\82ê
\82½
\81I", Monnam(mdef));
2647 pline("%s is covered with your goo!", Monnam(mdef));
2649 pline("%s
\82Í
\82Ë
\82Î
\82Â
\82
\82à
\82Ì
\82Å
\95¢
\82í
\82ê
\82½
\81I", Monnam(mdef));
2650 if (resists_acid(mdef)) {
2652 pline("It seems harmless to %s.", mon_nam(mdef));
2654 pline("
\82µ
\82©
\82µ
\81C%s
\82Í
\82È
\82ñ
\82Æ
\82à
\82È
\82¢
\81D", mon_nam(mdef));
2659 if (can_blnd(&youmonst, mdef, mattk->aatyp,
2660 (struct obj *) 0)) {
2663 pline("%s can't see in there!", Monnam(mdef));
2665 pline("%s
\82Í
\96Ú
\82ª
\8c©
\82¦
\82È
\82
\82È
\82Á
\82½
\81I", mon_nam(mdef));
2667 dam += mdef->mblinded;
2670 mdef->mblinded = dam;
2677 pline_The("air around %s crackles with electricity.",
2679 pline("%s
\82Ì
\89ñ
\82è
\82Ì
\8bó
\8bC
\82Í
\93d
\8bC
\82Å
\83s
\83\8a\83s
\83\8a\82µ
\82Ä
\82¢
\82é
\81D",
2681 if (resists_elec(mdef)) {
2683 pline("%s seems unhurt.", Monnam(mdef));
2685 pline("
\82µ
\82©
\82µ
\81C%s
\82Í
\95½
\8bC
\82È
\82æ
\82¤
\82¾
\81D", Monnam(mdef));
2688 golemeffects(mdef, (int) mattk->adtyp, dam);
2694 if (resists_cold(mdef)) {
2696 pline("%s seems mildly chilly.", Monnam(mdef));
2698 pline("%s
\82Í
\97â
\82¦
\82½
\82æ
\82¤
\82¾
\81D", Monnam(mdef));
2702 pline("%s is freezing to death!", Monnam(mdef));
2704 pline("%s
\82Í
\93\80\8e\80\82µ
\82»
\82¤
\82¾
\81I", Monnam(mdef));
2705 golemeffects(mdef, (int) mattk->adtyp, dam);
2711 if (resists_fire(mdef)) {
2713 pline("%s seems mildly hot.", Monnam(mdef));
2715 pline("%s
\82Í
\92g
\82©
\82
\82È
\82Á
\82½
\82æ
\82¤
\82¾
\81D", Monnam(mdef));
2719 pline("%s is burning to a crisp!", Monnam(mdef));
2721 pline("%s
\82Í
\94R
\82¦
\82Ä
\83J
\83\89\83J
\83\89\82É
\82È
\82Á
\82½
\81I", Monnam(mdef));
2722 golemeffects(mdef, (int) mattk->adtyp, dam);
2728 xdrainenergym(mdef, TRUE);
2734 if (DEADMONSTER(mdef)) {
2736 if (DEADMONSTER(mdef)) /* not lifesaved */
2740 You("%s %s!", is_animal(youmonst.data) ? "regurgitate" : "expel",
2743 You("%s
\82ð%s
\82µ
\82½
\81I", mon_nam(mdef),
2744 is_animal(youmonst.data) ? "
\93f
\82«
\96ß" : "
\94r
\8fo");
2746 if (Slow_digestion || is_animal(youmonst.data)) {
2748 pline("Obviously, you didn't like %s taste.",
2749 s_suffix(mon_nam(mdef)));
2751 pline("
\82Ç
\82¤
\82à%s
\82Ì
\96¡
\82Í
\8dD
\82«
\82É
\82È
\82ê
\82È
\82¢
\81D",
2761 missum(mdef, mattk, wouldhavehit)
2762 register struct monst *mdef;
2763 register struct attack *mattk;
2764 boolean wouldhavehit;
2766 if (wouldhavehit) /* monk is missing due to penalty for wearing suit */
2768 Your("armor is rather cumbersome...");
2770 Your("
\96h
\8bï
\82Í
\8f
\82µ
\8e×
\96\82\82¾
\81D
\81D
\81D");
2772 if (could_seduce(&youmonst, mdef, mattk))
2774 You("pretend to be friendly to %s.", mon_nam(mdef));
2776 You("%s
\82É
\97F
\8dD
\93I
\82È
\82Ó
\82è
\82ð
\82µ
\82½
\81D", mon_nam(mdef));
2777 else if (canspotmon(mdef) && flags.verbose)
2779 You("miss %s.", mon_nam(mdef));
2781 Your("%s
\82Ö
\82Ì
\8dU
\8c\82\82Í
\8aO
\82ê
\82½
\81D", mon_nam(mdef));
2786 Your("
\89½
\8eÒ
\82©
\82Ö
\82Ì
\8dU
\8c\82\82Í
\8aO
\82ê
\82½
\81D");
2787 if (!mdef->msleeping && mdef->mcanmove)
2791 /* attack monster as a monster; returns True if mon survives */
2794 register struct monst *mon;
2796 struct attack *mattk, alt_attk;
2797 struct obj *weapon, **originalweapon;
2798 boolean altwep = FALSE, weapon_used = FALSE, odd_claw = TRUE;
2799 int i, tmp, armorpenalty, sum[NATTK], nsum = 0, dhit = 0, attknum = 0;
2800 int dieroll, multi_claw = 0;
2802 /* with just one touch/claw/weapon attack, both rings matter;
2803 with more than one, alternate right and left when checking
2804 whether silver ring causes successful hit */
2805 for (i = 0; i < NATTK; i++) {
2807 mattk = getmattk(&youmonst, mon, i, sum, &alt_attk);
2808 if (mattk->aatyp == AT_WEAP
2809 || mattk->aatyp == AT_CLAW || mattk->aatyp == AT_TUCH)
2812 multi_claw = (multi_claw > 1); /* switch from count to yes/no */
2814 for (i = 0; i < NATTK; i++) {
2815 /* sum[i] = 0; -- now done above */
2816 mattk = getmattk(&youmonst, mon, i, sum, &alt_attk);
2818 switch (mattk->aatyp) {
2820 /* if (!uwep) goto weaponless; */
2822 odd_claw = !odd_claw; /* see case AT_CLAW,AT_TUCH below */
2823 /* if we've already hit with a two-handed weapon, we don't
2824 get to make another weapon attack (note: monsters who
2825 use weapons do not have this restriction, but they also
2826 never have the opportunity to use two weapons) */
2827 if (weapon_used && sum[i - 1] && uwep && bimanual(uwep))
2829 /* Certain monsters don't use weapons when encountered as enemies,
2830 * but players who polymorph into them have hands or claws and
2831 * thus should be able to use weapons. This shouldn't prohibit
2832 * the use of most special abilities, either.
2833 * If monster has multiple claw attacks, only one can use weapon.
2836 /* Potential problem: if the monster gets multiple weapon attacks,
2837 * we currently allow the player to get each of these as a weapon
2838 * attack. Is this really desirable?
2840 /* approximate two-weapon mode; known_hitum() -> hmon() -> &c
2841 might destroy the weapon argument, but it might also already
2842 be Null, and we want to track that for passive() */
2843 originalweapon = (altwep && uswapwep) ? &uswapwep : &uwep;
2844 if (uswapwep /* set up 'altwep' flag for next iteration */
2845 /* only consider seconary when wielding one-handed primary */
2846 && uwep && (uwep->oclass == WEAPON_CLASS || is_weptool(uwep))
2848 /* only switch if not wearing shield and not at artifact;
2849 shield limitation is iffy since still get extra swings
2850 if polyform has them, but it matches twoweap behavior;
2851 twoweap also only allows primary to be an artifact, so
2852 if alternate weapon is one, don't use it */
2853 && !uarms && !uswapwep->oartifact
2854 /* only switch to uswapwep if it's a weapon */
2855 && (uswapwep->oclass == WEAPON_CLASS || is_weptool(uswapwep))
2856 /* only switch if uswapwep is not bow, arrows, or darts */
2857 && !(is_launcher(uswapwep) || is_ammo(uswapwep)
2858 || is_missile(uswapwep)) /* dart, shuriken, boomerang */
2859 /* and not two-handed and not incapable of being wielded */
2860 && !bimanual(uswapwep)
2861 && !(objects[uswapwep->otyp].oc_material == SILVER
2863 altwep = !altwep; /* toggle for next attack */
2864 weapon = *originalweapon;
2865 if (!weapon) /* no need to go beyond no-gloves to rings; not ...*/
2866 originalweapon = &uarmg; /*... subject to erosion damage */
2868 tmp = find_roll_to_hit(mon, AT_WEAP, weapon, &attknum,
2871 dhit = (tmp > dieroll || u.uswallow);
2872 /* caller must set bhitpos */
2873 if (!known_hitum(mon, weapon, &dhit, tmp,
2874 armorpenalty, mattk, dieroll)) {
2875 /* enemy dead, before any special abilities used */
2880 /* originalweapon points to an equipment slot which might
2881 now be empty if the weapon was destroyed during the hit;
2882 passive(,weapon,...) won't call passive_obj() in that case */
2883 weapon = *originalweapon; /* might receive passive erosion */
2884 /* might be a worm that gets cut in half; if so, early return */
2885 if (m_at(u.ux + u.dx, u.uy + u.dy) != mon) {
2886 i = NATTK; /* skip additional attacks */
2887 /* proceed with uswapwep->cursed check, then exit loop */
2890 /* Do not print "You hit" message; known_hitum already did it. */
2891 if (dhit && mattk->adtyp != AD_SPEL && mattk->adtyp != AD_PHYS)
2892 sum[i] = damageum(mon, mattk, 0);
2895 if (uwep && !cantwield(youmonst.data) && !weapon_used)
2899 if (uwep && youmonst.data->mlet == S_LICH && !weapon_used)
2908 tmp = find_roll_to_hit(mon, mattk->aatyp, (struct obj *) 0,
2909 &attknum, &armorpenalty);
2911 dhit = (tmp > dieroll || u.uswallow);
2913 int compat, specialdmg;
2914 long silverhit = 0L;
2915 #if 0 /*JP*//*
\82·
\82×
\82Ä
\81u
\8dU
\8c\82\82µ
\82½
\81v
\82É
\82·
\82é */
2916 const char *verb = 0; /* verb or body part */
2920 && (compat = could_seduce(&youmonst, mon, mattk)) != 0) {
2923 (mon->mcansee && haseyes(mon->data)) ? "smile at"
2926 (compat == 2) ? "engagingly" : "seductively");
2928 You("%s
\82Ö%s%s
\81D",
2930 compat == 2 ? "
\96£
\97Í
\93I
\82É" : "
\97U
\98f
\93I
\82É",
2931 mon->mcansee && haseyes(mon->data) ? "
\94÷
\8fÎ
\82Ý
\82©
\82¯
\82½"
2932 : "
\98b
\82µ
\82©
\82¯
\82½");
2934 /* doesn't anger it; no wakeup() */
2935 sum[i] = damageum(mon, mattk, 0);
2940 specialdmg = 0; /* blessed and/or silver bonus */
2941 switch (mattk->aatyp) {
2944 /* verb=="claws" may be overridden below */
2946 verb = (mattk->aatyp == AT_TUCH) ? "touch" : "claws";
2948 /* decide if silver-hater will be hit by silver ring(s);
2949 for 'multi_claw' where attacks alternate right/left,
2950 assume 'even' claw or touch attacks use right hand
2951 or paw, 'odd' ones use left for ring interaction;
2952 even vs odd is based on actual attacks rather
2953 than on index into mon->dat->mattk[] so that {bite,
2954 claw,claw} instead of {claw,claw,bite} doesn't
2955 make poly'd hero mysteriously become left-handed */
2956 odd_claw = !odd_claw;
2957 specialdmg = special_dmgval(&youmonst, mon,
2959 | ((odd_claw || !multi_claw)
2961 | ((!odd_claw || !multi_claw)
2966 /* assumes mind flayer's tentacles-on-head rather
2967 than sea monster's tentacle-as-arm */
2976 specialdmg = special_dmgval(&youmonst, mon, W_ARMF,
2981 verb = "head butt"; /* mbodypart(mon,HEAD)=="head" */
2982 /* hypothetical; if any form with a head-butt attack
2983 could wear a helmet, it would hit shades when
2984 wearing a blessed (or silver) one */
2986 specialdmg = special_dmgval(&youmonst, mon, W_ARMH,
3005 if (mon->data == &mons[PM_SHADE] && !specialdmg) {
3007 if (!strcmp(verb, "hit")
3008 || (mattk->aatyp == AT_CLAW && humanoid(mon->data)))
3012 Your("%s %s harmlessly through %s.",
3013 verb, vtense(verb, "pass"), mon_nam(mon));
3015 Your("
\8dU
\8c\82\82Í%s
\82ð
\92Ê
\82è
\82Ê
\82¯
\82½
\81D",
3019 if (mattk->aatyp == AT_TENT) {
3021 Your("tentacles suck %s.", mon_nam(mon));
3023 Your("
\90G
\8eè
\82ª%s
\82Ì
\91Ì
\89t
\82ð
\8bz
\82¢
\82Æ
\82Á
\82½
\81D", mon_nam(mon));
3026 if (mattk->aatyp == AT_CLAW)
3027 verb = "hit"; /* not "claws" */
3030 You("%s %s.", verb, mon_nam(mon));
3032 You("%s
\82ð
\8dU
\8c\82\82µ
\82½
\81D", mon_nam(mon));
3034 if (silverhit && flags.verbose)
3035 silver_sears(&youmonst, mon, silverhit);
3037 sum[i] = damageum(mon, mattk, specialdmg);
3039 } else { /* !dhit */
3040 missum(mon, mattk, (tmp + armorpenalty > dieroll));
3046 long silverhit = 0L;
3047 boolean byhand = hug_throttles(&mons[u.umonnum]), /* rope golem */
3048 unconcerned = (byhand && !can_be_strangled(mon));
3050 if (sticks(mon->data) || u.uswallow || notonhead
3051 || (byhand && (uwep || !has_head(mon->data)))) {
3052 /* can't hold a holder due to subsequent ambiguity over
3053 who is holding whom; can't hug engulfer from inside;
3054 can't hug a worm tail (would immobilize entire worm!);
3055 byhand: can't choke something that lacks a head;
3056 not allowed to make a choking hug if wielding a weapon
3057 (but might have grabbed w/o weapon, then wielded one,
3058 and may even be attacking a different monster now) */
3059 if (byhand && uwep && u.ustuck
3060 && !(sticks(u.ustuck->data) || u.uswallow))
3062 continue; /* not 'break'; bypass passive counter-attack */
3064 /* automatic if prev two attacks succeed, or if
3065 already grabbed in a previous attack */
3068 /* choking hug/throttling grab uses hands (gloves or rings);
3069 normal hug uses outermost of cloak/suit/shirt */
3070 specialdmg = special_dmgval(&youmonst, mon,
3071 byhand ? (W_ARMG | W_RINGL | W_RINGR)
3072 : (W_ARMC | W_ARM | W_ARMU),
3075 /* strangling something which can't be strangled */
3076 if (mattk != &alt_attk) {
3080 /* change damage to 1d1; not strangling but still
3081 doing [minimal] physical damage to victim's body */
3082 mattk->damn = mattk->damd = 1;
3083 /* don't give 'unconcerned' feedback if there is extra damage
3084 or if it is nearly destroyed or if creature doesn't have
3085 the mental ability to be concerned in the first place */
3086 if (specialdmg || mindless(mon->data)
3087 || mon->mhp <= 1 + max(u.udaminc, 1))
3088 unconcerned = FALSE;
3090 if (mon->data == &mons[PM_SHADE]) {
3092 const char *verb = byhand ? "grasp" : "hug";
3095 /* hugging a shade; successful if blessed outermost armor
3096 for normal hug, or blessed gloves or silver ring(s) for
3097 choking hug; deals damage but never grabs hold */
3100 You("%s %s%s", verb, mon_nam(mon), exclam(specialdmg));
3102 You("%s
\82ð
\82Â
\82©
\82ñ
\82¾%s", mon_nam(mon), exclam(specialdmg));
3104 if (silverhit && flags.verbose)
3105 silver_sears(&youmonst, mon, silverhit);
3106 sum[i] = damageum(mon, mattk, specialdmg);
3109 Your("%s passes harmlessly through %s.",
3110 verb, mon_nam(mon));
3112 You("%s
\82ð
\82Â
\82©
\82Ü
\82¦
\82æ
\82¤
\82Æ
\82µ
\82½
\82ª
\92Ê
\82è
\82Ê
\82¯
\82½
\81D",
3118 /* hug attack against ordinary foe */
3119 if (mon == u.ustuck) {
3121 pline("%s is being %s%s.", Monnam(mon),
3122 byhand ? "throttled" : "crushed",
3123 /* extra feedback for non-breather being choked */
3124 unconcerned ? " but doesn't seem concerned" : "");
3126 pline("%s
\82Í%s%s
\81D", Monnam(mon),
3127 byhand ? "
\8eñ
\82ð
\8di
\82ß
\82ç
\82ê
\82Ä
\82¢
\82é" : "
\89\9f\82µ
\82Â
\82Ô
\82³
\82ê
\82Ä
\82¢
\82é",
3128 /* extra feedback for non-breather being choked */
3129 unconcerned ? "
\82ª
\81C
\8bC
\82É
\82µ
\82Ä
\82¢
\82È
\82¢
\82æ
\82¤
\82¾" : "");
3131 if (silverhit && flags.verbose)
3132 silver_sears(&youmonst, mon, silverhit);
3133 sum[i] = damageum(mon, mattk, specialdmg);
3134 } else if (i >= 2 && sum[i - 1] && sum[i - 2]) {
3135 /* in case we're hugging a new target while already
3136 holding something else; yields feedback
3137 "<u.ustuck> is no longer in your clutches" */
3138 if (u.ustuck && u.ustuck != mon)
3141 You("grab %s!", mon_nam(mon));
3143 You("%s
\82ð
\82Â
\82©
\82Ü
\82¦
\82½
\81I", mon_nam(mon));
3145 if (silverhit && flags.verbose)
3146 silver_sears(&youmonst, mon, silverhit);
3147 sum[i] = damageum(mon, mattk, specialdmg);
3149 break; /* AT_HUGS */
3152 case AT_EXPL: /* automatic hit if next to */
3155 sum[i] = explum(mon, mattk);
3159 tmp = find_roll_to_hit(mon, mattk->aatyp, (struct obj *) 0,
3160 &attknum, &armorpenalty);
3161 if ((dhit = (tmp > rnd(20 + i)))) {
3163 if (mon->data == &mons[PM_SHADE])
3165 Your("attempt to surround %s is harmless.", mon_nam(mon));
3167 You("%s
\82ð
\88ù
\82Ý
\82±
\82à
\82¤
\82Æ
\82µ
\82½
\82ª
\8e¸
\94s
\82µ
\82½
\81D", mon_nam(mon));
3169 sum[i] = gulpum(mon, mattk);
3170 if (sum[i] == 2 && (mon->data->mlet == S_ZOMBIE
3171 || mon->data->mlet == S_MUMMY)
3172 && rn2(5) && !Sick_resistance) {
3174 You_feel("%ssick.", (Sick) ? "very " : "");
3176 You_feel("%s
\8bC
\95ª
\82ª
\88«
\82¢
\81D", (Sick) ? "
\82Æ
\82Ä
\82à" : "");
3177 mdamageu(mon, rnd(8));
3181 missum(mon, mattk, FALSE);
3186 /* No check for uwep; if wielding nothing we want to
3187 * do the normal 1-2 points bare hand damage...
3189 if ((youmonst.data->mlet == S_KOBOLD
3190 || youmonst.data->mlet == S_ORC
3191 || youmonst.data->mlet == S_GNOME) && !weapon_used)
3198 /* Not break--avoid passive attacks from enemy */
3202 case AT_GAZE: /* all done using #monster command */
3206 default: /* Strange... */
3207 impossible("strange attack of yours (%d)", mattk->aatyp);
3210 u.mh = -1; /* dead in the current form */
3215 (void) passive(mon, weapon, 1, 0, mattk->aatyp, FALSE);
3216 nsum = 0; /* return value below used to be 'nsum > 0' */
3218 (void) passive(mon, weapon, sum[i], 1, mattk->aatyp, FALSE);
3222 /* don't use sum[i] beyond this point;
3223 'i' will be out of bounds if we get here via 'goto' */
3225 /* when using dual weapons, cursed secondary weapon doesn't weld,
3226 it gets dropped; do the same when multiple AT_WEAP attacks
3228 if (uswapwep && weapon == uswapwep && weapon->cursed) {
3230 break; /* don't proceed with additional attacks */
3232 /* stop attacking if defender has died;
3233 needed to defer this until after uswapwep->cursed check */
3234 if (DEADMONSTER(mon))
3237 break; /* No extra attacks if no longer a monster */
3239 break; /* If paralyzed while attacking, i.e. floating eye */
3241 /* return value isn't used, but make it match hitum()'s */
3242 return !DEADMONSTER(mon);
3245 /* Special (passive) attacks on you by monsters done here.
3248 passive(mon, weapon, mhit, malive, aatyp, wep_was_destroyed)
3250 struct obj *weapon; /* uwep or uswapwep or uarmg or uarmf or Null */
3254 boolean wep_was_destroyed;
3256 register struct permonst *ptr = mon->data;
3257 register int i, tmp;
3261 return (malive | mhit); /* no passive attacks */
3262 if (ptr->mattk[i].aatyp == AT_NONE)
3263 break; /* try this one */
3265 /* Note: tmp not always used */
3266 if (ptr->mattk[i].damn)
3267 tmp = d((int) ptr->mattk[i].damn, (int) ptr->mattk[i].damd);
3268 else if (ptr->mattk[i].damd)
3269 tmp = d((int) mon->m_lev + 1, (int) ptr->mattk[i].damd);
3273 /* These affect you even if they just died.
3275 switch (ptr->mattk[i].adtyp) {
3277 if (mhit && !mon->mcan && weapon) {
3278 if (aatyp == AT_KICK) {
3279 if (uarmf && !rn2(6))
3280 (void) erode_obj(uarmf, xname(uarmf), ERODE_BURN,
3281 EF_GREASE | EF_VERBOSE);
3282 } else if (aatyp == AT_WEAP || aatyp == AT_CLAW
3283 || aatyp == AT_MAGC || aatyp == AT_TUCH)
3284 passive_obj(mon, weapon, &(ptr->mattk[i]));
3288 if (mhit && rn2(2)) {
3289 if (Blind || !flags.verbose)
3291 You("are splashed!");
3293 You("
\89½
\82©
\82ð
\97\81\82Ñ
\82¹
\82ç
\82ê
\82½
\81I");
3296 You("are splashed by %s %s!", s_suffix(mon_nam(mon)),
3299 You("%s
\82Ì%s
\82ð
\97\81\82Ñ
\82¹
\82ç
\82ê
\82½
\81I", mon_nam(mon),
3303 if (!Acid_resistance)
3306 erode_armor(&youmonst, ERODE_CORRODE);
3308 if (mhit && weapon) {
3309 if (aatyp == AT_KICK) {
3310 if (uarmf && !rn2(6))
3311 (void) erode_obj(uarmf, xname(uarmf), ERODE_CORRODE,
3312 EF_GREASE | EF_VERBOSE);
3313 } else if (aatyp == AT_WEAP || aatyp == AT_CLAW
3314 || aatyp == AT_MAGC || aatyp == AT_TUCH)
3315 passive_obj(mon, weapon, &(ptr->mattk[i]));
3317 exercise(A_STR, FALSE);
3320 if (mhit) { /* successful attack */
3321 long protector = attk_protection((int) aatyp);
3323 /* hero using monsters' AT_MAGC attack is hitting hand to
3324 hand rather than casting a spell */
3325 if (aatyp == AT_MAGC)
3328 if (protector == 0L /* no protection */
3329 || (protector == W_ARMG && !uarmg
3330 && !uwep && !wep_was_destroyed)
3331 || (protector == W_ARMF && !uarmf)
3332 || (protector == W_ARMH && !uarmh)
3333 || (protector == (W_ARMC | W_ARMG) && (!uarmc || !uarmg))) {
3334 if (!Stone_resistance
3335 && !(poly_when_stoned(youmonst.data)
3336 && polymon(PM_STONE_GOLEM))) {
3337 done_in_by(mon, STONING); /* "You turn to stone..." */
3344 if (mhit && !mon->mcan && weapon) {
3345 if (aatyp == AT_KICK) {
3347 (void) erode_obj(uarmf, xname(uarmf), ERODE_RUST,
3348 EF_GREASE | EF_VERBOSE);
3349 } else if (aatyp == AT_WEAP || aatyp == AT_CLAW
3350 || aatyp == AT_MAGC || aatyp == AT_TUCH)
3351 passive_obj(mon, weapon, &(ptr->mattk[i]));
3355 if (mhit && !mon->mcan && weapon) {
3356 if (aatyp == AT_KICK) {
3358 (void) erode_obj(uarmf, xname(uarmf), ERODE_CORRODE,
3359 EF_GREASE | EF_VERBOSE);
3360 } else if (aatyp == AT_WEAP || aatyp == AT_CLAW
3361 || aatyp == AT_MAGC || aatyp == AT_TUCH)
3362 passive_obj(mon, weapon, &(ptr->mattk[i]));
3366 /* wrath of gods for attacking Oracle */
3368 shieldeff(u.ux, u.uy);
3370 pline("A hail of magic missiles narrowly misses you!");
3372 pline("
\96\82\96@
\82Ì
\96î
\82Ì
\89J
\82ª
\82©
\82·
\82ß
\82Ä
\82¢
\82Á
\82½
\81I");
3375 You("are hit by magic missiles appearing from thin air!");
3377 pline("
\93Ë
\94@
\8bó
\92\86\82É
\8c»
\82í
\82ê
\82½
\96\82\96@
\82Ì
\96î
\82ª
\96½
\92\86\82µ
\82½
\81I");
3381 case AD_ENCH: /* KMH -- remove enchantment (disenchanter) */
3383 if (aatyp == AT_KICK) {
3386 } else if (aatyp == AT_BITE || aatyp == AT_BUTT
3387 || (aatyp >= AT_STNG && aatyp < AT_WEAP)) {
3388 break; /* no object involved */
3390 passive_obj(mon, weapon, &(ptr->mattk[i]));
3397 /* These only affect you if they still live.
3399 if (malive && !mon->mcan && rn2(3)) {
3400 switch (ptr->mattk[i].adtyp) {
3402 if (ptr == &mons[PM_FLOATING_EYE]) {
3403 if (!canseemon(mon)) {
3408 if (ureflects("%s gaze is reflected by your %s.",
3409 s_suffix(Monnam(mon)))) {
3411 if (ureflects("%s
\82Ì
\82É
\82ç
\82Ý
\82Í%s
\82É
\82æ
\82Á
\82Ä
\94½
\8eË
\82³
\82ê
\82½
\81D",
3415 } else if (Free_action) {
3417 You("momentarily stiffen under %s gaze!",
3418 s_suffix(mon_nam(mon)));
3420 You("%s
\82Ì
\82É
\82ç
\82Ý
\82Å
\88ê
\8fu
\8dd
\92¼
\82µ
\82½
\81I",
3423 } else if (Hallucination && rn2(4)) {
3425 pline("%s looks %s%s.", Monnam(mon),
3426 !rn2(2) ? "" : "rather ",
3427 !rn2(2) ? "numb" : "stupified");
3429 pline("%s
\82Í%s
\82Î
\82©
\82É
\82È
\82Á
\82½
\82æ
\82¤
\82¾
\81D", Monnam(mon),
3430 !rn2(2) ? "" : "
\8f
\82µ");
3434 You("are frozen by %s gaze!", s_suffix(mon_nam(mon)));
3436 You("%s
\82Ì
\82É
\82ç
\82Ý
\82Å
\93®
\82¯
\82È
\82
\82È
\82Á
\82½
\81I", mon_nam(mon));
3437 nomul((ACURR(A_WIS) > 12 || rn2(4)) ? -tmp : -127);
3439 multi_reason = "frozen by a monster's gaze";
3441 multi_reason = "
\89ö
\95¨
\82Ì
\82É
\82ç
\82Ý
\82Å
\8dd
\92¼
\82µ
\82Ä
\82¢
\82é
\8e\9e\82É";
3446 pline("%s cannot defend itself.",
3447 Adjmonnam(mon, "blind"));
3449 pline("%s
\82Í
\96h
\8cä
\82Å
\82«
\82È
\82¢
\81D",
3450 Adjmonnam(mon,"
\96Ú
\82Ì
\8c©
\82¦
\82È
\82¢"));
3455 } else if (Free_action) {
3457 You("momentarily stiffen.");
3459 You("
\88ê
\8fu
\8dd
\92¼
\82µ
\82½
\81D");
3460 } else { /* gelatinous cube */
3462 You("are frozen by %s!", mon_nam(mon));
3464 You("%s
\82É
\82æ
\82Á
\82Ä
\93®
\82¯
\82È
\82
\82È
\82Á
\82½
\81I", mon_nam(mon));
3465 nomovemsg = You_can_move_again;
3468 multi_reason = "frozen by a monster";
3470 multi_reason = "
\89ö
\95¨
\82É
\82æ
\82Á
\82Ä
\8dd
\92¼
\82µ
\82Ä
\82¢
\82é
\8e\9e\82É";
3471 exercise(A_DEX, FALSE);
3474 case AD_COLD: /* brown mold or blue jelly */
3475 if (monnear(mon, u.ux, u.uy)) {
3476 if (Cold_resistance) {
3477 shieldeff(u.ux, u.uy);
3479 You_feel("a mild chill.");
3481 You("
\8a¦
\82³
\82ð
\8a´
\82¶
\82½
\81D");
3482 ugolemeffects(AD_COLD, tmp);
3486 You("are suddenly very cold!");
3488 You("
\93Ë
\91R
\81C
\96Ò
\97ó
\82É
\8a¦
\82
\82È
\82Á
\82½
\81I");
3490 /* monster gets stronger with your heat! */
3491 mon->mhp += tmp / 2;
3492 if (mon->mhpmax < mon->mhp)
3493 mon->mhpmax = mon->mhp;
3494 /* at a certain point, the monster will reproduce! */
3495 if (mon->mhpmax > ((int) (mon->m_lev + 1) * 8))
3496 (void) split_mon(mon, &youmonst);
3499 case AD_STUN: /* specifically yellow mold */
3501 make_stunned((long) tmp, TRUE);
3504 if (monnear(mon, u.ux, u.uy)) {
3505 if (Fire_resistance) {
3506 shieldeff(u.ux, u.uy);
3508 You_feel("mildly warm.");
3510 You("
\92g
\82©
\82³
\82ð
\8a´
\82¶
\82½
\81D");
3511 ugolemeffects(AD_FIRE, tmp);
3515 You("are suddenly very hot!");
3517 You("
\93Ë
\91R
\81C
\96Ò
\97ó
\82É
\94M
\82
\82È
\82Á
\82½
\81I");
3518 mdamageu(mon, tmp); /* fire damage */
3522 if (Shock_resistance) {
3523 shieldeff(u.ux, u.uy);
3525 You_feel("a mild tingle.");
3527 You("
\83s
\83\8a\83s
\83\8a\82Æá
\83\82ê
\82ð
\8a´
\82¶
\82½
\81D");
3528 ugolemeffects(AD_ELEC, tmp);
3532 You("are jolted with electricity!");
3534 You("
\93d
\8bC
\83V
\83\87\83b
\83N
\82ð
\82¤
\82¯
\82½
\81I");
3541 return (malive | mhit);
3545 * Special (passive) attacks on an attacking object by monsters done here.
3546 * Assumes the attack was successful.
3549 passive_obj(mon, obj, mattk)
3551 struct obj *obj; /* null means pick uwep, uswapwep or uarmg */
3552 struct attack *mattk; /* null means we find one internally */
3554 struct permonst *ptr = mon->data;
3557 /* [this first bit is obsolete; we're not called with Null anymore] */
3558 /* if caller hasn't specified an object, use uwep, uswapwep or uarmg */
3560 obj = (u.twoweap && uswapwep && !rn2(2)) ? uswapwep : uwep;
3561 if (!obj && mattk->adtyp == AD_ENCH)
3562 obj = uarmg; /* no weapon? then must be gloves */
3564 return; /* no object to affect */
3567 /* if caller hasn't specified an attack, find one */
3571 return; /* no passive attacks */
3572 if (ptr->mattk[i].aatyp == AT_NONE)
3573 break; /* try this one */
3575 mattk = &(ptr->mattk[i]);
3578 switch (mattk->adtyp) {
3580 if (!rn2(6) && !mon->mcan
3581 /* steam vortex: fire resist applies, fire damage doesn't */
3582 && mon->data != &mons[PM_STEAM_VORTEX]) {
3583 (void) erode_obj(obj, NULL, ERODE_BURN, EF_NONE);
3588 (void) erode_obj(obj, NULL, ERODE_CORRODE, EF_GREASE);
3593 (void) erode_obj(obj, (char *) 0, ERODE_RUST, EF_GREASE);
3598 (void) erode_obj(obj, (char *) 0, ERODE_CORRODE, EF_GREASE);
3603 if (drain_item(obj, TRUE) && carried(obj)
3604 && (obj->known || obj->oclass == ARMOR_CLASS)) {
3606 pline("%s less effective.", Yobjnam2(obj, "seem"));
3608 Your("%s
\82©
\82ç
\96\82\97Í
\82ª
\8fÁ
\82¦
\82½
\82æ
\82¤
\82¾
\81D", xname(obj));
3620 /* Note: caller must ascertain mtmp is mimicking... */
3622 stumble_onto_mimic(mtmp)
3626 const char *fmt = "Wait! That's %s!", *generic = "a monster", *what = 0;
3628 const char *fmt = "
\82¿
\82å
\82Á
\82Æ
\82Ü
\82Á
\82½
\81I%s
\82¾
\81I", *generic = "
\89ö
\95¨", *what = 0;
3630 if (!u.ustuck && !mtmp->mflee && dmgtype(mtmp->data, AD_STCK))
3635 what = generic; /* with default fmt */
3636 else if (M_AP_TYPE(mtmp) == M_AP_MONSTER)
3637 what = a_monnam(mtmp); /* differs from what was sensed */
3639 int glyph = levl[u.ux + u.dx][u.uy + u.dy].glyph;
3641 if (glyph_is_cmap(glyph) && (glyph_to_cmap(glyph) == S_hcdoor
3642 || glyph_to_cmap(glyph) == S_vcdoor))
3644 fmt = "The door actually was %s!";
3646 fmt = "
\94à
\82Í
\8eÀ
\8dÛ
\82É
\82Í%s
\82¾
\82Á
\82½
\81I";
3647 else if (glyph_is_object(glyph) && glyph_to_obj(glyph) == GOLD_PIECE)
3649 fmt = "That gold was %s!";
3651 fmt = "
\8bà
\89Ý
\82Í%s
\82¾
\82Á
\82½
\81I";
3653 /* cloned Wiz starts out mimicking some other monster and
3654 might make himself invisible before being revealed */
3655 if (mtmp->minvis && !See_invisible)
3658 what = a_monnam(mtmp);
3663 wakeup(mtmp, FALSE); /* clears mimicking */
3664 /* if hero is blind, wakeup() won't display the monster even though
3665 it's no longer concealed */
3666 if (!canspotmon(mtmp)
3667 && !glyph_is_invisible(levl[mtmp->mx][mtmp->my].glyph))
3668 map_invisible(mtmp->mx, mtmp->my);
3675 char *hands = makeplural(body_part(HAND));
3677 if (!u.umconf || mon->mconf)
3679 if (u.umconf == 1) {
3682 Your("%s stop tingling.", hands);
3684 Your("%s
\82Ìá
\83\82ê
\82ª
\82Æ
\82ê
\82½
\81D", hands);
3687 Your("%s stop glowing %s.", hands, hcolor(NH_RED));
3689 Your("%s
\82Ì%s
\8bP
\82«
\82Í
\82È
\82
\82È
\82Á
\82½
\81D", hands, hcolor(NH_RED));
3693 pline_The("tingling in your %s lessens.", hands);
3695 pline("%s
\82Ìá
\83\82ê
\82ª
\82Æ
\82ê
\82Ä
\82«
\82½
\81D",hands);
3698 Your("%s no longer glow so brightly %s.", hands, hcolor(NH_RED));
3700 Your("%s
\82Ì%s
\8bP
\82«
\82ª
\82È
\82
\82È
\82Á
\82Ä
\82«
\82½
\81D",hands, hcolor(NH_RED));
3706 flash_hits_mon(mtmp, otmp)
3708 struct obj *otmp; /* source of flash */
3710 int tmp, amt, res = 0, useeit = canseemon(mtmp);
3712 if (mtmp->msleeping) {
3713 mtmp->msleeping = 0;
3716 pline_The("flash awakens %s.", mon_nam(mtmp));
3718 pline("
\91M
\8cõ
\82Å%s
\82ª
\96Ú
\82ð
\8ao
\82Ü
\82µ
\82½
\81D", mon_nam(mtmp));
3721 } else if (mtmp->data->mlet != S_LIGHT) {
3722 if (!resists_blnd(mtmp)) {
3723 tmp = dist2(otmp->ox, otmp->oy, mtmp->mx, mtmp->my);
3726 pline("%s is blinded by the flash!", Monnam(mtmp));
3728 pline("%s
\82Í
\91M
\8cõ
\82Å
\96Ú
\82ª
\8c©
\82¦
\82È
\82
\82È
\82Á
\82½
\81I", Monnam(mtmp));
3731 if (mtmp->data == &mons[PM_GREMLIN]) {
3732 /* Rule #1: Keep them out of the light. */
3733 amt = otmp->otyp == WAN_LIGHT ? d(1 + otmp->spe, 4)
3734 : rn2(min(mtmp->mhp, 4));
3735 light_hits_gremlin(mtmp, amt);
3737 if (!DEADMONSTER(mtmp)) {
3738 if (!context.mon_moving)
3739 setmangry(mtmp, TRUE);
3740 if (tmp < 9 && !mtmp->isshk && rn2(4))
3741 monflee(mtmp, rn2(4) ? rnd(100) : 0, FALSE, TRUE);
3743 mtmp->mblinded = (tmp < 3) ? 0 : rnd(1 + 50 / tmp);
3751 light_hits_gremlin(mon, dmg)
3756 pline("%s %s!", Monnam(mon),
3757 (dmg > mon->mhp / 2) ? "wails in agony" : "cries out in pain");
3759 pline("%s
\82Í%s
\81I", Monnam(mon),
3760 (dmg > mon->mhp / 2) ? "
\8bê
\92É
\82Ì
\90º
\82ð
\82 \82°
\82½" : "
\8c\83\92É
\82Å
\8b©
\82ñ
\82¾");
3763 wake_nearto(mon->mx, mon->my, 30);
3764 if (DEADMONSTER(mon)) {
3765 if (context.mon_moving)
3766 monkilled(mon, (char *) 0, AD_BLND);
3769 } else if (cansee(mon->mx, mon->my) && !canspotmon(mon)) {
3770 map_invisible(mon->mx, mon->my);